211 Commits
udc ... vic

Author SHA1 Message Date
7854cf6443 sepolicy: qti: Allow system server to detect oem charging
Signed-off-by: AnierinB <anierin@evolution-x.org>
2025-09-12 13:53:12 -04:00
DragonEmperor9480
87797f25be sepolicy: adress fingerprint denials
*1565  1775 E [ANC_TAC][File]: AncMkDir: fail to mkdir /data/vendor/fingerprint/info, errno = 13, errnostr = Permission denied
*667   667 W qseecomd: type=1400 audit(0.0:82): avc:  denied  { write } for  name="debase_context" dev="sda2" ino=565 scontext=u:r:tee:s0 tcontext=u:object_r:vendor_persist_fingerprint_file:s0 tclass=file permissive=0
*1565  1565 W fingerprint@2.1: type=1400 audit(0.0:106): avc:  denied  { write } for  name="tee_bind_core" dev="proc" ino=4026532098 scontext=u:r:hal_fingerprint_default:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=0
*667   667 W qseecomd: type=1400 audit(0.0:107): avc:  denied  { write } for  name="debase_context" dev="sda2" ino=565 scontext=u:r:tee:s0 tcontext=u:object_r:vendor_persist_fingerprint_file:s0 tclass=file permissive=0
*1565  1565 W fingerprint@2.1: type=1400 audit(0.0:78): avc:  denied  { write } for  name="tee_bind_core" dev="proc" ino=4026532098 scontext=u:r:hal_fingerprint_default:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=0
*1565  1565 W fingerprint@2.1: type=1400 audit(0.0:79): avc:  denied  { read } for  name="u:object_r:serialno_prop:s0" dev="tmpfs" ino=3880 scontext=u:r:hal_fingerprint_default:s0 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=0
*1565  1565 W fingerprint@2.1: type=1400 audit(0.0:80): avc:  denied  { create } for  name="image_raw" scontext=u:r:hal_fingerprint_default:s0 tcontext=u:object_r:fingerprint_vendor_data_file:s0 tclass=dir permissive=0
2025-09-12 13:53:12 -04:00
bc83d6ab33 sepolicy: qti: Allow system_server to r/w oplus_chg nodes 2025-09-12 13:53:12 -04:00
Broly1
55220ee27f keyhandler: Move Alert Slider to Sound settings and remove icon 2025-09-12 13:53:12 -04:00
Adhitya Mohan
6d23f9acaa Add icon and summary for alert slider settings 2025-09-12 13:53:12 -04:00
Adhitya Mohan
30dc0eecac Keyhandler: Export Keyhandler setting and service 2025-09-12 13:53:12 -04:00
inferno0230
da51d42fd5 sensors: Bump android.hardware.sensors to V3-ndk
Signed-off-by: inferno0230 <mail@inferno0230.in>
2025-09-12 13:53:12 -04:00
Alcatraz323
1a522811ae Implement DSPVolumeSynchronizer
Some Xiaomi devices have a speaker that needs a framework to cooperate
with DSP to synchronize volume so that the DSP can limit bass when the
volume is high to prevent distortion.

Change-Id: I750803d94161e1e7482552d2a39566f42e82fc0a
2025-09-12 13:53:12 -04:00
Ghosuto
99ff16bb54 dolby: Update to use new tooltip position provider API 2025-09-12 13:53:12 -04:00
Sugakesshaa
636b4d6428 vintf: Add oplus Dolby Atmos entries to FCM
Change-Id: Ifc4dff53e516f33b9e5581d56ce6f9c00f0da8cf
2025-09-12 13:53:12 -04:00
Sugakesshaa
fa4fe970ce dolby: Create a split makefile for Dolby
Change-Id: Ie191d7af0ee55c44cc939fc5dd1b6e45c965dbf4
2025-09-12 13:53:12 -04:00
Adithya R
9a9ac9f666 sepolicy: qti: Add sepolicy for Dolby Atmos
Change-Id: I8c41ff32e579cec9c871d6a0177ca027034281c8
2025-09-12 13:53:12 -04:00
Sugakesshaa
f725f3be91 dolby: Rebrand to oplus
Change-Id: Ic54a93647c0dcbe3b1ef8b576d80cc4c6bf74992
2025-09-12 13:53:12 -04:00
Fabian Leutenegger
cd00f3d796 dolby: Switch to MaterialTheme settingsBackground for EqualizerScreen background color
Change-Id: I546e3528814276eb857a650cb6c173d914550fb5
2025-09-12 13:53:12 -04:00
Bruno Martins
a726af6db4 dolby: Use all shared resources from devicesettings
Change-Id: Icd7f381c574ea36eb4d797cefd60ba9f1a0941bd
2025-09-12 13:53:12 -04:00
Pranav Vashi
9e91203f38 dolby: Remove deprecated PlainTooltipBox
Change-Id: I70ffff5ba30c5eeaff431e46c82eaf05d46e4cb0
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-09-12 13:53:12 -04:00
basamaryan
fe45968ff3 dolby: Fix build with kotlinc 1.9.0
Reformat the code while at it

Change-Id: I4f9fdc9d25eb57240612cff1b3bef3663014f9a8
2025-09-12 13:53:12 -04:00
Michael Bestas
556ea40ab7 dolby: Convert to SwitchPreferenceCompat
Change-Id: Ic1cbaba37d499da1855af9c3930f2df426e2d3af
2025-09-12 13:53:12 -04:00
Chaohui Wang
fcb33262c5 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-09-12 13:53:12 -04:00
Peter Kalauskas
8f6493a247 dolby: Enable use_resource_processor for all sysui deps
This will make the build faster

Test: m checkbuild
Bug: 295208392
Change-Id: I0c1bd901429bbe3bf81c1530e156735f8637a96e
2025-09-12 13:53:12 -04:00
Adithya R
2d7496345c 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-09-12 13:53:12 -04:00
Adithya R
460a99212e dolby: Introduce graphical equalizer
Squashed:

dolby: Refresh preset name on main screen

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

Change-Id: I38ee6ce594e5671af42afc3d4bf0f004329482b9
2025-09-12 13:53:12 -04:00
Pranav Vashi
a9875242af dolby: Add launcher icon
Change-Id: I4d36842ca96048f9b55604d66cc7741759d657f3
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
[adithya2306: Add monochrome icon as well]
Signed-off-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
2025-09-12 13:53:12 -04:00
Adithya R
cb104e3d65 dolby: Restore current profile _after_ resetting profiles
Ensure to end the onBootCompleted routine with the correct profile set.

Change-Id: I2d5f74a7c0145af2f9d064cd98fa2dc70e5a7acd
2025-09-12 13:53:12 -04:00
Adithya R
e5a3466a01 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-09-12 13:53:12 -04:00
Adithya R
791acfda43 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-09-12 13:53:12 -04:00
Adithya R
e7acd1fa7f dolby: Rewrite in Kotlin
Some cleanup and restructuring while we're at it.

Change-Id: I2f1fc53c202d91421c7b6af68c814c25398a62e4
2025-09-12 13:53:12 -04:00
Adithya R
55a0e6b7fc dolby: Revert "Re-enable speaker virtualization after bootup"
No longer necessary

Change-Id: Iac820eafa71ea3e4ccaad2bfa0fb76c37279a22a
2025-09-12 13:53:12 -04:00
Adithya R
b46821b47c 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-09-12 13:53:12 -04:00
Sugakesshaa
3fec8a2160 sepolicy: qti: Allow powerhal write to /proc
Change-Id: Id894d56fdf0df323e75004c90c0b904eb450837c
2025-09-12 13:53:12 -04:00
Sugakesshaa
55c9700299 sepolicy: qti: Allow binder calls for sensor hal to system_server
Change-Id: Ic624ff754f0bf7f60f443a449987e30ca2691dfd
2025-09-12 13:53:12 -04:00
pjgowtham
1e93163668 aidl: sensors: Add clang-format
Change-Id: Ifece344ef765d5437eefd59ecbe4cd50ce1295f5
2025-09-12 13:53:12 -04:00
pjgowtham
e5e0f18f31 overlay/sensors: Configure Doze brightness sensor
Oplus doze brightness sensors either reports 0 or 1

0.0 - Dark environment
1.0 - Bright environment

aod_light_mode value of 1 enables qcom,mdss-dsi-aod-low-mode-command
and any other value would enable qcom,mdss-dsi-aod-high-mode-command

