28 Commits

Author SHA1 Message Date
Pranav Vashi
3ad971a4d0 dolby: Exempt installing package in clone or private space
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:34 +09:00
someone5678
faff5eda60 XiaomiEuicc: Don't fatally crash when euicc package is not exists
Log:
01-18 20:01:59.274  5014  5014 E AndroidRuntime: FATAL EXCEPTION: main
01-18 20:01:59.274  5014  5014 E AndroidRuntime: Process: org.lineageos.euicc, PID: 5014
01-18 20:01:59.274  5014  5014 E AndroidRuntime: java.lang.RuntimeException: Unable to start receiver org.lineageos.euicc.BootCompletedReceiver: java.lang.IllegalArgumentException: Unknown package: com.google.euiccpixel
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.app.ActivityThread.handleReceiver(ActivityThread.java:4500)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.app.ActivityThread.-$$Nest$mhandleReceiver(Unknown Source:0)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2282)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:205)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:294)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8291)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Unknown package: com.google.euiccpixel
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Parcel.createExceptionOrNull(Parcel.java:3061)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Parcel.createException(Parcel.java:3041)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:3024)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2966)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.content.pm.IPackageManager$Stub$Proxy.setApplicationEnabledSetting(IPackageManager.java:6107)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.app.ApplicationPackageManager.setApplicationEnabledSetting(ApplicationPackageManager.java:3185)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at org.lineageos.euicc.EuiccDisabler.enableOrDisableEuicc(EuiccDisabler.kt:43)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at org.lineageos.euicc.BootCompletedReceiver.onReceive(BootCompletedReceiver.kt:16)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	at android.app.ActivityThread.handleReceiver(ActivityThread.java:4491)
01-18 20:01:59.274  5014  5014 E AndroidRuntime: 	... 9 more

Change-Id: I86880342693c92afddf09dbe8db22255ca93c355
2025-08-30 08:17:34 +09:00
Marat Budkevich
4a9b9c64a3 dolby: translate strings to Russian 2025-08-30 08:17:30 +09:00
someone5678
effd1112ce XiaomiEuicc: Move to priv-app and grant required permissions
* We are trying to use functions that required
  priviledged permissions
  (e.g. android.permission.CHANGE_COMPONENT_ENABLED_STATE)

* To make these functions correctly, move this app to priv-app

* Signing with platform key
* Add android.permission.CHANGE_COMPONENT_ENABLED_STATE
* Indicates and grant WRITE_EMBEDDED_SUBSCRIPTIONS permission
* Whitelist Hidden API

Log:
08-26 21:24:38.610  4898  4898 E AndroidRuntime: FATAL EXCEPTION: main
08-26 21:24:38.610  4898  4898 E AndroidRuntime: Process: co.aospa.euicc, PID: 4898
08-26 21:24:38.610  4898  4898 E AndroidRuntime: java.lang.RuntimeException: Unable to start receiver co.aospa.euicc.BootCompletedReceiver: java.lang.SecurityException: Attempt to change component state; pid=4898, uid=10191, package=com.google.android.euicc
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.app.ActivityThread.handleReceiver(ActivityThread.java:4316)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.app.ActivityThread.-$$Nest$mhandleReceiver(Unknown Source:0)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2153)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:201)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:288)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7960)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:942)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: Caused by: java.lang.SecurityException: Attempt to change component state; pid=4898, uid=10191, package=com.google.android.euicc
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Parcel.createExceptionOrNull(Parcel.java:3011)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Parcel.createException(Parcel.java:2995)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2978)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2920)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.content.pm.IPackageManager$Stub$Proxy.setApplicationEnabledSetting(IPackageManager.java:5938)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.app.ApplicationPackageManager.setApplicationEnabledSetting(ApplicationPackageManager.java:3177)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at co.aospa.euicc.EuiccDisabler.enableOrDisableEuicc(EuiccDisabler.kt:43)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at co.aospa.euicc.BootCompletedReceiver.onReceive(BootCompletedReceiver.kt:16)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.app.ActivityThread.handleReceiver(ActivityThread.java:4307)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	... 9 more
08-26 21:24:38.610  4898  4898 E AndroidRuntime: Caused by: android.os.RemoteException: Remote stack trace:
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at com.android.server.pm.PackageManagerService.setEnabledSettings(PackageManagerService.java:3784)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at com.android.server.pm.PackageManagerService.-$$Nest$msetEnabledSettings(Unknown Source:0)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at com.android.server.pm.PackageManagerService$IPackageManagerImpl.setApplicationEnabledSetting(PackageManagerService.java:5527)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2971)
08-26 21:24:38.610  4898  4898 E AndroidRuntime: 	at com.android.server.pm.PackageManagerService$IPackageManagerImpl.onTransact(PackageManagerService.java:6042)
08-26 21:24:38.610  4898  4898 E AndroidRuntime:

Change-Id: Ied5d023e0f403e9c6f4908c59bcbb538aeef4574
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:30 +09:00
Peter Cai
a7d76e22ab XiaomiEuicc: Disable EuiccGoogle when GMS and GSF are not installed
* This avoids EuiccGoogle / GoogleCarrierServices crashing, taking the
  whole telephony stack with them when no GMS or GSF is installed.
* This approach is no-op when GAPPS add-on is flashed before the first
  boot, and thus should not cause issues with eSIM when GAPPS is
  flashed.
* With microG, this also works after installing the microG GMS & GSF
  packages and rebooting, although manual activation of the eSIM is
  needed via Settings - Network.
* The only downside is that users will still see one or two crashes
  during the first boot because our application only starts after the
  device is booted.

Change-Id: Ice053b623d8f4a8e3783d82ffe0dc67f2cba558e
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:30 +09:00
Bruno Martins
112b6e65a5 Introduce XiaomiEuicc
This is a companion app for EuiccGoogle (SIM Manager), that basically
sends over the mapping of the SIM slots and sets proper SIM tray
illustration (props to Yuri for the lottie animations).

For the time being it only includes the mappings for one of the
Xiaoi 12T Pro models (22081212UG).

Change-Id: I09db5d6a9acbf05bf82803682572aeae54337c1b
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:30 +09:00
Adithya R
66b7e5f0bd dolby: Add intelligent equalizer setting
Move preference-related classes to a new package while we're at it,
to reduce code clutter.

Change-Id: I2430e8ab9b6758503ce1777ec985a3e400b55b8e
2025-08-30 08:17:30 +09:00
Pranav Vashi
06f019bf69 dolby: Remove deprecated PlainTooltipBox
Change-Id: I70ffff5ba30c5eeaff431e46c82eaf05d46e4cb0
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:30 +09:00
Adithya R
77abe718c0 dolby: Introduce graphic equalizer
Squashed:

dolby: Refresh preset name on main screen

Change-Id: I96783e2a03c384f031787f4cc9140f7d64dadb2f
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

Change-Id: I38ee6ce594e5671af42afc3d4bf0f004329482b9
2025-08-30 08:17:30 +09:00
Pranav Vashi
c9a5a86f52 dolby: Override AudioFx
Change-Id: I8523c10fdec7809f2872db82d85e89d076ae582a
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:30 +09:00
Bruno Martins
70b0bfc610 dolby: Use all shared resources from devicesettings
Change-Id: Icd7f381c574ea36eb4d797cefd60ba9f1a0941bd
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-08-30 08:17:30 +09:00
basamaryan
e079e41b81 dolby: Fix build with kotlinc 1.9.0
Reformat the code while at it

Change-Id: I4f9fdc9d25eb57240612cff1b3bef3663014f9a8
2025-08-30 08:17:30 +09:00
Michael Bestas
fa5a6884ca dolby: Convert to SwitchPreferenceCompat
Change-Id: Ic1cbaba37d499da1855af9c3930f2df426e2d3af
2025-08-30 08:17:30 +09:00
Chaohui Wang
b0d195100d dolby: Migrate to CompoundButton.OnCheckedChangeListener
Switch and SwitchCompat are both CompoundButton.

Using CompoundButton in Java will helps migration in the future.

Bug: 306658427 | AOSP | AOSP
Test: manual - check Settings pages
Test: m RunSettingsLibRoboTests
Change-Id: I85a70d4c504d8584030ea4a058f30d74206ab835
2025-08-30 08:17:30 +09:00
Peter Kalauskas
49a47612f7 dolby: Enable use_resource_processor for all sysui deps
This will make the build faster

Test: m checkbuild
Bug: 295208392
Change-Id: I0c1bd901429bbe3bf81c1530e156735f8637a96e
2025-08-30 08:17:30 +09:00
Adithya R
f77a16cfd8 dolby: Restore current profile _after_ resetting profiles
Ensure to end the onBootCompleted routine with the correct profile set.

Change-Id: I2d5f74a7c0145af2f9d064cd98fa2dc70e5a7acd
2025-08-30 08:17:30 +09:00
Adithya R
1c8db194bb dolby: Do not set volume leveler amount
This value is set to zero in almost every known dax-default.xml,
including ours.
DaxService also doesn't mess with this value, instead only sets
VolumeLevelerEnabled.

Change-Id: Ib944728d478cff58aebc4f47128bcd5fe32ff9f6
2025-08-30 08:17:30 +09:00
Adithya R
016b2b0865 dolby: Restore all settings upon bootup
Dolby often messes up restoring profile-specific settings after a reboot.
"Fine. I'll do it myself."

Change-Id: Ic255c6922eabae0b522c05110f87e2c10a97fb6c
2025-08-30 08:17:30 +09:00
Adithya R
df6692a710 dolby: Rewrite in Kotlin
Some cleanup and restructuring while we're at it.

Change-Id: I2f1fc53c202d91421c7b6af68c814c25398a62e4
2025-08-30 08:17:30 +09:00
Adithya R
5e4c3ec014 dolby: Revert "Re-enable speaker virtualization after bootup"
No longer necessary

Change-Id: Iac820eafa71ea3e4ccaad2bfa0fb76c37279a22a
2025-08-30 08:17:30 +09:00
Adithya R
c37be681c2 xiaomi: Introduce Dolby Atmos
Moved from marble/sm8450-common

History:

commit 82fe03168c0402e4cb10d25859c3b398c0ef654a
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Thu Mar 21 21:35:36 2024 +0530

    marble: parts: Restore dolby profile on audio changes

    Something keeps resetting back at random times, from what I observed,
    after resuming media or on a device change, lets workaround that.

    Change-Id: Id065f2482636194655c2399f0c35ad56b8e7a29d

commit c4400bd1326f65aeac1d0f26bb830ce7fd079773
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Fri Feb 2 09:29:08 2024 +0530

    marble: parts/keyhandler: Guard debug logging

    Change-Id: I246941f26cd1f71b696eb3c996794c9baa5dbc00

commit f11b70a98a11d0b89673d73002996aed9f11fbd7
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Sun Dec 31 20:36:52 2023 +0530

    marble: parts: Re-enable speaker virtualization after bootup

    For whatever reason, speaker virtualization isn't automatically
    restored at bootup unlike the other parameters. It was reported to be
    fixed by connecting and disconnecting headphones or disabling and
    enabling the toggle, so let's just automate that at bootup.

commit abcff4fb947c89b69c1d25bd290fd91b7873af6a
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Fri Oct 20 06:49:19 2023 +0530

    marble: parts: Implement profile-specific Dolby settings

    Some refactoring and cleanup while we're at it.

commit dc54f9ddeff212d017b0cba16e56516e99335bb3
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Mon Oct 9 21:58:58 2023 +0530

    marble: parts: Remove play/pause hack while toggling Dolby

    Not required with/fixed by:
    35217: audioflinger: Do not allow DAP effect to be suspended | https://gerrit.aospa.co/c/AOSPA/android_frameworks_av/+/35217

commit dd2acc8e0c10d05f86ff229412cc9f72ea242b44
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Wed Sep 13 21:41:20 2023 +0530

    marble: parts: Set proper summary for dolby settings

    Show the current status in Settings > Sound as well as the QS tile.

commit 92d341ba3d22f323eded525487db4289d6edc0fe
Author: Fabian Leutenegger <fabian.leutenegger@bluewin.ch>
Date:   Fri Aug 25 10:26:53 2023 +0200

    marble: parts: Always refresh playback if status changed

     * otherwise dolby would stay active even if you disable its setting

    Change-Id: If59d8081fa12da2aa67e5149db97965c0805d76e

commit b1944744649b6fddcb7bc3864b92f298b6e78821
Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Mon Aug 21 13:21:18 2023 +0530

    marble: parts: Introduce Dolby Atmos

    Based on existing dirac implementation and observing stock
    sound effects app and daxservice.

    Thanks to jhenrique09 for the hack from old dirac parts
    "Pause/play music stream to get effects applied".

    TODO: bring back misound (same as stock)

    Co-authored-by: Henrique Silva <jhenrique09.mcz@hotmail.com>

Change-Id: I79841c045fe7b92c438177916f756faab72ff0e9
2025-08-30 08:17:30 +09:00
Fabian Leutenegger
fb97f04c35 healthd-ext: Fix charge_counter and ETA values
Based on 137843ec4f