Change-Id: I98e3ea6abe0375ca75dad1b82e0bc6a1551cbb0e
2025-09-12 13:53:12 -04:00
pjgowtham
373f8335ec overlay: qssi: Define quick_pickup sensor string
Tests: Ensure quick pickup works when the "Lift to check phone"
is enabled under settings (with fingerprint enrolled)

Change-Id: I00626512dcca51d666e37dda4b281575bf1a2ea7
2025-09-12 13:53:12 -04:00
Sebastiano Barezzi
4b6662f6cf overlay: qssi: Enable config_dozePulsePickup
Change-Id: Ice5cd780eb77e2ae78a3a84a0140c321ad84f143
2025-09-12 13:53:12 -04:00
pjgowtham
35c76b7f85 sepolicy: qti: Label sensors AIDL multihal
Change-Id: I51d1f5542f3bb6922d0f3d9b39777bc8b1ff58ff
Signed-off-by: Vaisakh Murali <mvaisakh@statixos.com>
2025-09-12 13:53:12 -04:00
pjgowtham
62f85bdab9 aidl: sensors: Standardize qti.sensor.amd to glance sensor
Change-Id: I65150cffde2bd8a48c33b26a0f139a24687f8591
2025-09-12 13:53:12 -04:00
Sugakesshaa
37f2b80fcc aidl: sensors: Invert value for pickup gesture event
- oplus pickup sensor inverts the value for it to work properly;
- Hence, invert the event check for it to work accordingly.

thanks to @ cyberknight777 for the idea

Test: Build, test lift to check phone.

Change-Id: If09de1758823e2246106d6e278ecc80ca5327ee5
2025-09-12 13:53:12 -04:00
Cosmin Tanislav
a71cd8bba5 aidl: sensors: Change standard tilt_detector to pickup_gesture
* ignore non-wakeup sensor variant
* ignore events that do not properly match a pickup

pjgowtham: The tilt_detector sensor already has inverted sensor events
for it to be any useful as standard sensor. Thus repurpose them as
pickup sensor.

Change-Id: Ibe2f9fee1551da613713d40c1b8d0a26d38a93ae
Signed-off-by: ralph950412 <ralph950412@gmail.com>
Signed-off-by: Sugakesshaa <sugakesshaa@pixelos.net>
2025-09-12 13:53:12 -04:00
Cosmin Tanislav
07a7277cc7 aidl: sensors: Avoid target name conflicts
Change-Id: Ib6426caf68fe1a7a7f637bdc5c4f0036866f8b78
Signed-off-by: ralph950412 <ralph950412@gmail.com>
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
2025-09-12 13:53:12 -04:00
Arian
357e7bdd36 aidl: sensors: Change default applicable license to Android-Apache-2.0
hardware_interfaces_license is not available here.

Change-Id: I8c8d00cdeda2739c3e4419f979f1fbf0ef66fc0a
2025-09-12 13:53:12 -04:00
ralph950412
f1565a99e2 aidl: sensors: Import 2.X sensors hal proxy
* From android-14.0.0_r15

Change-Id: Id6f37920db2869574ca1b8e04c10e6ec3268ad4b
Signed-off-by: ralph950412 <ralph950412@gmail.com>
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
2025-09-12 13:53:12 -04:00
ralph950412
5dc2395c1a aidl: sensors: Import aidl sensors MultiHal
* From android-14.0.0_r15

Change-Id: Id7d8dfae1290bdba84d5a9f4c6583d54a2769ba8
Signed-off-by: ralph950412 <ralph950412@gmail.com>
2025-09-12 13:53:12 -04:00
pjgowtham
b93792e127 aidl: vibrator: Use THUD effect from wly for DOUBLE_CLICK
Change-Id: I4f1a718254ca1df5167956371e11b4102b10094c
2025-09-12 13:53:12 -04:00
pjgowtham
befcb928b3 aidl: vibrator: Minimize code for ledVibratorDevice
This fixes vibration on ziti where it works only when strace is used.

* Minimize code wherever applicable.
* Remove writes to /rtp since we are not using them.

Change-Id: I385fe64b33e541bc398e58dbbf67a728edff8b24
2025-09-12 13:53:12 -04:00
pjgowtham
7f3969b7c7 sepolicy: qti: Allow init to write to usb nodes for enabling OTG
Change-Id: I14d209d1d04ba6aae077f828a71f5683b4a6405c
2025-09-12 13:53:12 -04:00
inferno0230
34a24318a8 sepolicy: qti: Label SM7550 charging sysfs path
Change-Id: Ia79079f3df34714e5a8f9294d3db6048552609e6
Signed-off-by: inferno0230 <mail@inferno0230.in>
2025-09-09 22:06:47 +02:00
LuK1337
495cfb6640 sepolicy: qti: Allow vendor_init to set vendor_fingerprint_prop
Change-Id: Icc898bba9d8a06b79e1cfcf34412871471a9bdf7
Signed-off-by: inferno0230 <mail@inferno0230.in>
2025-09-09 19:54:53 +05:30
dianlujitao
7a643a4105 sepolicy: qti: Move proc_horae to vendor
This fixes booting AOSP GSIs.

Fixes: 8acb73ff6a ("sepolicy: qti: Add support for horae service")
Change-Id: Ica812bb31d6c60b4ec5f6837de7712bd0c275543
2025-09-07 15:29:03 +08:00
dianlujitao
8ae5447fc5 Euicc: Add China version support
Despite lack of native eSIM hardware, this enables managing removable
eUICCs through EuiccGoogle

Change-Id: I9d5a360dde85ede18761ff795641e199507ff688
2025-09-06 14:39:20 +00:00
LuK1337
20b9ca79d6 livedisplay: Use PWM turbo for IAntiFlicker if available
Change-Id: I4162f79c5309038dfff1bd00f2ca8a726c7eb206
2025-09-06 13:56:59 +00:00
LuK1337
b7e4686284 kernel-headers: Add PANEL_IOCTL_{GET,SET}_PWM_TURBO
Change-Id: I0c63693be15a09baa582d14113b642e086e94d6e
2025-09-06 13:56:59 +00:00
grep
641f44934c vintf: Bump vendor.oplus.hardware.charger to V8
lexus shipped with V8.

Change-Id: I0b4733fcb7f5e3ac0834b8526e1ec5a99fd0e8c3
2025-09-06 12:25:27 +02:00
Bruno Martins
d2e134e7c0 interfaces: Mark all aidl interfaces as system_ext_specific
Change-Id: I62d8099cae1d3c2cbe98d5bc514a0713eb84cbe9
2025-09-05 17:11:22 +01:00
Bruno Martins
860533d2bb interfaces: Update ICharger all the way to V8
V7 adds GET_RX_DISABLE_STATUS and SET_RX_DISABLE enum entries on top of
V6 and V8 finally adds only GET_BATTERY_SEC_IC_TEST_STATUS.

Change-Id: I134bac4ffc536280dbb778a4a349943b67c175dc
2025-09-05 15:49:48 +01:00
Bruno Martins
70168c51f2 interfaces: Bump ICharger directly to V5
Looks like V4 never existed.

Change-Id: I1999da190461411913e98d98c258a2825fb039d5
2025-09-05 15:48:10 +01:00
Bruno Martins
c0d70dc0f9 interfaces: Update ICharger to V3
Change-Id: Ife15bb3b9f51dbc83bb975a7603f47985e1178bd
2025-09-05 15:47:13 +01:00
Bruno Martins
e8d95112d7 interfaces: Update ICharger to V2
Change-Id: I2ffe384dad647c3e115d6bb1d2e7d85e94d720e5
2025-09-05 15:46:18 +01:00
Bruno Martins
8c1e19bdb8 interfaces: Add vendor.oplus.hardware.charger V1
Change-Id: Ia3916a80e106c3b92428b1239c0fae90b8a5eaf3
2025-09-05 15:45:00 +01:00
Bruno Martins
a9438581bb sepolicy: qti: Add inital eSIM support
Change-Id: Iae2d3c17a6eb5a9b1c71198c8ac861ad4e5f85d5
2025-09-05 13:42:42 +00:00
Bruno Martins
63795ed4d4 sepolicy: qti: Update compatibility mapping files
Change-Id: I6d10fa03042e4f360a494a7eb2c9ffd0502c86a4
2025-09-04 16:05:55 +01:00
chandu078
8acb73ff6a sepolicy: qti: Add support for horae service
Service required for thermal management, as it reports and updates shell
temperature to /proc/shell-temp.

Change-Id: I02e2ddeda461cbb2ead1348edc6ebf57b8f7fdde
2025-09-04 13:30:17 +01:00
LuK1337
3633fe6cbe oplus: Get rid of in_ prefix
Change-Id: Ibdafd315098ccc54ec19f298bdb28cb894017489
2025-09-04 11:17:09 +00:00
pjgowtham
b122025d2d Introduce vendor.oplus.hardware.performance-service
Dummy service named differently from the stock one to avoid conflicts.

This can be used on devices that do not include CPU ricing, but still
require the service to register for camera and prebuilt audio stack to
actually work.

Change-Id: I41087aefe9af57e7a1161a3a71ab3b9e849925f2
2025-09-04 10:14:22 +00:00
pjgowtham
8ecfa3412a interfaces: Add vendor.oplus.hardware.performance V1
Change-Id: I5a56cdc826495e1770905e3286bcbc2bef0cf2a3
2025-09-04 10:16:09 +01:00
LineageOS Infra
826524b2cb Automatic translation import
Change-Id: I433a0975161c90f6e9cec98e824f56c3c80e39a1
2025-09-01 14:54:29 +00:00
Bruno Martins
8393454ee6 usb_compositions: Restore QCOM VID/PID combos for diag
This re-allows installing Qualcomm drivers for accessing diag,
serial_cdev, rmnet (and others) devices. Needed for QPST Flash Tool.

Change-Id: Iafe2236bb63adb005bfecae46887c58c69db8ca2
2025-09-01 14:03:27 +00:00
dianlujitao
0b09eeb4b7 KeyHandler: Populate tri-state-key state on boot
Change-Id: I11e785b5824d581f748e038f292c8846b2a13a0f
2025-09-01 14:50:41 +01:00
LuK1337
23a4f0c429 sepolicy: qti: Add system_oplus_radio_prop to *.ignore.cil
Change-Id: If943028a54f7a7f32f289bf080f6565052bdaf40
2025-08-31 20:00:33 +02:00
pjgowtham
0ad31fba1e sepolicy: qti: Let qti secure_element rw /dev/nq-nci
vendor.qti.secu: type=1400 audit(0.0:2346): avc:  denied  { getattr }
for  path=/dev/nq-nci dev=tmpfs ino=1371
scontext=u:r:hal_secure_element_default:s0
tcontext=u:object_r:nfc_device:s0 tclass=chr_file permissive=1

Spotted on ferrari.

Change-Id: I8869fffae3cc6028b6b8ff009bd84108e2a53ada
2025-08-25 13:59:35 +02:00
pjgowtham
9b27b2665b fingerprint: Shim property_get() as well
On OnePlus Nord CE3 (ziti), shimming `__system_property_get()` is not
enough. Without this change, `vendor.fingerprint.cali` is set to 0 when
`ro.boot.vbmeta.device_state` is unset.

Test: Ensure adb logcat | grep "lcd LockState" does not show up as NULL
      Ensure adb shell getprop vendor.fingerprint.cali is 1
Change-Id: I913f00db1542a28aaaa11dba93fcce67b39717bf
2025-08-25 09:49:43 +00:00
pjgowtham
1477e8b42e sepolicy: qti: Label awinic vibrator sysfs for ziti
Change-Id: I6543983b6de8f7852015ea6a304be9aa809dc65f
2025-08-24 21:23:41 +05:30
LuK1337
4af7f26d3f sepolicy: qti: oplusSensor -> oplus_sensor
Matches new AIDL naming style.

Change-Id: I93a22091f54df5c48d105bc82d51b90bcf1e59e3
2025-08-22 10:06:40 +02:00
pjgowtham
04441ff343 sepolicy: qti: Label and add rules for oplusSensor AIDL
Change-Id: I451d7bf6bb110ed900ff5258cdcf6566945ab490
2025-08-22 10:06:39 +02:00
pjgowtham
93e8cfc069 sepolicy: qti: Let vendor_hal_oplusSensor_default search /dev/block
Change-Id: I248bd96c9753a4c9f51643368a0a5f67d52729df
2025-08-22 09:58:37 +02:00
pjgowtham
17d525da8f sepolicy: qti: Let hal_oplus_charger_aidl rw /dev/oplus_chg
Change-Id: I222aed7542f5750a3fe2f062998237bc00d22a3a
2025-08-22 09:49:45 +02:00
pjgowtham
af977627d4 sepolicy: qti: Let hal_oplus_charger_aidl rw vendor_sysfs_battery_supply
Change-Id: I058aad89acba10eaae84734341d30d1efa8e4a2f
2025-08-22 09:49:45 +02:00
pjgowtham
00c112c97a sepolicy: qti: Update qseecom rules for fingerprint
Change-Id: I34cbd4642f1c03446d1e57da079e5e495c2326cc
2025-08-22 07:43:54 +00:00
pjgowtham
9914060348 sepolicy: qti: Label goodix fingerprint property
W /system/bin/init: type=1107 audit(0.0:13): uid=0 auid=4294967295
ses=4294967295 subj=u:r:init:s0 msg='avc:  denied  { set } for
property=gf.debug.dump_data pid=1873 uid=1000 gid=1000
scontext=u:r:hal_fingerprint_default:s0 tcontext=u:object_r:default_prop:s0
tclass=property_service permissive=0'

Change-Id: I07acc42f6a5cba7e7b94f8473feb0540eee9096c
2025-08-22 07:43:54 +00:00
pjgowtham
abe43816a2 sepolicy: qti: Let camera hal rw /proc/qcom_flash
On Ziti (OnePlus Nord CE 3), this seems necessary for the torchlight
function to work.

Change-Id: I37ac5d7a1578d939d61728e8292c47b2fa9d870d
2025-08-22 09:35:36 +02:00
pjgowtham
655f8c1814 sepolicy: qti: Label wly wakeup nodes
wly / # cat /sys/devices/platform/soc/984000.i2c/i2c-5/5-003b/name
p9415-rx
wly / # cat /sys/devices/platform/soc/990000.i2c/i2c-6/6-004b/name
synaptics-s3908
wly / # cat /sys/devices/platform/soc/a84000.i2c/i2c-8/8-0028/name
sn-nci

Change-Id: I8aef0c21df2af86b06515ef609729c352770a260
2025-08-22 09:28:01 +02:00
pjgowtham
8da66b3786 sepolicy: qti: Label ferrari wakeup nodes
ferrari / # cat /sys/devices/platform/soc/990000.i2c/i2c-5/5-004b/name
synaptics-s3908
ferrari / # cat /sys/devices/platform/soc/a84000.i2c/i2c-7/7-0028/name
sn-nci

Change-Id: Ia2af6499a912697694ee24f209726a974887545f
2025-08-22 09:26:25 +02:00
pjgowtham
19cd98ab96 sepolicy: qti: Label lunaa/ziti wakeup nodes
lunaa / # cat /sys/devices/platform/soc/a84000.i2c/i2c-1/1-0008/name
st21nfc
lunaa / # cat /sys/devices/platform/soc/a94000.i2c/i2c-2/2-0038/name
fts
ziti / # ls /sys/devices/platform/soc/a94000.spi/spi_master/spi1/spi1.0/
driver           fts_rw_reg  supplier:18200000.rsc:rpmh-regulator-ldoc12
driver_override  input       supplier:18200000.rsc:rpmh-regulator-ldoc3
fts_dump_reg     modalias    supplier:f000000.pinctrl
fts_esd_check    of_node     supplier:regulator.36
fts_fw_version   power       supplier:regulator.47
fts_hw_reset     statistics  uevent
fts_irq          subsystem   wakeup

Change-Id: I2933a1fb695f72cd859d6654947ac37bd7f3f77f
2025-08-21 17:22:41 +05:30
LuK1337
4ee6ecda7e livedisplay: Add IAdaptiveBacklight support
Change-Id: Id11b96f58efb494b05e089d9954139d0c01366be
2025-08-18 00:16:52 +02:00
LuK1337
ef177ba4aa kernel-headers: Add PANEL_IOCTL_{GET,SET}_CABC_STATUS
Change-Id: I011b689bbba2888d3d7bf94cfc8e012d2ea3bfaf
2025-08-17 23:55:40 +02:00
LuK1337
622f8070f3 livedisplay: Migrate to AIDL
Change-Id: I8dbe9ed99549aff3e7fcff553482a4c45aae67ef
2025-08-17 23:40:08 +02:00
basamaryan
55dd4cee89 sepolicy: qti: Label missing SM8350 wakeup nodes
MT2111_IND / # cat /sys/devices/platform/soc/884000.i2c/i2c-10/10-0028/name
sn-nci
MT2111_IND / # cat /sys/devices/platform/soc/990000.i2c/i2c-7/7-004b/name
synaptics-s3908