Co-authored-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
Change-Id: I3d000d283302a84ee9fcbd5a85ef26817b68c0a7
2025-08-30 08:17:29 +09:00
chrisl7
f22d34a902 healthd-ext: Define override to QTI AIDL healthd-ext hal
Change-Id: I26009b1f20c02219dd371ad184cad4eafb9e8eec
2025-08-30 08:17:29 +09:00
chrisl7
fc72f77dbb healthd-ext: Rename hal to xiaomi to avoid compilation conflicts
Change-Id: I8f33b6870eccfd19272cfbdb816b5b53371012c5
2025-08-30 08:17:29 +09:00
Fenglin Wu
c7c86c36ae healthd-ext: Update AIDL HAL service installation paths
Update the installation path for vendor and recovery partition
respectively.

Change-Id: I1908d10d782127f555e2fb316f3640bc93efcdbd
2025-08-30 08:17:29 +09:00
Fenglin Wu
1511e49ec4 healthd-ext: Add suspend support for charger mode
Override ChargerEnableSuspend() function to true to support kernel
suspend and resume in charger mode.

Change-Id: I01ceaecf7e918504624b2bf1bfb34207fcde74e7
2025-08-30 08:17:29 +09:00
Fenglin Wu
192d2b4a1c healthd-ext: Add health HAL AIDL implementation
Add health HAL AIDL implementation which is a service running for
both health HAL and charger mode.

Change-Id: I1f3205d1e34d93ed1739d5fa29c95a8f2b2d2894
2025-08-30 08:17:29 +09:00
Jignesh Mehta
27eecd2bd4 Light: Add null check for lights smart pointer
lights smart pointer was used without null pointer check.
This change adds null check.

Change-Id: Ifdd82290cfe4d7ca781adbed8c8a65961c70e244
Signed-off-by: Immanuel Raj <iamimmanuelraj@gmail.com>
2025-08-30 08:17:24 +09:00
79 changed files with 1442 additions and 1895 deletions

View File