Change-Id: I76b2da5f17b2b64254a8f21e328352bb0743bcf0
2025-08-17 21:19:08 +02:00
Michael Bestas
fc992cd6c8 overlay: qssi: Remove deprecated telephony overlays
These are no longer wired up and should be set in CarrierConfig
where needed

Change-Id: Ie16d41b2ee73c77c3475dd0b24e4d46804195a5c
2025-08-15 21:39:22 +00:00
Cosmin Tanislav
037413d7ac overlay: qssi: Remove unused config_speed_up_audio_on_mt_calls
Change-Id: I2860ab34e0252418236a4d90623b4fbfc6ad994a
2025-08-15 21:39:11 +00:00
dianlujitao
d3b35847b1 IFAAService: Wire up oplus fingerprint pay AIDL
Change-Id: Ibbac7e3c4d6591b712cbdcfb3eda955fbb78f8f3
2025-08-10 15:38:47 +01:00
dianlujitao
6be8136317 Import IFAAService from hardware/xiaomi
Change-Id: I55b8c0d1a8832b85f90fb0874d93a146be772176
2025-08-10 15:38:47 +01:00
dianlujitao
179e2abe46 sepolicy: qti: Add support for fingerprint pay
Change-Id: I298b9b1c8b733c05fd16687ec06fa9dd916e972c
2025-08-10 15:38:45 +01:00
dianlujitao
5d5ed9cad8 Add vendor.oplus.hardware.biometrics.fingerprintpay-V1 AIDL interface
Based on CPH2653_15.0.0.840

Change-Id: I65d6755874e96b905c4a528dcdf000d30a159314
2025-08-09 11:04:37 +01:00
dianlujitao
0d8b5aa9d4 sepolicy: Move attributes to public
Change-Id: I527559b1a970cbbeefff0825a494be0d577ecda3
2025-08-09 11:04:37 +01:00
Vivekachooz
08ff2f8522 sepolicy: qti: Label missing sm6375 wakeup nodes
Change-Id: Ia2123ff041617a39d34bc691d9cc662a2f60daec
2025-08-08 20:17:33 +05:30
Sebastiano Barezzi
91ac590976 overlay: qssi: Drop MMS user agent overlays
* Current profile URL points to a 404 page

Change-Id: I92f3ded52dda04f6cec5709d51c84b32f39d8095
2025-08-06 17:18:07 +02:00
LuK1337
f9faa7d9ed sepolicy: qti: Remove unwanted newline at the end of genfs_contexts
Accidentally introduced with e8f2b8aacd.

Change-Id: I6b902f867f6282781073a635a69ac8cc77575c4e
2025-08-02 22:35:44 +02:00
dianlujitao
5be9c6e55b Introduce nrmodeswitcher
This configures the NR mode to "SA Preferred" upon each boot (a setting
that persists even after a factory reset), which is desirable in most
cases. The mode can be customized using ro.vendor.radio.auto_nr_mode:
  0: NSA Preferred
  1: NSA Only
  2: SA Only
  3: SA Preferred

Change-Id: I86ad739167a51af04c041887a93462bf5bb5e32f
2025-07-30 22:45:08 +01:00
pjgowtham
29a150eca3 wvmkiller: Restart widevine hal 1.4 on disabling L1
Change-Id: I7690e13524418204c005e3e562dc951a90bdbdd1
2025-07-30 22:42:26 +01:00
dianlujitao
39ad2e265c Add vendor.oplus.hardware.radio-V2 AIDL interface
Based on oplus-telephony-common.jar from qssi_64-user 15 AP3A.240617.008 1748422485332 release-keys

Change-Id: I90058c22ca1317967605690165efd0c5c4504fed
2025-07-27 10:31:02 +01:00
dianlujitao
8fa8bee879 Add vendor.oplus.hardware.radio-V1 AIDL interface
Based on oplus-telephony-common.jar from qssi-user 14 UKQ1.230924.001 1699668118465 release-keys

Change-Id: I3b29f44a9e3a3c2b2c5fd843d3d19b37eb0037c0
2025-07-27 10:31:02 +01:00
Bruno Martins
9315077c67 interfaces: Add vendor.oplus.hardware.esim V1
Change-Id: I7cbbdc8910073261b3f07603b3dc012de3fdbfc0
2025-07-27 10:31:02 +01:00
Bruno Martins
a2bf842855 sepolicy: qti: Label oplus sensor props
Change-Id: I72fca9f8507cace163f1e344d60f619d1d87e3e9
2025-07-27 10:31:02 +01:00
chandu078
5da3fbb258 sepolicy: qti: Allow rild to search oplus_reserve_file
Change-Id: I4d700def0c84da2cda2af8e88b6cac224b6dffc3
2025-07-26 21:20:50 +05:30
Bruno Martins
21cab7e9a9 usb_compositions: 0x05C6 -> 0x22D9
Wrong VID causes ADB/USB issues on Windows.

Change-Id: Iadf9c00b679af90614553957142ae839c9d74492
Signed-off-by: inferno0230 <mail@inferno0230.in>
2025-07-22 22:05:34 +00:00
Bruno Martins
3b02db249a sepolicy: qti: Add support for pogo pin keyboard
Change-Id: I941e779c380f85edb61c69fcf891dacd40921d9f
2025-07-19 23:46:02 +01:00
Bruno Martins
8ae42047ec vintf: Add pogo pin keyboard interface
Change-Id: I13e53a96f10ad82d450b4acb7106e4aa39e7686c
2025-07-19 23:46:02 +01:00
LuK1337
e8f2b8aacd sepolicy: qti: Label OnePlus Pad 3 wakeup nodes
Change-Id: Ife85a0aee81ee79c115aeaf475b130fae7177fa1
2025-07-19 18:36:42 +00:00
LuK1337
f6bd8f76c4 sepolicy: qti: Add rules for nvram{_qmi,_server}
Spotted on erhai.

Change-Id: Idec44370c5e51fd65394fd7c9523b905d9a400d1
2025-07-19 18:36:42 +00:00
LuK1337
d4cfb60cf7 Introduce OplusPen
Change-Id: Icfc9d2d8172aa01bf1c71a5a23a8e6387660a746
2025-07-19 18:36:42 +00:00
LineageOS Infra
d58d8728aa Automatic translation import
Change-Id: I06723c2cb0ac2c6d2d6c693eb2927ffd7f9f54a7
2025-07-15 17:08:20 +00:00
Bruno Martins
363fa24baa vintf: Update fwk matrix for OOS 15.0.2
Change-Id: I3b851053dc540ee94b49128119ddb06146b5c6ed
2025-07-12 17:53:54 +00:00
Bruno Martins
a18c5e4bd5 sepolicy: qti: Label reserve files
Not everything is used, but it doesn't hurt to be labeled.

Change-Id: I540ab1c8617702d36a1da62feb3c5db2dd00ad99
2025-07-12 17:04:16 +01:00
LuK1337
c890a7708a sepolicy: qti: Use custom label for oplus subsys_imsrtp
Matches stock ROM (and fixes build for older platforms).

Also, it seems like the previous rule was wrong anyway given that it
allowed wrong domain to register this service.