@@ -1,48 +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",
"preinstalled-packages-platform-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,
}
prebuilt_etc {
name: "preinstalled-packages-platform-dspvolume",
relative_install_path: "sysconfig",
src: "preinstalled-packages-platform-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,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2025 crDroid Android 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.
-->
<config>
<!-- Dolby -->
<install-in-user-type package="org.lineageos.dspvolume.xiaomi">
<install-in user-type="FULL" />
<install-in user-type="PROFILE" />
<do-not-install-in user-type="android.os.usertype.profile.CLONE" />
<do-not-install-in user-type="android.os.usertype.profile.PRIVATE" />
</install-in-user-type>
</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,5 +1,5 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,7 +8,7 @@ package co.aospa.euicc
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ApplicationInfoFlags
import android.content.pm.PackageManager.PackageInfoFlags
import android.util.Log
object EuiccDisabler {
@@ -25,14 +25,14 @@ object EuiccDisabler {
)
private fun isInstalled(pm: PackageManager, pkgName: String) = runCatching {
val info = pm.getApplicationInfo(pkgName, ApplicationInfoFlags.of(0))
info.flags and ApplicationInfo.FLAG_INSTALLED != 0
val info = pm.getPackageInfo(pkgName, PackageInfoFlags.of(0))
info.applicationInfo.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
val info = pm.getPackageInfo(pkgName, PackageInfoFlags.of(0))
Log.d(TAG, "package $pkgName installed, enabled = ${info.applicationInfo.enabled}")
info.applicationInfo.enabled
}.getOrDefault(false)
fun enableOrDisableEuicc(context: Context) {

View File

@@ -1,74 +0,0 @@
//
// Copyright (C) 2024 The LineageOS Project
// 2024 Paranoid Android
//
// SPDX-License-Identifier: Apache-2.0
//
soong_config_module_type {
name: "xiaomi_hardware_biometrics_config_default",
module_type: "cc_defaults",
config_namespace: "xiaomi_hardware_biometrics",
bool_variables: [
"run_32bit",
],
properties: ["compile_multilib"],
}
xiaomi_hardware_biometrics_config_default {
name: "xiaomi_hardware_biometrics_config_default",
soong_config_variables: {
run_32bit: {
conditions_default: {
compile_multilib: "64",
},
compile_multilib: "prefer32",
},
},
}
cc_binary {
name: "android.hardware.biometrics.fingerprint-service.xiaomi",
defaults: ["xiaomi_hardware_biometrics_config_default"],
relative_install_path: "hw",
init_rc: ["android.hardware.biometrics.fingerprint-service.xiaomi.rc"],
vintf_fragments: ["android.hardware.biometrics.fingerprint-service.xiaomi.xml"],
srcs: [
"CancellationSignal.cpp",
"Fingerprint.cpp",
"FingerprintConfig.cpp",
"LockoutTracker.cpp",
"Session.cpp",
"service.cpp",
],
local_include_dirs: [
"include",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"libcutils",
"libhardware",
"libdl",
"liblog",
"android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.config",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.Props",
"libudfpshandlerfactory",
],
vendor: true,
header_libs: ["xiaomifingerprint_headers"],
}
sysprop_library {
name: "android.hardware.biometrics.fingerprint.Props",
srcs: ["fingerprint.sysprop"],
property_owner: "Vendor",
vendor: true,
}

View File

@@ -1,17 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "CancellationSignal.h"
namespace aidl::android::hardware::biometrics::fingerprint {
CancellationSignal::CancellationSignal(Session* session) : mSession(session) {}
ndk::ScopedAStatus CancellationSignal::cancel() {
return mSession->cancel();
}
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,25 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
#include "Session.h"
namespace aidl::android::hardware::biometrics::fingerprint {
class CancellationSignal
: public ::aidl::android::hardware::biometrics::common::BnCancellationSignal {
public:
CancellationSignal(Session* session);
ndk::ScopedAStatus cancel() override;
private:
Session* mSession;
};
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,248 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
* 2024 Paranoid Android
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Fingerprint.h"
#include <android-base/properties.h>
#include <fingerprint.sysprop.h>
#include "util/Util.h"
#include <android-base/logging.h>
#include <android-base/strings.h>
namespace aidl::android::hardware::biometrics::fingerprint {
namespace {
constexpr int MAX_ENROLLMENTS_PER_USER = 5;
constexpr char HW_COMPONENT_ID[] = "fingerprintSensor";
constexpr char HW_VERSION[] = "vendor/model/revision";
constexpr char FW_VERSION[] = "1.01";
constexpr char SERIAL_NUMBER[] = "00000001";
constexpr char SW_COMPONENT_ID[] = "matchingAlgorithm";
constexpr char SW_VERSION[] = "vendor/version/revision";
typedef struct fingerprint_hal {
const char* class_name;
} fingerprint_hal_t;
static const fingerprint_hal_t kModules[] = {
{"fortsense"}, {"fpc"}, {"fpc_fod"}, {"goodix"}, {"goodix:gf_fingerprint"},
{"goodix_fod"}, {"goodix_fod6"}, {"silead"}, {"syna"},
};
} // namespace
static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1);
static Fingerprint* sInstance;
Fingerprint::Fingerprint(std::shared_ptr<FingerprintConfig> config) : mConfig(std::move(config)) {
sInstance = this; // keep track of the most recent instance
if (mDevice) {
ALOGI("fingerprint HAL already opened");
} else {
for (auto& [module] : kModules) {
std::string class_name;
std::string class_module_id;
auto parts = ::android::base::Split(module, ":");
if (parts.size() == 2) {
class_name = parts[0];
class_module_id = parts[1];
} else {
class_name = module;
class_module_id = FINGERPRINT_HARDWARE_MODULE_ID;
}
mDevice = openFingerprintHal(class_name.c_str(), class_module_id.c_str());
if (!mDevice) {
ALOGE("Can't open HAL module, class: %s, module_id: %s", class_name.c_str(),
class_module_id.c_str());
continue;
}
ALOGI("Opened fingerprint HAL, class: %s, module_id: %s", class_name.c_str(),
class_module_id.c_str());
break;
}
if (!mDevice) {
ALOGE("Can't open any fingerprint HAL module");
}
}
std::string sensorTypeProp = mConfig->get<std::string>("type");
if (sensorTypeProp == "udfps" || sensorTypeProp == "udfps_optical") {
if (sensorTypeProp == "udfps") {
mSensorType = FingerprintSensorType::UNDER_DISPLAY_ULTRASONIC;
} else {
mSensorType = FingerprintSensorType::UNDER_DISPLAY_OPTICAL;
}
mUdfpsHandlerFactory = getUdfpsHandlerFactory();
if (!mUdfpsHandlerFactory) {
ALOGE("Can't get UdfpsHandlerFactory");
} else {
mUdfpsHandler = mUdfpsHandlerFactory->create();
if (!mUdfpsHandler) {
ALOGE("Can't create UdfpsHandler");
} else {
mUdfpsHandler->init(mDevice);
}
}
} else if (sensorTypeProp == "side") {
mSensorType = FingerprintSensorType::POWER_BUTTON;
} else if (sensorTypeProp == "home") {
mSensorType = FingerprintSensorType::HOME_BUTTON;
} else if (sensorTypeProp == "rear") {
mSensorType = FingerprintSensorType::REAR;
} else {
mSensorType = FingerprintSensorType::UNKNOWN;
UNIMPLEMENTED(FATAL) << "unrecognized or unimplemented fingerprint behavior: "
<< sensorTypeProp;
}
ALOGI("sensorTypeProp: %s", sensorTypeProp.c_str());
}
Fingerprint::~Fingerprint() {
ALOGV("~Fingerprint()");
if (mUdfpsHandler) {
mUdfpsHandlerFactory->destroy(mUdfpsHandler);
}
if (mDevice == nullptr) {
ALOGE("No valid device");
return;
}
int err;
if (0 != (err = mDevice->common.close(reinterpret_cast<hw_device_t*>(mDevice)))) {
ALOGE("Can't close fingerprint module, error: %d", err);
return;
}
mDevice = nullptr;
}
fingerprint_device_t* Fingerprint::openFingerprintHal(const char* class_name,
const char* module_id) {
const hw_module_t* hw_mdl = nullptr;
ALOGD("Opening fingerprint hal library...");
if (hw_get_module_by_class(module_id, class_name, &hw_mdl) != 0) {
ALOGE("Can't open fingerprint HW Module");
return nullptr;
}
if (!hw_mdl) {
ALOGE("No valid fingerprint module");
return nullptr;
}
auto module = reinterpret_cast<const fingerprint_module_t*>(hw_mdl);
if (!module->common.methods->open) {
ALOGE("No valid open method");
return nullptr;
}
hw_device_t* device = nullptr;
if (module->common.methods->open(hw_mdl, nullptr, &device) != 0) {
ALOGE("Can't open fingerprint methods");
return nullptr;
}
auto fp_device = reinterpret_cast<fingerprint_device_t*>(device);
if (fp_device->set_notify(fp_device, Fingerprint::notify) != 0) {
ALOGE("Can't register fingerprint module callback");
return nullptr;
}
return fp_device;
}
std::vector<SensorLocation> Fingerprint::getSensorLocations() {
std::vector<SensorLocation> locations;
auto loc = mConfig->get<std::string>("sensor_location");
auto entries = ::android::base::Split(loc, ",");
for (const auto& entry : entries) {
auto isValidStr = false;
auto dim = ::android::base::Split(entry, "|");
if (dim.size() != 3 and dim.size() != 4) {
if (!loc.empty()) {
ALOGE("Invalid sensor location input (x|y|radius) or (x|y|radius|display): %s",
loc.c_str());
}
} else {
int32_t x, y, r;
std::string d;
isValidStr = ParseInt(dim[0], &x) && ParseInt(dim[1], &y) && ParseInt(dim[2], &r);
if (dim.size() == 4) {
d = dim[3];
isValidStr = isValidStr && !d.empty();
}
if (isValidStr)
locations.push_back({.sensorLocationX = x,
.sensorLocationY = y,
.sensorRadius = r,
.display = d});
}
}
return locations;
}
void Fingerprint::notify(const fingerprint_msg_t* msg) {
Fingerprint* thisPtr = sInstance;
if (thisPtr == nullptr || thisPtr->mSession == nullptr || thisPtr->mSession->isClosed()) {
ALOGE("Receiving callbacks before a session is opened.");
return;
}
thisPtr->mSession->notify(msg);
}
ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
std::vector<common::ComponentInfo> componentInfo = {
{HW_COMPONENT_ID, HW_VERSION, FW_VERSION, SERIAL_NUMBER, "" /* softwareVersion */},
{SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
"" /* serialNumber */, SW_VERSION}};
auto sensorId = mConfig->get<std::int32_t>("sensor_id");
auto sensorStrength = mConfig->get<std::int32_t>("sensor_strength");
auto navigationGuesture = mConfig->get<bool>("navigation_gesture");
auto detectInteraction = mConfig->get<bool>("detect_interaction");
auto displayTouch = mConfig->get<bool>("display_touch");
auto controlIllumination = mConfig->get<bool>("control_illumination");
common::CommonProps commonProps = {sensorId, (common::SensorStrength)sensorStrength,
MAX_ENROLLMENTS_PER_USER, componentInfo};
std::vector<SensorLocation> sensorLocations = getSensorLocations();
std::vector<std::string> sensorLocationStrings;
std::transform(sensorLocations.begin(), sensorLocations.end(),
std::back_inserter(sensorLocationStrings),
[](const SensorLocation& obj) { return obj.toString(); });
ALOGI("sensor type: %s, location: %s", ::android::internal::ToString(mSensorType).c_str(),
::android::base::Join(sensorLocationStrings, ", ").c_str());
*out = {{commonProps, mSensorType, sensorLocations, navigationGuesture, detectInteraction,
displayTouch, controlIllumination, std::nullopt}};
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* out) {
CHECK(mSession == nullptr || mSession->isClosed()) << "Open session already exists!";
mSession = SharedRefBase::make<Session>(mDevice, mUdfpsHandler, userId, cb, mLockoutTracker);
*out = mSession;
mSession->linkToDeath(cb->asBinder().get());
return ndk::ScopedAStatus::ok();
}
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
* 2024 Paranoid Android
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/biometrics/fingerprint/BnFingerprint.h>
#include "FingerprintConfig.h"
#include "LockoutTracker.h"
#include "Session.h"
#include "UdfpsHandler.h"
using ::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType;
using ::aidl::android::hardware::biometrics::fingerprint::ISession;
using ::aidl::android::hardware::biometrics::fingerprint::ISessionCallback;
using ::aidl::android::hardware::biometrics::fingerprint::SensorProps;
namespace aidl::android::hardware::biometrics::fingerprint {
class Fingerprint : public BnFingerprint {
public:
Fingerprint(std::shared_ptr<FingerprintConfig> config);
~Fingerprint();
ndk::ScopedAStatus getSensorProps(std::vector<SensorProps>* _aidl_return) override;
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* out) override;
private:
fingerprint_device_t* openFingerprintHal(const char* class_name, const char* module_id);
std::vector<SensorLocation> getSensorLocations();
static void notify(const fingerprint_msg_t* msg);
std::shared_ptr<FingerprintConfig> mConfig;
std::shared_ptr<Session> mSession;
LockoutTracker mLockoutTracker;
FingerprintSensorType mSensorType;
fingerprint_device_t* mDevice;
UdfpsHandlerFactory* mUdfpsHandlerFactory;
UdfpsHandler* mUdfpsHandler;
};
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) 2024 The Android Open Source Project
* 2024 Paranoid Android
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "FingerprintConfig"
#include "FingerprintConfig.h"
#include <android-base/logging.h>
#include <fingerprint.sysprop.h>
using namespace ::android::fingerprint::xiaomi;
namespace aidl::android::hardware::biometrics::fingerprint {
// Wrapper to system property access functions
#define CREATE_GETTER_SETTER_WRAPPER(_NAME_, _T_) \
ConfigValue _NAME_##Getter() { \
return FingerprintHalProperties::_NAME_(); \
} \
bool _NAME_##Setter(const ConfigValue& v) { \
return FingerprintHalProperties::_NAME_(std::get<_T_>(v)); \
}
CREATE_GETTER_SETTER_WRAPPER(type, OptString)
CREATE_GETTER_SETTER_WRAPPER(sensor_id, OptInt32)
CREATE_GETTER_SETTER_WRAPPER(sensor_location, OptString)
CREATE_GETTER_SETTER_WRAPPER(sensor_strength, OptInt32)
CREATE_GETTER_SETTER_WRAPPER(navigation_gesture, OptBool)
CREATE_GETTER_SETTER_WRAPPER(detect_interaction, OptBool)
CREATE_GETTER_SETTER_WRAPPER(display_touch, OptBool)
CREATE_GETTER_SETTER_WRAPPER(control_illumination, OptBool)
// Name, Getter, Setter, Parser and default value
#define NGS(_NAME_) #_NAME_, _NAME_##Getter, _NAME_##Setter
static Config::Data configData[] = {
{NGS(type), &Config::parseString, ""},
{NGS(sensor_id), &Config::parseInt32, "0"},
{NGS(sensor_location), &Config::parseString, ""},
{NGS(sensor_strength), &Config::parseInt32, "2"}, // STRONG
{NGS(navigation_gesture), &Config::parseBool, "false"},
{NGS(detect_interaction), &Config::parseBool, "false"},
{NGS(display_touch), &Config::parseBool, "false"},
{NGS(control_illumination), &Config::parseBool, "false"},
};
Config::Data* FingerprintConfig::getConfigData(int* size) {
*size = sizeof(configData) / sizeof(configData[0]);
return configData;
}
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,18 +0,0 @@
/*
* Copyright (C) 2024 The Android Open Source Project
* 2024 Paranoid Android
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "config/Config.h"
namespace aidl::android::hardware::biometrics::fingerprint {
class FingerprintConfig : public Config {
Config::Data* getConfigData(int* size) override;
};
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,62 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "LockoutTracker.h"
#include <fingerprint.sysprop.h>
#include "Fingerprint.h"
#include "util/Util.h"
using namespace ::android::fingerprint::xiaomi;
namespace aidl::android::hardware::biometrics::fingerprint {
void LockoutTracker::reset(bool clearAttemptCounter) {
if (clearAttemptCounter) {
mFailedCount = 0;
}
mLockoutTimedStart = 0;
mCurrentMode = LockoutMode::kNone;
}
void LockoutTracker::addFailedAttempt() {
mFailedCount++;
if (mFailedCount >= LOCKOUT_PERMANENT_THRESHOLD) {
mCurrentMode = LockoutMode::kPermanent;
} else if (mFailedCount >= LOCKOUT_TIMED_THRESHOLD) {
if (mCurrentMode == LockoutMode::kNone) {
mCurrentMode = LockoutMode::kTimed;
mLockoutTimedStart = Util::getSystemNanoTime();
}
}
}
LockoutTracker::LockoutMode LockoutTracker::getMode() {
if (mCurrentMode == LockoutMode::kTimed) {
if (Util::hasElapsed(mLockoutTimedStart, LOCKOUT_TIMED_DURATION)) {
mCurrentMode = LockoutMode::kNone;
mLockoutTimedStart = 0;
}
}
return mCurrentMode;
}
int64_t LockoutTracker::getLockoutTimeLeft() {
int64_t res = 0;
if (mLockoutTimedStart > 0) {
auto now = Util::getSystemNanoTime();
auto elapsed = (now - mLockoutTimedStart) / 1000000LL;
res = LOCKOUT_TIMED_DURATION - elapsed;
LOG(INFO) << "elapsed=" << elapsed << " now = " << now
<< " mLockoutTimedStart=" << mLockoutTimedStart << " res=" << res;
}
return res;
}
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <android/binder_to_string.h>
#include <stdint.h>
#include <string>
#define LOCKOUT_TIMED_THRESHOLD 5
#define LOCKOUT_TIMED_DURATION 10000
#define LOCKOUT_PERMANENT_THRESHOLD 20
namespace aidl::android::hardware::biometrics::fingerprint {
class LockoutTracker {
public:
LockoutTracker() : mFailedCount(0) {}
~LockoutTracker() {}
enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
void reset(bool clearAttemptCounter);
LockoutMode getMode();
void addFailedAttempt();
int64_t getLockoutTimeLeft();
inline std::string toString() const {
std::ostringstream os;
os << "----- LockoutTracker:: -----" << std::endl;
os << "LockoutTracker::mFailedCount:" << mFailedCount;
os << ", LockoutTracker::mCurrentMode:" << (int)mCurrentMode;
os << std::endl;
return os.str();
}
private:
int32_t mFailedCount;
int64_t mLockoutTimedStart;
LockoutMode mCurrentMode;
};
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,388 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <thread>
#include "Legacy2Aidl.h"
#include "Session.h"
#include "CancellationSignal.h"
namespace aidl::android::hardware::biometrics::fingerprint {
void onClientDeath(void* cookie) {
ALOGI("FingerprintService has died");
Session* session = static_cast<Session*>(cookie);
if (session && !session->isClosed()) {
session->close();
}
}
Session::Session(fingerprint_device_t* device, UdfpsHandler* udfpsHandler, int userId,
std::shared_ptr<ISessionCallback> cb, LockoutTracker lockoutTracker)
: mDevice(device),
mLockoutTracker(lockoutTracker),
mUserId(userId),
mCb(cb),
mUdfpsHandler(udfpsHandler) {
mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
auto path = std::format("/data/vendor_de/{}/fpdata/", userId);
mDevice->set_active_group(mDevice, mUserId, path.c_str());
}
ndk::ScopedAStatus Session::generateChallenge() {
uint64_t challenge = mDevice->pre_enroll(mDevice);
ALOGI("generateChallenge: %ld", challenge);
mCb->onChallengeGenerated(challenge);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) {
ALOGI("revokeChallenge: %ld", challenge);
mDevice->post_enroll(mDevice);
mCb->onChallengeRevoked(challenge);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::enroll(const HardwareAuthToken& hat,
std::shared_ptr<ICancellationSignal>* out) {
hw_auth_token_t authToken;
translate(hat, authToken);
int error = mDevice->enroll(mDevice, &authToken, mUserId, 60);
if (error) {
ALOGE("enroll failed: %d", error);
mCb->onError(Error::UNABLE_TO_PROCESS, error);
}
*out = SharedRefBase::make<CancellationSignal>(this);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::authenticate(int64_t operationId,
std::shared_ptr<ICancellationSignal>* out) {
checkSensorLockout();
int error = mDevice->authenticate(mDevice, operationId, mUserId);
if (error) {
ALOGE("authenticate failed: %d", error);
mCb->onError(Error::UNABLE_TO_PROCESS, error);
}
*out = SharedRefBase::make<CancellationSignal>(this);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::detectInteraction(std::shared_ptr<ICancellationSignal>* out) {
ALOGD("Detect interaction is not supported");
mCb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
*out = SharedRefBase::make<CancellationSignal>(this);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::enumerateEnrollments() {
int error = mDevice->enumerate(mDevice);
if (error) {
ALOGE("enumerate failed: %d", error);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
ALOGI("removeEnrollments, size: %zu", enrollmentIds.size());
for (int32_t fid : enrollmentIds) {
int error = mDevice->remove(mDevice, mUserId, fid);
if (error) {
ALOGE("remove failed: %d", error);
}
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::getAuthenticatorId() {
uint64_t auth_id = mDevice->get_authenticator_id(mDevice);
ALOGI("getAuthenticatorId: %ld", auth_id);
mCb->onAuthenticatorIdRetrieved(auth_id);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
uint64_t auth_id = mDevice->get_authenticator_id(mDevice);
ALOGI("invalidateAuthenticatorId: %ld", auth_id);
mCb->onAuthenticatorIdInvalidated(auth_id);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::resetLockout(const HardwareAuthToken& /*hat*/) {
clearLockout(true);
if (mIsLockoutTimerStarted) mIsLockoutTimerAborted = true;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t x, int32_t y, float minor,
float major) {
if (mUdfpsHandler) {
mUdfpsHandler->onFingerDown(x, y, minor, major);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) {
if (mUdfpsHandler) {
mUdfpsHandler->onFingerUp();
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onUiReady() {
// TODO: stub
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::authenticateWithContext(
int64_t operationId, const common::OperationContext& /*context*/,
std::shared_ptr<common::ICancellationSignal>* out) {
return authenticate(operationId, out);
}
ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat,
const common::OperationContext& /*context*/,
std::shared_ptr<common::ICancellationSignal>* out) {
return enroll(hat, out);
}
ndk::ScopedAStatus Session::detectInteractionWithContext(
const common::OperationContext& /*context*/,
std::shared_ptr<common::ICancellationSignal>* out) {
return detectInteraction(out);
}
ndk::ScopedAStatus Session::onPointerDownWithContext(const PointerContext& context) {
return onPointerDown(context.pointerId, context.x, context.y, context.minor, context.major);
}
ndk::ScopedAStatus Session::onPointerUpWithContext(const PointerContext& context) {
return onPointerUp(context.pointerId);
}
ndk::ScopedAStatus Session::onContextChanged(const common::OperationContext& /*context*/) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onPointerCancelWithContext(const PointerContext& /*context*/) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::setIgnoreDisplayTouches(bool /*shouldIgnore*/) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::cancel() {
if (mUdfpsHandler) {
mUdfpsHandler->cancel();
}
int ret = mDevice->cancel(mDevice);
if (ret == 0) {
mCb->onError(Error::CANCELED, 0 /* vendorCode */);
return ndk::ScopedAStatus::ok();
}
return ndk::ScopedAStatus::fromServiceSpecificError(ret);
}
ndk::ScopedAStatus Session::close() {
mClosed = true;
mCb->onSessionClosed();
AIBinder_DeathRecipient_delete(mDeathRecipient);
return ndk::ScopedAStatus::ok();
}
binder_status_t Session::linkToDeath(AIBinder* binder) {
return AIBinder_linkToDeath(binder, mDeathRecipient, this);
}
bool Session::isClosed() {
return mClosed;
}
// Translate from errors returned by traditional HAL (see fingerprint.h) to
// AIDL-compliant Error
Error Session::VendorErrorFilter(int32_t error, int32_t* vendorCode) {
*vendorCode = 0;
switch (error) {
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
return Error::HW_UNAVAILABLE;
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
return Error::UNABLE_TO_PROCESS;
case FINGERPRINT_ERROR_TIMEOUT:
return Error::TIMEOUT;
case FINGERPRINT_ERROR_NO_SPACE:
return Error::NO_SPACE;
case FINGERPRINT_ERROR_CANCELED:
return Error::CANCELED;
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
return Error::UNABLE_TO_REMOVE;
case FINGERPRINT_ERROR_LOCKOUT: {
*vendorCode = FINGERPRINT_ERROR_LOCKOUT;
return Error::VENDOR;
}
default:
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
// vendor specific code.
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
return Error::VENDOR;
}
}
ALOGE("Unknown error from fingerprint vendor library: %d", error);
return Error::UNABLE_TO_PROCESS;
}
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
// to AIDL-compliant AcquiredInfo
AcquiredInfo Session::VendorAcquiredFilter(int32_t info, int32_t* vendorCode) {
*vendorCode = 0;
switch (info) {
case FINGERPRINT_ACQUIRED_GOOD:
return AcquiredInfo::GOOD;
case FINGERPRINT_ACQUIRED_PARTIAL:
return AcquiredInfo::PARTIAL;
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
return AcquiredInfo::INSUFFICIENT;
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
return AcquiredInfo::SENSOR_DIRTY;
case FINGERPRINT_ACQUIRED_TOO_SLOW:
return AcquiredInfo::TOO_SLOW;
case FINGERPRINT_ACQUIRED_TOO_FAST:
return AcquiredInfo::TOO_FAST;
default:
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
// vendor specific code.
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
return AcquiredInfo::VENDOR;
}
}
ALOGE("Unknown acquired message from fingerprint vendor library: %d", info);
return AcquiredInfo::UNKNOWN;
}
bool Session::checkSensorLockout() {
LockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
if (lockoutMode == LockoutTracker::LockoutMode::kPermanent) {
ALOGE("Fail: lockout permanent");
mCb->onLockoutPermanent();
mIsLockoutTimerAborted = true;
return true;
}
if (lockoutMode == LockoutTracker::LockoutMode::kTimed) {
int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
ALOGE("Fail: lockout timed: %ld", timeLeft);
mCb->onLockoutTimed(timeLeft);
if (!mIsLockoutTimerStarted) startLockoutTimer(timeLeft);
return true;
}
return false;
}
void Session::clearLockout(bool clearAttemptCounter) {
mLockoutTracker.reset(clearAttemptCounter);
mCb->onLockoutCleared();
}
void Session::startLockoutTimer(int64_t timeout) {
std::function<void()> action = std::bind(&Session::lockoutTimerExpired, this);
std::thread([timeout, action]() {
std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
action();
}).detach();
mIsLockoutTimerStarted = true;
}
void Session::lockoutTimerExpired() {
if (!mIsLockoutTimerAborted) clearLockout(false);
mIsLockoutTimerStarted = false;
mIsLockoutTimerAborted = false;
}
void Session::notify(const fingerprint_msg_t* msg) {
// const uint64_t devId = reinterpret_cast<uint64_t>(mDevice);
switch (msg->type) {
case FINGERPRINT_ERROR: {
int32_t vendorCode = 0;
Error result = VendorErrorFilter(msg->data.error, &vendorCode);
ALOGD("onError(%hhd, %d)", result, vendorCode);
mCb->onError(result, vendorCode);
} break;
case FINGERPRINT_ACQUIRED: {
int32_t vendorCode = 0;
AcquiredInfo result =
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
ALOGD("onAcquired(%hhd, %d)", result, vendorCode);
if (mUdfpsHandler) {
mUdfpsHandler->onAcquired(static_cast<int32_t>(result), vendorCode);
}
// don't process vendor messages further since frameworks try to disable
// udfps display mode on vendor acquired messages but our sensors send a
// vendor message during processing...
if (result != AcquiredInfo::VENDOR) {
mCb->onAcquired(result, vendorCode);
}
} break;
case FINGERPRINT_TEMPLATE_ENROLLING: {
ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)", msg->data.enroll.finger.fid,
msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining);
mCb->onEnrollmentProgress(msg->data.enroll.finger.fid,
msg->data.enroll.samples_remaining);
} break;
case FINGERPRINT_TEMPLATE_REMOVED: {
ALOGD("onRemove(fid=%d, gid=%d, rem=%d)", msg->data.removed.finger.fid,
msg->data.removed.finger.gid, msg->data.removed.remaining_templates);
std::vector<int> enrollments;
enrollments.push_back(msg->data.removed.finger.fid);
mCb->onEnrollmentsRemoved(enrollments);
} break;
case FINGERPRINT_AUTHENTICATED: {
ALOGD("onAuthenticated(fid=%d, gid=%d)", msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid);
if (msg->data.authenticated.finger.fid != 0) {
const hw_auth_token_t hat = msg->data.authenticated.hat;
HardwareAuthToken authToken;
translate(hat, authToken);
mCb->onAuthenticationSucceeded(msg->data.authenticated.finger.fid, authToken);
mLockoutTracker.reset(true);
} else {
mCb->onAuthenticationFailed();
mLockoutTracker.addFailedAttempt();
checkSensorLockout();
}
} break;
case FINGERPRINT_TEMPLATE_ENUMERATING: {
ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)", msg->data.enumerated.finger.fid,
msg->data.enumerated.finger.gid, msg->data.enumerated.remaining_templates);
static std::vector<int> enrollments;
enrollments.push_back(msg->data.enumerated.finger.fid);
if (msg->data.enumerated.remaining_templates == 0) {
mCb->onEnrollmentsEnumerated(enrollments);
enrollments.clear();
}
} break;
}
}
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,100 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#define LOG_TAG "android.hardware.biometrics.fingerprint-service.xiaomi"
#include <aidl/android/hardware/biometrics/fingerprint/BnSession.h>
#include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
#include <android/log.h>
#include <hardware/hardware.h>
#include <log/log.h>
#include "fingerprint.h"
#include "LockoutTracker.h"
#include "UdfpsHandler.h"
using ::aidl::android::hardware::biometrics::common::ICancellationSignal;
using ::aidl::android::hardware::biometrics::common::OperationContext;
using ::aidl::android::hardware::biometrics::fingerprint::PointerContext;
using ::aidl::android::hardware::keymaster::HardwareAuthToken;
namespace aidl::android::hardware::biometrics::fingerprint {
void onClientDeath(void* cookie);
class Session : public BnSession {
public:
Session(fingerprint_device_t* device, UdfpsHandler* udfpsHandler, int userId,
std::shared_ptr<ISessionCallback> cb, LockoutTracker lockoutTracker);
ndk::ScopedAStatus generateChallenge() override;
ndk::ScopedAStatus revokeChallenge(int64_t challenge) override;
ndk::ScopedAStatus enroll(const HardwareAuthToken& hat,
std::shared_ptr<ICancellationSignal>* out) override;
ndk::ScopedAStatus authenticate(int64_t operationId,
std::shared_ptr<ICancellationSignal>* out) override;
ndk::ScopedAStatus detectInteraction(std::shared_ptr<ICancellationSignal>* out) override;
ndk::ScopedAStatus enumerateEnrollments() override;
ndk::ScopedAStatus removeEnrollments(const std::vector<int32_t>& enrollmentIds) override;
ndk::ScopedAStatus getAuthenticatorId() override;
ndk::ScopedAStatus invalidateAuthenticatorId() override;
ndk::ScopedAStatus resetLockout(const HardwareAuthToken& hat) override;
ndk::ScopedAStatus close() override;
ndk::ScopedAStatus onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor,
float major) override;
ndk::ScopedAStatus onPointerUp(int32_t pointerId) override;
ndk::ScopedAStatus onUiReady() override;
ndk::ScopedAStatus authenticateWithContext(int64_t operationId, const OperationContext& context,
std::shared_ptr<ICancellationSignal>* out) override;
ndk::ScopedAStatus enrollWithContext(const HardwareAuthToken& hat,
const OperationContext& context,
std::shared_ptr<ICancellationSignal>* out) override;
ndk::ScopedAStatus detectInteractionWithContext(
const OperationContext& context, std::shared_ptr<ICancellationSignal>* out) override;
ndk::ScopedAStatus onPointerDownWithContext(const PointerContext& context) override;
ndk::ScopedAStatus onPointerUpWithContext(const PointerContext& context) override;
ndk::ScopedAStatus onContextChanged(const OperationContext& context) override;
ndk::ScopedAStatus onPointerCancelWithContext(const PointerContext& context) override;
ndk::ScopedAStatus setIgnoreDisplayTouches(bool shouldIgnore) override;
ndk::ScopedAStatus cancel();
binder_status_t linkToDeath(AIBinder* binder);
bool isClosed();
void notify(const fingerprint_msg_t* msg);
private:
fingerprint_device_t* mDevice;
LockoutTracker mLockoutTracker;
bool mClosed = false;
// static ndk::ScopedAStatus ErrorFilter(int32_t error);
static Error VendorErrorFilter(int32_t error, int32_t* vendorCode);
static AcquiredInfo VendorAcquiredFilter(int32_t info, int32_t* vendorCode);
bool checkSensorLockout();
void clearLockout(bool clearAttemptCounter);
void startLockoutTimer(int64_t timeout);
void lockoutTimerExpired();
// lockout timer
bool mIsLockoutTimerStarted = false;
bool mIsLockoutTimerAborted = false;
// The user ID for which this session was created.
int32_t mUserId;
// Callback for talking to the framework. This callback must only be called from non-binder
// threads to prevent nested binder calls and consequently a binder thread exhaustion.
// Practically, it means that this callback should always be called from the worker thread.
std::shared_ptr<ISessionCallback> mCb;
// Binder death handler.
AIBinder_DeathRecipient* mDeathRecipient;
UdfpsHandler* mUdfpsHandler;
};
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,9 +0,0 @@
service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.xiaomi
# "class hal" causes a race condition on some devices due to files created
# in /data. As a workaround, postpone startup until later in boot once
# /data is mounted.
class late_start
user system
group system input uhid
shutdown critical
task_profiles ProcessCapacityHigh MaxPerformance