Change-Id: Iad2e3e9a4b1b73c989571d37ae58cac91b018ecb
2025-07-08 09:46:45 +02:00
Michael Bestas
8c9358776c sepolicy: qti: Remove duplicate labels
Change-Id: I3575e6bad93b2f9d69f94033944c44b7f9fbc243
2025-07-07 13:52:00 +03:00
Bruno Martins
1a462ed83c touch: Implement GloveMode support
Change-Id: I1bb2f502e5b6947dfb2d68572b098d0e5b058c28
2025-07-06 23:56:31 +01:00
Bruno Martins
74dbc92458 Euicc: Add OnePlus 13 support
Change-Id: I970d9fbc0ee975962887ea0d61beeee5001183cf
2025-07-06 23:56:31 +01:00
chandu078
6c901c1bef sepolicy: qti: Bring up support for dodge (OnePlus 13)
Co-authored-by: Bruno Martins <bgcngm@gmail.com>
Change-Id: I63828b2c1cb27524845cc63271c0978de78b3374
Signed-off-by: chandu078 <chandudyavanapelli03@gmail.com>
2025-07-06 23:56:31 +01:00
dianlujitao
12190ecbc4 aidl: vibrator: qti: load effects from blobs
Change-Id: I55350bea3b7c4f31a62b60a6792ba2a343c72970
2025-07-06 23:01:45 +01:00
dianlujitao
b0fb5146b2 vintf: add more AIDL services to device FCM
Change-Id: I1f61cb7a96d23ce90fa6be7a2431015b2a727be1
2025-07-06 14:51:27 +01:00
DtHnAme
00f0edf25e power: Implement DT2W through OplusTouch
Co-authored-by: Maitreya25 <maitreyapatni25@gmail.com>
Co-authored-by: Mashopy <eliasgheeraert@gmail.com>
Co-authored-by: Bruno Martins <bgcngm@gmail.com>
Change-Id: I5ad57428aeefe68c8a188aa1e445f4091cbc0d8a
2025-07-06 14:51:26 +01:00
Maitreya25
165c5e47a9 touch: Support interfacing with stock OplusTouch service
Co-authored-by: inferno0230 <mail@inferno0230.in>
Co-authored-by: Mashopy <eliasgheeraert@gmail.com>
Co-authored-by: Bruno Martins <bgcngm@gmail.com>
Change-Id: I305ac931dac35a7fa422745f4250ffb1145c3bf6
2025-07-06 15:39:16 +02:00
LuK1337
8b6ff63e03 touch: Introduce vendor.oplus.hardware.touch-headers
Change-Id: If93b1305f7ee82f2c954969f83c052d0b3a2772b
2025-07-06 15:39:15 +02:00
chandu078
a6255edcb4 sepolicy: qti: Bring up support for waffle (OnePlus 12)
Co-authored-by: John Galt <johngaltfirstrun@gmail.com>
Change-Id: I5b3a87dda201c5779ab4826352ffddc3d1ce4fd2
Signed-off-by: chandu078 <chandudyavanapelli03@gmail.com>
2025-07-04 03:12:32 +01:00
bengris32
07c948a77c oplus-fwk: Add OplusNecManager stub implementation
* Required by RMX3572 (RMX3572_11.F.08_2080_202407301657) IMS stack.

Change-Id: I471f990a5f3717f0db4d289b8cf6764e10cd47e3
Signed-off-by: bengris32 <bengris32@protonmail.ch>
2025-07-04 02:08:46 +00:00
Bruno Martins
bb5f08081e sepolicy: qti: Rewrite touchdaemon rules
Change-Id: I313ef308979b3428fbb3a01ae44b4a914b479b34
2025-06-29 14:52:38 +00:00
Fenglin Wu
e42da48bbd vibrator: qti: Add external control support for sun platform
Add haptics module in sun platform to support external control.

Change-Id: Ie735e8fb50912156b680fd2bf4a0d38c7d2f1c77
2025-06-29 14:48:01 +00:00
LuK1337
d9b3335f6a vintf: Add ICameraRfiService V3
Spotted on erhai.

Change-Id: I6c3e87167d25f4354ace385f3f0c5d9f114c2bf1
2025-06-29 16:11:45 +02:00
Fenglin Wu
332e7e4baf vibrator: qti: Add external control support for pineapple
Pineapple SOC uses PMIC that has haptics module can support external
control. Add support for it.

Change-Id: I471561a91be8fd054d34dc83860b5b53b8026706
Signed-off-by: madmax7896 <madmax78968@gmail.com>
2025-06-21 11:44:48 +00:00
Bruno Martins
a50f0d25f8 sepolicy: qti: Remove redundant rules
Change-Id: Ic7dd3562f8d84d83180317acc75ee7a3d147c8fa
2025-06-21 11:29:33 +00:00
LuK1337
3f8e847483 sepolicy: qti: LC_ALL=C sort wakeup nodes
Change-Id: Ib92a476695552d848d5d13a856012bf64bff8615
2025-06-19 15:20:16 +02:00
chandu078
f875d13162 Euicc: Add OnePlus 12 support
Change-Id: I9a3c9f37ce3e905ea1c69a8877f99201dc758b52
Signed-off-by: chandu078 <chandudyavanapelli03@gmail.com>
2025-06-19 15:04:28 +02:00
chandu078
a0c3a0b5fb vintf: Update fwk matrix to support waffle
Based on relevant interfaces from CPH2581_15.0.0.510(EX01)

Change-Id: Iaddd07fdfcf8d06642ce091c55051292ea545aef
Signed-off-by: chandu078 <chandudyavanapelli03@gmail.com>
2025-06-18 18:29:51 +00:00
Michael Bestas
b3c23f51f2 overlay: qssi: Remove deprecated config_mobile_tcp_buffers/networkAttributes
Change-Id: Ieda947e283cde11cf74a01dc1b438e1deeb902c9
2025-06-16 22:28:48 +01:00
Bruno Martins
dc9a1d06e2 touch: Use CHECK_EQ(a, b) assertion
Change-Id: I7522c86f168a2a5226b2ef28903afa74cee62997
2025-06-07 19:00:50 +01:00
Bruno Martins
ae39496553 touch: Enable HighTouchPollingRate by default
Every new device supports the feature.

Change-Id: I9a08dfb6f8f416af99f9811aa1fa1f1166d2b9f4
2025-06-06 20:56:56 +00:00
Bruno Martins
a79e50e87a touch: Add soong configuration for features
Change-Id: I73870f82b6dfc5f9b13e1a450796060bc8dc58f1
2025-06-06 20:56:56 +00:00
Bruno Martins
cfceb7c1c3 touch: Migrate to AIDL
Change-Id: I7fc7992744df049835213c58261eb81579d6f3c1
2025-06-06 20:56:56 +00:00
LuK1337
90b33a8325 powershare: Use EX_SERVICE_SPECIFIC exception code for setEnabled()
Makes it match hardware/lineage/interfaces/powershare/aidl/default.

Change-Id: I5a4978cc7b62127dd00795dd6aaff10c2f2ade38
2025-05-27 00:39:02 +02:00
Michael Bestas
8e39a4f7a4 configs: Create usb_compositions.conf with OPPO USB IDs
Change-Id: I5ed2df909951675e9a9a9dfbe3c7ff7ddcdaeafe
2025-05-23 20:50:10 +00:00
Bruno Martins
7f612125c2 powershare: Migrate to AIDL
Change-Id: I181478469e0de7e913a8e3fb665155b63a74f63a
2025-05-10 11:48:17 +00:00
Alexander Koskovich
c085cde213 sepolicy: qti: Label missing wakeup node on OP9
Error opening kernel wakelock stats for: wakeup85 (../../devices/platform/soc/990000.i2c/i2c-9/9-0048/wakeup/wakeup85): Permission denied

Change-Id: I2ade1c6a791bc3f184cba70c763b8b511b526cea
2025-04-27 04:27:01 +00:00
Bruno Martins
ec00c65468 powershare: Fix PowerShare QS tile state toggle
Assuming that the node exists and is writable, this was always
returning true, causing the QS tile state to look as turned on
even after disabling the feature.

Change-Id: I6c833438e500a8050cd0a27fe576d789e86a727e
2025-04-25 13:10:19 +00:00
Bruno Martins
9ca0fcaa96 vintf: Mark all HALs as optional
Change-Id: Ic00e778bd4e60c7ba1b3e4d2a25f79bca8277cfc
2025-04-21 00:05:19 +01:00
LineageOS Infra
df48e72f9c Automatic translation import
Change-Id: I92ebfad3057ce416cbc2f3567d30924b8b634a2d
2025-04-15 13:55:17 +00:00
Mashopy
406d2da3d3 vibrator: richtap: Fixup service declaration for loading AAC effects
The previous declaration was resulting in non-working vibrator effects
on vitamin due to the perms being set too late and the service running
too soon at the same time.

This match vitamin's vendor.oplus.hardware.vibrator-service declaration.

Change-Id: Iec7bf9c070da280b9b4920b4d85a22abea3aad67
2025-04-13 23:45:55 +00:00
Mashopy
4cdcb94010 oplus: Run bpfix
Change-Id: Ida4dd24167f0f15b1e67a3ae3f73454caa4e1f6e
2025-04-13 23:45:13 +00:00
LuK1337
1fc2c39807 sepolicy: qti: Label just crtc early_wakeup
Prevents us from overriding QCOM sepolicy rules.

Change-Id: I8c7446b4aa04503af7efc11a53f67b1edb6e3b1e
2025-04-09 19:21:16 +02:00
LineageOS Infra
93e25021b2 Automatic translation import
Change-Id: Ife02e8ee27d8d656c6a24e28b86ffaab03b762e2
2025-04-07 16:25:24 +00:00
Bruno Martins
ba4c32da03 oplus: Declare hidl_pixelworks_feature_interface
Change-Id: I0896a93cc6c44628d5b79c75e58db9dcf6f58683
2025-04-06 00:51:34 +01:00
Bruno Martins
d5f168f6a8 aidl: vibrator: Drop compile_multilib from dummy richtap lib
Not necessarily needed and prevents builds to start on 32-bit-only
targets with this repository also present.

Change-Id: Ic9838753240a25883d591b4be385691f2e070a07
2025-03-31 17:39:50 +00:00
Bruno Martins
fd03aaaed9 fingerprint: Do not notify AIDL HAL about touch events
As previously noticed with uff fingerprint HIDL HAL, Oplus makes
use of touch down/up events for product testing. With the most
recent AIDL HAL, entering the code paths for factory tests breaks
fingerprint registration.

By setting halHandlesDisplayTouches prop to true, the framework
will skip passing the display touch events in ISession#onPointerDown
and ISession#onPointerUp down to the HAL.

Change-Id: I194719f27c182d044c0f4e349c3e0ef032361fbd
2025-03-28 08:03:04 +00:00
Edwin Moquete
a6435e6bc0 doze: Fix compilation on V QPR2
Change-Id: If1693603abc530af3b761b53396f2dda8225177e
2025-03-12 23:35:45 +00:00
Cosmin Tanislav
18ef7dd547 oplus: switch to common QCOM AIDL bootctrl HAL
Change-Id: I04ab771d3b1c38b58913607fbff1bb3b55e1fe25
2025-03-12 04:36:08 +00:00
LuK1337
41fb946c65 audio_amplifier: Add lahaina SoC
Change-Id: Icb52dd78e34e6cfd8f4f3e93917f32e9660ca602
2025-03-07 14:53:54 +01:00
e50dfe2d6c doze: Move to PreferenceFragmentCompat
PreferenceFragment was deprecated in API level 28.

https://developer.android.com/jetpack/androidx/releases/preference#1.1.0

Change-Id: Ie8a4b04bd588afbbbc5882349ddbc05f988f80bf
Signed-off-by: AnierinB <anierin@evolution-x.org>
2025-02-26 23:00:34 +00:00
Bruno Martins
aaf90056ca sepolicy: qti: Address new denials with fingerprint AIDL HAL
Change-Id: I6c0834bc7fba8e9ea7bb1955e8ff29b7009de383
2025-02-26 00:22:54 +00:00
LuK1337
7591d33cea fingerprint: Add a shim to manipulate fingerprint SensorProps
OPlus fingerprint AIDL reports sensor properties through custom system
properties rather than the standard IFingerprint::getSensorProps
interface, so AOSP is not aware of them.

Provide a shim to hijack the binder interface and standardize these
custom system properties.

These properties are read from TA and automatically set when the
fingerprint AIDL starts. Possible values are based on observation from
OplusCommercialEngineerMode.apk.

Co-authored-by: dianlujitao <dianlujitao@lineageos.org>
Change-Id: Ia25e0c007af845c14fb98cb201bac334d70a74a4
2025-02-26 00:22:54 +00:00
Bruno Martins
63127da10c fingerprint: Move shims and UDFPS extension out of HIDL
Change-Id: I29e31088c6380076221ad419a195a460079165d6
2025-02-26 00:22:54 +00:00
Bruno Martins
48f3da9e08 sepolicy: Label commondcs service and adjust rules
Change-Id: If5d76109413e54c9f5a78aea7490b71dd7687d1e
2025-02-26 00:22:54 +00:00
Bruno Martins
5134fa4830 Introduce vendor.oplus.hardware.commondcs-service
Change-Id: I4d91094cc2274a168b147a53d5ebe412a867e920
2025-02-26 00:22:54 +00:00
Bruno Martins
9f1f2c1765 interfaces: Add vendor.oplus.hardware.commondcs V1
Change-Id: I181fd1da49dc124ebfe631f9139149327ed4f847
2025-02-26 00:22:54 +00:00
Albert Tang
2f24de9fb5 audio_amplifier: Add holi SoC
Change-Id: Iea9d6e446d9e394eafced3062232a4a65f577296
2025-02-22 20:40:55 +01:00
LuK1337
c0e82d61b6 audio_amplifier: Use hw_module_t->dso instead of RTLD_NEXT
W audio_amplifier: amp_module_open: enable_snd_device not found (undefined symbol: enable_snd_device)
E audio_hw_primary: Amplifier initialization failed

Change-Id: If313889c4749c589d0682982f1d804e4069ffff9
2025-02-22 20:40:55 +01:00
Michael Bestas
ee64733e0f Remove no longer used Android.mk guard
Change-Id: Ia284075607a1ce3d9312c593258d0b1afcd868b2
2025-02-19 22:58:04 +00:00
Michael Bestas
fff84ef56b audio_amplifier: Convert to blueprint
dlopen audio.primary instead of linking against it to avoid soong
namespace hell.

Change-Id: Ic9d420864cb5a6f1018210a84f0f3e6636550caa
2025-02-19 22:58:04 +00:00
Alexander Winkowski
5a4c2cf7a4 audio_amplifier: Make all the functions static
Change-Id: I64b94b6995399b773046928528d9fe5a29cb26f9
2025-02-19 22:58:04 +00:00
Alexander Winkowski
1166219abe audio_amplifier: Fix PCM device check
It should've been && instead of ||, but pcm_open() always
returns a valid pointer, so we just drop the NULL check.

Change-Id: Ibf1d0b34b02ca5910cd4c1bee4d55a04205e2203
2025-02-19 22:58:04 +00:00
Bruno Martins
1177faa26d sepolicy: qti: Allow audio HAL to read debug audio props
Change-Id: Ibe64d56f8451ee1d90f4087ca45e075424a4749b
2025-02-16 17:17:57 +00:00
Bruno Martins
d6563515fa sepolicy: qti: Label ro.sys.engineering.pre prop
Change-Id: I5b25f13b158df6a3e0b63efde70f8750798875e4
2025-02-16 17:17:57 +00:00
LineageOS Infra
81d0ee9346 Automatic translation import
Change-Id: I2607a25274068809ee540c55b4afd42270b5d96a
2025-02-15 15:47:19 +00:00
Bruno Martins
a4ba2641dd sepolicy: qti: Remove duplicate snxxx AIDL rules
These now became a duplicate of qcom/sepolicy_vndr.

Change-Id: I7cac7b77322d88181d0a119ce0b28c678c0202e0
2025-02-14 08:44:04 +00:00
LuK1337
8d237bfc07 bootctrl: Remove HIDL variants
No longer used by anything.

Change-Id: I2dc8a42f8f758b8247eb7b14846e731c48d1601e
2025-02-11 19:05:16 +00:00
Michael Bestas
8aa74e5081 gpt-utils: Make BSG/SG configurable
Change-Id: Ibbadee63bddcf03a259649aec9cb0dab6c206833
2025-02-11 19:05:16 +00:00
Bruno Martins
95e9749902 interfaces: Update OplusTouch to V2
Change-Id: I6982de269930a321a58d5145470ccef5b2da4e45
2025-02-11 01:41:54 +00:00
John Galt
37688c9479 sepolicy: qti: add rules for URCC
Change-Id: I449705696de0bc303df6ae27ef322f2cc74b95b5
2025-02-11 00:18:26 +00:00
John Galt
e3197d473f interfaces: unfreeze touch aidl
Allows building deps for proprietary touch stack