View File

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

View File

@@ -1,79 +0,0 @@
# fingerprint.sysprop
# module becomes static class (Java) / namespace (C++) for serving API
module: "android.fingerprint.xiaomi.FingerprintHalProperties"
owner: Vendor
# type of fingerprint sensor (default: none)
prop {
prop_name: "persist.vendor.fingerprint.type"
type: String
scope: Internal
access: ReadWrite
enum_values: "udfps|udfps_optical|side|home|rear"
api_name: "type"
}
# sensor location
# <x>|<y>|<radius>|<display> in pixel, can have multiple values separated by comma
prop {
prop_name: "persist.vendor.fingerprint.sensor_location"
type: String
scope: Internal
access: ReadWrite
api_name: "sensor_location"
}
# sensor id (default: 0)
prop {
prop_name: "persist.vendor.fingerprint.sensor_id"
type: Integer
scope: Internal
access: ReadWrite
api_name: "sensor_id"
}
# sensor strength (default: 2)
# [0=CONVENIENCE, 1=WEAK, 2=STRONG]
prop {
prop_name: "persist.vendor.fingerprint.sensor_strength"
type: Integer
scope: Internal
access: ReadWrite
api_name: "sensor_strength"
}
# whether support navigation guestures (default: false)
prop {
prop_name: "persist.vendor.fingerprint.navigation_gesture"
type: Boolean
scope: Internal
access: ReadWrite
api_name: "navigation_gesture"
}
# whether support detect interaction (default: false)
prop {
prop_name: "persist.vendor.fingerprint.detect_interaction"
type: Boolean
scope: Internal
access: ReadWrite
api_name: "detect_interaction"
}
# whether support display touch by hal (default: false)
prop {
prop_name: "persist.vendor.fingerprint.udfps.display_touch"
type: Boolean
scope: Internal
access: ReadWrite
api_name: "display_touch"
}
# whether support illumination control by hal (default: false)
prop {
prop_name: "persist.vendor.fingerprint.udfps.control_illumination"
type: Boolean
scope: Internal
access: ReadWrite
api_name: "control_illumination"
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
#include <hardware/hw_auth_token.h>
#include <endian.h>
namespace aidl::android::hardware::biometrics::fingerprint {
inline void translate(const ::aidl::android::hardware::keymaster::HardwareAuthToken& authToken,
hw_auth_token_t& hat) {
hat.challenge = authToken.challenge;
hat.user_id = authToken.userId;
hat.authenticator_id = authToken.authenticatorId;
// these are in host order: translate to network order
hat.authenticator_type = htobe32(static_cast<uint32_t>(authToken.authenticatorType));
hat.timestamp = htobe64(authToken.timestamp.milliSeconds);
std::copy(authToken.mac.begin(), authToken.mac.end(), hat.hmac);
}
inline void translate(const hw_auth_token_t& hat,
::aidl::android::hardware::keymaster::HardwareAuthToken& authToken) {
authToken.challenge = hat.challenge;
authToken.userId = hat.user_id;
authToken.authenticatorId = hat.authenticator_id;
// these are in network order: translate to host
authToken.authenticatorType =
static_cast<::aidl::android::hardware::keymaster::HardwareAuthenticatorType>(
be32toh(hat.authenticator_type));
authToken.timestamp.milliSeconds = be64toh(hat.timestamp);
authToken.mac.insert(authToken.mac.begin(), std::begin(hat.hmac), std::end(hat.hmac));
}
} // namespace aidl::android::hardware::biometrics::fingerprint

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Fingerprint.h"
#include "FingerprintConfig.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using ::aidl::android::hardware::biometrics::fingerprint::Fingerprint;
using ::aidl::android::hardware::biometrics::fingerprint::FingerprintConfig;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<FingerprintConfig> config = std::make_shared<FingerprintConfig>();
config->init();
std::shared_ptr<Fingerprint> fingerprint = ndk::SharedRefBase::make<Fingerprint>(config);
const std::string instance = std::string() + Fingerprint::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(fingerprint->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,12 +1,12 @@
<!--
Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause-Clear
-->
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.health</name>
<version>3</version>
<version>1</version>
<fqname>IHealth/default</fqname>
</hal>
</manifest>

28
aidl/light/Android.bp Normal file
View File

@@ -0,0 +1,28 @@
//
// Copyright (C) 2021-2024 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "android.hardware.light-service.xiaomi",
defaults: ["hidl_defaults"],
vendor: true,
relative_install_path: "hw",
init_rc: ["android.hardware.light-service.xiaomi.rc"],
vintf_fragments: ["android.hardware.light-service.xiaomi.xml"],
srcs: [
"BacklightDevice.cpp",
"Devices.cpp",
"LedDevice.cpp",
"Lights.cpp",
"RgbLedDevice.cpp",
"Utils.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"android.hardware.light-V2-ndk",
],
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2022-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "BacklightDevice.h"
#define LOG_TAG "BacklightDevice"
#include <android-base/logging.h>
#include <fstream>
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
static const std::string kBacklightBasePath = "/sys/class/backlight/";
static const uint32_t kDefaultMaxBrightness = 255;
static const std::string kBrightnessNode = "brightness";
static const std::string kMaxBrightnessNode = "max_brightness";
BacklightDevice::BacklightDevice(std::string name)
: mName(name), mBasePath(kBacklightBasePath + name + "/") {
if (!readFromFile(mBasePath + kMaxBrightnessNode, mMaxBrightness)) {
mMaxBrightness = kDefaultMaxBrightness;
}
};
std::string BacklightDevice::getName() const {
return mName;
}
bool BacklightDevice::exists() const {
return std::ifstream(mBasePath + kBrightnessNode).good();
}
bool BacklightDevice::setBrightness(uint8_t value) {
return writeToFile(mBasePath + kBrightnessNode, scaleBrightness(value, mMaxBrightness));
}
void BacklightDevice::dump(int fd) const {
dprintf(fd, "Name: %s", mName.c_str());
dprintf(fd, ", exists: %d", exists());
dprintf(fd, ", base path: %s", mBasePath.c_str());
dprintf(fd, ", max brightness: %u", mMaxBrightness);
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2022-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <cstdint>
#include <string>
#include "IDumpable.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
/**
* A Linux backlight device.
* @see https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-backlight
*/
class BacklightDevice : public IDumpable {
public:
BacklightDevice() = delete;
/**
* Constructor.
*
* @param name The name of the backlight device
*/
BacklightDevice(std::string name);
/**
* Get the name of the backlight device.
*
* @return std::string The name of the backlight device
*/
std::string getName() const;
/**
* Return whether this backlight device exists.
*
* @return bool true if the backlight device exists, false otherwise
*/
bool exists() const;
/**
* Set the brightness of this backlight device.
*
* @param value The brightness value to set
* @return bool true if the brightness was set successfully, false otherwise
*/
bool setBrightness(uint8_t value);
void dump(int fd) const override;
private:
std::string mName;
std::string mBasePath;
uint32_t mMaxBrightness;
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

220
aidl/light/Devices.cpp Normal file
View File

@@ -0,0 +1,220 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Devices.h"
#define LOG_TAG "Devices"
#include <android-base/logging.h>
namespace aidl {
namespace android {
namespace hardware {
namespace light {
static const std::string kBacklightDevices[] = {
"backlight",
"panel0-backlight",
};
static std::vector<BacklightDevice> getBacklightDevices() {
std::vector<BacklightDevice> devices;
for (const auto& device : kBacklightDevices) {
BacklightDevice backlight(device);
if (backlight.exists()) {
LOG(INFO) << "Found backlight device: " << backlight.getName();
devices.push_back(backlight);
}
}
return devices;
}
static const std::string kLedBacklightDevices[] = {
"lcd-backlight",
};
static std::vector<LedDevice> getBacklightLedDevices() {
std::vector<LedDevice> devices;
for (const auto& device : kLedBacklightDevices) {
LedDevice backlight(device);
if (backlight.exists()) {
LOG(INFO) << "Found backlight LED device: " << backlight.getName();
devices.push_back(backlight);
}
}
return devices;
}
static const std::string kButtonLedDevices[] = {
"button-backlight",
"button-backlight1",
"button-backlight2",
};
static std::vector<LedDevice> getButtonLedDevices() {
std::vector<LedDevice> devices;
for (const auto& device : kButtonLedDevices) {
LedDevice button(device);
if (button.exists()) {
LOG(INFO) << "Found button LED device: " << button.getName();
devices.emplace_back(button);
}
}
return devices;
}
static const std::string kRgbLedDevices[][4] = {
{"red", "green", "blue", "/sys/class/leds/rgb/rgb_blink"},
};
static std::vector<RgbLedDevice> getNotificationRgbLedDevices() {
std::vector<RgbLedDevice> devices;
for (const auto& device : kRgbLedDevices) {
LedDevice red(device[0]);
LedDevice green(device[1]);
LedDevice blue(device[2]);
RgbLedDevice rgbLedDevice(red, green, blue, device[3]);
if (rgbLedDevice.exists()) {
LOG(INFO) << "Found notification RGB LED device: " << red.getName() << ", "
<< green.getName() << ", " << blue.getName();
devices.emplace_back(red, green, blue, device[3]);
}
}
return devices;
}
static const std::string kNotificationLedDevices[] = {
"left",
"white",
};
static std::vector<LedDevice> getNotificationLedDevices() {
std::vector<LedDevice> devices;
for (const auto& device : kNotificationLedDevices) {
LedDevice notification(device);
if (notification.exists()) {
LOG(INFO) << "Found notification LED device: " << notification.getName();
devices.emplace_back(notification);
}
}
return devices;
}
Devices::Devices()
: mBacklightDevices(getBacklightDevices()),
mBacklightLedDevices(getBacklightLedDevices()),
mButtonLedDevices(getButtonLedDevices()),
mNotificationRgbLedDevices(getNotificationRgbLedDevices()),
mNotificationLedDevices(getNotificationLedDevices()) {
if (!hasBacklightDevices()) {
LOG(INFO) << "No backlight devices found";
}
if (!hasButtonDevices()) {
LOG(INFO) << "No button devices found";
}
if (!hasNotificationDevices()) {
LOG(INFO) << "No notification devices found";
}
}
bool Devices::hasBacklightDevices() const {
return !mBacklightDevices.empty() || !mBacklightLedDevices.empty();
}
bool Devices::hasButtonDevices() const {
return !mButtonLedDevices.empty();
}
bool Devices::hasNotificationDevices() const {
return !mNotificationRgbLedDevices.empty() || !mNotificationLedDevices.empty();
}
void Devices::setBacklightColor(rgb color) {
for (auto& device : mBacklightDevices) {
device.setBrightness(color.toBrightness());
}
for (auto& device : mBacklightLedDevices) {
device.setBrightness(color.toBrightness());
}
}
void Devices::setButtonsColor(rgb color) {
for (auto& device : mButtonLedDevices) {
device.setBrightness(color.toBrightness());
}
}
void Devices::setNotificationColor(rgb color, LightMode mode, uint32_t flashOnMs,
uint32_t flashOffMs) {
for (auto& device : mNotificationRgbLedDevices) {
device.setBrightness(color, mode, flashOnMs, flashOffMs);
}
for (auto& device : mNotificationLedDevices) {
device.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
}
}
void Devices::dump(int fd) const {
dprintf(fd, "Backlight devices:\n");
for (const auto& device : mBacklightDevices) {
dprintf(fd, "- ");
device.dump(fd);
dprintf(fd, "\n");
}
dprintf(fd, "\n");
dprintf(fd, "Backlight LED devices:\n");
for (const auto& device : mBacklightLedDevices) {
dprintf(fd, "- ");
device.dump(fd);
dprintf(fd, "\n");
}
dprintf(fd, "\n");
dprintf(fd, "Button LED devices:\n");
for (const auto& device : mButtonLedDevices) {
dprintf(fd, "- ");
device.dump(fd);
dprintf(fd, "\n");
}
dprintf(fd, "\n");
dprintf(fd, "Notification RGB LED devices:\n");
for (const auto& device : mNotificationRgbLedDevices) {
dprintf(fd, "- ");
device.dump(fd);
dprintf(fd, "\n");
}
dprintf(fd, "\n");
dprintf(fd, "Notification LED devices:\n");
for (const auto& device : mNotificationLedDevices) {
dprintf(fd, "- ");
device.dump(fd);
dprintf(fd, "\n");
}
return;
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

52
aidl/light/Devices.h Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <vector>
#include "BacklightDevice.h"
#include "IDumpable.h"
#include "LedDevice.h"
#include "RgbLedDevice.h"
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
class Devices : public IDumpable {
public:
Devices();
bool hasBacklightDevices() const;
bool hasButtonDevices() const;
bool hasNotificationDevices() const;
void setBacklightColor(rgb color);
void setButtonsColor(rgb color);
void setNotificationColor(rgb color, LightMode mode = LightMode::STATIC, uint32_t flashOnMs = 0,
uint32_t flashOffMs = 0);
void dump(int fd) const override;
private:
// Backlight
std::vector<BacklightDevice> mBacklightDevices;
std::vector<LedDevice> mBacklightLedDevices;
// Buttons
std::vector<LedDevice> mButtonLedDevices;
// Notifications
std::vector<RgbLedDevice> mNotificationRgbLedDevices;
std::vector<LedDevice> mNotificationLedDevices;
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

32
aidl/light/IDumpable.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
namespace aidl {
namespace android {
namespace hardware {
namespace light {
/**
* Interface for dumpable objects using AIDL dump()'s file descriptor.
*/
class IDumpable {
public:
virtual ~IDumpable() = default;
/**
* Write information regarding this object to the given file descriptor using dprintf().
* You should avoid ending newline, since the caller will add it.
* @param fd The file descriptor to write to.
*/
virtual void dump(int fd) const = 0;
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

158
aidl/light/LedDevice.cpp Normal file
View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "LedDevice.h"
#define LOG_TAG "LedDevice"
#include <android-base/logging.h>
#include <fstream>
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
static const uint32_t kDefaultMaxBrightness = 255;
static const std::string kBaseLedsPath = "/sys/class/leds/";
static const std::string kBrightnessNode = "brightness";
static const std::string kMaxBrightnessNode = "max_brightness";
static const std::string kBreathNodes[] = {
"breath",
"blink",
};
static const std::string kBlinkNode = "blink";
static const std::string kStartIdxNode = "start_idx";
static const std::string kDutyPctsNode = "duty_pcts";
static const std::string kPauseLoNode = "pause_lo";
static const std::string kPauseHiNode = "pause_hi";
static const std::string kRampStepMsNode = "ramp_step_ms";
static constexpr int kRampSteps = 8;
static constexpr int kRampMaxStepDurationMs = 50;
LedDevice::LedDevice(std::string name)
: mName(name), mIdx(0), mBasePath(kBaseLedsPath + name + "/") {
if (!readFromFile(mBasePath + kMaxBrightnessNode, mMaxBrightness)) {
mMaxBrightness = kDefaultMaxBrightness;
}
for (const auto& node : kBreathNodes) {
if (std::ifstream(mBasePath + node).good()) {
mBreathNode = node;
break;
}
}
mSupportsTimed = std::ifstream(mBasePath + kBlinkNode).good() &&
std::ifstream(mBasePath + kStartIdxNode).good() &&
std::ifstream(mBasePath + kDutyPctsNode).good() &&
std::ifstream(mBasePath + kPauseLoNode).good() &&
std::ifstream(mBasePath + kPauseHiNode).good() &&
std::ifstream(mBasePath + kRampStepMsNode).good();
}
std::string LedDevice::getName() const {
return mName;
}
bool LedDevice::supportsBreath() const {
return !mBreathNode.empty();
}
bool LedDevice::supportsTimed() const {
return mSupportsTimed;
}
bool LedDevice::exists() const {
return std::ifstream(mBasePath + kBrightnessNode).good();
}
static std::string getScaledDutyPercent(uint8_t brightness) {
std::string output;
for (int i = 0; i < kRampSteps; i++) {
if (i != 0) {
output += ",";
}
output += std::to_string(i * 100 * brightness / (0xFF * kRampSteps));
}
return output;
}
bool LedDevice::setBrightness(uint8_t value, LightMode mode, uint32_t flashOnMs,
uint32_t flashOffMs) {
// Disable current blinking
if (mSupportsTimed) {
writeToFile(mBasePath + kBlinkNode, 0);
}
if (supportsBreath()) {
writeToFile(mBasePath + mBreathNode, 0);
}
switch (mode) {
case LightMode::TIMED:
if (mSupportsTimed) {
int32_t stepDuration = kRampMaxStepDurationMs;
int32_t pauseLo = flashOffMs;
int32_t pauseHi = flashOnMs - (stepDuration * kRampSteps * 2);
if (pauseHi < 0) {
stepDuration = flashOnMs / (kRampSteps * 2);
pauseHi = 0;
}
return writeToFile(mBasePath + kStartIdxNode, mIdx * kRampSteps) &&
writeToFile(mBasePath + kDutyPctsNode, getScaledDutyPercent(value)) &&
writeToFile(mBasePath + kPauseLoNode, pauseLo) &&
writeToFile(mBasePath + kPauseHiNode, pauseHi) &&
writeToFile(mBasePath + kRampStepMsNode, stepDuration) &&
writeToFile(mBasePath + kBlinkNode, 1);
}
// Fallthrough to breath mode if timed is not supported
FALLTHROUGH_INTENDED;
case LightMode::BREATH:
if (supportsBreath()) {
return writeToFile(mBasePath + mBreathNode, value > 0 ? 1 : 0);
break;
}
// Fallthrough to static mode if breath is not supported
FALLTHROUGH_INTENDED;
case LightMode::STATIC:
return writeToFile(mBasePath + kBrightnessNode, scaleBrightness(value, mMaxBrightness));
break;
default:
LOG(ERROR) << "Unknown mode: " << mode;
return false;
break;
}
}
void LedDevice::setIdx(int idx) {
mIdx = idx;
}
void LedDevice::dump(int fd) const {
dprintf(fd, "Name: %s", mName.c_str());
dprintf(fd, ", index: %d", mIdx);
dprintf(fd, ", exists: %d", exists());
dprintf(fd, ", base path: %s", mBasePath.c_str());
dprintf(fd, ", max brightness: %u", mMaxBrightness);
dprintf(fd, ", supports breath: %d", supportsBreath());
dprintf(fd, ", supports timed: %d", supportsTimed());
dprintf(fd, ", breath node: %s", mBreathNode.c_str());
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

102
aidl/light/LedDevice.h Normal file
View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <cstdint>
#include <string>
#include "IDumpable.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
enum LightMode {
STATIC,
BREATH,
TIMED,
};
/**
* A Linux LED device.
* @see https://docs.kernel.org/leds/leds-class.html
*/
class LedDevice : public IDumpable {
public:
LedDevice() = delete;
/**
* Constructor.
*
* @param name The name of the LED device
*/
LedDevice(std::string name);
/**
* Get the name of the LED device.
*
* @return std::string The name of the LED device
*/
std::string getName() const;
/**
* Return whether this LED device exists.
*
* @return bool true if the LED device exists, false otherwise
*/
bool exists() const;
/**
* Return whether this LED device supports breathing.
* When it doesn't, calling setBrightness with LightMode::BREATH will behave like
* LightMode::STATIC.
*
* @return bool true if the LED device supports breathing, false otherwise
*/
bool supportsBreath() const;
/**
* Return whether this LED device supports timed mode.
* When it doesn't, calling setBrightness with LightMode::TIMED will behave like
* LightMode::BREATH.
*
* @return bool true if the LED device supports timed mode, false otherwise
*/
bool supportsTimed() const;
/**
* Set the brightness of the LED device.
*
* @param value The brightness value to set
* @param mode The light mode to use
* @return bool true if the brightness was set successfully, false otherwise
*/
bool setBrightness(uint8_t value, LightMode mode = LightMode::STATIC, uint32_t flashOnMs = 0,
uint32_t flashOffMs = 0);
/**
* Set the index of the LED device.
*
* @param idx The index to set
*/
void setIdx(int idx);
void dump(int fd) const override;
private:
std::string mName;
int mIdx;
std::string mBasePath;
uint32_t mMaxBrightness;
std::string mBreathNode;
bool mSupportsTimed;
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

133
aidl/light/Lights.cpp Normal file
View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Lights.h"
#define LOG_TAG "Lights"
#include <android-base/logging.h>
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
#define AutoHwLight(light) \
{ .id = static_cast<int32_t>(light), .ordinal = 0, .type = light }
Lights::Lights() {
if (mDevices.hasBacklightDevices()) {
mLights.push_back(AutoHwLight(LightType::BACKLIGHT));
}
if (mDevices.hasButtonDevices()) {
mLights.push_back(AutoHwLight(LightType::BUTTONS));
}
if (mDevices.hasNotificationDevices()) {
mLights.push_back(AutoHwLight(LightType::BATTERY));
mLights.push_back(AutoHwLight(LightType::NOTIFICATIONS));
mLights.push_back(AutoHwLight(LightType::ATTENTION));
}
}
ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state) {
rgb color(state.color);
LightType type = static_cast<LightType>(id);
switch (type) {
case LightType::BACKLIGHT:
mDevices.setBacklightColor(color);
break;
case LightType::BUTTONS:
mDevices.setButtonsColor(color);
break;
case LightType::BATTERY:
mLastBatteryState = state;
updateNotificationColor();
break;
case LightType::NOTIFICATIONS:
mLastNotificationsState = state;
updateNotificationColor();
break;
case LightType::ATTENTION:
mLastAttentionState = state;
updateNotificationColor();
break;
default:
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
break;
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* _aidl_return) {
for (const auto& light : mLights) {
_aidl_return->push_back(light);
}
return ndk::ScopedAStatus::ok();
}
binder_status_t Lights::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
dprintf(fd, "Lights AIDL:\n");
dprintf(fd, "\n");
dprintf(fd, "Lights:\n");
for (const auto& light : mLights) {
dprintf(fd, "- %d: LightType::%s\n", light.id, toString(light.type).c_str());
}
dprintf(fd, "\n");
dprintf(fd, "Devices:\n");
mDevices.dump(fd);
dprintf(fd, "\n");
return STATUS_OK;
}
void Lights::updateNotificationColor() {
std::lock_guard<std::mutex> lock(mLedMutex);
bool isBatteryLit = rgb(mLastBatteryState.color).isLit();
bool isAttentionLit = rgb(mLastAttentionState.color).isLit();
bool isNotificationsLit = rgb(mLastNotificationsState.color).isLit();
const HwLightState state = isNotificationsLit ? mLastNotificationsState
: isAttentionLit ? mLastAttentionState
: isBatteryLit ? mLastBatteryState
: HwLightState();
rgb color(state.color);
LightMode lightMode;
switch (state.flashMode) {
case FlashMode::NONE:
lightMode = LightMode::STATIC;
break;
case FlashMode::TIMED:
lightMode = LightMode::TIMED;
break;
case FlashMode::HARDWARE:
lightMode = LightMode::BREATH;
break;
default:
LOG(ERROR) << "Unknown flash mode: " << static_cast<int>(state.flashMode);
lightMode = LightMode::STATIC;
break;
}
mDevices.setNotificationColor(color, lightMode, state.flashOnMs, state.flashOffMs);
return;
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

43
aidl/light/Lights.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/light/BnLights.h>
#include <mutex>
#include "Devices.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
class Lights : public BnLights {
public:
Lights();
ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override;
ndk::ScopedAStatus getLights(std::vector<HwLight>* _aidl_return) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
private:
std::vector<HwLight> mLights;
Devices mDevices;
HwLightState mLastBatteryState;
HwLightState mLastNotificationsState;
HwLightState mLastAttentionState;
std::mutex mLedMutex;
void updateNotificationColor();
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

146
aidl/light/RgbLedDevice.cpp Normal file
View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "RgbLedDevice.h"
#define LOG_TAG "RgbLedDevice"
#include <android-base/logging.h>
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
RgbLedDevice::RgbLedDevice(LedDevice red, LedDevice green, LedDevice blue, std::string rgbSyncNode)
: mRed(red), mGreen(green), mBlue(blue), mRgbSyncNode(rgbSyncNode), mColors(Color::NONE) {
if (mRed.exists()) {
mColors |= Color::RED;
}
if (mGreen.exists()) {
mColors |= Color::GREEN;
}
if (mBlue.exists()) {
mColors |= Color::BLUE;
}
if (supportsRgbSync()) {
mRed.setIdx(0);
mGreen.setIdx(1);
mBlue.setIdx(2);
}
}
bool RgbLedDevice::exists() const {
return mColors != Color::NONE;
}
bool RgbLedDevice::supportsBreath() const {
return (!mRed.exists() || mRed.supportsBreath()) &&
(!mGreen.exists() || mGreen.supportsBreath()) &&
(!mBlue.exists() || mBlue.supportsBreath());
}
bool RgbLedDevice::supportsTimed() const {
return (!mRed.exists() || mRed.supportsTimed()) &&
(!mGreen.exists() || mGreen.supportsTimed()) &&
(!mBlue.exists() || mBlue.supportsTimed());
}
bool RgbLedDevice::supportsRgbSync() const {
return std::ifstream(mRgbSyncNode).good();
}
bool RgbLedDevice::setBrightness(rgb color, LightMode mode, uint32_t flashOnMs,
uint32_t flashOffMs) {
bool rc = true;
if (mColors == Color::NONE) {
LOG(ERROR) << "No LEDs found";
return false;
}
if (mode == LightMode::TIMED && !supportsTimed()) {
// Not all LEDs support timed mode, force breathing mode
mode = LightMode::BREATH;
}
if (mode == LightMode::BREATH && !supportsBreath()) {
// Not all LEDs support breathing, force static mode
mode = LightMode::STATIC;
}
if (mode == LightMode::TIMED && supportsRgbSync()) {
rc &= writeToFile(mRgbSyncNode, 0);
}
if (mColors == Color::ALL) {
rc &= mRed.setBrightness(color.red, mode, flashOnMs, flashOffMs);
rc &= mGreen.setBrightness(color.green, mode, flashOnMs, flashOffMs);
rc &= mBlue.setBrightness(color.blue, mode, flashOnMs, flashOffMs);
} else {
// Check if we have only one LED
if (mColors == Color::RED) {
rc &= mRed.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
} else if (mColors == Color::GREEN) {
rc &= mGreen.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
} else if (mColors == Color::BLUE) {
rc &= mBlue.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
} else {
// We only have two LEDs, blend the missing color in the other two
if ((mColors & Color::RED) == Color::NONE) {
rc &= mBlue.setBrightness((color.blue + color.red) / 2, mode, flashOnMs,
flashOffMs);
rc &= mGreen.setBrightness((color.green + color.red) / 2, mode, flashOnMs,
flashOffMs);
} else if ((mColors & Color::GREEN) == Color::NONE) {
rc &= mRed.setBrightness((color.red + color.green) / 2, mode, flashOnMs,
flashOffMs);
rc &= mBlue.setBrightness((color.blue + color.green) / 2, mode, flashOnMs,
flashOffMs);
} else if ((mColors & Color::BLUE) == Color::NONE) {
rc &= mRed.setBrightness((color.red + color.blue) / 2, mode, flashOnMs, flashOffMs);
rc &= mGreen.setBrightness((color.green + color.blue) / 2, mode, flashOnMs,
flashOffMs);
}
}
}
if (mode == LightMode::TIMED && supportsRgbSync()) {
rc &= writeToFile(mRgbSyncNode, 1);
}
return rc;
}
void RgbLedDevice::dump(int fd) const {
dprintf(fd, "Exists: %d", exists());
dprintf(fd, ", supports breath: %d", supportsBreath());
dprintf(fd, ", supports timed: %d", supportsTimed());
dprintf(fd, ", supports RGB sync: %d", supportsRgbSync());
dprintf(fd, ", colors:");
if (mColors != Color::NONE) {
if (mColors & Color::RED) {
dprintf(fd, "\nRed: ");
mRed.dump(fd);
}
if (mColors & Color::GREEN) {
dprintf(fd, "\nGreen: ");
mGreen.dump(fd);
}
if (mColors & Color::BLUE) {
dprintf(fd, "\nBlue: ");
mBlue.dump(fd);
}
} else {
dprintf(fd, " None");
}
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

104
aidl/light/RgbLedDevice.h Normal file
View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "IDumpable.h"
#include "LedDevice.h"
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
/**
* A pool of LED devices that will be toggled based on the wanted color.
* Support all types of LED combinations, with a maximum of 3 LEDs.
* Also supports 2 color LEDs (*cough* ASUS *cough*).
*/
class RgbLedDevice : public IDumpable {
public:
RgbLedDevice() = delete;
/**
* Constructor.
*
* @param red The red LED device
* @param green The green LED device
* @param blue The blue LED device
* @param rgbSyncNode The path to RGB sync trigger
*/
RgbLedDevice(LedDevice red, LedDevice green, LedDevice blue, std::string rgbSyncNode);
/**
* Return whether this RGB LED device exists.
* This is true when at least one of the LEDs exists.
*
* @return bool true if the RGB LED device exists, false otherwise
*/
bool exists() const;
/**
* Return whether this RGB LED device supports breathing.
* This is true when all existing LEDs support breathing.
* In case this is false, calling setBrightness with LightMode::BREATH will behave like
* LightMode::STATIC.
*
* @return bool true if the RGB LED device supports breathing, false otherwise
*/
bool supportsBreath() const;
/**
* Return whether this RGB LED device supports timed mode.
* This is true when all existing LEDs support timed mode.
* In case this is false, calling setBrightness with LightMode::TIMED will behave like
* LightMode::BREATH.
*
* @return bool true if the RGB LED device supports timed mode, false otherwise
*/
bool supportsTimed() const;
/**
* Return whether this RGB LED device supports RGB sync.
*
* @return bool true if the RGB LED device supports RGB sync, false otherwise
*/
bool supportsRgbSync() const;
/**
* Set the brightness of this RGB LED device.
*
* @param color The color to set
* @param mode The mode to set
* @return bool true if the brightness was set successfully, false otherwise
*/
bool setBrightness(rgb color, LightMode mode = LightMode::STATIC, uint32_t flashOnMs = 0,
uint32_t flashOffMs = 0);
void dump(int fd) const override;
enum Color {
NONE = 0,
RED = 1 << 0,
GREEN = 1 << 1,
BLUE = 1 << 2,
ALL = RED | GREEN | BLUE,
};
private:
LedDevice mRed;
LedDevice mGreen;
LedDevice mBlue;
std::string mRgbSyncNode;
int mColors;
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

54
aidl/light/Utils.cpp Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Utils.h"
namespace aidl {
namespace android {
namespace hardware {
namespace light {
rgb::rgb() : red(0), green(0), blue(0) {}
rgb::rgb(uint8_t r, uint8_t g, uint8_t b) : red(r), green(g), blue(b){};
rgb::rgb(uint32_t color) {
// Extract brightness from AARRGGBB.
uint8_t alpha = (color >> 24) & 0xFF;
// Retrieve each of the RGB colors
red = (color >> 16) & 0xFF;
green = (color >> 8) & 0xFF;
blue = color & 0xFF;
// Scale RGB colors if a brightness has been applied by the user
if (alpha > 0 && alpha < 0xFF) {
red = red * alpha / 0xFF;
green = green * alpha / 0xFF;
blue = blue * alpha / 0xFF;
}
}
bool rgb::isLit() {
return !!red || !!green || !!blue;
}
static constexpr uint8_t kRedWeight = 77;
static constexpr uint8_t kGreenWeight = 150;
static constexpr uint8_t kBlueWeight = 29;
uint8_t rgb::toBrightness() {
return (kRedWeight * red + kGreenWeight * green + kBlueWeight * blue) >> 8;
}
uint32_t scaleBrightness(uint8_t brightness, uint32_t maxBrightness) {
return brightness * maxBrightness / 0xFF;
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

60
aidl/light/Utils.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <cstdint>
#include <fstream>
#include <string>
namespace aidl {
namespace android {
namespace hardware {
namespace light {
struct rgb {
rgb();
rgb(uint8_t r, uint8_t g, uint8_t b);
rgb(uint32_t color);
uint8_t red;
uint8_t green;
uint8_t blue;
bool isLit();
uint8_t toBrightness();
};
uint32_t scaleBrightness(uint8_t brightness, uint32_t maxBrightness);
template <typename T>
bool readFromFile(const std::string& file, T& content) {
std::ifstream fileStream(file);
if (!fileStream) {
return false;
}
fileStream >> content;
return true;
}
template <typename T>
bool writeToFile(const std::string& file, const T content) {
std::ofstream fileStream(file);
if (!fileStream) {
return false;
}
fileStream << content;
return true;
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@@ -0,0 +1,106 @@
on early-boot
# Backlight devices
chown system system /sys/class/backlight/backlight/brightness
chown system system /sys/class/backlight/backlight/max_brightness
chown system system /sys/class/backlight/panel0-backlight/brightness
chown system system /sys/class/backlight/panel0-backlight/max_brightness
# LED devices
chown system system /sys/class/leds/blue/blink
chown system system /sys/class/leds/blue/breath
chown system system /sys/class/leds/blue/brightness
chown system system /sys/class/leds/blue/duty_pcts
chown system system /sys/class/leds/blue/max_brightness
chown system system /sys/class/leds/blue/pause_hi
chown system system /sys/class/leds/blue/pause_lo
chown system system /sys/class/leds/blue/ramp_step_ms
chown system system /sys/class/leds/blue/start_idx
chown system system /sys/class/leds/button-backlight/blink
chown system system /sys/class/leds/button-backlight/breath
chown system system /sys/class/leds/button-backlight/brightness
chown system system /sys/class/leds/button-backlight/duty_pcts
chown system system /sys/class/leds/button-backlight/max_brightness
chown system system /sys/class/leds/button-backlight/pause_hi
chown system system /sys/class/leds/button-backlight/pause_lo
chown system system /sys/class/leds/button-backlight/ramp_step_ms
chown system system /sys/class/leds/button-backlight/start_idx
chown system system /sys/class/leds/button-backlight1/blink
chown system system /sys/class/leds/button-backlight1/breath
chown system system /sys/class/leds/button-backlight1/brightness
chown system system /sys/class/leds/button-backlight1/duty_pcts
chown system system /sys/class/leds/button-backlight1/max_brightness
chown system system /sys/class/leds/button-backlight1/pause_hi
chown system system /sys/class/leds/button-backlight1/pause_lo
chown system system /sys/class/leds/button-backlight1/ramp_step_ms
chown system system /sys/class/leds/button-backlight1/start_idx
chown system system /sys/class/leds/button-backlight2/blink
chown system system /sys/class/leds/button-backlight2/breath
chown system system /sys/class/leds/button-backlight2/brightness
chown system system /sys/class/leds/button-backlight2/duty_pcts
chown system system /sys/class/leds/button-backlight2/max_brightness
chown system system /sys/class/leds/button-backlight2/pause_hi
chown system system /sys/class/leds/button-backlight2/pause_lo
chown system system /sys/class/leds/button-backlight2/ramp_step_ms
chown system system /sys/class/leds/button-backlight2/start_idx
chown system system /sys/class/leds/green/blink
chown system system /sys/class/leds/green/breath
chown system system /sys/class/leds/green/brightness
chown system system /sys/class/leds/green/duty_pcts
chown system system /sys/class/leds/green/max_brightness
chown system system /sys/class/leds/green/pause_hi
chown system system /sys/class/leds/green/pause_lo
chown system system /sys/class/leds/green/ramp_step_ms
chown system system /sys/class/leds/green/start_idx
chown system system /sys/class/leds/lcd-backlight/blink
chown system system /sys/class/leds/lcd-backlight/breath
chown system system /sys/class/leds/lcd-backlight/brightness
chown system system /sys/class/leds/lcd-backlight/duty_pcts
chown system system /sys/class/leds/lcd-backlight/max_brightness
chown system system /sys/class/leds/lcd-backlight/pause_hi
chown system system /sys/class/leds/lcd-backlight/pause_lo
chown system system /sys/class/leds/lcd-backlight/ramp_step_ms
chown system system /sys/class/leds/lcd-backlight/start_idx
chown system system /sys/class/leds/left/blink
chown system system /sys/class/leds/left/breath
chown system system /sys/class/leds/left/brightness
chown system system /sys/class/leds/left/duty_pcts
chown system system /sys/class/leds/left/max_brightness
chown system system /sys/class/leds/left/pause_hi
chown system system /sys/class/leds/left/pause_lo
chown system system /sys/class/leds/left/ramp_step_ms
chown system system /sys/class/leds/left/start_idx
chown system system /sys/class/leds/red/blink
chown system system /sys/class/leds/red/breath
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/red/duty_pcts
chown system system /sys/class/leds/red/max_brightness
chown system system /sys/class/leds/red/pause_hi
chown system system /sys/class/leds/red/pause_lo
chown system system /sys/class/leds/red/ramp_step_ms
chown system system /sys/class/leds/red/start_idx
chown system system /sys/class/leds/rgb/rgb_blink
chown system system /sys/class/leds/white/blink
chown system system /sys/class/leds/white/breath
chown system system /sys/class/leds/white/brightness
chown system system /sys/class/leds/white/duty_pcts
chown system system /sys/class/leds/white/max_brightness
chown system system /sys/class/leds/white/pause_hi
chown system system /sys/class/leds/white/pause_lo
chown system system /sys/class/leds/white/ramp_step_ms
chown system system /sys/class/leds/white/start_idx
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.xiaomi
class hal
user system
group system
shutdown critical

View File

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

30
aidl/light/service.cpp Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Lights.h"
#define LOG_TAG "android.hardware.light-service.xiaomi"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using ::aidl::android::hardware::light::Lights;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>();
if (!lights) {
return EXIT_FAILURE;
}
const std::string instance = std::string() + Lights::descriptor + "/default";
binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?android:attr/colorControlNormal"
android:height="24dp"
android:width="24dp"
android:viewportWidth="72.0"
android:viewportHeight="72.0">
<path
android:fillColor="#FF000000"
android:pathData="M45,9L45,27L51,27L51,21L63,21L63,15L51,15L51,9L45,9M9,15L9,21L39,21L39,15L9,15M21,27L21,33L9,33L9,39L21,39L21,45L27,45L27,27L21,27M33,33L33,39L63,39L63,33L33,33M33,45L33,63L39,63L39,57L63,57L63,51L39,51L39,45L33,45M9,51L9,57L27,57L27,51L9,51z"/>
</vector>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?android:attr/colorControlNormal"
android:height="24dp"
android:width="24dp"
android:viewportWidth="72.0"
android:viewportHeight="72.0">
<path
android:fillColor="#FF000000"
android:pathData="M21,6L21,39L30,39L30,66C34.0185,62.1036 36.3516,56.7839 39.2006,52C43.3436,45.0435 48.7076,37.7933 51,30L40,30C43.3656,21.916 48.5711,14.4315 51,6L21,6z"/>
</vector>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?android:attr/colorControlNormal"
android:height="24dp"
android:width="24dp"
android:viewportWidth="72.0"
android:viewportHeight="72.0">
<path
android:fillColor="#FF000000"
android:pathData="M7.84,13.82C9.62,11.74 12.52,12.02 14.98,11.95C16.97,15.97 19,19.98 21,24C24,24 27,24 30,24C28,20 26,16 24,12C26,12 28,12 30,12C32,16 34,20 36,24C39,24 42,24 45,24C43,20 41,16 39,12C41,12 43,12 45,12C47,16 49,20 51,24C54,24 57,24 60,24C58,20 56,16 54,12C58,12 62,12 66,12C65.99,25.69 66.01,39.38 66,53.07C66.42,56.49 63.62,59.98 60.12,59.96C44.39,60.06 28.66,59.97 12.93,60C9.52,60.43 6.02,57.62 6.04,54.12C5.93,42.75 6.06,31.37 6,19.99C5.95,17.82 6.08,15.36 7.84,13.82Z"/>
</vector>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?android:attr/colorControlNormal"
android:height="24dp"
android:width="24dp"
android:viewportWidth="72.0"
android:viewportHeight="72.0">
<path
android:fillColor="#FF000000"
android:pathData="M36,9L36,40C32.245,38.8901 27.6726,38.2912 24.0154,40.179C17.5734,43.5044 15.8784,53.3215 20.4336,58.8912C25.822,65.4796 38.0937,64.1632 41.2577,55.9961C42.655,52.3894 42,47.7931 42,44L42,21L54,21L54,9L36,9z"/>
</vector>

View File

@@ -8,16 +8,16 @@
<!-- Dolby Atmos -->
<string-array name="dolby_profile_entries">
<item>@string/dolby_profile_dynamic</item>
<item>@string/dolby_profile_movie</item>
<item>@string/dolby_profile_video</item>
<item>@string/dolby_profile_music</item>
<item>@string/dolby_profile_custom</item>
<item>@string/dolby_profile_voice</item>
</string-array>
<string-array name="dolby_profile_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>8</item>
</string-array>
<string-array name="dolby_preset_entries" translatable="false">

View File

@@ -27,13 +27,13 @@
<string name="dolby_volume_leveler">Volume leveler</string>
<string name="dolby_connect_headphones">Connect headphones</string>
<string name="dolby_reset_profile">Reset to defaults</string>
<string name="dolby_reset_profile_toast">Successfully reset settings for %1$s profile</string>
<string name="dolby_reset_profile_toast">Succesfully reset settings for %1$s profile</string>
<!-- Dolby profiles -->
<string name="dolby_profile_dynamic">Dynamic</string>
<string name="dolby_profile_movie">Movie</string>
<string name="dolby_profile_video">Movie/Video</string>
<string name="dolby_profile_music">Music</string>
<string name="dolby_profile_custom">Custom</string>
<string name="dolby_profile_voice">Voice</string>
<!-- Dolby equalizer presets -->
<string name="dolby_preset_default">Flat (off)</string>

View File

@@ -18,7 +18,8 @@
android:entryValues="@array/dolby_profile_values"
android:defaultValue="0"
android:title="@string/dolby_profile_title"
android:summary="%s" />
android:summary="%s"
android:icon="@drawable/ic_dolby" />
<PreferenceCategory
android:title="@string/dolby_category_settings">

View File

@@ -11,13 +11,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.android.settingslib.spa.framework.theme.settingsBackground
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsTheme
@Composable
fun EqualizerScreen(
@@ -29,7 +28,7 @@ fun EqualizerScreen(
.fillMaxSize()
.padding(SettingsDimension.itemPadding)
.then(modifier),
color = MaterialTheme.colorScheme.settingsBackground
color = SettingsTheme.colorScheme.background
) {
Column(
verticalArrangement = Arrangement.Top,

View File

@@ -111,7 +111,6 @@ class DolbySettingsFragment : PreferenceFragment(),
switchBar.setChecked(dsOn)
profilePref.onPreferenceChangeListener = this
updateProfileIcon(profile)
profilePref.setEnabled(dsOn)
profilePref.apply {
if (entryValues.contains(profile.toString())) {
@@ -164,7 +163,6 @@ class DolbySettingsFragment : PreferenceFragment(),
val profile = newValue.toString().toInt()
dolbyController.profile = profile
(preferenceManager.preferenceDataStore as DolbyPreferenceStore).profile = profile
updateProfileIcon(profile)
updateProfileSpecificPrefs()
}
@@ -230,10 +228,10 @@ class DolbySettingsFragment : PreferenceFragment(),
ieqPref.setEnabled(enable)
dialoguePref.setEnabled(enable)
volumePref.setEnabled(enable)
bassPref.setEnabled(enable)
resetPref.setEnabled(enable)
hpVirtPref.setEnabled(enable && !isOnSpeaker)
stereoPref.setEnabled(enable && !isOnSpeaker)
bassPref.setEnabled(enable && !isOnSpeaker)
if (!enable) return
@@ -261,11 +259,11 @@ class DolbySettingsFragment : PreferenceFragment(),
spkVirtPref.setChecked(dolbyController.getSpeakerVirtEnabled(currentProfile))
volumePref.setChecked(dolbyController.getVolumeLevelerEnabled(currentProfile))
bassPref.setChecked(dolbyController.getBassEnhancerEnabled(currentProfile))
// below prefs are not enabled on loudspeaker
if (isOnSpeaker) {
stereoPref.summary = headphoneRes
bassPref.summary = headphoneRes
hpVirtPref.summary = headphoneRes
return
}
@@ -280,22 +278,17 @@ class DolbySettingsFragment : PreferenceFragment(),
}
}
bassPref.apply {
setChecked(dolbyController.getBassEnhancerEnabled(currentProfile))
summary = null
}
hpVirtPref.apply {
setChecked(dolbyController.getHeadphoneVirtEnabled(currentProfile))
summary = null
}
}
private fun updateProfileIcon(profile: Int) {
when (profile) {
0 -> profilePref.setIcon(R.drawable.ic_profile_dynamic)
1 -> profilePref.setIcon(R.drawable.ic_profile_movie)
2 -> profilePref.setIcon(R.drawable.ic_profile_music)
3 -> profilePref.setIcon(R.drawable.ic_profile_custom)
else -> profilePref.setIcon(R.drawable.ic_dolby)
}
}
companion object {
private const val TAG = "DolbySettingsFragment"
private val ATTRIBUTES_MEDIA = AudioAttributes.Builder()

View File

@@ -1,31 +0,0 @@
//
// Copyright (C) 2022-2024 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
cc_library_static {
name: "libudfpshandlerfactory",
srcs: ["UdfpsHandler.cpp"],
vendor: true,
header_libs: ["xiaomifingerprint_headers"],
}
cc_library_headers {
name: "xiaomifingerprint_headers",
export_include_dirs: ["include"],
vendor: true,
header_libs: ["libhardware_headers"],
export_header_lib_headers: ["libhardware_headers"],
}
cc_library_static {
name: "libudfps_extension.xiaomi",
srcs: ["UdfpsExtension.cpp"],
include_dirs: [
"frameworks/native/services/surfaceflinger/CompositionEngine/include",
],
header_libs: [
"generated_kernel_headers",
],
}

View File

@@ -14,6 +14,7 @@ cc_binary {
relative_install_path: "hw",
srcs: [
"BiometricsFingerprint.cpp",
"UdfpsHandler.cpp",
"service.cpp",
],
@@ -30,9 +31,24 @@ cc_binary {
"android.hardware.biometrics.fingerprint@2.3",
],
static_libs: [
"libudfpshandlerfactory",
],
header_libs: ["xiaomifingerprint_headers"],
}
cc_library_headers {
name: "xiaomifingerprint_headers",
export_include_dirs: ["include"],
vendor: true,
header_libs: ["libhardware_headers"],
export_header_lib_headers: ["libhardware_headers"],
}
cc_library_static {
name: "libudfps_extension.xiaomi",
srcs: ["UdfpsExtension.cpp"],
include_dirs: [
"frameworks/native/services/surfaceflinger/CompositionEngine/include",
],
header_libs: [
"generated_kernel_headers",
],
}

View File

@@ -1,27 +0,0 @@
aidl_interface {
name: "vendor.xiaomi.hardware.displayfeature",
vendor_available: true,
srcs: [
"vendor/xiaomi/hardware/displayfeature_aidl/*.aidl",
],
stability: "vintf",
backend: {
java: {
sdk_version: "module_current",
min_sdk_version: "30",
lint: {
// Disable linter to avoid error about fixed size arrays.
// Interface will only be accessed on devices >= U.
enabled: false,
},
},
},
owner: "xiaomi",
versions_with_info: [
{
version: "2",
imports: [],
},
],
frozen: true,
}

View File

@@ -1 +0,0 @@
cd486b29c0e2df9789995f54ffb594530db39428

View File

@@ -1,15 +0,0 @@
package vendor.xiaomi.hardware.displayfeature_aidl;
import vendor.xiaomi.hardware.displayfeature_aidl.IDisplayFeatureCallback;
@VintfStability
interface IDisplayFeature {
void notifyBrightness(int brightness);
void registerCallback(int displayId, IDisplayFeatureCallback callback);
void sendMessage(int messageId, int param, String message);
void sendPanelCommand(String command);
void sendPostProcCommand(int commandId, int param);
void sendRefreshCommand();
void setFeature(int featureId, int param1, int param2, int param3);
void setFunction(int functionId, int param1, int param2, int param3);
}

View File

@@ -1,6 +0,0 @@
package vendor.xiaomi.hardware.displayfeature_aidl;
@VintfStability
interface IDisplayFeatureCallback {
float displayfeatureInfoChanged(int displayId, int caseId, float modeId, float cookie);
}

View File

@@ -1,30 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package vendor.xiaomi.hardware.displayfeature_aidl;
@VintfStability
interface IDisplayFeature {
void notifyBrightness(int brightness);
void registerCallback(int displayId, vendor.xiaomi.hardware.displayfeature_aidl.IDisplayFeatureCallback callback);
void sendMessage(int messageId, int param, String message);
void sendPanelCommand(String command);
void sendPostProcCommand(int commandId, int param);
void sendRefreshCommand();
void setFeature(int featureId, int param1, int param2, int param3);
void setFunction(int functionId, int param1, int param2, int param3);
}

View File

@@ -1,23 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package vendor.xiaomi.hardware.displayfeature_aidl;
@VintfStability
interface IDisplayFeatureCallback {
float displayfeatureInfoChanged(int displayId, int caseId, float modeId, float cookie);
}

View File

@@ -1,15 +0,0 @@
package vendor.xiaomi.hardware.displayfeature_aidl;
import vendor.xiaomi.hardware.displayfeature_aidl.IDisplayFeatureCallback;
@VintfStability
interface IDisplayFeature {
void notifyBrightness(int brightness);
void registerCallback(int displayId, IDisplayFeatureCallback callback);
void sendMessage(int messageId, int param, String message);
void sendPanelCommand(String command);
void sendPostProcCommand(int commandId, int param);
void sendRefreshCommand();
void setFeature(int featureId, int param1, int param2, int param3);
void setFunction(int functionId, int param1, int param2, int param3);
}

View File

@@ -1,6 +0,0 @@
package vendor.xiaomi.hardware.displayfeature_aidl;
@VintfStability
interface IDisplayFeatureCallback {
float displayfeatureInfoChanged(int displayId, int caseId, float modeId, float cookie);
}

View File

@@ -1,27 +0,0 @@
aidl_interface {
name: "vendor.xiaomi.hardware.fingerprintextension",
vendor_available: true,
srcs: [
"vendor/xiaomi/hardware/fingerprintextension/*.aidl",
],
stability: "vintf",
backend: {
java: {
sdk_version: "module_current",
min_sdk_version: "30",
lint: {
// Disable linter to avoid error about fixed size arrays.
// Interface will only be accessed on devices >= U.
enabled: false,
},
},
},
owner: "xiaomi",
versions_with_info: [
{
version: "1",
imports: [],
},
],
frozen: true,
}

View File

@@ -1,6 +0,0 @@
package vendor.xiaomi.hardware.fingerprintextension;
@VintfStability
interface IXiaomiFingerprint {
int extCmd(int cmd, int param1);
}

View File

@@ -1,23 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package vendor.xiaomi.hardware.fingerprintextension;
@VintfStability
interface IXiaomiFingerprint {
int extCmd(int cmd, int param1);
}

View File

@@ -1,6 +0,0 @@
package vendor.xiaomi.hardware.fingerprintextension;
@VintfStability
interface IXiaomiFingerprint {
int extCmd(int cmd, int param1);
}

View File

@@ -1,27 +0,0 @@
aidl_interface {
name: "vendor.xiaomi.hw.touchfeature",
vendor_available: true,
srcs: [
"vendor/xiaomi/hw/touchfeature/*.aidl",
],
stability: "vintf",
backend: {
java: {
sdk_version: "module_current",
min_sdk_version: "30",
lint: {
// Disable linter to avoid error about fixed size arrays.
// Interface will only be accessed on devices >= U.
enabled: false,
},
},
},
owner: "xiaomi",
versions_with_info: [
{
version: "1",
imports: [],
},
],
frozen: true,
}

View File

@@ -1 +0,0 @@
2c3f4fe227305cd02c47fd3e1f847ac139b353cf

View File

@@ -1,14 +0,0 @@
package vendor.xiaomi.hw.touchfeature;
@VintfStability
interface ITouchFeature {
int getModeCurValueString(int touchId, int mode);
int getModeValues(int touchId, int mode);
int getTouchModeCurValue(int touchId, int mode);
int getTouchModeDefValue(int touchId, int mode);
int getTouchModeMaxValue(int touchId, int mode);
int getTouchModeMinValue(int touchId, int mode);
boolean resetTouchMode(int touchId, int mode);
boolean setEdgeMode(int touchId, int mode, in int[] value, int length);
void setTouchMode(int touchId, int mode, int value);
}

View File

@@ -1,31 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package vendor.xiaomi.hw.touchfeature;
@VintfStability
interface ITouchFeature {
int getModeCurValueString(int touchId, int mode);
int getModeValues(int touchId, int mode);
int getTouchModeCurValue(int touchId, int mode);
int getTouchModeDefValue(int touchId, int mode);
int getTouchModeMaxValue(int touchId, int mode);
int getTouchModeMinValue(int touchId, int mode);
boolean resetTouchMode(int touchId, int mode);
boolean setEdgeMode(int touchId, int mode, in int[] value, int length);
void setTouchMode(int touchId, int mode, int value);
}

View File

@@ -1,31 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package vendor.xiaomi.hw.touchfeature;
@VintfStability
interface ITouchFeature {
int getModeCurValueString(int touchId, int mode);
int getModeValues(int touchId, int mode);
int getTouchModeCurValue(int touchId, int mode);
int getTouchModeDefValue(int touchId, int mode);
int getTouchModeMaxValue(int touchId, int mode);
int getTouchModeMinValue(int touchId, int mode);
boolean resetTouchMode(int touchId, int mode);
boolean setEdgeMode(int touchId, int mode, in int[] value, int length);
void setTouchMode(int touchId, int mode, int value);
}

View File

@@ -3,14 +3,6 @@
SPDX-License-Identifier: Apache-2.0
-->
<compatibility-matrix version="1.0" type="framework">
<hal format="hidl" optional="true">
<name>android.hardware.media.c2</name>
<version>1.0</version>
<interface>
<name>IComponentStore</name>
<instance>dolby</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>com.fingerprints.extension</name>
<version>1.0</version>
@@ -57,22 +49,6 @@
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.dolby.hardware.dms</name>
<version>2.0</version>
<interface>
<name>IDms</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.dolby_v3_6.hardware.dms360</name>
<version>2.0</version>
<interface>
<name>IDms</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.goodix.hardware.biometrics.fingerprint</name>
<version>2.1</version>
@@ -209,17 +185,6 @@
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.xiaomi.hardware.misys</name>
<version>1.0</version>
<version>2.0</version>
<version>3.0</version>
<version>4.0</version>
<interface>
<name>IMiSys</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.xiaomi.hardware.mlipay</name>
<version>1.0-1</version>
@@ -260,15 +225,6 @@
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.xiaomi.hw.touchfeature</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>ITouchFeature</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>vendor.xiaomi.sensor.citsensorservice</name>
<version>1.1</version>