Change-Id: I647b27fa1985fa0ed1bff389295cc6333006495e
2025-02-11 00:18:26 +00:00
Dr-chen99
07bc326cf0 sepolicy: qti: Add touch aidl service as a client of power hal
Change-Id: I4824fadf7c4d590bc7adc3c35996d9101b820022
Signed-off-by: pppig236 <priv@pppig236.com>
2025-02-11 00:18:26 +00:00
John Galt
31ea1b8880 vintf: add oplus touch and urcc
Change-Id: I62ab1be42e0c54b8762a0375127225b87f28c92e
2025-02-11 00:18:26 +00:00
Dr-chen99
2ef6bca1a6 interfaces: import touch aidl
Change-Id: I72363277a140dadf08c39823072578d99dc65753
Signed-off-by: pppig236 <priv@pppig236.com>
2025-02-11 00:18:22 +00:00
pjgowtham
331acdbd34 sepolicy: qti: Label and write rules for oplus_consumer_ir device
Change-Id: I4bb3275183250531324f0a396be0c83c6a5b30fe
2025-02-08 23:25:14 +00:00
pjgowtham
c342915eda Introduce android.hardware.ir-service.oplus
Change-Id: Iffeb34f8c7864dad223d20e1de2a819a345678c6
2025-02-08 23:25:14 +00:00
Bruno Martins
465fa45b1a sepolicy: qti: Partially hide labels of services relocated by Oneplus
Keeping these common labels will break sm8650+ due to no longer existing
types, so make available only when applicable to legacy-um, sm8450 and
sm8550.

Change-Id: Ieb9c703c4cdf1d25bdccd7352055978b14cde8fd
2025-02-08 18:05:17 +00:00
Bruno Martins
71f8171439 oplus: Deprecate NXP NFC and old HALs for good
Seems like these are not used anymore.

Change-Id: I7cf12951fae70d87ef4e33e89c0aa88529c08ac4
2025-02-08 15:50:02 +00:00
Sebastiano Barezzi
ad80010b94 oplus: Keep a single clang-format in rootdir
Change-Id: Iffe5b37c311dc0ed0c9b5c91a2f94e9ff72f4a8a
2025-02-07 19:17:25 +00:00
LuK1337
b2c137ff35 aidl: vibrator: Clean up aac_vibra_function.h
Change-Id: I9ec5c9631679624d8dc710e790d84895de183d54
2025-02-07 12:49:19 +01:00
Bruno Martins
d2bc42dafc aidl: vibrator: Add dummy libaacvibrator shared_lib
All targets must provide it and dummy one will be overriden.

Change-Id: I64b6180e93cf2c34382282dc8574bf79814f096e
2025-02-07 01:09:54 +00:00
Cosmin Tanislav
fe3c661e29 sepolicy: qti: let vibrator service access richtap dev
Change-Id: I19cf413ebe128ac952e2f5237907b7bb7afcbc7f
2025-02-07 00:34:41 +00:00
Cosmin Tanislav
2823ba9b6c sepolicy: qti: label richtap vibrator service
Change-Id: I9e08ded8362b359b60523c07c172d26706e4246d
2025-02-07 00:34:41 +00:00
Cosmin Tanislav
538d6790d0 aidl: vibrator: implement richtap vibrator service
Change-Id: Ieab0cfca22c0fd8a63c33ce2a6a21e982e57aee8
2025-02-07 00:34:28 +00:00
Bruno Martins
32be43fe84 aidl: vibrator: Place modded QTI impl into its own dir
Change-Id: Ie21de7e1ddfd964c9d1b4a838521503887dcc994
2025-02-06 23:12:37 +00:00
Tim Zimmermann
2ac71df739 aidl: Add missing vintf version entries
* This is required for devices using a target-level that actually
  has these HALs in their compatibility matrix

Change-Id: I29cba455ab92e7708ece405bb29ea1c46e46cf41
2025-02-06 23:12:34 +00:00
dianlujitao
309c373f06 bootctrl: add AIDL variants
Change-Id: I2dbcd362490b171f402c080485226d90d8ffaa84
2025-02-06 20:21:18 +00:00
LineageOS Infra
566dd12b55 Automatic translation import
Change-Id: Ife9b592c7f9c5cee1c4b6745bacc1b135870ffca
2025-02-01 14:28:34 +00:00
dianlujitao
2194d3fbac gpt-utils: Add OTA support for pdp partition
Change-Id: Ide7bf934a2592fe50027ff0836190d3b20ea390b
2025-01-30 19:39:40 +08:00
LAVEENA FULWANI
5d9c06b541 gpt-utils: Adding partitions in PTN_SWAP_LIST
Change-Id: I9fadf0a5ff04b44a1cf9172c48a3e87c03511bc6
2025-01-30 19:39:40 +08:00
Roopesh Nataraja
cf82d4e147 gpt-utils: Add OTA support for spuservice partition
Add spuservice partition to PTN_SWAP_LIST to support OTA handling.

Change-Id: I733bd2844e0788b9cc12a33d66e1cc67c6cbc52a
2025-01-30 19:39:40 +08:00
Anubhav
ca7d3a1466 gpt-utils: Fixes in oem-recovery in gpt_boot_chain_swap
Change-Id: I503a51a8aa685534d0f1d5d45ea4d1a539cb07ee
2025-01-30 19:39:40 +08:00
dianlujitao
e773c45961 Revert "gpt-utils: Check ufs device first before checking partition names"
This reverts commit 5cea739d3d.

Change-Id: I2518a79a3fef78a307e6fbf65bfd34dfb49069b8
2025-01-30 19:39:40 +08:00
Karra Harshitha
4d04a8c99b gpt-utils: Add OTA support for pvmfw partition
Add pvmfw partition to PTN_SWAP_LIST
to support OTA handling.

Change-Id: I7bf22c0e9316a7390f133b4651d6fd3f89999b3d
2025-01-30 19:39:40 +08:00
Anthony Adamo
1da51d9614 gpt-utils: Add OTA support for cpucp_dtb partition
add entry for the new cpucp_dtb  partition to the PTN_SWAP_LIST
to support OTA handeling.

Change-Id: Ie36eeffe360be4cb929569d232cab63be3029d09
2025-01-30 19:39:40 +08:00
Bruno Martins
cbbcc714d4 sepolicy: Add service context for ICameraRfiService
Change-Id: Id0b2a950b057202788cee676737837a0d8ecff6f
2025-01-15 20:24:47 +00:00
Bruno Martins
24eb056d25 vintf: Update fwk matrix for OOS 15
Change-Id: I5138658f3db9ef12c15086c3bbcc2a2035eff816
2025-01-15 20:24:29 +00:00
patr_
8691a3526e sepolicy: qti: Move some SM8150/SM8250 wakeup nodes to qcom sepolicy
All of these are labeled already for lito.

Change-Id: I9a6e04b9119826eb95f2003812fca12e13641ae1
2024-12-27 21:50:53 +00:00
patr_
d168819307 vintf: Add version 1.0 for vendor.oplus.hardware.cameraMDM
Used on avicii.

Change-Id: Ib02fb994f391bd015ec2171cfa13690e847b032a
2024-12-08 01:31:58 +01:00
LineageOS Infra
77522b8050 Automatic translation import
Change-Id: Iee296c9cee2dadf859ee0d808824b8e0ecd06224
2024-12-02 02:54:15 +00:00
LuK1337
9bb70db51d sepolicy: qti: Allow sensors to read /proc/oplusVersion/*
E sensors-hal: ambient_light:131, fail to open /proc/oplusVersion/prjName
E sensors-hal: is_aging_vesion:59, fail to open /proc/oplusVersion/engVersion

Change-Id: I2c4f9e00e689a7fa0650d53868b9921d5e8d001c
2024-11-27 18:56:15 +01:00
LuK1337
3899884705 oplus: Add README file with Soong options documentation
Change-Id: I5e8748b748782a654e94ae5ebf69961d4bf9bd46
2024-11-23 20:55:08 +01:00
LuK1337
60f641a773 vibrator: Migrate to select()
Change-Id: I625cfa648f321ba5f3b3d255a42b4d489a7abaef
2024-11-22 22:15:24 +01:00
LuK1337
8b3ffd3d7b livedisplay: Migrate to select()
Change-Id: I5d2d6f351431c13c36bcb7118e3fe5babfbe1872
2024-11-22 21:48:41 +01:00
LuK1337
5acd6429ef touch: Migrate to select()
Change-Id: I92f7a7100c16b133f24c9cc9882093324f64452f
2024-11-22 21:24:49 +01:00
486 changed files with 17030 additions and 3749 deletions

1
.clang-format Symbolic link
View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,30 @@
<?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

@@ -0,0 +1,5 @@
<?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

@@ -0,0 +1,9 @@
<?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

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

View File

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

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

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

View File

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

View File

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

24
IFAAService/Android.bp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,5 +4,18 @@
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="alert_slider_category_title">Sleamhnán foláirimh</string>
<string name="alert_slider_selection_dialog_title">Gníomh</string>
<string name="alert_slider_top_position">Seasamh barr</string>
<string name="alert_slider_middle_position">Seasamh meánach</string>
<string name="alert_slider_bottom_position">Seasamh bun</string>
<string name="alert_slider_mode_none">Dada</string>
<string name="alert_slider_mode_silent">Ciúin</string>
<string name="alert_slider_mode_normal">Gnáth</string>
<string name="alert_slider_mode_vibration">Creathadh</string>
<string name="alert_slider_mode_dnd_priority_only">Tosaíocht amháin</string>
<string name="alert_slider_mode_dnd_total_silence">Ciúnas iomlán</string>
<string name="alert_slider_mode_dnd_alarms_only">Aláraim amháin</string>
<string name="alert_slider_mute_media_title">Balbhaigh meáin</string>
<string name="alert_slider_mute_media_summary">Balbhaigh na meáin nuair a bhíonn tú ag aistriú chuig an gciúin</string>
</resources>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

29
Pen/Android.bp Normal file
View File

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

31
Pen/AndroidManifest.xml Normal file
View File

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

View File

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

3
Pen/proguard.flags Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

19
README.md Normal file
View File

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

22
aidl/commondcs/Android.bp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

19
aidl/ir/Android.bp Normal file
View File

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

77
aidl/ir/ConsumerIr.cpp Normal file
View File

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

30
aidl/ir/ConsumerIr.h Normal file
View File

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

View File

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

View File

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

25
aidl/ir/service.cpp Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,5 @@
/*
* Copyright (C) 2019 The LineageOS Project
*
* SPDX-FileCopyrightText: 2019-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,11 +12,10 @@
#include <oplus/oplus_display_panel.h>
#include <fstream>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
namespace V2_1 {
namespace implementation {
static const std::string kModeBasePath = "/sys/class/drm/card0-DSI-1/";
static const std::string kDefaultPath = "/data/vendor/display/default_display_mode";
@@ -30,8 +28,8 @@ const std::map<int32_t, DisplayModes::ModeInfo> DisplayModes::kModeMap = {
{3, {"Brilliant", 4, 0}},
};
DisplayModes::DisplayModes(std::shared_ptr<V2_0::sdm::SDMController> controller)
: mController(std::move(controller)),
DisplayModes::DisplayModes(std::shared_ptr<sdm::SDMController> controller)
: mController(controller),
mOplusDisplayFd(open("/dev/oplus_display", O_RDWR)),
mCurrentModeId(0),
mDefaultModeId(0) {
@@ -43,31 +41,31 @@ DisplayModes::DisplayModes(std::shared_ptr<V2_0::sdm::SDMController> controller)
setDisplayMode(mDefaultModeId, false);
}
// Methods from ::vendor::lineage::livedisplay::V2_1::IDisplayModes follow.
Return<void> DisplayModes::getDisplayModes(getDisplayModes_cb resultCb) {
std::vector<V2_0::DisplayMode> modes;
// Methods from ::aidl::vendor::lineage::livedisplay::BnDisplayModes follow.
ndk::ScopedAStatus DisplayModes::getDisplayModes(std::vector<DisplayMode>* _aidl_return) {
std::vector<DisplayMode> modes;
for (const auto& entry : kModeMap) {
modes.push_back({entry.first, entry.second.name});
}
resultCb(modes);
return Void();
*_aidl_return = modes;
return ndk::ScopedAStatus::ok();
}
Return<void> DisplayModes::getCurrentDisplayMode(getCurrentDisplayMode_cb resultCb) {
resultCb({mCurrentModeId, kModeMap.at(mCurrentModeId).name});
return Void();
ndk::ScopedAStatus DisplayModes::getCurrentDisplayMode(DisplayMode* _aidl_return) {
*_aidl_return = {mCurrentModeId, kModeMap.at(mCurrentModeId).name};
return ndk::ScopedAStatus::ok();
}
Return<void> DisplayModes::getDefaultDisplayMode(getDefaultDisplayMode_cb resultCb) {
resultCb({mDefaultModeId, kModeMap.at(mDefaultModeId).name});
return Void();
ndk::ScopedAStatus DisplayModes::getDefaultDisplayMode(DisplayMode* _aidl_return) {
*_aidl_return = {mDefaultModeId, kModeMap.at(mDefaultModeId).name};
return ndk::ScopedAStatus::ok();
}
Return<bool> DisplayModes::setDisplayMode(int32_t modeID, bool makeDefault) {
ndk::ScopedAStatus DisplayModes::setDisplayMode(int32_t modeID, bool makeDefault) {
const auto iter = kModeMap.find(modeID);
if (iter == kModeMap.end()) {
return false;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
if (mOplusDisplayFd >= 0) {
ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_SEED, &iter->second.seedMode);
@@ -85,11 +83,10 @@ Return<bool> DisplayModes::setDisplayMode(int32_t modeID, bool makeDefault) {
if (mOnDisplayModeSet) {
mOnDisplayModeSet();
}
return true;
return ndk::ScopedAStatus::ok();
}
} // namespace implementation
} // namespace V2_1
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,8 +1,7 @@
<manifest version="1.0" type="device">
<hal format="hidl">
<hal format="aidl">
<name>vendor.lineage.livedisplay</name>
<transport>hwbinder</transport>
<version>2.1</version>
<version>1</version>
<interface>
<name>IAntiFlicker</name>
<instance>default</instance>

View File

@@ -1,8 +1,7 @@
<manifest version="1.0" type="device">
<hal format="hidl">
<hal format="aidl">
<name>vendor.lineage.livedisplay</name>
<transport>hwbinder</transport>
<version>2.1</version>
<version>1</version>
<interface>
<name>IDisplayModes</name>
<instance>default</instance>

View File

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

View File

@@ -1,8 +1,7 @@
<manifest version="1.0" type="device">
<hal format="hidl">
<hal format="aidl">
<name>vendor.lineage.livedisplay</name>
<transport>hwbinder</transport>
<version>2.1</version>
<version>1</version>
<interface>
<name>ISunlightEnhancement</name>
<instance>default</instance>

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
on init
chown system system /proc/wireless/enable_tx
service vendor.powershare-hal-1-0 /vendor/bin/hw/vendor.lineage.powershare@1.0-service.oplus
service vendor.powershare-hal /vendor/bin/hw/vendor.lineage.powershare-service.oplus
class hal
user system
group system

View File

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

57
aidl/sensors/Android.bp Normal file
View File

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

810
aidl/sensors/HalProxy.cpp Normal file
View File

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

View File

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

View File

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

View File

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

36
aidl/sensors/service.cpp Normal file
View File

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

61
aidl/touch/Android.bp Normal file
View File

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

63
aidl/touch/GloveMode.cpp Normal file
View File

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

32
aidl/touch/GloveMode.h Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -1,43 +1,31 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <vendor/lineage/touch/1.0/ITouchscreenGesture.h>
#include <aidl/vendor/lineage/touch/BnTouchscreenGesture.h>
#include <aidl/vendor/oplus/hardware/touch/IOplusTouch.h>
#include <map>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
namespace V1_0 {
namespace implementation {
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::vendor::lineage::touch::V1_0::Gesture;
using aidl::vendor::oplus::hardware::touch::IOplusTouch;
class TouchscreenGesture : public ITouchscreenGesture {
class TouchscreenGesture : public BnTouchscreenGesture {
public:
// Methods from ::vendor::lineage::touch::V1_0::ITouchscreenGesture follow.
Return<void> getSupportedGestures(getSupportedGestures_cb resultCb) override;
Return<bool> setGestureEnabled(const Gesture& gesture, bool enabled) override;
explicit TouchscreenGesture(std::shared_ptr<IOplusTouch> oplusTouch);
ndk::ScopedAStatus getSupportedGestures(std::vector<Gesture>* _aidl_return) override;
ndk::ScopedAStatus setGestureEnabled(const Gesture& gesture, bool enabled) override;
private:
std::shared_ptr<IOplusTouch> mOplusTouch;
// See: drivers/input/touchscreen/oplus_touchscreen_v2/touchpanel_common.h
static constexpr int kGestureStartKey = 246;
enum {
@@ -91,8 +79,7 @@ class TouchscreenGesture : public ITouchscreenGesture {
static const int kSupportedGestures;
};
} // namespace implementation
} // namespace V1_0
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

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

60
aidl/touch/service.cpp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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