├── .clang-format ├── Android.bp ├── KeyHandler ├── Android.bp ├── AndroidManifest.xml ├── proguard.flags ├── res │ ├── values-ar │ │ └── strings.xml │ ├── values-ast-rES │ │ └── strings.xml │ ├── values-az │ │ └── strings.xml │ ├── values-bg │ │ └── strings.xml │ ├── values-ca │ │ └── strings.xml │ ├── values-cs │ │ └── strings.xml │ ├── values-cy │ │ └── strings.xml │ ├── values-da │ │ └── strings.xml │ ├── values-de │ │ └── strings.xml │ ├── values-el │ │ └── strings.xml │ ├── values-en-rAU │ │ └── strings.xml │ ├── values-en-rCA │ │ └── strings.xml │ ├── values-en-rGB │ │ └── strings.xml │ ├── values-en-rIN │ │ └── strings.xml │ ├── values-es │ │ └── strings.xml │ ├── values-fa │ │ └── strings.xml │ ├── values-fi │ │ └── strings.xml │ ├── values-fr │ │ └── strings.xml │ ├── values-fur-rIT │ │ └── strings.xml │ ├── values-ga-rIE │ │ └── strings.xml │ ├── values-hu │ │ └── strings.xml │ ├── values-in │ │ └── strings.xml │ ├── values-is │ │ └── strings.xml │ ├── values-it │ │ └── strings.xml │ ├── values-iw │ │ └── strings.xml │ ├── values-ja │ │ └── strings.xml │ ├── values-ka │ │ └── strings.xml │ ├── values-ko │ │ └── strings.xml │ ├── values-nl │ │ └── strings.xml │ ├── values-pl │ │ └── strings.xml │ ├── values-pt-rBR │ │ └── strings.xml │ ├── values-pt-rPT │ │ └── strings.xml │ ├── values-ro │ │ └── strings.xml │ ├── values-ru │ │ └── strings.xml │ ├── values-sl │ │ └── strings.xml │ ├── values-sq │ │ └── strings.xml │ ├── values-sv │ │ └── strings.xml │ ├── values-ta │ │ └── strings.xml │ ├── values-tr │ │ └── strings.xml │ ├── values-ug │ │ └── strings.xml │ ├── values-vi │ │ └── strings.xml │ ├── values-zh-rCN │ │ └── strings.xml │ ├── values-zh-rTW │ │ └── strings.xml │ ├── values │ │ ├── arrays.xml │ │ └── strings.xml │ └── xml │ │ └── button_panel.xml ├── src │ └── org │ │ └── lineageos │ │ └── settings │ │ └── device │ │ ├── BootCompletedReceiver.kt │ │ ├── ButtonSettingsActivity.kt │ │ ├── ButtonSettingsFragment.kt │ │ ├── ConfigPanelSearchIndexablesProvider.kt │ │ └── KeyHandler.kt ├── tri-state-key-calibrate.rc └── tri-state-key-calibrate.sh ├── aidl ├── livedisplay │ ├── Android.bp │ ├── AntiFlicker.cpp │ ├── SunlightEnhancement.cpp │ ├── include │ │ └── livedisplay │ │ │ └── oneplus │ │ │ ├── AntiFlicker.h │ │ │ └── SunlightEnhancement.h │ ├── service.cpp │ ├── vendor.lineage.livedisplay-service.oneplus-af.xml │ ├── vendor.lineage.livedisplay-service.oneplus-pa.xml │ ├── vendor.lineage.livedisplay-service.oneplus-se.xml │ └── vendor.lineage.livedisplay-service.oneplus.rc ├── touch │ ├── Android.bp │ ├── TouchscreenGesture.cpp │ ├── TouchscreenGesture.h │ ├── TouchscreenGestureConfig.h │ ├── service.cpp │ ├── vendor.lineage.touch-service.oneplus.rc │ └── vendor.lineage.touch-service.oneplus.xml └── vibrator │ ├── Android.bp │ ├── Vibrator.cpp │ ├── include │ └── Vibrator.h │ ├── service.cpp │ ├── vendor.qti.hardware.vibrator.service.oneplus.rc │ └── vendor.qti.hardware.vibrator.service.oneplus.xml ├── audio_amplifier ├── Android.bp └── audio_amplifier.c ├── dirac_gef ├── Android.bp ├── AndroidManifest.xml ├── assets │ └── dirac_gef_init.txt ├── proguard.flags └── src │ └── org │ └── lineageos │ └── dirac │ └── gef │ └── BootCompletedReceiver.kt ├── doze ├── Android.bp ├── AndroidManifest.xml ├── proguard.flags ├── res │ ├── drawable │ │ ├── ic_pickup.xml │ │ └── ic_pocket.xml │ ├── values │ │ ├── arrays.xml │ │ └── config.xml │ └── xml │ │ └── doze_settings.xml └── src │ └── org │ └── lineageos │ └── settings │ └── doze │ ├── BootCompletedReceiver.kt │ ├── DozeService.kt │ ├── DozeSettingsActivity.kt │ ├── DozeSettingsFragment.kt │ ├── PickupSensor.kt │ ├── PocketSensor.kt │ └── Utils.kt ├── hidl └── fingerprint │ ├── Android.bp │ ├── BiometricsFingerprint.cpp │ ├── BiometricsFingerprint.h │ ├── UdfpsExtension.cpp │ ├── android.hardware.biometrics.fingerprint@2.3-service.oneplus.rc │ ├── android.hardware.biometrics.fingerprint@2.3-service.oneplus.xml │ ├── properties.cpp │ └── service.cpp ├── interfaces ├── Android.bp ├── goodix │ └── hardware │ │ └── biometrics │ │ └── fingerprint │ │ └── 2.1 │ │ ├── Android.bp │ │ ├── IGoodixFingerprintDaemon.hal │ │ └── IGoodixFingerprintDaemonCallback.hal ├── oneplus │ ├── camera │ │ └── CameraHIDL │ │ │ └── 1.0 │ │ │ ├── Android.bp │ │ │ └── IOnePlusCameraProvider.hal │ ├── fingerprint │ │ └── extension │ │ │ └── 1.0 │ │ │ ├── Android.bp │ │ │ ├── IVendorFingerprintExtensions.hal │ │ │ ├── IVendorFingerprintExtensionsCallback.hal │ │ │ └── types.hal │ └── hardware │ │ └── drmkey │ │ └── 1.0 │ │ ├── Android.bp │ │ └── IOneplusDrmKey.hal └── update-makefiles.sh ├── oneplus-fwk ├── Android.bp └── src │ └── android │ ├── os │ └── OPDiagnoseManager.java │ └── util │ └── OpFeatures.java └── wifi-mac-generator ├── Android.bp ├── wifi-mac-generator.rc └── wifi-mac-generator.sh /.clang-format: -------------------------------------------------------------------------------- 1 | ../../build/soong/scripts/system-clang-format -------------------------------------------------------------------------------- /Android.bp: -------------------------------------------------------------------------------- 1 | soong_namespace { 2 | imports: [ 3 | "hardware/google/interfaces", 4 | "hardware/google/pixel", 5 | ], 6 | } 7 | -------------------------------------------------------------------------------- /KeyHandler/Android.bp: -------------------------------------------------------------------------------- 1 | android_app { 2 | name: "KeyHandler", 3 | 4 | srcs: ["src/**/*.kt"], 5 | resource_dirs: ["res"], 6 | 7 | certificate: "platform", 8 | platform_apis: true, 9 | system_ext_specific: true, 10 | 11 | static_libs: [ 12 | "org.lineageos.settings.resources", 13 | ], 14 | 15 | optimize: { 16 | proguard_flags_files: ["proguard.flags"], 17 | }, 18 | } 19 | 20 | sh_binary { 21 | name: "tri-state-key-calibrate", 22 | init_rc: ["tri-state-key-calibrate.rc"], 23 | src: "tri-state-key-calibrate.sh", 24 | vendor: true, 25 | } 26 | -------------------------------------------------------------------------------- /KeyHandler/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 21 | 22 | 23 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /KeyHandler/proguard.flags: -------------------------------------------------------------------------------- 1 | -keep class org.lineageos.settings.device.* { 2 | *; 3 | } 4 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ar/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | شريط تمرير التنبيه 8 | إجراء 9 | الموضع العلوي 10 | الموضع الأوسط 11 | الموضع السفلي 12 | لا شيء 13 | صامت 14 | عادي 15 | اهتزاز 16 | الأولوية فقط 17 | كتم الصوت تمامًا 18 | التنبيهات فقط 19 | كتم صوت الوسائط 20 | كتم صوت الوسائط عند التبديل إلى صامت 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ast-rES/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Eslizador pa les alertes 8 | Aición 9 | Posición cimera 10 | Posición central 11 | Posición baxera 12 | Nada 13 | Silenciu 14 | Normal 15 | Vibración 16 | Namás con prioridá 17 | Silenciu total 18 | Namás les alarmes 19 | Desactivar el soníu multimedia 20 | Desactiva\'l soníu de los elementos multimedia al cambiar a «Silenciu» 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-az/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Xəbərdarlıq diyircəyi 8 | Hərəkət 9 | Üst mövqe 10 | Orta mövqe 11 | Alt mövqe 12 | Heç biri 13 | Səssiz 14 | Normal 15 | Titrəmə 16 | Yalnız prioritet 17 | Tam səssizlik 18 | Yalnız zəngli saatlar 19 | Media səsi yoxdur 20 | Səssizə keçərkən medianı səssizə al 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-bg/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Плъзгач за предупреждение 8 | Действие 9 | Горна позиция 10 | Средна позиция 11 | Долна позиция 12 | Нищо 13 | Тих 14 | Нормален 15 | Вибрация 16 | Само важни 17 | Тотална тишина 18 | Само аларми 19 | Заглуши медията 20 | Заглуши само когато се превключва в тих режим 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ca/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Control lliscant d\'alerta 8 | Acció 9 | Posició superior 10 | Posició central 11 | Posició inferior 12 | Cap 13 | Silenci 14 | Normal 15 | Vibració 16 | Només prioritat 17 | Silenci total 18 | Només alarmes 19 | Silencia la multimèdia 20 | Silencia el contingut multimèdia quan canvieu a silenci 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-cs/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Posuvník oznámení 8 | Akce 9 | Pozice nahoře 10 | Pozice uprostřed 11 | Pozice dole 12 | Žádný 13 | Tichý 14 | Normální 15 | Vibrace 16 | Pouze prioritní 17 | Úplné ticho 18 | Pouze budíky 19 | Ztlumit média 20 | Ztlumit média při přechodu na tichý režim 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-cy/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Llithridd rhybuddion 8 | Gweithred 9 | Lleoliad brig 10 | Lleoliad canol 11 | Lleoliad gwaelod 12 | Dim 13 | Distaw 14 | Arferol 15 | Dirgryniad 16 | Blaenoriaeth yn unig 17 | Distawrwydd llwyr 18 | Larymau yn unig 19 | Tewi cyfryngau 20 | Tewi cyfryngau wrth newid i ddistaw 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-da/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Ingen 8 | 9 | -------------------------------------------------------------------------------- /KeyHandler/res/values-de/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Alarmschieberegler 8 | Aktion 9 | Obere Position 10 | Mittlere Position 11 | Untere Position 12 | Keine 13 | Lautlos 14 | Normal 15 | Vibration 16 | Nur Priorität 17 | Völlige Stille 18 | Nur Alarme 19 | Medien stumm 20 | Medien beim Umschalten auf lautlos stummschalten 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-el/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Διακόπτης ειδοποιήσεων 8 | Ενέργεια 9 | Πάνω θέση 10 | Μεσαία θέση 11 | Κάτω θέση 12 | Τίποτα 13 | Αθόρυβο 14 | Κανονικό 15 | Δόνηση 16 | Μόνο προτεραιότητας 17 | Πλήρης σίγαση 18 | Μόνο ξυπνητήρια 19 | Σίγαση πολυμέσων 20 | Σίγαση πολυμέσων κατά την εναλλαγή σε αθόρυβο 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-en-rAU/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Alert slider 8 | Action 9 | Top position 10 | Middle position 11 | Bottom position 12 | None 13 | Silent 14 | Normal 15 | Vibration 16 | Priority only 17 | Total silence 18 | Alarms only 19 | Mute media 20 | Mute media when switching to silent 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-en-rCA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Alert slider 8 | Action 9 | Top position 10 | Middle position 11 | Bottom position 12 | None 13 | Silent 14 | Normal 15 | Vibration 16 | Priority only 17 | Total silence 18 | Alarms only 19 | Mute media 20 | Mute media when switching to silent 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-en-rGB/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Alert slider 8 | Action 9 | Top position 10 | Middle position 11 | Bottom position 12 | None 13 | Silent 14 | Normal 15 | Vibration 16 | Priority only 17 | Total silence 18 | Alarms only 19 | Mute media 20 | Mute media when switching to silent 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-en-rIN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Alert slider 8 | Action 9 | Top position 10 | Middle position 11 | Bottom position 12 | None 13 | Silent 14 | Normal 15 | Vibration 16 | Priority only 17 | Total silence 18 | Alarms only 19 | Mute media 20 | Mute media when switching to silent 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Control deslizante de alertas 8 | Acción 9 | Posición superior 10 | Posición central 11 | Posición inferior 12 | Ninguno 13 | Silencio 14 | Normal 15 | Vibración 16 | Solo prioritarias 17 | Silencio total 18 | Solo alarmas 19 | Silenciar multimedia 20 | Silenciar multimedia al activar el modo silencio 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-fa/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | نوار لغزنده هشدار 8 | عمل 9 | موقعیت بالا 10 | موقعیت وسط 11 | موقعیت پایین 12 | هیچ 13 | بی‌صدا 14 | عادی 15 | لرزش 16 | فقط اولویت ها 17 | سکوت کامل 18 | فقط هشدار ها 19 | رسانه بی صدا 20 | هنگام جابجایی به بی‌صدا، رسانه را بی‌صدا کنید 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-fi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Mykistä media 8 | Mykistä media kun vaihdetaan äänettömään tilaan. 9 | 10 | -------------------------------------------------------------------------------- /KeyHandler/res/values-fr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Curseur d\'alerte 8 | Action 9 | En haut 10 | Au milieu 11 | En bas 12 | Aucun 13 | Silencieux 14 | Normal 15 | Vibration 16 | Prioritaires uniquement 17 | Silence total 18 | Alarmes uniquement 19 | Couper le son du média 20 | Couper le son du média lors du passage en mode silencieux 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-fur-rIT/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Cursôr notifichis 8 | Azion 9 | Posizion superiôr 10 | Posizion centrâl 11 | Posizion inferiôr 12 | Nuie 13 | Cidin 14 | Normâl 15 | Vibrazion 16 | Dome prioritâts 17 | Cidin dal dut 18 | Dome sveis 19 | Cidine il multimedia 20 | Cidine i multimedia se tu passis ae modalitât cidine 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ga-rIE/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Sleamhnán rabhadh 8 | Gníomh 9 | Seasamh barr 10 | Seasamh meánach 11 | Seasamh bun 12 | Dada 13 | Ciúin 14 | Gnáth 15 | Creathadh 16 | Tosaíocht amháin 17 | Ciúnas iomlán 18 | Aláraim amháin 19 | Balbhaigh na meáin 20 | Balbhaigh na meáin agus tú ag aistriú chuig an gciúin 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-hu/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Riasztási csúszka 8 | Művelet 9 | Felül 10 | Középen 11 | Alul 12 | Egyik sem 13 | Néma 14 | Normális 15 | Rezgés 16 | Csak a fontosak 17 | Teljes némítás 18 | Csak az ébresztések 19 | Médianémítás 20 | Médianémítás csendesre váltáskor 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-in/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Tindakan 8 | Posisi atas 9 | Posisi tengah 10 | Posisi bawah 11 | Tidak ada 12 | Senyap 13 | Normal 14 | Getaran 15 | Hanya prioritas 16 | Senyap total 17 | Hanya alarm 18 | 19 | -------------------------------------------------------------------------------- /KeyHandler/res/values-is/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Aðvaranasleði 8 | Aðgerð 9 | Staða efst 10 | Miðjustaða 11 | Staða neðst 12 | Ekkert 13 | Hljóðlaust 14 | Venjulegt 15 | Titringur 16 | Aðeins í forgangi 17 | Algjör þögn 18 | Aðeins áminningar 19 | Þagga niður margmiðlun 20 | Þagga niður efni þegar skipt er í hljóðlaust 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Slider notifiche 8 | Azione 9 | Posizione superiore 10 | Posizione centrale 11 | Posizione inferiore 12 | Niente 13 | Silenzioso 14 | Normale 15 | Vibrazione 16 | Solo priorità 17 | Silenzio totale 18 | Solo sveglie 19 | Silenzia media 20 | Silenzia i media quando si passa alla modalità silenziosa 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-iw/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | מתג התראות 8 | פעולה 9 | ממוקם למעלה 10 | ממוקם באמצע 11 | ממוקם למטה 12 | ללא 13 | שקט 14 | רגיל 15 | רטט 16 | עדיפות בלבד 17 | מושתק לחלוטין 18 | שעון מעורר בלבד 19 | השתקת מדיה 20 | השתקת מדיה במעבר להשתקה 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ja/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | アラートスライダー 8 | 動作 9 | 上部 10 | 中央 11 | 下部 12 | なし 13 | サイレント 14 | 標準 15 | バイブ 16 | 重要な通知のみ 17 | 完全サイレント 18 | アラームのみ 19 | メディアをミュート 20 | サイレントモードに切り替えたときにメディア音量をミュートします 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ka/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | გაფრთხილების სრიალა 8 | მოქმედება 9 | ზედა მდებარეობა 10 | შუა მდებარეობა 11 | ქვედა მდებარეობა 12 | არცერთი 13 | უხმო 14 | ჩვეულებრივი 15 | ვიბრაცია 16 | მხოლოდ უპირატესი 17 | სრულიად უხმო 18 | მხოლოდ მაღვიძარები 19 | ფაილის დადუმება 20 | ფაილის დადუმება უხმოზე გადართვისას 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ko/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 알림 슬라이더 8 | 동작 9 | 슬라이더가 위쪽에 있을 때 10 | 슬라이더가 중간에 있을 때 11 | 슬라이더가 아래에 있을 때 12 | 없음 13 | 무음 14 | 기본 15 | 진동 16 | 중요 알림만 17 | 완전 무음 18 | 알람만 19 | 미디어 볼륨 음소거 20 | 무음으로 전환할 때 미디어 볼륨 음소거 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-nl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Schuifregelaar meldingen 8 | Actie 9 | Bovenste positie 10 | Middelste positie 11 | Onderste positie 12 | Geen 13 | Stil 14 | Normaal 15 | Trillen 16 | Alleen prioriteit 17 | Totale stilte 18 | Alleen alarmen 19 | Media dempen 20 | Media dempen bij overschakelen naar stil 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-pl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Suwak alarmowy 8 | Akcja 9 | Górna pozycja 10 | Środkowa pozycja 11 | Dolna pozycja 12 | Brak 13 | Cichy 14 | Normalny 15 | Wibracje 16 | Tylko priorytetowe 17 | Całkowita cisza 18 | Tylko alarmy 19 | Wycisz multimedia 20 | Wycisz multimedia po przełączeniu na Cichy 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-pt-rBR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Controle deslizante de alerta 8 | Ação 9 | Em cima 10 | No centro 11 | Em baixo 12 | Nenhum 13 | Silencioso 14 | Normal 15 | Vibração 16 | Somente prioridade 17 | Silêncio total 18 | Somente alarmes 19 | Silenciar mídia 20 | Silenciar mídia ao mudar para o modo silencioso 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-pt-rPT/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Botão deslizante 8 | Ação 9 | Para cima 10 | No meio 11 | Em baixo 12 | Nenhum 13 | Silencioso 14 | Normal 15 | Vibração 16 | Apenas prioritárias 17 | Silêncio total 18 | Apenas alarmes 19 | Silenciar multimédia 20 | Silenciar multimédia ao ativar modo silencioso 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ro/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Alert slider 8 | Acțiune 9 | Sus 10 | Mijloc 11 | Jos 12 | Niciuna 13 | Silențios 14 | Normal 15 | Vibrație 16 | Numai cu prioritate 17 | Niciun sunet 18 | Numai alarme 19 | Fără sunet media 20 | Fără sunet media când se schimbă la silențios 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Переключатель оповещений 8 | Действие 9 | Верхнее положение 10 | Среднее положение 11 | Нижнее положение 12 | Ничего 13 | Без звука 14 | Обычный 15 | Вибрация 16 | Только важные 17 | Полная тишина 18 | Только будильник 19 | Выключить звук медиа 20 | Отключение звука мультимедиа при переключении на беззвучный режим 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-sl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Drsnik za opozorila 8 | Dejanje 9 | Zgornji položaj 10 | Srednji položaj 11 | Spodnji položaj 12 | Brez 13 | Tiho 14 | Običajno 15 | Vibriranje 16 | Samo prednostno 17 | Popolna tišina 18 | Samo budilke 19 | Utišaj predstavnost 20 | Utišaj predstavnost med preklapljanjem na tiho 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-sq/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Rrëshqitësi i alarmit 8 | Veprimi 9 | Pozicioni i lartë 10 | Pozicioni i mesëm 11 | Pozicioni i poshtëm 12 | Asnjë 13 | Pa zë 14 | Normal 15 | Dridhje 16 | Vetëm kryesoret 17 | Heshtje e plotë 18 | Vetëm alarmet 19 | Hesht median 20 | Hesht median kur kalon në heshtje 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-sv/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Åtgärd 8 | Inget 9 | Normal 10 | Vibration 11 | 12 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ta/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | முதற் நிலை 8 | நடு நிலை 9 | கீழ் நிலை 10 | 11 | -------------------------------------------------------------------------------- /KeyHandler/res/values-tr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Uyarı kaydırıcısı 8 | Eylem 9 | Üst konum 10 | Orta konum 11 | Alt konum 12 | Hiçbiri 13 | Sessiz 14 | Normal 15 | Titreşim 16 | Sadece öncelik 17 | Tam sessizlik 18 | Yalnızca alarmlar 19 | Medyayı sustur 20 | Sessize geçerken medyayı sustur 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-ug/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | ئاگاھلاندۇرۇش سىيرىغۇچ 8 | مەشغۇلات 9 | چوققا نۇقتا 10 | ئوتتۇرا نۇقتا 11 | ئاستى نۇقتا 12 | يوق 13 | ئۈنسىز 14 | ئادەتتىكى 15 | تىترەت 16 | ئالدىنلىقلا 17 | تامامەن ئۈنسىز 18 | قوڭغۇراقلا 19 | ۋاسىتە ئۈنسىز 20 | ئۈنسىز ھالەتكە ئالماشتۇرغاندا ۋاسىتىنى ئۈنسىزلەيدۇ 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-vi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Thanh trượt cảnh báo 8 | Thao tác 9 | Vị trí trên cùng 10 | Vị trí giữa 11 | Vị trí dưới cùng 12 | Không có 13 | Im lặng 14 | Bình thường 15 | Rung 16 | Chỉ ưu tiên 17 | Hoàn toàn im lặng 18 | Chỉ báo thức 19 | Tắt tiếng phương tiện 20 | Tắt tiếng phương tiện khi chuyển sang chế độ im lặng 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 警报滑块 8 | 操作 9 | 顶部位置 10 | 中间位置 11 | 底部位置 12 | 13 | 静音 14 | 正常 15 | 振动 16 | 仅限优先 17 | 完全静音 18 | 仅限闹钟 19 | 静音,包括媒体音量 20 | 切换静音同时静音媒体 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values-zh-rTW/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 警示滑桿 8 | 動作 9 | 頂部位置 10 | 中間位置 11 | 底部位置 12 | 13 | 靜音 14 | 一般 15 | 震動 16 | 僅限優先 17 | 一律靜音 18 | 僅限鬧鐘 19 | 靜音,包括媒體 20 | 切換靜音時靜音媒體 21 | 22 | -------------------------------------------------------------------------------- /KeyHandler/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | @string/alert_slider_mode_none 9 | @string/alert_slider_mode_normal 10 | @string/alert_slider_mode_vibration 11 | @string/alert_slider_mode_silent 12 | @string/alert_slider_mode_dnd_priority_only 13 | @string/alert_slider_mode_dnd_total_silence 14 | @string/alert_slider_mode_dnd_alarms_only 15 | 16 | 17 | 18 | -1 19 | 2 20 | 1 21 | 0 22 | 3 23 | 4 24 | 5 25 | 26 | 27 | -------------------------------------------------------------------------------- /KeyHandler/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Alert slider 9 | Action 10 | Top position 11 | Middle position 12 | Bottom position 13 | None 14 | Silent 15 | Normal 16 | Vibration 17 | Priority only 18 | Total silence 19 | Alarms only 20 | Mute media 21 | Mute media when switching to silent 22 | 23 | -------------------------------------------------------------------------------- /KeyHandler/res/xml/button_panel.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 15 | 16 | 24 | 25 | 33 | 34 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /KeyHandler/src/org/lineageos/settings/device/BootCompletedReceiver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.device 7 | 8 | import android.content.BroadcastReceiver 9 | import android.content.Context 10 | import android.content.Intent 11 | import android.util.Log 12 | 13 | class BootCompletedReceiver : BroadcastReceiver() { 14 | override fun onReceive(context: Context, intent: Intent) { 15 | Log.d(TAG, "Starting") 16 | context.startService(Intent(context, KeyHandler::class.java)) 17 | } 18 | 19 | companion object { 20 | private const val TAG = "KeyHandler" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /KeyHandler/src/org/lineageos/settings/device/ButtonSettingsActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2024 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.device 7 | 8 | import android.os.Bundle 9 | 10 | import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity 11 | 12 | class ButtonSettingsActivity : CollapsingToolbarBaseActivity() { 13 | public override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | fragmentManager.beginTransaction().replace( 16 | com.android.settingslib.collapsingtoolbar.R.id.content_frame, 17 | ButtonSettingsFragment() 18 | ).commit() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /KeyHandler/src/org/lineageos/settings/device/ButtonSettingsFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.device 7 | 8 | import android.os.Bundle 9 | import android.view.MenuItem 10 | import androidx.preference.PreferenceFragment 11 | 12 | class ButtonSettingsFragment : PreferenceFragment() { 13 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { 14 | addPreferencesFromResource(R.xml.button_panel) 15 | activity.actionBar!!.setDisplayHomeAsUpEnabled(true) 16 | } 17 | 18 | override fun addPreferencesFromResource(preferencesResId: Int) { 19 | super.addPreferencesFromResource(preferencesResId) 20 | } 21 | 22 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 23 | when (item.itemId) { 24 | R.id.home -> { 25 | activity.finish() 26 | return true 27 | } 28 | } 29 | return super.onOptionsItemSelected(item) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /KeyHandler/src/org/lineageos/settings/device/ConfigPanelSearchIndexablesProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.device 7 | 8 | import android.database.Cursor 9 | import android.database.MatrixCursor 10 | import android.provider.SearchIndexableResource 11 | import android.provider.SearchIndexablesProvider 12 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME 13 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID 14 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION 15 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS 16 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE 17 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK 18 | import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID 19 | import android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS 20 | import android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS 21 | import android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS 22 | 23 | class ConfigPanelSearchIndexablesProvider : SearchIndexablesProvider() { 24 | override fun onCreate(): Boolean = true 25 | 26 | override fun queryXmlResources(projection: Array?): Cursor { 27 | val cursor = MatrixCursor(INDEXABLES_XML_RES_COLUMNS) 28 | INDEXABLE_RES.forEach { 29 | cursor.addRow(generateResourceRef(it)) 30 | } 31 | return cursor 32 | } 33 | 34 | override fun queryRawData(projection: Array?): Cursor { 35 | return MatrixCursor(INDEXABLES_RAW_COLUMNS) 36 | } 37 | 38 | override fun queryNonIndexableKeys(projection: Array?): Cursor { 39 | return MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS) 40 | } 41 | 42 | private fun generateResourceRef(sir: SearchIndexableResource): Array { 43 | val ref = arrayOfNulls(7) 44 | ref[COLUMN_INDEX_XML_RES_RANK] = sir.rank 45 | ref[COLUMN_INDEX_XML_RES_RESID] = sir.xmlResId 46 | ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = null 47 | ref[COLUMN_INDEX_XML_RES_ICON_RESID] = sir.iconResId 48 | ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = "com.android.settings.action.EXTRA_SETTINGS" 49 | ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = "org.lineageos.settings.device" 50 | ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = sir.className 51 | return ref 52 | } 53 | 54 | companion object { 55 | private const val TAG = "ConfigPanelSearchIndexablesProvider" 56 | 57 | private val INDEXABLE_RES = arrayOf( 58 | SearchIndexableResource( 59 | 1, R.xml.button_panel, ButtonSettingsActivity::class.java.name, 0 60 | ) 61 | ) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /KeyHandler/src/org/lineageos/settings/device/KeyHandler.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2023 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.device 7 | 8 | import android.app.NotificationManager 9 | import android.app.Service 10 | import android.content.BroadcastReceiver 11 | import android.content.Context 12 | import android.content.Intent 13 | import android.content.IntentFilter 14 | import android.content.SharedPreferences 15 | import android.media.AudioManager 16 | import android.media.AudioSystem 17 | import android.os.IBinder 18 | import android.os.UEventObserver 19 | import android.os.VibrationAttributes 20 | import android.os.VibrationEffect 21 | import android.os.Vibrator 22 | import android.provider.Settings 23 | import androidx.preference.PreferenceManager 24 | 25 | import java.util.concurrent.Executors 26 | 27 | class KeyHandler : Service() { 28 | private lateinit var audioManager: AudioManager 29 | private lateinit var notificationManager: NotificationManager 30 | private lateinit var vibrator: Vibrator 31 | private lateinit var sharedPreferences: SharedPreferences 32 | 33 | private val executorService = Executors.newSingleThreadExecutor() 34 | 35 | private var wasMuted = false 36 | private val broadcastReceiver = object : BroadcastReceiver() { 37 | override fun onReceive(context: Context, intent: Intent) { 38 | val stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1) 39 | val state = intent.getBooleanExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, false) 40 | if (stream == AudioSystem.STREAM_MUSIC && !state) { 41 | wasMuted = false 42 | } 43 | } 44 | } 45 | 46 | private val alertSliderEventObserver = object : UEventObserver() { 47 | private val lock = Any() 48 | 49 | override fun onUEvent(event: UEvent) { 50 | synchronized(lock) { 51 | event.get("SWITCH_STATE")?.let { 52 | handleMode(it.toInt()) 53 | return 54 | } 55 | event.get("STATE")?.let { 56 | val none = it.contains("USB=0") 57 | val vibration = it.contains("HOST=0") 58 | val silent = it.contains("null)=0") 59 | 60 | if (none && !vibration && !silent) { 61 | handleMode(POSITION_BOTTOM) 62 | } else if (!none && vibration && !silent) { 63 | handleMode(POSITION_MIDDLE) 64 | } else if (!none && !vibration && silent) { 65 | handleMode(POSITION_TOP) 66 | } 67 | 68 | return 69 | } 70 | } 71 | } 72 | } 73 | 74 | override fun onCreate() { 75 | audioManager = getSystemService(AudioManager::class.java)!! 76 | notificationManager = getSystemService(NotificationManager::class.java)!! 77 | vibrator = getSystemService(Vibrator::class.java)!! 78 | sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) 79 | 80 | registerReceiver( 81 | broadcastReceiver, 82 | IntentFilter(AudioManager.STREAM_MUTE_CHANGED_ACTION) 83 | ) 84 | alertSliderEventObserver.startObserving("tri-state-key") 85 | alertSliderEventObserver.startObserving("tri_state_key") 86 | } 87 | 88 | override fun onBind(intent: Intent?): IBinder? = null 89 | 90 | private fun vibrateIfNeeded(mode: Int) { 91 | when (mode) { 92 | AudioManager.RINGER_MODE_VIBRATE -> vibrator.vibrate( 93 | MODE_VIBRATION_EFFECT, 94 | HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES 95 | ) 96 | AudioManager.RINGER_MODE_NORMAL -> vibrator.vibrate( 97 | MODE_NORMAL_EFFECT, 98 | HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES 99 | ) 100 | } 101 | } 102 | 103 | private fun handleMode(position: Int) { 104 | val muteMedia = sharedPreferences.getBoolean(MUTE_MEDIA_WITH_SILENT, false) 105 | 106 | val mode = when (position) { 107 | POSITION_TOP -> sharedPreferences.getString(ALERT_SLIDER_TOP_KEY, "0")!!.toInt() 108 | POSITION_MIDDLE -> sharedPreferences.getString(ALERT_SLIDER_MIDDLE_KEY, "1")!!.toInt() 109 | POSITION_BOTTOM -> sharedPreferences.getString(ALERT_SLIDER_BOTTOM_KEY, "2")!!.toInt() 110 | else -> return 111 | } 112 | 113 | executorService.submit { 114 | when (mode) { 115 | AudioManager.RINGER_MODE_SILENT -> { 116 | setZenMode(Settings.Global.ZEN_MODE_OFF) 117 | audioManager.ringerModeInternal = mode 118 | if (muteMedia) { 119 | audioManager.adjustVolume(AudioManager.ADJUST_MUTE, 0) 120 | wasMuted = true 121 | } 122 | } 123 | AudioManager.RINGER_MODE_VIBRATE, AudioManager.RINGER_MODE_NORMAL -> { 124 | setZenMode(Settings.Global.ZEN_MODE_OFF) 125 | audioManager.ringerModeInternal = mode 126 | if (muteMedia && wasMuted) { 127 | audioManager.adjustVolume(AudioManager.ADJUST_UNMUTE, 0) 128 | } 129 | } 130 | ZEN_PRIORITY_ONLY, ZEN_TOTAL_SILENCE, ZEN_ALARMS_ONLY -> { 131 | audioManager.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL 132 | setZenMode(mode - ZEN_OFFSET) 133 | if (muteMedia && wasMuted) { 134 | audioManager.adjustVolume(AudioManager.ADJUST_UNMUTE, 0) 135 | } 136 | } 137 | } 138 | vibrateIfNeeded(mode) 139 | } 140 | } 141 | 142 | private fun setZenMode(zenMode: Int) { 143 | // Set zen mode 144 | notificationManager.setZenMode(zenMode, null, TAG) 145 | 146 | // Wait until zen mode change is committed 147 | while (notificationManager.zenMode != zenMode) { 148 | Thread.sleep(10) 149 | } 150 | } 151 | 152 | companion object { 153 | private const val TAG = "KeyHandler" 154 | 155 | // Slider key positions 156 | private const val POSITION_TOP = 1 157 | private const val POSITION_MIDDLE = 2 158 | private const val POSITION_BOTTOM = 3 159 | 160 | // Preference keys 161 | private const val ALERT_SLIDER_TOP_KEY = "config_top_position" 162 | private const val ALERT_SLIDER_MIDDLE_KEY = "config_middle_position" 163 | private const val ALERT_SLIDER_BOTTOM_KEY = "config_bottom_position" 164 | private const val MUTE_MEDIA_WITH_SILENT = "config_mute_media" 165 | 166 | // ZEN constants 167 | private const val ZEN_OFFSET = 2 168 | private const val ZEN_PRIORITY_ONLY = 3 169 | private const val ZEN_TOTAL_SILENCE = 4 170 | private const val ZEN_ALARMS_ONLY = 5 171 | 172 | // Vibration attributes 173 | private val HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = 174 | VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK) 175 | 176 | // Vibration effects 177 | private val MODE_NORMAL_EFFECT = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK) 178 | private val MODE_VIBRATION_EFFECT = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK) 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /KeyHandler/tri-state-key-calibrate.rc: -------------------------------------------------------------------------------- 1 | service vendor.tri-state-key-calibrate /vendor/bin/tri-state-key-calibrate 2 | class main 3 | user system 4 | group system 5 | oneshot 6 | disabled 7 | 8 | on post-fs-data 9 | start vendor.tri-state-key-calibrate 10 | -------------------------------------------------------------------------------- /KeyHandler/tri-state-key-calibrate.sh: -------------------------------------------------------------------------------- 1 | #!/vendor/bin/sh 2 | if [[ -f /mnt/vendor/persist/engineermode/tri_state_hall_data ]]; then 3 | CALIBRATION_DATA="$(cat /mnt/vendor/persist/engineermode/tri_state_hall_data)" 4 | CALIBRATION_DATA="${CALIBRATION_DATA//;/,}" 5 | echo -n $CALIBRATION_DATA > /sys/devices/platform/soc/soc:tri_state_key/hall_data_calib 6 | fi 7 | -------------------------------------------------------------------------------- /aidl/livedisplay/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // SPDX-FileCopyrightText: 2019-2025 The LineageOS Project 3 | // SPDX-License-Identifier: Apache-2.0 4 | // 5 | 6 | filegroup { 7 | name: "vendor.lineage.livedisplay-oneplus-af", 8 | srcs: ["AntiFlicker.cpp"], 9 | } 10 | 11 | filegroup { 12 | name: "vendor.lineage.livedisplay-oneplus-se", 13 | srcs: ["SunlightEnhancement.cpp"], 14 | } 15 | 16 | cc_library_headers { 17 | name: "vendor.lineage.livedisplay-oneplus-headers", 18 | vendor_available: true, 19 | export_include_dirs: ["include"], 20 | } 21 | 22 | cc_binary { 23 | name: "vendor.lineage.livedisplay-service.oneplus", 24 | init_rc: ["vendor.lineage.livedisplay-service.oneplus.rc"], 25 | vintf_fragments: select(soong_config_variable("ONEPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_AF"), { 26 | "false": [], 27 | default: ["vendor.lineage.livedisplay-service.oneplus-af.xml"], 28 | }) + select(soong_config_variable("ONEPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_PA"), { 29 | "false": [], 30 | default: ["vendor.lineage.livedisplay-service.oneplus-pa.xml"], 31 | }) + select(soong_config_variable("ONEPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_SE"), { 32 | "false": [], 33 | default: ["vendor.lineage.livedisplay-service.oneplus-se.xml"], 34 | }), 35 | relative_install_path: "hw", 36 | srcs: [ 37 | ":vendor.lineage.livedisplay-sdm-pa", 38 | ":vendor.lineage.livedisplay-sdm-utils", 39 | ":vendor.lineage.livedisplay-oneplus-af", 40 | ":vendor.lineage.livedisplay-oneplus-se", 41 | "service.cpp", 42 | ], 43 | shared_libs: [ 44 | "libbase", 45 | "libbinder_ndk", 46 | "libbinder", 47 | "libutils", 48 | "vendor.lineage.livedisplay-V1-ndk", 49 | ], 50 | header_libs: [ 51 | "vendor.lineage.livedisplay-sdm-headers", 52 | "vendor.lineage.livedisplay-oneplus-headers", 53 | ], 54 | cflags: select(soong_config_variable("ONEPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_AF"), { 55 | "false": ["-DENABLE_AF=false"], 56 | default: ["-DENABLE_AF=true"], 57 | }) + select(soong_config_variable("ONEPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_PA"), { 58 | "false": ["-DENABLE_PA=false"], 59 | default: ["-DENABLE_PA=true"], 60 | }) + select(soong_config_variable("ONEPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_SE"), { 61 | "false": ["-DENABLE_SE=false"], 62 | default: ["-DENABLE_SE=true"], 63 | }), 64 | proprietary: true, 65 | } 66 | -------------------------------------------------------------------------------- /aidl/livedisplay/AntiFlicker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #define LOG_TAG "AntiFlickerService" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace aidl { 13 | namespace vendor { 14 | namespace lineage { 15 | namespace livedisplay { 16 | 17 | static constexpr const char* kDcDimmingPath = "/sys/class/drm/card0-DSI-1/dimlayer_bl_en"; 18 | 19 | ndk::ScopedAStatus AntiFlicker::getEnabled(bool* _aidl_return) { 20 | std::ifstream file(kDcDimmingPath); 21 | int result = -1; 22 | if (file.fail()) { 23 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 24 | } 25 | file >> result; 26 | LOG(DEBUG) << "Got result " << result << " fail " << file.fail(); 27 | *_aidl_return = result > 0; 28 | return ndk::ScopedAStatus::ok(); 29 | } 30 | 31 | ndk::ScopedAStatus AntiFlicker::setEnabled(bool enabled) { 32 | std::ofstream file(kDcDimmingPath); 33 | file << (enabled ? "1" : "0"); 34 | if (file.fail()) { 35 | LOG(DEBUG) << "setEnabled fail " << file.fail(); 36 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 37 | } 38 | return ndk::ScopedAStatus::ok(); 39 | } 40 | 41 | } // namespace livedisplay 42 | } // namespace lineage 43 | } // namespace vendor 44 | } // namespace aidl 45 | -------------------------------------------------------------------------------- /aidl/livedisplay/SunlightEnhancement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #define LOG_TAG "SunlightEnhancementService" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace aidl { 13 | namespace vendor { 14 | namespace lineage { 15 | namespace livedisplay { 16 | 17 | static constexpr const char* kHbmPath = "/sys/class/drm/card0-DSI-1/hbm"; 18 | 19 | ndk::ScopedAStatus SunlightEnhancement::getEnabled(bool* _aidl_return) { 20 | std::ifstream file(kHbmPath); 21 | int result = -1; 22 | if (file.fail()) { 23 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 24 | } 25 | file >> result; 26 | LOG(DEBUG) << "Got result " << result << " fail " << file.fail(); 27 | *_aidl_return = result > 0; 28 | return ndk::ScopedAStatus::ok(); 29 | } 30 | 31 | ndk::ScopedAStatus SunlightEnhancement::setEnabled(bool enabled) { 32 | std::ofstream file(kHbmPath); 33 | file << (enabled ? "5" : "0"); 34 | if (file.fail()) { 35 | LOG(DEBUG) << "setEnabled fail " << file.fail(); 36 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 37 | } 38 | return ndk::ScopedAStatus::ok(); 39 | } 40 | 41 | } // namespace livedisplay 42 | } // namespace lineage 43 | } // namespace vendor 44 | } // namespace aidl 45 | -------------------------------------------------------------------------------- /aidl/livedisplay/include/livedisplay/oneplus/AntiFlicker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2021-2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | namespace aidl { 11 | namespace vendor { 12 | namespace lineage { 13 | namespace livedisplay { 14 | 15 | class AntiFlicker : public BnAntiFlicker { 16 | // Methods from ::aidl::vendor::lineage::livedisplay::BnAntiFlicker follow. 17 | ndk::ScopedAStatus getEnabled(bool* _aidl_return) override; 18 | ndk::ScopedAStatus setEnabled(bool enabled) override; 19 | }; 20 | 21 | } // namespace livedisplay 22 | } // namespace lineage 23 | } // namespace vendor 24 | } // namespace aidl 25 | -------------------------------------------------------------------------------- /aidl/livedisplay/include/livedisplay/oneplus/SunlightEnhancement.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | namespace aidl { 11 | namespace vendor { 12 | namespace lineage { 13 | namespace livedisplay { 14 | 15 | class SunlightEnhancement : public BnSunlightEnhancement { 16 | // Methods from ::aidl::vendor::lineage::livedisplay::BnSunlightEnhancement follow. 17 | ndk::ScopedAStatus getEnabled(bool* _aidl_return) override; 18 | ndk::ScopedAStatus setEnabled(bool enabled) override; 19 | }; 20 | 21 | } // namespace livedisplay 22 | } // namespace lineage 23 | } // namespace vendor 24 | } // namespace aidl 25 | -------------------------------------------------------------------------------- /aidl/livedisplay/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #define LOG_TAG "vendor.lineage.livedisplay-service-oneplus" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using ::aidl::vendor::lineage::livedisplay::AntiFlicker; 17 | using ::aidl::vendor::lineage::livedisplay::SunlightEnhancement; 18 | using ::aidl::vendor::lineage::livedisplay::sdm::PictureAdjustment; 19 | using ::aidl::vendor::lineage::livedisplay::sdm::SDMController; 20 | 21 | int main() { 22 | android::ProcessState::self()->setThreadPoolMaxThreadCount(1); 23 | android::ProcessState::self()->startThreadPool(); 24 | 25 | LOG(INFO) << "LiveDisplay HAL service is starting."; 26 | 27 | std::shared_ptr controller = 28 | ENABLE_PA ? std::make_shared() : nullptr; 29 | 30 | std::shared_ptr af = ENABLE_AF ? ndk::SharedRefBase::make() : nullptr; 31 | std::shared_ptr pa = 32 | ENABLE_PA ? ndk::SharedRefBase::make(controller) : nullptr; 33 | std::shared_ptr se = 34 | ENABLE_SE ? ndk::SharedRefBase::make() : nullptr; 35 | 36 | if (af) { 37 | std::string instance = std::string() + AntiFlicker::descriptor + "/default"; 38 | binder_status_t status = AServiceManager_addService(af->asBinder().get(), instance.c_str()); 39 | CHECK_EQ(status, STATUS_OK); 40 | } 41 | 42 | if (pa) { 43 | std::string instance = std::string() + PictureAdjustment::descriptor + "/default"; 44 | binder_status_t status = AServiceManager_addService(pa->asBinder().get(), instance.c_str()); 45 | CHECK_EQ(status, STATUS_OK); 46 | } 47 | 48 | if (se) { 49 | std::string instance = std::string() + SunlightEnhancement::descriptor + "/default"; 50 | binder_status_t status = AServiceManager_addService(se->asBinder().get(), instance.c_str()); 51 | CHECK_EQ(status, STATUS_OK); 52 | } 53 | 54 | ABinderProcess_joinThreadPool(); 55 | return EXIT_FAILURE; // should not reach 56 | } 57 | -------------------------------------------------------------------------------- /aidl/livedisplay/vendor.lineage.livedisplay-service.oneplus-af.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | vendor.lineage.livedisplay 4 | 1 5 | 6 | IAntiFlicker 7 | default 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /aidl/livedisplay/vendor.lineage.livedisplay-service.oneplus-pa.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | vendor.lineage.livedisplay 4 | 1 5 | 6 | IPictureAdjustment 7 | default 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /aidl/livedisplay/vendor.lineage.livedisplay-service.oneplus-se.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | vendor.lineage.livedisplay 4 | 1 5 | 6 | ISunlightEnhancement 7 | default 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /aidl/livedisplay/vendor.lineage.livedisplay-service.oneplus.rc: -------------------------------------------------------------------------------- 1 | on init 2 | chown system graphics /sys/class/drm/card0-DSI-1/dimlayer_bl_en 3 | chown system graphics /sys/class/drm/card0-DSI-1/hbm 4 | chmod 0666 /sys/class/drm/card0-DSI-1/dimlayer_bl_en 5 | chmod 0666 /sys/class/drm/card0-DSI-1/hbm 6 | 7 | service vendor.livedisplay-hal /vendor/bin/hw/vendor.lineage.livedisplay-service.oneplus 8 | class late_start 9 | user system 10 | group system 11 | -------------------------------------------------------------------------------- /aidl/touch/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // SPDX-FileCopyrightText: 2025 The LineageOS Project 3 | // SPDX-License-Identifier: Apache-2.0 4 | // 5 | 6 | filegroup { 7 | name: "vendor.lineage.touch-oneplus-touchgesture", 8 | srcs: ["TouchscreenGesture.cpp"], 9 | } 10 | 11 | cc_library_headers { 12 | name: "vendor.lineage.touch-oneplus-headers", 13 | vendor_available: true, 14 | export_include_dirs: ["."], 15 | } 16 | 17 | cc_binary { 18 | name: "vendor.lineage.touch-service.oneplus", 19 | init_rc: ["vendor.lineage.touch-service.oneplus.rc"], 20 | vintf_fragments: ["vendor.lineage.touch-service.oneplus.xml"], 21 | vendor: true, 22 | relative_install_path: "hw", 23 | srcs: [ 24 | ":vendor.lineage.touch-oneplus-touchgesture", 25 | "service.cpp", 26 | ], 27 | shared_libs: [ 28 | "libbase", 29 | "liblog", 30 | "libbinder_ndk", 31 | "libutils", 32 | "vendor.lineage.touch-V1-ndk", 33 | ], 34 | header_libs: [ 35 | "vendor.lineage.touch-oneplus-headers", 36 | ], 37 | include_dirs: select(soong_config_variable("ONEPLUS_LINEAGE_TOUCH_HAL", "INCLUDE_DIR"), { 38 | any @ flag_val: [flag_val], 39 | default: [], 40 | }), 41 | } 42 | -------------------------------------------------------------------------------- /aidl/touch/TouchscreenGesture.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #define LOG_TAG "TouchscreenGestureService" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace aidl { 14 | namespace vendor { 15 | namespace lineage { 16 | namespace touch { 17 | 18 | ndk::ScopedAStatus TouchscreenGesture::getSupportedGestures(std::vector* _aidl_return) { 19 | std::vector gestures; 20 | 21 | for (const auto& entry : kGestureInfoMap) { 22 | if (access(entry.second.path, F_OK) != -1) { 23 | gestures.push_back({entry.first, entry.second.name, entry.second.keycode}); 24 | } 25 | } 26 | 27 | *_aidl_return = gestures; 28 | return ndk::ScopedAStatus::ok(); 29 | } 30 | 31 | ndk::ScopedAStatus TouchscreenGesture::setGestureEnabled(const Gesture& gesture, bool enabled) { 32 | const auto entry = kGestureInfoMap.find(gesture.id); 33 | if (entry == kGestureInfoMap.end()) { 34 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 35 | } 36 | 37 | std::ofstream file(entry->second.path); 38 | file << (enabled ? "1" : "0"); 39 | LOG(DEBUG) << "Wrote file " << entry->second.path << " fail " << file.fail(); 40 | 41 | return ndk::ScopedAStatus::ok(); 42 | } 43 | 44 | } // namespace touch 45 | } // namespace lineage 46 | } // namespace vendor 47 | } // namespace aidl 48 | -------------------------------------------------------------------------------- /aidl/touch/TouchscreenGesture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | namespace aidl { 12 | namespace vendor { 13 | namespace lineage { 14 | namespace touch { 15 | 16 | class TouchscreenGesture : public BnTouchscreenGesture { 17 | public: 18 | ndk::ScopedAStatus getSupportedGestures(std::vector* _aidl_return) override; 19 | ndk::ScopedAStatus setGestureEnabled(const Gesture& gesture, bool enabled) override; 20 | 21 | typedef struct { 22 | int32_t keycode; 23 | const char* name; 24 | const char* path; 25 | } GestureInfo; 26 | }; 27 | 28 | } // namespace touch 29 | } // namespace lineage 30 | } // namespace vendor 31 | } // namespace aidl 32 | -------------------------------------------------------------------------------- /aidl/touch/TouchscreenGestureConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "TouchscreenGesture.h" 11 | 12 | namespace aidl { 13 | namespace vendor { 14 | namespace lineage { 15 | namespace touch { 16 | 17 | const std::map kGestureInfoMap = { 18 | {0, {251, "Two fingers down swipe", "/proc/touchpanel/double_swipe_enable"}}, 19 | {1, {252, "Down arrow", "/proc/touchpanel/down_arrow_enable"}}, 20 | {2, {253, "Left arrow", "/proc/touchpanel/left_arrow_enable"}}, 21 | {3, {254, "Right arrow", "/proc/touchpanel/right_arrow_enable"}}, 22 | {4, {247, "Letter M", "/proc/touchpanel/letter_m_enable"}}, 23 | {5, {250, "Letter O", "/proc/touchpanel/letter_o_enable"}}, 24 | {6, {248, "Letter S", "/proc/touchpanel/letter_s_enable"}}, 25 | {7, {246, "Letter W", "/proc/touchpanel/letter_w_enable"}}, 26 | {8, {255, "Single Tap", "/proc/touchpanel/single_tap_enable"}}, 27 | }; 28 | 29 | } // namespace touch 30 | } // namespace lineage 31 | } // namespace vendor 32 | } // namespace aidl 33 | -------------------------------------------------------------------------------- /aidl/touch/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #define LOG_TAG "vendor.lineage.touch@1.0-service.oneplus" 7 | 8 | #include "TouchscreenGesture.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using aidl::vendor::lineage::touch::TouchscreenGesture; 15 | 16 | int main() { 17 | binder_status_t status = STATUS_OK; 18 | 19 | ABinderProcess_setThreadPoolMaxThreadCount(0); 20 | std::shared_ptr tg = ndk::SharedRefBase::make(); 21 | 22 | const std::string instanceTg = std::string(TouchscreenGesture::descriptor) + "/default"; 23 | status = AServiceManager_addService(tg->asBinder().get(), instanceTg.c_str()); 24 | CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instanceTg << " " << status; 25 | 26 | ABinderProcess_joinThreadPool(); 27 | return EXIT_FAILURE; // should not reach 28 | } 29 | -------------------------------------------------------------------------------- /aidl/touch/vendor.lineage.touch-service.oneplus.rc: -------------------------------------------------------------------------------- 1 | on boot 2 | chmod 0660 /proc/touchpanel/double_swipe_enable 3 | chmod 0660 /proc/touchpanel/down_arrow_enable 4 | chmod 0660 /proc/touchpanel/left_arrow_enable 5 | chmod 0660 /proc/touchpanel/letter_m_enable 6 | chmod 0660 /proc/touchpanel/letter_o_enable 7 | chmod 0660 /proc/touchpanel/letter_s_enable 8 | chmod 0660 /proc/touchpanel/letter_w_enable 9 | chmod 0660 /proc/touchpanel/right_arrow_enable 10 | chmod 0660 /proc/touchpanel/single_tap_enable 11 | chown system system /proc/touchpanel/double_swipe_enable 12 | chown system system /proc/touchpanel/down_arrow_enable 13 | chown system system /proc/touchpanel/left_arrow_enable 14 | chown system system /proc/touchpanel/letter_m_enable 15 | chown system system /proc/touchpanel/letter_o_enable 16 | chown system system /proc/touchpanel/letter_s_enable 17 | chown system system /proc/touchpanel/letter_w_enable 18 | chown system system /proc/touchpanel/right_arrow_enable 19 | chown system system /proc/touchpanel/single_tap_enable 20 | 21 | service vendor.touch-hal /vendor/bin/hw/vendor.lineage.touch-service.oneplus 22 | class hal 23 | user system 24 | group system 25 | -------------------------------------------------------------------------------- /aidl/touch/vendor.lineage.touch-service.oneplus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | vendor.lineage.touch 4 | 1 5 | ITouchscreenGesture/default 6 | 7 | 8 | -------------------------------------------------------------------------------- /aidl/vibrator/Android.bp: -------------------------------------------------------------------------------- 1 | Common_CFlags = ["-Wall"] 2 | Common_CFlags += ["-Werror"] 3 | 4 | cc_library_shared { 5 | name: "vendor.qti.hardware.vibrator.impl.oneplus", 6 | vendor: true, 7 | cflags: Common_CFlags, 8 | srcs: [ 9 | "Vibrator.cpp", 10 | ], 11 | shared_libs: [ 12 | "libcutils", 13 | "libutils", 14 | "liblog", 15 | "libqtivibratoreffect", 16 | "libbinder_ndk", 17 | "android.hardware.vibrator-V1-ndk", 18 | ], 19 | export_include_dirs: ["include"], 20 | } 21 | 22 | cc_binary { 23 | name: "vendor.qti.hardware.vibrator.service.oneplus", 24 | vendor: true, 25 | relative_install_path: "hw", 26 | init_rc: ["vendor.qti.hardware.vibrator.service.oneplus.rc"], 27 | vintf_fragments: [ 28 | "vendor.qti.hardware.vibrator.service.oneplus.xml", 29 | ], 30 | cflags: Common_CFlags, 31 | srcs: [ 32 | "service.cpp", 33 | ], 34 | shared_libs: [ 35 | "libcutils", 36 | "libutils", 37 | "libbase", 38 | "libbinder_ndk", 39 | "android.hardware.vibrator-V1-ndk", 40 | "vendor.qti.hardware.vibrator.impl.oneplus", 41 | ], 42 | } 43 | -------------------------------------------------------------------------------- /aidl/vibrator/Vibrator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #define LOG_TAG "vendor.qti.vibrator" 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "include/Vibrator.h" 43 | #ifdef USE_EFFECT_STREAM 44 | #include "effect.h" 45 | #endif 46 | 47 | namespace aidl { 48 | namespace android { 49 | namespace hardware { 50 | namespace vibrator { 51 | 52 | #define STRONG_MAGNITUDE 0x7fff 53 | #define MEDIUM_MAGNITUDE 0x5fff 54 | #define LIGHT_MAGNITUDE 0x3fff 55 | #define INVALID_VALUE -1 56 | #define CUSTOM_DATA_LEN 3 57 | #define NAME_BUF_SIZE 32 58 | 59 | #define MSM_CPU_LAHAINA 415 60 | #define APQ_CPU_LAHAINA 439 61 | #define MSM_CPU_SHIMA 450 62 | #define MSM_CPU_SM8325 501 63 | #define APQ_CPU_SM8325P 502 64 | #define MSM_CPU_YUPIK 475 65 | 66 | #define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)%8))) 67 | 68 | static const char LED_DEVICE[] = "/sys/class/leds/vibrator"; 69 | 70 | static std::map>> LED_EFFECTS{ 71 | { Effect::CLICK, { 72 | { "/sys/class/leds/vibrator/ignore_store", "0" }, 73 | { "/sys/class/leds/vibrator/duration", "10" }, 74 | { "/sys/class/leds/vibrator/vmax", "0x1f" }, 75 | { "/sys/class/leds/vibrator/gain", "0x80" }, 76 | { "/sys/class/leds/vibrator/seq", "0x00 0x03" }, 77 | { "/sys/class/leds/vibrator/loop", "0x00 0x00" }, 78 | { "/sys/class/leds/vibrator/brightness", "1" }, 79 | }}, 80 | { Effect::DOUBLE_CLICK, { 81 | { "/sys/class/leds/vibrator/ignore_store", "0" }, 82 | { "/sys/class/leds/vibrator/duration", "30" }, 83 | { "/sys/class/leds/vibrator/vmax", "0x1f" }, 84 | { "/sys/class/leds/vibrator/gain", "0x80" }, 85 | { "/sys/class/leds/vibrator/seq", "0x00 0x03" }, 86 | { "/sys/class/leds/vibrator/loop", "0x00 0x00" }, 87 | { "/sys/class/leds/vibrator/brightness", "1" }, 88 | { "SLEEP", "150" }, 89 | { "/sys/class/leds/vibrator/ignore_store", "0" }, 90 | { "/sys/class/leds/vibrator/duration", "30" }, 91 | { "/sys/class/leds/vibrator/vmax", "0x1f" }, 92 | { "/sys/class/leds/vibrator/gain", "0x80" }, 93 | { "/sys/class/leds/vibrator/seq", "0x00 0x03" }, 94 | { "/sys/class/leds/vibrator/loop", "0x00 0x00" }, 95 | { "/sys/class/leds/vibrator/brightness", "1" }, 96 | }}, 97 | { Effect::TICK, { 98 | { "/sys/class/leds/vibrator/ignore_store", "0" }, 99 | { "/sys/class/leds/vibrator/duration", "30" }, 100 | { "/sys/class/leds/vibrator/vmax", "0x1f" }, 101 | { "/sys/class/leds/vibrator/gain", "0x80" }, 102 | { "/sys/class/leds/vibrator/seq", "0x00 0x03" }, 103 | { "/sys/class/leds/vibrator/loop", "0x00 0x00" }, 104 | { "/sys/class/leds/vibrator/brightness", "1" }, 105 | }}, 106 | { Effect::HEAVY_CLICK, { 107 | { "/sys/class/leds/vibrator/ignore_store", "0" }, 108 | { "/sys/class/leds/vibrator/duration", "10" }, 109 | { "/sys/class/leds/vibrator/vmax", "0x1f" }, 110 | { "/sys/class/leds/vibrator/gain", "0x80" }, 111 | { "/sys/class/leds/vibrator/seq", "0x00 0x03" }, 112 | { "/sys/class/leds/vibrator/loop", "0x00 0x00" }, 113 | { "/sys/class/leds/vibrator/brightness", "1" }, 114 | }} 115 | }; 116 | 117 | InputFFDevice::InputFFDevice() 118 | { 119 | DIR *dp; 120 | FILE *fp = NULL; 121 | struct dirent *dir; 122 | uint8_t ffBitmask[FF_CNT / 8]; 123 | char devicename[PATH_MAX]; 124 | const char *INPUT_DIR = "/dev/input/"; 125 | char name[NAME_BUF_SIZE]; 126 | int fd, ret; 127 | int soc = property_get_int32("ro.vendor.qti.soc_id", -1); 128 | 129 | mVibraFd = INVALID_VALUE; 130 | mSupportGain = false; 131 | mSupportEffects = false; 132 | mSupportExternalControl = false; 133 | mCurrAppId = INVALID_VALUE; 134 | mCurrMagnitude = 0x7fff; 135 | mInExternalControl = false; 136 | 137 | dp = opendir(INPUT_DIR); 138 | if (!dp) { 139 | ALOGE("open %s failed, errno = %d", INPUT_DIR, errno); 140 | return; 141 | } 142 | 143 | memset(ffBitmask, 0, sizeof(ffBitmask)); 144 | while ((dir = readdir(dp)) != NULL){ 145 | if (dir->d_name[0] == '.' && 146 | (dir->d_name[1] == '\0' || 147 | (dir->d_name[1] == '.' && dir->d_name[2] == '\0'))) 148 | continue; 149 | 150 | snprintf(devicename, PATH_MAX, "%s%s", INPUT_DIR, dir->d_name); 151 | fd = TEMP_FAILURE_RETRY(open(devicename, O_RDWR)); 152 | if (fd < 0) { 153 | ALOGE("open %s failed, errno = %d", devicename, errno); 154 | continue; 155 | } 156 | 157 | ret = TEMP_FAILURE_RETRY(ioctl(fd, EVIOCGNAME(sizeof(name)), name)); 158 | if (ret == -1) { 159 | ALOGE("get input device name %s failed, errno = %d\n", devicename, errno); 160 | close(fd); 161 | continue; 162 | } 163 | 164 | if (strcmp(name, "qcom-hv-haptics") && strcmp(name, "qti-haptics")) { 165 | ALOGD("not a qcom/qti haptics device\n"); 166 | close(fd); 167 | continue; 168 | } 169 | 170 | ALOGI("%s is detected at %s\n", name, devicename); 171 | ret = TEMP_FAILURE_RETRY(ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffBitmask)), ffBitmask)); 172 | if (ret == -1) { 173 | ALOGE("ioctl failed, errno = %d", errno); 174 | close(fd); 175 | continue; 176 | } 177 | 178 | if (test_bit(FF_CONSTANT, ffBitmask) || 179 | test_bit(FF_PERIODIC, ffBitmask)) { 180 | mVibraFd = fd; 181 | if (test_bit(FF_CUSTOM, ffBitmask)) 182 | mSupportEffects = true; 183 | if (test_bit(FF_GAIN, ffBitmask)) 184 | mSupportGain = true; 185 | 186 | if (soc <= 0 && (fp = fopen("/sys/devices/soc0/soc_id", "r")) != NULL) { 187 | fscanf(fp, "%u", &soc); 188 | fclose(fp); 189 | } 190 | switch (soc) { 191 | case MSM_CPU_LAHAINA: 192 | case APQ_CPU_LAHAINA: 193 | case MSM_CPU_SHIMA: 194 | case MSM_CPU_SM8325: 195 | case APQ_CPU_SM8325P: 196 | case MSM_CPU_YUPIK: 197 | mSupportExternalControl = true; 198 | break; 199 | default: 200 | mSupportExternalControl = false; 201 | break; 202 | } 203 | break; 204 | } 205 | 206 | close(fd); 207 | } 208 | 209 | closedir(dp); 210 | } 211 | 212 | /** Play vibration 213 | * 214 | * @param effectId: ID of the predefined effect will be played. If effectId is valid 215 | * (non-negative value), the timeoutMs value will be ignored, and the 216 | * real playing length will be set in param@playLengtMs and returned 217 | * to VibratorService. If effectId is invalid, value in param@timeoutMs 218 | * will be used as the play length for playing a constant effect. 219 | * @param timeoutMs: playing length, non-zero means playing, zero means stop playing. 220 | * @param playLengthMs: the playing length in ms unit which will be returned to 221 | * VibratorService if the request is playing a predefined effect. 222 | * The custom_data in periodic is reused for returning the playLengthMs 223 | * from kernel space to userspace if the pattern is defined in kernel 224 | * driver. It's been defined with following format: 225 | * . 226 | * The effect-ID is used for passing down the predefined effect to 227 | * kernel driver, and the rest two parameters are used for returning 228 | * back the real playing length from kernel driver. 229 | */ 230 | int InputFFDevice::play(int effectId, uint32_t timeoutMs, long *playLengthMs) { 231 | struct ff_effect effect; 232 | struct input_event play; 233 | int16_t data[CUSTOM_DATA_LEN] = {0, 0, 0}; 234 | int ret; 235 | #ifdef USE_EFFECT_STREAM 236 | const struct effect_stream *stream; 237 | #endif 238 | 239 | /* For QMAA compliance, return OK even if vibrator device doesn't exist */ 240 | if (mVibraFd == INVALID_VALUE) { 241 | if (playLengthMs != NULL) 242 | *playLengthMs = 0; 243 | return 0; 244 | } 245 | 246 | if (timeoutMs != 0) { 247 | if (mCurrAppId != INVALID_VALUE) { 248 | ret = TEMP_FAILURE_RETRY(ioctl(mVibraFd, EVIOCRMFF, mCurrAppId)); 249 | if (ret == -1) { 250 | ALOGE("ioctl EVIOCRMFF failed, errno = %d", -errno); 251 | goto errout; 252 | } 253 | mCurrAppId = INVALID_VALUE; 254 | } 255 | 256 | memset(&effect, 0, sizeof(effect)); 257 | if (effectId != INVALID_VALUE) { 258 | data[0] = effectId; 259 | effect.type = FF_PERIODIC; 260 | effect.u.periodic.waveform = FF_CUSTOM; 261 | effect.u.periodic.magnitude = mCurrMagnitude; 262 | effect.u.periodic.custom_data = data; 263 | effect.u.periodic.custom_len = sizeof(int16_t) * CUSTOM_DATA_LEN; 264 | #ifdef USE_EFFECT_STREAM 265 | stream = get_effect_stream(effectId); 266 | if (stream != NULL) { 267 | effect.u.periodic.custom_data = (int16_t *)stream; 268 | effect.u.periodic.custom_len = sizeof(*stream); 269 | } 270 | #endif 271 | } else { 272 | effect.type = FF_CONSTANT; 273 | effect.u.constant.level = mCurrMagnitude; 274 | effect.replay.length = timeoutMs; 275 | } 276 | 277 | effect.id = mCurrAppId; 278 | effect.replay.delay = 0; 279 | 280 | ret = TEMP_FAILURE_RETRY(ioctl(mVibraFd, EVIOCSFF, &effect)); 281 | if (ret == -1) { 282 | ALOGE("ioctl EVIOCSFF failed, errno = %d", -errno); 283 | goto errout; 284 | } 285 | 286 | mCurrAppId = effect.id; 287 | if (effectId != INVALID_VALUE && playLengthMs != NULL) { 288 | *playLengthMs = data[1] * 1000 + data[2]; 289 | #ifdef USE_EFFECT_STREAM 290 | if (stream != NULL && stream->play_rate_hz != 0) 291 | *playLengthMs = ((stream->length * 1000) / stream->play_rate_hz) + 1; 292 | #endif 293 | } 294 | 295 | play.value = 1; 296 | play.type = EV_FF; 297 | play.code = mCurrAppId; 298 | play.time.tv_sec = 0; 299 | play.time.tv_usec = 0; 300 | ret = TEMP_FAILURE_RETRY(write(mVibraFd, (const void*)&play, sizeof(play))); 301 | if (ret == -1) { 302 | ALOGE("write failed, errno = %d\n", -errno); 303 | ret = TEMP_FAILURE_RETRY(ioctl(mVibraFd, EVIOCRMFF, mCurrAppId)); 304 | if (ret == -1) 305 | ALOGE("ioctl EVIOCRMFF failed, errno = %d", -errno); 306 | goto errout; 307 | } 308 | } else if (mCurrAppId != INVALID_VALUE) { 309 | ret = TEMP_FAILURE_RETRY(ioctl(mVibraFd, EVIOCRMFF, mCurrAppId)); 310 | if (ret == -1) { 311 | ALOGE("ioctl EVIOCRMFF failed, errno = %d", -errno); 312 | goto errout; 313 | } 314 | mCurrAppId = INVALID_VALUE; 315 | } 316 | return 0; 317 | 318 | errout: 319 | mCurrAppId = INVALID_VALUE; 320 | return ret; 321 | } 322 | 323 | int InputFFDevice::on(int32_t timeoutMs) { 324 | return play(INVALID_VALUE, timeoutMs, NULL); 325 | } 326 | 327 | int InputFFDevice::off() { 328 | return play(INVALID_VALUE, 0, NULL); 329 | } 330 | 331 | int InputFFDevice::setAmplitude(uint8_t amplitude) { 332 | int tmp, ret; 333 | struct input_event ie; 334 | 335 | /* For QMAA compliance, return OK even if vibrator device doesn't exist */ 336 | if (mVibraFd == INVALID_VALUE) 337 | return 0; 338 | 339 | tmp = amplitude * (STRONG_MAGNITUDE - LIGHT_MAGNITUDE) / 255; 340 | tmp += LIGHT_MAGNITUDE; 341 | ie.type = EV_FF; 342 | ie.code = FF_GAIN; 343 | ie.value = tmp; 344 | 345 | ret = TEMP_FAILURE_RETRY(write(mVibraFd, &ie, sizeof(ie))); 346 | if (ret == -1) { 347 | ALOGE("write FF_GAIN failed, errno = %d", -errno); 348 | return ret; 349 | } 350 | 351 | mCurrMagnitude = tmp; 352 | return 0; 353 | } 354 | 355 | int InputFFDevice::playEffect(int effectId, EffectStrength es, long *playLengthMs) { 356 | switch (es) { 357 | case EffectStrength::LIGHT: 358 | mCurrMagnitude = LIGHT_MAGNITUDE; 359 | break; 360 | case EffectStrength::MEDIUM: 361 | mCurrMagnitude = MEDIUM_MAGNITUDE; 362 | break; 363 | case EffectStrength::STRONG: 364 | mCurrMagnitude = STRONG_MAGNITUDE; 365 | break; 366 | default: 367 | return -1; 368 | } 369 | 370 | return play(effectId, INVALID_VALUE, playLengthMs); 371 | } 372 | 373 | LedVibratorDevice::LedVibratorDevice() { 374 | char devicename[PATH_MAX]; 375 | int fd; 376 | 377 | mDetected = false; 378 | 379 | snprintf(devicename, sizeof(devicename), "%s/%s", LED_DEVICE, "activate"); 380 | fd = TEMP_FAILURE_RETRY(open(devicename, O_RDWR)); 381 | if (fd < 0) { 382 | ALOGE("open %s failed, errno = %d", devicename, errno); 383 | return; 384 | } 385 | 386 | mDetected = true; 387 | } 388 | 389 | int LedVibratorDevice::write_value(const char *file, const char *value) { 390 | int fd; 391 | int ret; 392 | 393 | fd = TEMP_FAILURE_RETRY(open(file, O_WRONLY)); 394 | if (fd < 0) { 395 | ALOGE("open %s failed, errno = %d", file, errno); 396 | return -errno; 397 | } 398 | 399 | ret = TEMP_FAILURE_RETRY(write(fd, value, strlen(value) + 1)); 400 | if (ret == -1) { 401 | ret = -errno; 402 | } else if (ret != strlen(value) + 1) { 403 | /* even though EAGAIN is an errno value that could be set 404 | by write() in some cases, none of them apply here. So, this return 405 | value can be clearly identified when debugging and suggests the 406 | caller that it may try to call vibrator_on() again */ 407 | ret = -EAGAIN; 408 | } else { 409 | ret = 0; 410 | } 411 | 412 | errno = 0; 413 | close(fd); 414 | 415 | return ret; 416 | } 417 | 418 | int LedVibratorDevice::on(int32_t timeoutMs) { 419 | char file[PATH_MAX]; 420 | char value[32]; 421 | int ret; 422 | 423 | snprintf(file, sizeof(file), "%s/%s", LED_DEVICE, "state"); 424 | ret = write_value(file, "1"); 425 | if (ret < 0) 426 | goto error; 427 | 428 | snprintf(file, sizeof(file), "%s/%s", LED_DEVICE, "duration"); 429 | snprintf(value, sizeof(value), "%u\n", timeoutMs); 430 | ret = write_value(file, value); 431 | if (ret < 0) 432 | goto error; 433 | 434 | snprintf(file, sizeof(file), "%s/%s", LED_DEVICE, "activate"); 435 | ret = write_value(file, "1"); 436 | if (ret < 0) 437 | goto error; 438 | 439 | return 0; 440 | 441 | error: 442 | ALOGE("Failed to turn on vibrator ret: %d\n", ret); 443 | return ret; 444 | } 445 | 446 | int LedVibratorDevice::off() 447 | { 448 | char file[PATH_MAX]; 449 | int ret; 450 | 451 | snprintf(file, sizeof(file), "%s/%s", LED_DEVICE, "activate"); 452 | ret = write_value(file, "0"); 453 | return ret; 454 | } 455 | 456 | ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { 457 | *_aidl_return = IVibrator::CAP_ON_CALLBACK; 458 | 459 | if (ledVib.mDetected) { 460 | *_aidl_return |= IVibrator::CAP_PERFORM_CALLBACK; 461 | ALOGD("QTI Vibrator reporting capabilities: %d", *_aidl_return); 462 | return ndk::ScopedAStatus::ok(); 463 | } 464 | 465 | if (ff.mSupportGain) 466 | *_aidl_return |= IVibrator::CAP_AMPLITUDE_CONTROL; 467 | if (ff.mSupportEffects) 468 | *_aidl_return |= IVibrator::CAP_PERFORM_CALLBACK; 469 | if (ff.mSupportExternalControl) 470 | *_aidl_return |= IVibrator::CAP_EXTERNAL_CONTROL; 471 | 472 | ALOGD("QTI Vibrator reporting capabilities: %d", *_aidl_return); 473 | return ndk::ScopedAStatus::ok(); 474 | } 475 | 476 | ndk::ScopedAStatus Vibrator::off() { 477 | int ret; 478 | 479 | ALOGD("QTI Vibrator off"); 480 | if (ledVib.mDetected) 481 | ret = ledVib.off(); 482 | else 483 | ret = ff.off(); 484 | if (ret != 0) 485 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_SERVICE_SPECIFIC)); 486 | 487 | return ndk::ScopedAStatus::ok(); 488 | } 489 | 490 | ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, 491 | const std::shared_ptr& callback) { 492 | int ret; 493 | 494 | ALOGD("Vibrator on for timeoutMs: %d", timeoutMs); 495 | if (ledVib.mDetected) 496 | ret = ledVib.on(timeoutMs); 497 | else 498 | ret = ff.on(timeoutMs); 499 | 500 | if (ret != 0) 501 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_SERVICE_SPECIFIC)); 502 | 503 | if (callback != nullptr) { 504 | std::thread([=] { 505 | ALOGD("Starting on on another thread"); 506 | usleep(timeoutMs * 1000); 507 | ALOGD("Notifying on complete"); 508 | if (!callback->onComplete().isOk()) { 509 | ALOGE("Failed to call onComplete"); 510 | } 511 | }).detach(); 512 | } 513 | 514 | return ndk::ScopedAStatus::ok(); 515 | } 516 | 517 | ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength es, const std::shared_ptr& callback, int32_t* _aidl_return) { 518 | long playLengthMs; 519 | int ret; 520 | 521 | ALOGD("Vibrator perform effect %d", effect); 522 | 523 | if (ledVib.mDetected) { 524 | if (const auto it = LED_EFFECTS.find(effect); it != LED_EFFECTS.end()) { 525 | for (const auto &[path, value] : it->second) { 526 | if (path == "SLEEP") { 527 | usleep(atoi(value.c_str()) * 1000); 528 | } else { 529 | ledVib.write_value(path.c_str(), value.c_str()); 530 | } 531 | } 532 | 533 | // Restore gain from persist prop 534 | char gain[PROPERTY_VALUE_MAX]{}; 535 | property_get("persist.vendor.vib.gain", gain, "0x55"); 536 | ledVib.write_value("/sys/class/leds/vibrator/gain", gain); 537 | 538 | // Return magic value for play length so that we won't end up calling on() / off() 539 | playLengthMs = 150; 540 | } else { 541 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 542 | } 543 | } else { 544 | if (effect < Effect::CLICK || 545 | effect > Effect::HEAVY_CLICK) 546 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 547 | 548 | if (es != EffectStrength::LIGHT && es != EffectStrength::MEDIUM && 549 | es != EffectStrength::STRONG) 550 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 551 | 552 | ret = ff.playEffect((static_cast(effect)), es, &playLengthMs); 553 | if (ret != 0) 554 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_SERVICE_SPECIFIC)); 555 | } 556 | 557 | if (callback != nullptr) { 558 | std::thread([=] { 559 | ALOGD("Starting perform on another thread"); 560 | usleep(playLengthMs * 1000); 561 | ALOGD("Notifying perform complete"); 562 | callback->onComplete(); 563 | }).detach(); 564 | } 565 | 566 | *_aidl_return = playLengthMs; 567 | return ndk::ScopedAStatus::ok(); 568 | } 569 | 570 | ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector* _aidl_return) { 571 | if (ledVib.mDetected) { 572 | *_aidl_return = {Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK, Effect::HEAVY_CLICK}; 573 | } else { 574 | *_aidl_return = {Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK, Effect::THUD, 575 | Effect::POP, Effect::HEAVY_CLICK}; 576 | } 577 | 578 | return ndk::ScopedAStatus::ok(); 579 | } 580 | 581 | ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) { 582 | uint8_t tmp; 583 | int ret; 584 | 585 | if (ledVib.mDetected) 586 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 587 | 588 | ALOGD("Vibrator set amplitude: %f", amplitude); 589 | 590 | if (amplitude <= 0.0f || amplitude > 1.0f) 591 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT)); 592 | 593 | if (ff.mInExternalControl) 594 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 595 | 596 | tmp = (uint8_t)(amplitude * 0xff); 597 | ret = ff.setAmplitude(tmp); 598 | if (ret != 0) 599 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_SERVICE_SPECIFIC)); 600 | 601 | return ndk::ScopedAStatus::ok(); 602 | } 603 | 604 | ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) { 605 | if (ledVib.mDetected) 606 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 607 | 608 | ALOGD("Vibrator set external control: %d", enabled); 609 | if (!ff.mSupportExternalControl) 610 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 611 | 612 | ff.mInExternalControl = enabled; 613 | return ndk::ScopedAStatus::ok(); 614 | } 615 | 616 | ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t* maxDelayMs __unused) { 617 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 618 | } 619 | 620 | ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize __unused) { 621 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 622 | } 623 | 624 | ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector* supported __unused) { 625 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 626 | } 627 | 628 | ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive __unused, 629 | int32_t* durationMs __unused) { 630 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 631 | } 632 | 633 | ndk::ScopedAStatus Vibrator::compose(const std::vector& composite __unused, 634 | const std::shared_ptr& callback __unused) { 635 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 636 | } 637 | 638 | ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector* _aidl_return __unused) { 639 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 640 | } 641 | 642 | ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t id __unused, Effect effect __unused, 643 | EffectStrength strength __unused) { 644 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 645 | } 646 | 647 | ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t id __unused) { 648 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); 649 | } 650 | 651 | } // namespace vibrator 652 | } // namespace hardware 653 | } // namespace android 654 | } // namespace aidl 655 | 656 | -------------------------------------------------------------------------------- /aidl/vibrator/include/Vibrator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #pragma once 31 | 32 | #include 33 | 34 | namespace aidl { 35 | namespace android { 36 | namespace hardware { 37 | namespace vibrator { 38 | 39 | class InputFFDevice { 40 | public: 41 | InputFFDevice(); 42 | int playEffect(int effectId, EffectStrength es, long *playLengthMs); 43 | int on(int32_t timeoutMs); 44 | int off(); 45 | int setAmplitude(uint8_t amplitude); 46 | bool mSupportGain; 47 | bool mSupportEffects; 48 | bool mSupportExternalControl; 49 | bool mInExternalControl; 50 | private: 51 | int play(int effectId, uint32_t timeoutMs, long *playLengthMs); 52 | int mVibraFd; 53 | int16_t mCurrAppId; 54 | int16_t mCurrMagnitude; 55 | }; 56 | 57 | class LedVibratorDevice { 58 | public: 59 | LedVibratorDevice(); 60 | int on(int32_t timeoutMs); 61 | int off(); 62 | bool mDetected; 63 | int write_value(const char *file, const char *value); 64 | }; 65 | 66 | class Vibrator : public BnVibrator { 67 | public: 68 | class InputFFDevice ff; 69 | class LedVibratorDevice ledVib; 70 | ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override; 71 | ndk::ScopedAStatus off() override; 72 | ndk::ScopedAStatus on(int32_t timeoutMs, 73 | const std::shared_ptr& callback) override; 74 | ndk::ScopedAStatus perform(Effect effect, EffectStrength strength, 75 | const std::shared_ptr& callback, 76 | int32_t* _aidl_return) override; 77 | ndk::ScopedAStatus getSupportedEffects(std::vector* _aidl_return) override; 78 | ndk::ScopedAStatus setAmplitude(float amplitude) override; 79 | ndk::ScopedAStatus setExternalControl(bool enabled) override; 80 | ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs); 81 | ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize); 82 | ndk::ScopedAStatus getSupportedPrimitives(std::vector* supported) override; 83 | ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive, 84 | int32_t* durationMs) override; 85 | ndk::ScopedAStatus compose(const std::vector& composite, 86 | const std::shared_ptr& callback) override; 87 | ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector* _aidl_return) override; 88 | ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override; 89 | ndk::ScopedAStatus alwaysOnDisable(int32_t id) override; 90 | }; 91 | 92 | } // namespace vibrator 93 | } // namespace hardware 94 | } // namespace android 95 | } // namespace aidl 96 | -------------------------------------------------------------------------------- /aidl/vibrator/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, The Linux Foundation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above 10 | * copyright notice, this list of conditions and the following 11 | * disclaimer in the documentation and/or other materials provided 12 | * with the distribution. 13 | * * Neither the name of The Linux Foundation nor the names of its 14 | * contributors may be used to endorse or promote products derived 15 | * from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #define LOG_TAG "vendor.qti.hardware.vibrator.service" 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include "Vibrator.h" 37 | 38 | using aidl::android::hardware::vibrator::Vibrator; 39 | 40 | int main() { 41 | ABinderProcess_setThreadPoolMaxThreadCount(0); 42 | std::shared_ptr vib = ndk::SharedRefBase::make(); 43 | 44 | const std::string instance = std::string() + Vibrator::descriptor + "/default"; 45 | binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str()); 46 | CHECK(status == STATUS_OK); 47 | 48 | ABinderProcess_joinThreadPool(); 49 | return EXIT_FAILURE; // should not reach 50 | } 51 | -------------------------------------------------------------------------------- /aidl/vibrator/vendor.qti.hardware.vibrator.service.oneplus.rc: -------------------------------------------------------------------------------- 1 | service vendor.qti.vibrator /vendor/bin/hw/vendor.qti.hardware.vibrator.service.oneplus 2 | class hal 3 | user system 4 | group system input 5 | -------------------------------------------------------------------------------- /aidl/vibrator/vendor.qti.hardware.vibrator.service.oneplus.xml: -------------------------------------------------------------------------------- 1 | 28 | 29 | 30 | android.hardware.vibrator 31 | IVibrator/default 32 | 33 | 34 | -------------------------------------------------------------------------------- /audio_amplifier/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // SPDX-FileCopyrightText: 2020-2025 The LineageOS Project 3 | // SPDX-License-Identifier: Apache-2.0 4 | // 5 | 6 | cc_library_shared { 7 | name: "audio_amplifier.qcom", 8 | relative_install_path: "hw", 9 | vendor: true, 10 | owner: "qti", 11 | 12 | srcs: [ 13 | "audio_amplifier.c", 14 | ], 15 | 16 | include_dirs: [ 17 | "external/tinyalsa/include", 18 | "external/tinycompress/include", 19 | "system/media/audio_route/include", 20 | "system/media/audio_utils/include", 21 | ] + select(soong_config_variable("ANDROID", "target_board_platform"), { 22 | "lito": [ 23 | "hardware/qcom-caf/sm8250/audio/hal", 24 | "hardware/qcom-caf/sm8250/audio/hal/audio_extn", 25 | "hardware/qcom-caf/sm8250/audio/hal/msm8974", 26 | ], 27 | default: [], 28 | }), 29 | 30 | header_libs: [ 31 | "libhardware_headers", 32 | "qti_kernel_headers", 33 | ], 34 | 35 | shared_libs: [ 36 | "libcutils", 37 | "libdl", 38 | "libhardware", 39 | "liblog", 40 | "libtinyalsa", 41 | ], 42 | } 43 | -------------------------------------------------------------------------------- /audio_amplifier/audio_amplifier.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2015 The CyanogenMod Project 3 | * SPDX-FileCopyrightText: 2020-2025 The LineageOS Project 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #define LOG_TAG "audio_amplifier" 8 | //#define LOG_NDEBUG 0 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* clang-format off */ 20 | #include "platform.h" 21 | #include "platform_api.h" 22 | /* clang-format on */ 23 | 24 | #define UNUSED __attribute__((unused)) 25 | 26 | typedef struct amp_device { 27 | amplifier_device_t amp_dev; 28 | struct audio_device* adev; 29 | struct audio_usecase* usecase_tx; 30 | struct pcm* tfa98xx_out; 31 | const struct hw_module_t* module_ahal; 32 | typeof(enable_snd_device)* enable_snd_device; 33 | typeof(enable_audio_route)* enable_audio_route; 34 | typeof(disable_snd_device)* disable_snd_device; 35 | typeof(disable_audio_route)* disable_audio_route; 36 | typeof(platform_get_pcm_device_id)* platform_get_pcm_device_id; 37 | typeof(get_usecase_from_list)* get_usecase_from_list; 38 | } tfa_t; 39 | 40 | static tfa_t* tfa_dev = NULL; 41 | 42 | static int is_speaker(uint32_t snd_device) { 43 | int speaker = 0; 44 | switch (snd_device) { 45 | case SND_DEVICE_OUT_SPEAKER: 46 | case SND_DEVICE_OUT_SPEAKER_REVERSE: 47 | case SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES: 48 | case SND_DEVICE_OUT_VOICE_SPEAKER: 49 | case SND_DEVICE_OUT_VOICE_SPEAKER_2: 50 | case SND_DEVICE_OUT_SPEAKER_AND_HDMI: 51 | case SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET: 52 | case SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET: 53 | speaker = 1; 54 | break; 55 | } 56 | 57 | return speaker; 58 | } 59 | 60 | static int tfa98xx_start_feedback(void* adev, uint32_t snd_device) { 61 | tfa_dev->adev = (struct audio_device*)adev; 62 | int pcm_dev_tx_id = 0, rc = 0; 63 | struct pcm_config pcm_config_tfa98xx = { 64 | .channels = 2, 65 | .rate = 48000, 66 | .period_size = 256, 67 | .period_count = 4, 68 | .format = PCM_FORMAT_S16_LE, 69 | .start_threshold = 0, 70 | .stop_threshold = INT_MAX, 71 | .silence_threshold = 0, 72 | }; 73 | 74 | if (!tfa_dev) { 75 | ALOGE("%d: Invalid params", __LINE__); 76 | return -EINVAL; 77 | } 78 | 79 | if (tfa_dev->tfa98xx_out || !is_speaker(snd_device)) return 0; 80 | 81 | tfa_dev->usecase_tx = (struct audio_usecase*)calloc(1, sizeof(struct audio_usecase)); 82 | if (!tfa_dev->usecase_tx) { 83 | ALOGE("%d: failed to allocate usecase", __LINE__); 84 | return -ENOMEM; 85 | } 86 | tfa_dev->usecase_tx->id = USECASE_AUDIO_SPKR_CALIB_TX; 87 | tfa_dev->usecase_tx->type = PCM_CAPTURE; 88 | tfa_dev->usecase_tx->in_snd_device = SND_DEVICE_IN_CAPTURE_VI_FEEDBACK; 89 | #if __has_include("device_utils.h") 90 | list_init(&tfa_dev->usecase_tx->device_list); 91 | #endif 92 | 93 | list_add_tail(&tfa_dev->adev->usecase_list, &tfa_dev->usecase_tx->list); 94 | tfa_dev->enable_snd_device(tfa_dev->adev, tfa_dev->usecase_tx->in_snd_device); 95 | tfa_dev->enable_audio_route(tfa_dev->adev, tfa_dev->usecase_tx); 96 | 97 | pcm_dev_tx_id = 98 | tfa_dev->platform_get_pcm_device_id(tfa_dev->usecase_tx->id, tfa_dev->usecase_tx->type); 99 | ALOGD("pcm_dev_tx_id = %d", pcm_dev_tx_id); 100 | if (pcm_dev_tx_id < 0) { 101 | ALOGE("%d: Invalid pcm device for usecase (%d)", __LINE__, tfa_dev->usecase_tx->id); 102 | rc = -ENODEV; 103 | goto error; 104 | } 105 | 106 | tfa_dev->tfa98xx_out = 107 | pcm_open(tfa_dev->adev->snd_card, pcm_dev_tx_id, PCM_IN, &pcm_config_tfa98xx); 108 | if (!pcm_is_ready(tfa_dev->tfa98xx_out)) { 109 | ALOGE("%d: %s", __LINE__, pcm_get_error(tfa_dev->tfa98xx_out)); 110 | rc = -EIO; 111 | goto error; 112 | } 113 | 114 | rc = pcm_start(tfa_dev->tfa98xx_out); 115 | if (rc < 0) { 116 | ALOGE("%d: pcm start for TX failed", __LINE__); 117 | rc = -EINVAL; 118 | goto error; 119 | } 120 | return 0; 121 | 122 | error: 123 | ALOGE("%s: error case", __func__); 124 | if (tfa_dev->tfa98xx_out != 0) { 125 | pcm_close(tfa_dev->tfa98xx_out); 126 | tfa_dev->tfa98xx_out = NULL; 127 | } 128 | list_remove(&tfa_dev->usecase_tx->list); 129 | tfa_dev->disable_snd_device(tfa_dev->adev, tfa_dev->usecase_tx->in_snd_device); 130 | tfa_dev->disable_audio_route(tfa_dev->adev, tfa_dev->usecase_tx); 131 | free(tfa_dev->usecase_tx); 132 | 133 | return rc; 134 | } 135 | 136 | static void tfa98xx_stop_feedback(void* adev, uint32_t snd_device) { 137 | tfa_dev->adev = (struct audio_device*)adev; 138 | if (!tfa_dev) { 139 | ALOGE("%s: Invalid params", __func__); 140 | return; 141 | } 142 | 143 | if (!is_speaker(snd_device)) return; 144 | 145 | if (tfa_dev->tfa98xx_out) { 146 | pcm_close(tfa_dev->tfa98xx_out); 147 | tfa_dev->tfa98xx_out = NULL; 148 | } 149 | 150 | tfa_dev->disable_snd_device(tfa_dev->adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK); 151 | 152 | tfa_dev->usecase_tx = 153 | tfa_dev->get_usecase_from_list(tfa_dev->adev, USECASE_AUDIO_SPKR_CALIB_TX); 154 | if (tfa_dev->usecase_tx) { 155 | list_remove(&tfa_dev->usecase_tx->list); 156 | tfa_dev->disable_audio_route(tfa_dev->adev, tfa_dev->usecase_tx); 157 | free(tfa_dev->usecase_tx); 158 | } 159 | return; 160 | } 161 | 162 | static int amp_set_feedback(UNUSED amplifier_device_t* device, void* adev, uint32_t devices, 163 | bool enable) { 164 | tfa_dev->adev = (struct audio_device*)adev; 165 | if (enable) { 166 | tfa98xx_start_feedback(tfa_dev->adev, devices); 167 | } else { 168 | tfa98xx_stop_feedback(tfa_dev->adev, devices); 169 | } 170 | return 0; 171 | } 172 | 173 | static int amp_dev_close(hw_device_t* device) { 174 | tfa_t* dev = (tfa_t*)device; 175 | if (dev) free(dev); 176 | 177 | return 0; 178 | } 179 | 180 | static int amp_module_open(const hw_module_t* module, const char* name, hw_device_t** device) { 181 | if (strcmp(name, AMPLIFIER_HARDWARE_INTERFACE)) { 182 | ALOGE("%s:%d: %s does not match amplifier hardware interface name\n", __func__, __LINE__, 183 | name); 184 | return -ENODEV; 185 | } 186 | 187 | tfa_dev = calloc(1, sizeof(tfa_t)); 188 | if (!tfa_dev) { 189 | ALOGE("%s:%d: Unable to allocate memory for amplifier device\n", __func__, __LINE__); 190 | return -ENOMEM; 191 | } 192 | 193 | tfa_dev->amp_dev.common.tag = HARDWARE_DEVICE_TAG; 194 | tfa_dev->amp_dev.common.module = (hw_module_t*)module; 195 | tfa_dev->amp_dev.common.version = HARDWARE_DEVICE_API_VERSION(1, 0); 196 | tfa_dev->amp_dev.common.close = amp_dev_close; 197 | 198 | tfa_dev->amp_dev.set_input_devices = NULL; 199 | tfa_dev->amp_dev.set_output_devices = NULL; 200 | tfa_dev->amp_dev.enable_output_devices = NULL; 201 | tfa_dev->amp_dev.enable_input_devices = NULL; 202 | tfa_dev->amp_dev.set_mode = NULL; 203 | tfa_dev->amp_dev.output_stream_start = NULL; 204 | tfa_dev->amp_dev.input_stream_start = NULL; 205 | tfa_dev->amp_dev.output_stream_standby = NULL; 206 | tfa_dev->amp_dev.input_stream_standby = NULL; 207 | tfa_dev->amp_dev.set_parameters = NULL; 208 | tfa_dev->amp_dev.out_set_parameters = NULL; 209 | tfa_dev->amp_dev.in_set_parameters = NULL; 210 | tfa_dev->amp_dev.set_feedback = amp_set_feedback; 211 | 212 | if (hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, AUDIO_HARDWARE_MODULE_ID_PRIMARY, 213 | &tfa_dev->module_ahal)) { 214 | ALOGW("%s: Failed to load audio.primary", __func__); 215 | return -ENODEV; 216 | } 217 | 218 | #define LOAD_AHAL_SYMBOL(symbol) \ 219 | do { \ 220 | tfa_dev->symbol = dlsym(tfa_dev->module_ahal->dso, #symbol); \ 221 | if (tfa_dev->symbol == NULL) { \ 222 | ALOGW("%s: %s not found (%s)", __func__, #symbol, dlerror()); \ 223 | free(tfa_dev); \ 224 | return -ENODEV; \ 225 | } \ 226 | } while (0) 227 | 228 | LOAD_AHAL_SYMBOL(enable_snd_device); 229 | LOAD_AHAL_SYMBOL(enable_audio_route); 230 | LOAD_AHAL_SYMBOL(disable_snd_device); 231 | LOAD_AHAL_SYMBOL(disable_audio_route); 232 | LOAD_AHAL_SYMBOL(platform_get_pcm_device_id); 233 | LOAD_AHAL_SYMBOL(get_usecase_from_list); 234 | 235 | #undef LOAD_AHAL_SYMBOL 236 | 237 | *device = (hw_device_t*)tfa_dev; 238 | 239 | return 0; 240 | } 241 | 242 | static struct hw_module_methods_t hal_module_methods = { 243 | .open = amp_module_open, 244 | }; 245 | 246 | /* clang-format off */ 247 | amplifier_module_t HAL_MODULE_INFO_SYM = { 248 | .common = { 249 | .tag = HARDWARE_MODULE_TAG, 250 | .module_api_version = AMPLIFIER_MODULE_API_VERSION_0_1, 251 | .hal_api_version = HARDWARE_HAL_API_VERSION, 252 | .id = AMPLIFIER_HARDWARE_MODULE_ID, 253 | .name = "TFA98XX audio amplifier HAL", 254 | .author = "The LineageOS Project", 255 | .methods = &hal_module_methods, 256 | }, 257 | }; 258 | -------------------------------------------------------------------------------- /dirac_gef/Android.bp: -------------------------------------------------------------------------------- 1 | android_app { 2 | name: "OnePlusDiracGef", 3 | 4 | asset_dirs: ["assets"], 5 | srcs: ["src/**/*.kt"], 6 | 7 | certificate: "platform", 8 | platform_apis: true, 9 | system_ext_specific: true, 10 | 11 | optimize: { 12 | proguard_flags_files: ["proguard.flags"], 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /dirac_gef/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /dirac_gef/assets/dirac_gef_init.txt: -------------------------------------------------------------------------------- 1 | 47000100|0800 2 | 49000100|0800 3 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438e7da044001 4 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438b5da044001 5 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438e7da044001 6 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438b5da044001 7 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a2043880da044000 8 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a2043880da044001 9 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388080054001 10 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388180054001 11 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388280054001 12 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388380054001 13 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388480054001 14 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388580054001 15 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388680054001 16 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388780054001 17 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388880054001 18 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388980054001 19 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204380042c801002d011000400100080000000000000000000000002d011001400100080000000000000000000000002d011002400100080000000000000000000000002d011003400100080000000000000000000000002d011004400100080000000000000000000000002d011005400100080000000000000000000000002d011006400100080000000000000000000000002d011007400100080000000000000000000000002d011008400100080000000000000000000000002d01100940010008000000000000000000000048c801 20 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388080054001 21 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388180054001 22 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388280054001 23 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388380054001 24 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388480054001 25 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388580054001 26 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388680054001 27 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388780054001 28 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388880054001 29 | 46000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204388980054001 30 | 45000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a204380042c801012d011000400100080000000000000000000000012d011001400100080000000000000000000000012d011002400100080000000000000000000000012d011003400100080000000000000000000000012d011004400100080000000000000000000000012d011005400100080000000000000000000000012d011006400100080000000000000000000000012d011007400100080000000000000000000000012d011008400100080000000000000000000000012d01100940010008000000000000000000000048c801 31 | 44000100|0800 32 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a2043880da044000 33 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a2043881da044204010000004804 34 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438e7da044204000000004804 35 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438b5da044204000000004804 36 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438b6da04421c00000000000000000000000000000000000000000000000000000000481c 37 | 46000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a2043880da044000 38 | 45000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a2043881da044204000000004804 39 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438004214002d0110004001000800000003000000000000004814 40 | 45000100|0881da8480011081da848001180a28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438004214012d0110014001000800000004000000000000004814 41 | 45000100|0880da8480011080da848001180f28c4d8022880f7022880ee052880dc0b30b0a20430b4a20430b5a20438004214002d0110004001000800000003000000000000004814 42 | -------------------------------------------------------------------------------- /dirac_gef/proguard.flags: -------------------------------------------------------------------------------- 1 | -keep class org.lineageos.dirac.gef.* { 2 | *; 3 | } 4 | -------------------------------------------------------------------------------- /dirac_gef/src/org/lineageos/dirac/gef/BootCompletedReceiver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.lineageos.dirac.gef 18 | 19 | import android.content.BroadcastReceiver 20 | import android.content.Context 21 | import android.content.Intent 22 | import android.media.audiofx.AudioEffect 23 | import android.util.Log 24 | import com.android.internal.util.HexDump 25 | 26 | import java.util.UUID 27 | 28 | class BootCompletedReceiver : BroadcastReceiver() { 29 | private val audioEffect = AudioEffect( 30 | AudioEffect.EFFECT_TYPE_NULL, EFFECT_TYPE_DIRAC_GEF, 0, 0 31 | ) 32 | 33 | override fun onReceive(context: Context, intent: Intent) { 34 | Log.d(TAG, "Starting") 35 | context.assets.open("dirac_gef_init.txt").reader().forEachLine { 36 | val (param, value) = it.split("|") 37 | audioEffect.setParameter( 38 | HexDump.hexStringToByteArray(param), 39 | HexDump.hexStringToByteArray(value) 40 | ) 41 | } 42 | audioEffect.enabled = true 43 | } 44 | 45 | companion object { 46 | private const val TAG = "OnePlusDiracGef" 47 | 48 | private val EFFECT_TYPE_DIRAC_GEF = UUID.fromString("3799d6d1-22c5-43c3-b3ec-d664cf8d2f0d") 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /doze/Android.bp: -------------------------------------------------------------------------------- 1 | android_app { 2 | name: "OnePlusDoze", 3 | defaults: ["SettingsLibDefaults"], 4 | 5 | srcs: ["src/**/*.kt"], 6 | resource_dirs: ["res"], 7 | 8 | certificate: "platform", 9 | platform_apis: true, 10 | system_ext_specific: true, 11 | 12 | static_libs: [ 13 | "androidx.core_core", 14 | "androidx.preference_preference", 15 | "org.lineageos.settings.resources", 16 | ], 17 | 18 | optimize: { 19 | proguard_flags_files: ["proguard.flags"], 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /doze/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 | 46 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /doze/proguard.flags: -------------------------------------------------------------------------------- 1 | -keepclasseswithmembers class * { 2 | public (android.content.Context, android.util.AttributeSet); 3 | } 4 | 5 | -keep class ** extends androidx.preference.PreferenceFragment 6 | -keep class org.lineageos.settings.doze.* { 7 | *; 8 | } 9 | -------------------------------------------------------------------------------- /doze/res/drawable/ic_pickup.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /doze/res/drawable/ic_pocket.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /doze/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | @string/disabled 21 | @string/pick_up_gesture_summary 22 | @string/pick_up_wake_gesture_summary 23 | 24 | 25 | 26 | 0 27 | 1 28 | 2 29 | 30 | 31 | -------------------------------------------------------------------------------- /doze/res/values/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 1.0 24 | 0.0 25 | 26 | -------------------------------------------------------------------------------- /doze/res/xml/doze_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 22 | 23 | 26 | 27 | 31 | 32 | 38 | 39 | 42 | 43 | 51 | 52 | 53 | 54 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/BootCompletedReceiver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.content.BroadcastReceiver 9 | import android.content.Context 10 | import android.content.Intent 11 | import android.util.Log 12 | 13 | class BootCompletedReceiver : BroadcastReceiver() { 14 | override fun onReceive(context: Context, intent: Intent) { 15 | Log.d(TAG, "Starting") 16 | Utils.checkDozeService(context) 17 | } 18 | 19 | companion object { 20 | private const val TAG = "OnePlusDoze" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/DozeService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.app.Service 9 | import android.content.BroadcastReceiver 10 | import android.content.Context 11 | import android.content.Intent 12 | import android.content.IntentFilter 13 | import android.os.IBinder 14 | import android.util.Log 15 | 16 | class DozeService : Service() { 17 | private lateinit var pickupSensor: PickupSensor 18 | private lateinit var pocketSensor: PocketSensor 19 | 20 | private val screenStateReceiver = object : BroadcastReceiver() { 21 | override fun onReceive(context: Context, intent: Intent) { 22 | when (intent.action) { 23 | Intent.ACTION_SCREEN_ON -> onDisplayOn() 24 | Intent.ACTION_SCREEN_OFF -> onDisplayOff() 25 | } 26 | } 27 | } 28 | 29 | override fun onCreate() { 30 | Log.d(TAG, "Creating service") 31 | pickupSensor = PickupSensor( 32 | this, 33 | resources.getString(R.string.pickup_sensor_type), 34 | resources.getFloat(R.dimen.pickup_sensor_value), 35 | ) 36 | pocketSensor = PocketSensor( 37 | this, 38 | resources.getString(R.string.pocket_sensor_type), 39 | resources.getFloat(R.dimen.pocket_sensor_value) 40 | ) 41 | 42 | val screenStateFilter = IntentFilter() 43 | screenStateFilter.addAction(Intent.ACTION_SCREEN_ON) 44 | screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF) 45 | registerReceiver(screenStateReceiver, screenStateFilter) 46 | } 47 | 48 | override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 49 | return START_STICKY 50 | } 51 | 52 | override fun onDestroy() { 53 | super.onDestroy() 54 | 55 | unregisterReceiver(screenStateReceiver) 56 | pickupSensor.disable() 57 | pocketSensor.disable() 58 | } 59 | 60 | override fun onBind(intent: Intent?): IBinder? = null 61 | 62 | private fun onDisplayOn() { 63 | if (Utils.isPickUpEnabled(this)) { 64 | pickupSensor.disable() 65 | } 66 | if (Utils.isPocketEnabled(this)) { 67 | pocketSensor.disable() 68 | } 69 | } 70 | 71 | private fun onDisplayOff() { 72 | if (Utils.isPickUpEnabled(this)) { 73 | pickupSensor.enable() 74 | } 75 | if (Utils.isPocketEnabled(this)) { 76 | pocketSensor.enable() 77 | } 78 | } 79 | 80 | companion object { 81 | private const val TAG = "DozeService" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/DozeSettingsActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2024 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.os.Bundle 9 | import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity 10 | 11 | class DozeSettingsActivity : CollapsingToolbarBaseActivity() { 12 | override fun onCreate(savedInstanceState: Bundle?) { 13 | super.onCreate(savedInstanceState) 14 | supportFragmentManager 15 | .beginTransaction() 16 | .replace( 17 | com.android.settingslib.collapsingtoolbar.R.id.content_frame, 18 | DozeSettingsFragment(), 19 | TAG 20 | ).commit() 21 | } 22 | 23 | companion object { 24 | private const val TAG = "DozeSettingsActivity" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/DozeSettingsFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2024 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.app.Activity 9 | import android.app.AlertDialog 10 | import android.content.Context 11 | import android.os.Bundle 12 | import android.os.Handler 13 | import android.os.Looper 14 | import android.widget.CompoundButton 15 | import androidx.preference.* 16 | 17 | import com.android.settingslib.widget.MainSwitchPreference 18 | 19 | class DozeSettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener, 20 | CompoundButton.OnCheckedChangeListener { 21 | private lateinit var alwaysOnDisplayPreference: SwitchPreference 22 | private lateinit var switchBar: MainSwitchPreference 23 | 24 | private var pickUpPreference: ListPreference? = null 25 | private var pocketPreference: SwitchPreference? = null 26 | 27 | private val handler = Handler(Looper.getMainLooper()) 28 | 29 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { 30 | setPreferencesFromResource(R.xml.doze_settings, rootKey) 31 | 32 | val prefs = requireActivity().getSharedPreferences("doze_settings", Context.MODE_PRIVATE) 33 | if (savedInstanceState == null && !prefs.getBoolean("first_help_shown", false)) { 34 | AlertDialog.Builder(requireContext()) 35 | .setTitle(R.string.doze_settings_help_title) 36 | .setMessage(R.string.doze_settings_help_text) 37 | .setNegativeButton(R.string.dialog_ok) { _, _ -> 38 | prefs.edit().putBoolean("first_help_shown", true).apply() 39 | } 40 | .show() 41 | } 42 | 43 | val dozeEnabled = Utils.isDozeEnabled(requireContext()) 44 | switchBar = findPreference(Utils.DOZE_ENABLE)!! 45 | switchBar.addOnSwitchChangeListener(this) 46 | switchBar.isChecked = dozeEnabled 47 | 48 | alwaysOnDisplayPreference = findPreference(Utils.ALWAYS_ON_DISPLAY)!! 49 | alwaysOnDisplayPreference.isEnabled = dozeEnabled 50 | alwaysOnDisplayPreference.isChecked = Utils.isAlwaysOnEnabled(requireContext()) 51 | alwaysOnDisplayPreference.onPreferenceChangeListener = this 52 | 53 | val pickupSensorCategory = 54 | preferenceScreen.findPreference(Utils.CATEGORY_PICKUP_SENSOR)!! 55 | if (getString(R.string.pickup_sensor_type).isEmpty()) { 56 | preferenceScreen.removePreference(pickupSensorCategory) 57 | } 58 | 59 | val proximitySensorCategory = 60 | preferenceScreen.findPreference(Utils.CATEGORY_PROXIMITY_SENSOR)!! 61 | if (getString(R.string.pocket_sensor_type).isEmpty()) { 62 | preferenceScreen.removePreference(proximitySensorCategory) 63 | } 64 | 65 | pickUpPreference = findPreference(Utils.GESTURE_PICK_UP_KEY) 66 | pickUpPreference?.isEnabled = dozeEnabled 67 | pickUpPreference?.onPreferenceChangeListener = this 68 | 69 | pocketPreference = findPreference(Utils.GESTURE_POCKET_KEY) 70 | pocketPreference?.isEnabled = dozeEnabled 71 | pocketPreference?.onPreferenceChangeListener = this 72 | 73 | // Hide AOD if not supported and set all its dependents otherwise 74 | if (!Utils.alwaysOnDisplayAvailable(requireContext())) { 75 | preferenceScreen.removePreference(alwaysOnDisplayPreference) 76 | } else { 77 | pickupSensorCategory.dependency = Utils.ALWAYS_ON_DISPLAY 78 | proximitySensorCategory.dependency = Utils.ALWAYS_ON_DISPLAY 79 | } 80 | } 81 | 82 | override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { 83 | if (preference.key == Utils.ALWAYS_ON_DISPLAY) { 84 | Utils.enableAlwaysOn(requireContext(), newValue as Boolean) 85 | } 86 | handler.post { Utils.checkDozeService(requireContext()) } 87 | return true 88 | } 89 | 90 | override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) { 91 | Utils.enableDoze(requireContext(), isChecked) 92 | Utils.checkDozeService(requireContext()) 93 | 94 | switchBar.isChecked = isChecked 95 | 96 | if (!isChecked) { 97 | Utils.enableAlwaysOn(requireContext(), false) 98 | alwaysOnDisplayPreference.isChecked = false 99 | } 100 | 101 | alwaysOnDisplayPreference.isEnabled = isChecked 102 | pickUpPreference?.isEnabled = isChecked 103 | pocketPreference?.isEnabled = isChecked 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/PickupSensor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2025 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.content.Context 9 | import android.hardware.Sensor 10 | import android.hardware.SensorEvent 11 | import android.hardware.SensorEventListener 12 | import android.hardware.SensorManager 13 | import android.os.PowerManager 14 | import android.os.SystemClock 15 | import android.util.Log 16 | import android.view.Display 17 | 18 | import java.util.concurrent.Executors 19 | 20 | class PickupSensor( 21 | private val context: Context, sensorType: String, private val sensorValue: Float 22 | ) : SensorEventListener { 23 | private val powerManager = context.getSystemService(PowerManager::class.java)!! 24 | private val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG) 25 | 26 | private val sensorManager = context.getSystemService(SensorManager::class.java)!! 27 | private val sensor = Utils.getSensor(sensorManager, sensorType) 28 | 29 | private val executorService = Executors.newSingleThreadExecutor() 30 | private var entryTimestamp = 0L 31 | 32 | override fun onSensorChanged(event: SensorEvent) { 33 | if (DEBUG) Log.d(TAG, "Got sensor event: ${event.values[0]}") 34 | val delta = SystemClock.elapsedRealtime() - entryTimestamp 35 | if (delta < MIN_PULSE_INTERVAL_MS) { 36 | return 37 | } 38 | entryTimestamp = SystemClock.elapsedRealtime() 39 | if (event.values[0] == sensorValue) { 40 | if (Utils.isPickUpSetToWake(context)) { 41 | wakeLock.acquire(WAKELOCK_TIMEOUT_MS) 42 | powerManager.wakeUpWithProximityCheck( 43 | SystemClock.uptimeMillis(), 44 | PowerManager.WAKE_REASON_GESTURE, 45 | TAG, 46 | Display.DEFAULT_DISPLAY 47 | ) 48 | } else { 49 | Utils.launchDozePulse(context) 50 | } 51 | } 52 | } 53 | 54 | override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {} 55 | 56 | fun enable() { 57 | if (sensor != null) { 58 | Log.d(TAG, "Enabling") 59 | executorService.submit { 60 | entryTimestamp = SystemClock.elapsedRealtime() 61 | sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL) 62 | } 63 | } 64 | 65 | } 66 | 67 | fun disable() { 68 | if (sensor != null) { 69 | Log.d(TAG, "Disabling") 70 | executorService.submit { 71 | sensorManager.unregisterListener(this, sensor) 72 | } 73 | } 74 | } 75 | 76 | companion object { 77 | private const val TAG = "PickupSensor" 78 | private const val DEBUG = false 79 | 80 | private const val MIN_PULSE_INTERVAL_MS = 2500L 81 | private const val WAKELOCK_TIMEOUT_MS = 300L 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/PocketSensor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2024 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.content.Context 9 | import android.hardware.Sensor 10 | import android.hardware.SensorEvent 11 | import android.hardware.SensorEventListener 12 | import android.hardware.SensorManager 13 | import android.os.SystemClock 14 | import android.util.Log 15 | 16 | import java.util.concurrent.Executors 17 | 18 | class PocketSensor( 19 | private val context: Context, sensorType: String, private val sensorValue: Float 20 | ) : SensorEventListener { 21 | private val sensorManager = context.getSystemService(SensorManager::class.java)!! 22 | private val sensor = Utils.getSensor(sensorManager, sensorType) 23 | 24 | private val executorService = Executors.newSingleThreadExecutor() 25 | private var entryTimestamp = 0L 26 | 27 | override fun onSensorChanged(event: SensorEvent) { 28 | if (DEBUG) Log.d(TAG, "Got sensor event: ${event.values[0]}") 29 | val delta = SystemClock.elapsedRealtime() - entryTimestamp 30 | if (delta < MIN_PULSE_INTERVAL_MS) { 31 | return 32 | } 33 | entryTimestamp = SystemClock.elapsedRealtime() 34 | if (event.values[0] == sensorValue) { 35 | Utils.launchDozePulse(context) 36 | } 37 | } 38 | 39 | override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {} 40 | 41 | fun enable() { 42 | if (sensor != null) { 43 | Log.d(TAG, "Enabling") 44 | executorService.submit { 45 | entryTimestamp = SystemClock.elapsedRealtime() 46 | sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL) 47 | } 48 | } 49 | } 50 | 51 | fun disable() { 52 | if (sensor != null) { 53 | Log.d(TAG, "Disabling") 54 | executorService.submit { 55 | sensorManager.unregisterListener(this, sensor) 56 | } 57 | } 58 | } 59 | 60 | companion object { 61 | private const val TAG = "PocketSensor" 62 | private const val DEBUG = false 63 | 64 | private const val MIN_PULSE_INTERVAL_MS = 2500L 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /doze/src/org/lineageos/settings/doze/Utils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2024 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | package org.lineageos.settings.doze 7 | 8 | import android.content.Context 9 | import android.content.Intent 10 | import android.hardware.Sensor 11 | import android.hardware.SensorManager 12 | import android.hardware.display.AmbientDisplayConfiguration 13 | import android.os.UserHandle 14 | import android.provider.Settings 15 | import android.provider.Settings.Secure.DOZE_ALWAYS_ON 16 | import android.provider.Settings.Secure.DOZE_ENABLED 17 | import android.util.Log 18 | import androidx.preference.PreferenceManager 19 | 20 | object Utils { 21 | private const val TAG = "DozeUtils" 22 | 23 | private const val DOZE_INTENT = "com.android.systemui.doze.pulse" 24 | 25 | const val ALWAYS_ON_DISPLAY = "always_on_display" 26 | const val DOZE_ENABLE = "doze_enable" 27 | 28 | const val CATEGORY_PICKUP_SENSOR = "pickup_sensor" 29 | const val CATEGORY_PROXIMITY_SENSOR = "proximity_sensor" 30 | 31 | const val GESTURE_PICK_UP_KEY = "gesture_pick_up_type" 32 | const val GESTURE_POCKET_KEY = "gesture_pocket" 33 | 34 | private fun startService(context: Context) { 35 | Log.d(TAG, "Starting service") 36 | context.startServiceAsUser(Intent(context, DozeService::class.java), UserHandle.CURRENT) 37 | } 38 | 39 | private fun stopService(context: Context) { 40 | Log.d(TAG, "Stopping service") 41 | context.stopServiceAsUser(Intent(context, DozeService::class.java), UserHandle.CURRENT) 42 | } 43 | 44 | fun checkDozeService(context: Context) { 45 | if (isDozeEnabled(context) && !isAlwaysOnEnabled(context) && areGesturesEnabled(context)) { 46 | startService(context) 47 | } else { 48 | stopService(context) 49 | } 50 | } 51 | 52 | fun isDozeEnabled(context: Context): Boolean { 53 | return Settings.Secure.getInt(context.contentResolver, DOZE_ENABLED, 1) != 0 54 | } 55 | 56 | fun enableDoze(context: Context, enable: Boolean): Boolean { 57 | return Settings.Secure.putInt(context.contentResolver, DOZE_ENABLED, if (enable) 1 else 0) 58 | } 59 | 60 | fun launchDozePulse(context: Context) { 61 | Log.d(TAG, "Launch doze pulse") 62 | context.sendBroadcastAsUser(Intent(DOZE_INTENT), UserHandle(UserHandle.USER_CURRENT)) 63 | } 64 | 65 | fun enableAlwaysOn(context: Context, enable: Boolean): Boolean { 66 | return Settings.Secure.putIntForUser( 67 | context.contentResolver, DOZE_ALWAYS_ON, if (enable) 1 else 0, UserHandle.USER_CURRENT 68 | ) 69 | } 70 | 71 | fun isAlwaysOnEnabled(context: Context): Boolean { 72 | return Settings.Secure.getIntForUser( 73 | context.contentResolver, DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT 74 | ) != 0 75 | } 76 | 77 | fun alwaysOnDisplayAvailable(context: Context): Boolean { 78 | return AmbientDisplayConfiguration(context).alwaysOnAvailable() 79 | } 80 | 81 | private fun isGestureEnabled(context: Context, gesture: String?): Boolean { 82 | return PreferenceManager.getDefaultSharedPreferences(context) 83 | .getBoolean(gesture, false) 84 | } 85 | 86 | fun isPickUpEnabled(context: Context): Boolean { 87 | return PreferenceManager.getDefaultSharedPreferences(context) 88 | .getString(GESTURE_PICK_UP_KEY, "0") != "0" 89 | } 90 | 91 | fun isPickUpSetToWake(context: Context): Boolean { 92 | return PreferenceManager.getDefaultSharedPreferences(context) 93 | .getString(GESTURE_PICK_UP_KEY, "0") == "2" 94 | } 95 | 96 | fun isPocketEnabled(context: Context): Boolean { 97 | return isGestureEnabled(context, GESTURE_POCKET_KEY) 98 | } 99 | 100 | private fun areGesturesEnabled(context: Context): Boolean { 101 | return isPickUpEnabled(context) || isPocketEnabled(context) 102 | } 103 | 104 | fun getSensor(sm: SensorManager, type: String?): Sensor? { 105 | return sm.getSensorList(Sensor.TYPE_ALL).find { it.stringType == type } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /hidl/fingerprint/Android.bp: -------------------------------------------------------------------------------- 1 | cc_library_static { 2 | name: "libudfps_extension.oneplus", 3 | srcs: ["UdfpsExtension.cpp"], 4 | include_dirs: [ 5 | "frameworks/native/services/surfaceflinger/CompositionEngine/include", 6 | ], 7 | header_libs: [ 8 | "generated_kernel_headers", 9 | ], 10 | } 11 | 12 | cc_binary { 13 | name: "android.hardware.biometrics.fingerprint@2.3-service.oneplus", 14 | defaults: ["hidl_defaults"], 15 | init_rc: ["android.hardware.biometrics.fingerprint@2.3-service.oneplus.rc"], 16 | vintf_fragments: ["android.hardware.biometrics.fingerprint@2.3-service.oneplus.xml"], 17 | vendor: true, 18 | relative_install_path: "hw", 19 | srcs: [ 20 | "BiometricsFingerprint.cpp", 21 | "properties.cpp", 22 | "service.cpp", 23 | ], 24 | 25 | shared_libs: [ 26 | "libcutils", 27 | "liblog", 28 | "libhidlbase", 29 | "libhardware", 30 | "libutils", 31 | "android.hardware.biometrics.fingerprint@2.1", 32 | "android.hardware.biometrics.fingerprint@2.2", 33 | "android.hardware.biometrics.fingerprint@2.3", 34 | "vendor.oneplus.fingerprint.extension@1.0", 35 | ], 36 | } 37 | -------------------------------------------------------------------------------- /hidl/fingerprint/BiometricsFingerprint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.oneplus" 18 | #define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.3-service.oneplus" 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include "BiometricsFingerprint.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #define OP_ENABLE_FP_LONGPRESS 3 31 | #define OP_DISABLE_FP_LONGPRESS 4 32 | #define OP_RESUME_FP_ENROLL 8 33 | #define OP_FINISH_FP_ENROLL 10 34 | 35 | #define AUTH_STATUS_PATH "/sys/class/drm/card0-DSI-1/auth_status" 36 | #define NOTIFY_DIM_PATH "/sys/class/drm/card0-DSI-1/notify_dim" 37 | #define NOTIFY_PRESS_PATH "/sys/class/drm/card0-DSI-1/notify_fppress" 38 | #define POWER_STATUS_PATH "/sys/class/drm/card0-DSI-1/power_status" 39 | 40 | namespace { 41 | 42 | /* 43 | * Write value to path and close file. 44 | */ 45 | template 46 | static void set(const std::string& path, const T& value) { 47 | std::ofstream file(path); 48 | file << value; 49 | } 50 | 51 | } // anonymous namespace 52 | 53 | namespace android { 54 | namespace hardware { 55 | namespace biometrics { 56 | namespace fingerprint { 57 | namespace V2_3 { 58 | namespace implementation { 59 | 60 | // Supported fingerprint HAL version 61 | static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1); 62 | 63 | using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus; 64 | 65 | BiometricsFingerprint* BiometricsFingerprint::sInstance = nullptr; 66 | 67 | BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) { 68 | sInstance = this; // keep track of the most recent instance 69 | mDevice = openHal(); 70 | if (!mDevice) { 71 | ALOGE("Can't open HAL module"); 72 | } 73 | 74 | mVendorFpService = IVendorFingerprintExtensions::getService(); 75 | } 76 | 77 | BiometricsFingerprint::~BiometricsFingerprint() { 78 | ALOGV("~BiometricsFingerprint()"); 79 | if (mDevice == nullptr) { 80 | ALOGE("No valid device"); 81 | return; 82 | } 83 | int err; 84 | if (0 != (err = mDevice->common.close(reinterpret_cast(mDevice)))) { 85 | ALOGE("Can't close fingerprint module, error: %d", err); 86 | return; 87 | } 88 | mDevice = nullptr; 89 | } 90 | 91 | Return BiometricsFingerprint::isUdfps(uint32_t) { 92 | return true; 93 | } 94 | 95 | Return BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) { 96 | this->isCancelled = 0; 97 | set(NOTIFY_DIM_PATH, 1); // Fixme! workaround for in-app fod auth 98 | set(NOTIFY_PRESS_PATH, 1); 99 | 100 | return Void(); 101 | } 102 | 103 | Return BiometricsFingerprint::onFingerUp() { 104 | set(NOTIFY_PRESS_PATH, 0); 105 | 106 | return Void(); 107 | } 108 | 109 | Return BiometricsFingerprint::ErrorFilter(int32_t error) { 110 | switch (error) { 111 | case 0: 112 | return RequestStatus::SYS_OK; 113 | case -2: 114 | return RequestStatus::SYS_ENOENT; 115 | case -4: 116 | return RequestStatus::SYS_EINTR; 117 | case -5: 118 | return RequestStatus::SYS_EIO; 119 | case -11: 120 | return RequestStatus::SYS_EAGAIN; 121 | case -12: 122 | return RequestStatus::SYS_ENOMEM; 123 | case -13: 124 | return RequestStatus::SYS_EACCES; 125 | case -14: 126 | return RequestStatus::SYS_EFAULT; 127 | case -16: 128 | return RequestStatus::SYS_EBUSY; 129 | case -22: 130 | return RequestStatus::SYS_EINVAL; 131 | case -28: 132 | return RequestStatus::SYS_ENOSPC; 133 | case -110: 134 | return RequestStatus::SYS_ETIMEDOUT; 135 | default: 136 | ALOGE("An unknown error returned from fingerprint vendor library: %d", error); 137 | return RequestStatus::SYS_UNKNOWN; 138 | } 139 | } 140 | 141 | // Translate from errors returned by traditional HAL (see fingerprint.h) to 142 | // HIDL-compliant FingerprintError. 143 | FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) { 144 | switch (error) { 145 | case FINGERPRINT_ERROR_HW_UNAVAILABLE: 146 | return FingerprintError::ERROR_HW_UNAVAILABLE; 147 | case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: 148 | return FingerprintError::ERROR_UNABLE_TO_PROCESS; 149 | case FINGERPRINT_ERROR_TIMEOUT: 150 | return FingerprintError::ERROR_TIMEOUT; 151 | case FINGERPRINT_ERROR_NO_SPACE: 152 | return FingerprintError::ERROR_NO_SPACE; 153 | case FINGERPRINT_ERROR_CANCELED: 154 | return FingerprintError::ERROR_CANCELED; 155 | case FINGERPRINT_ERROR_UNABLE_TO_REMOVE: 156 | return FingerprintError::ERROR_UNABLE_TO_REMOVE; 157 | case FINGERPRINT_ERROR_LOCKOUT: 158 | return FingerprintError::ERROR_LOCKOUT; 159 | default: 160 | if (error >= FINGERPRINT_ERROR_VENDOR_BASE) { 161 | // vendor specific code. 162 | *vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE; 163 | return FingerprintError::ERROR_VENDOR; 164 | } 165 | } 166 | ALOGE("Unknown error from fingerprint vendor library: %d", error); 167 | return FingerprintError::ERROR_UNABLE_TO_PROCESS; 168 | } 169 | 170 | // Translate acquired messages returned by traditional HAL (see fingerprint.h) 171 | // to HIDL-compliant FingerprintAcquiredInfo. 172 | FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(int32_t info, 173 | int32_t* vendorCode) { 174 | switch (info) { 175 | case FINGERPRINT_ACQUIRED_GOOD: 176 | return FingerprintAcquiredInfo::ACQUIRED_GOOD; 177 | case FINGERPRINT_ACQUIRED_PARTIAL: 178 | return FingerprintAcquiredInfo::ACQUIRED_PARTIAL; 179 | case FINGERPRINT_ACQUIRED_INSUFFICIENT: 180 | return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; 181 | case FINGERPRINT_ACQUIRED_IMAGER_DIRTY: 182 | return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY; 183 | case FINGERPRINT_ACQUIRED_TOO_SLOW: 184 | return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW; 185 | case FINGERPRINT_ACQUIRED_TOO_FAST: 186 | return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST; 187 | default: 188 | if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) { 189 | // vendor specific code. 190 | *vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE; 191 | return FingerprintAcquiredInfo::ACQUIRED_VENDOR; 192 | } 193 | } 194 | ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info); 195 | return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; 196 | } 197 | 198 | Return BiometricsFingerprint::setNotify( 199 | const sp& clientCallback) { 200 | std::lock_guard lock(mClientCallbackMutex); 201 | mClientCallback = clientCallback; 202 | // This is here because HAL 2.3 doesn't have a way to propagate a 203 | // unique token for its driver. Subsequent versions should send a unique 204 | // token for each call to setNotify(). This is fine as long as there's only 205 | // one fingerprint device on the platform. 206 | return reinterpret_cast(mDevice); 207 | } 208 | 209 | Return BiometricsFingerprint::preEnroll() { 210 | set(POWER_STATUS_PATH, 1); 211 | 212 | return mDevice->pre_enroll(mDevice); 213 | } 214 | 215 | Return BiometricsFingerprint::enroll(const hidl_array& hat, 216 | uint32_t gid, uint32_t timeoutSec) { 217 | set(NOTIFY_DIM_PATH, 1); 218 | mVendorFpService->updateStatus(OP_DISABLE_FP_LONGPRESS); 219 | mVendorFpService->updateStatus(OP_RESUME_FP_ENROLL); 220 | 221 | const hw_auth_token_t* authToken = reinterpret_cast(hat.data()); 222 | return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec)); 223 | } 224 | 225 | Return BiometricsFingerprint::postEnroll() { 226 | set(NOTIFY_DIM_PATH, 0); 227 | mVendorFpService->updateStatus(OP_FINISH_FP_ENROLL); 228 | mVendorFpService->updateStatus(OP_ENABLE_FP_LONGPRESS); 229 | 230 | return ErrorFilter(mDevice->post_enroll(mDevice)); 231 | } 232 | 233 | Return BiometricsFingerprint::getAuthenticatorId() { 234 | return mDevice->get_authenticator_id(mDevice); 235 | } 236 | 237 | Return BiometricsFingerprint::cancel() { 238 | this->isCancelled = 1; 239 | set(NOTIFY_DIM_PATH, 0); 240 | mVendorFpService->updateStatus(OP_FINISH_FP_ENROLL); 241 | mVendorFpService->updateStatus(OP_ENABLE_FP_LONGPRESS); 242 | set(AUTH_STATUS_PATH, 2); 243 | 244 | return ErrorFilter(mDevice->cancel(mDevice)); 245 | } 246 | 247 | Return BiometricsFingerprint::enumerate() { 248 | return ErrorFilter(mDevice->enumerate(mDevice)); 249 | } 250 | 251 | Return BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { 252 | return ErrorFilter(mDevice->remove(mDevice, gid, fid)); 253 | } 254 | 255 | Return BiometricsFingerprint::setActiveGroup(uint32_t gid, 256 | const hidl_string& storePath) { 257 | if (storePath.size() >= PATH_MAX || storePath.size() <= 0) { 258 | ALOGE("Bad path length: %zd", storePath.size()); 259 | return RequestStatus::SYS_EINVAL; 260 | } 261 | if (access(storePath.c_str(), W_OK)) { 262 | return RequestStatus::SYS_EINVAL; 263 | } 264 | 265 | return ErrorFilter(mDevice->set_active_group(mDevice, gid, storePath.c_str())); 266 | } 267 | 268 | Return BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) { 269 | set(POWER_STATUS_PATH, 1); 270 | if (this->isCancelled) { 271 | set(NOTIFY_DIM_PATH, 1); 272 | set(AUTH_STATUS_PATH, 0); 273 | } else { 274 | set(AUTH_STATUS_PATH, 1); 275 | } 276 | mVendorFpService->updateStatus(OP_ENABLE_FP_LONGPRESS); 277 | 278 | return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid)); 279 | } 280 | 281 | IBiometricsFingerprint* BiometricsFingerprint::getInstance() { 282 | if (!sInstance) { 283 | sInstance = new BiometricsFingerprint(); 284 | } 285 | return sInstance; 286 | } 287 | 288 | const char* BiometricsFingerprint::getModuleId() { 289 | int sensor_version = -1; 290 | std::ifstream file("/sys/devices/platform/soc/soc:fingerprint_detect/sensor_version"); 291 | file >> sensor_version; 292 | ALOGI("fp sensor version is: 0x%x", sensor_version); 293 | return sensor_version == 0x9638 ? "goodix.g6.fod" : "goodix.fod"; 294 | } 295 | 296 | fingerprint_device_t* BiometricsFingerprint::openHal() { 297 | int err; 298 | const hw_module_t* hw_mdl = nullptr; 299 | ALOGD("Opening fingerprint hal library..."); 300 | if (0 != (err = hw_get_module(getModuleId(), &hw_mdl))) { 301 | ALOGE("Can't open fingerprint HW Module, error: %d", err); 302 | return nullptr; 303 | } 304 | 305 | if (hw_mdl == nullptr) { 306 | ALOGE("No valid fingerprint module"); 307 | return nullptr; 308 | } 309 | 310 | fingerprint_module_t const* module = reinterpret_cast(hw_mdl); 311 | if (module->common.methods->open == nullptr) { 312 | ALOGE("No valid open method"); 313 | return nullptr; 314 | } 315 | 316 | hw_device_t* device = nullptr; 317 | 318 | if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) { 319 | ALOGE("Can't open fingerprint methods, error: %d", err); 320 | return nullptr; 321 | } 322 | 323 | if (kVersion != device->version) { 324 | // enforce version on new devices because of HIDL@2.3 translation layer 325 | ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); 326 | return nullptr; 327 | } 328 | 329 | fingerprint_device_t* fp_device = reinterpret_cast(device); 330 | 331 | if (0 != (err = fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) { 332 | ALOGE("Can't register fingerprint module callback, error: %d", err); 333 | return nullptr; 334 | } 335 | 336 | return fp_device; 337 | } 338 | 339 | void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) { 340 | BiometricsFingerprint* thisPtr = 341 | static_cast(BiometricsFingerprint::getInstance()); 342 | std::lock_guard lock(thisPtr->mClientCallbackMutex); 343 | if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) { 344 | ALOGE("Receiving callbacks before the client callback is registered."); 345 | return; 346 | } 347 | const uint64_t devId = reinterpret_cast(thisPtr->mDevice); 348 | switch (msg->type) { 349 | case FINGERPRINT_ERROR: { 350 | int32_t vendorCode = 0; 351 | FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode); 352 | ALOGD("onError(%d)", result); 353 | if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) { 354 | ALOGE("failed to invoke fingerprint onError callback"); 355 | } 356 | getInstance()->onFingerUp(); 357 | } break; 358 | case FINGERPRINT_ACQUIRED: { 359 | int32_t vendorCode = 0; 360 | FingerprintAcquiredInfo result = 361 | VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); 362 | if (result == FingerprintAcquiredInfo::ACQUIRED_VENDOR && vendorCode == 0) { 363 | // We don't want to inform frameworks about that. 364 | ALOGD("onAcquired: Finger down"); 365 | } else if (result == FingerprintAcquiredInfo::ACQUIRED_VENDOR && vendorCode == 1) { 366 | // We don't want to inform frameworks about that. 367 | ALOGD("onAcquired: Finger up"); 368 | } else { 369 | ALOGD("onAcquired(%d)", result); 370 | if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) { 371 | ALOGE("failed to invoke fingerprint onAcquired callback"); 372 | } 373 | } 374 | } break; 375 | case FINGERPRINT_TEMPLATE_ENROLLING: 376 | ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)", msg->data.enroll.finger.fid, 377 | msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining); 378 | if (!thisPtr->mClientCallback 379 | ->onEnrollResult(devId, msg->data.enroll.finger.fid, 380 | msg->data.enroll.finger.gid, 381 | msg->data.enroll.samples_remaining) 382 | .isOk()) { 383 | ALOGE("failed to invoke fingerprint onEnrollResult callback"); 384 | } 385 | break; 386 | case FINGERPRINT_TEMPLATE_REMOVED: 387 | ALOGD("onRemove(fid=%d, gid=%d, rem=%d)", msg->data.removed.finger.fid, 388 | msg->data.removed.finger.gid, msg->data.removed.remaining_templates); 389 | if (!thisPtr->mClientCallback 390 | ->onRemoved(devId, msg->data.removed.finger.fid, 391 | msg->data.removed.finger.gid, 392 | msg->data.removed.remaining_templates) 393 | .isOk()) { 394 | ALOGE("failed to invoke fingerprint onRemoved callback"); 395 | } 396 | break; 397 | case FINGERPRINT_AUTHENTICATED: 398 | if (msg->data.authenticated.finger.fid != 0) { 399 | ALOGD("onAuthenticated(fid=%d, gid=%d)", msg->data.authenticated.finger.fid, 400 | msg->data.authenticated.finger.gid); 401 | const uint8_t* hat = reinterpret_cast(&msg->data.authenticated.hat); 402 | const hidl_vec token( 403 | std::vector(hat, hat + sizeof(msg->data.authenticated.hat))); 404 | if (!thisPtr->mClientCallback 405 | ->onAuthenticated(devId, msg->data.authenticated.finger.fid, 406 | msg->data.authenticated.finger.gid, token) 407 | .isOk()) { 408 | ALOGE("failed to invoke fingerprint onAuthenticated callback"); 409 | } 410 | getInstance()->onFingerUp(); 411 | } else { 412 | // Not a recognized fingerprint 413 | if (!thisPtr->mClientCallback 414 | ->onAuthenticated(devId, msg->data.authenticated.finger.fid, 415 | msg->data.authenticated.finger.gid, 416 | hidl_vec()) 417 | .isOk()) { 418 | ALOGE("failed to invoke fingerprint onAuthenticated callback"); 419 | } 420 | } 421 | break; 422 | case FINGERPRINT_TEMPLATE_ENUMERATING: 423 | ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)", msg->data.enumerated.finger.fid, 424 | msg->data.enumerated.finger.gid, msg->data.enumerated.remaining_templates); 425 | if (!thisPtr->mClientCallback 426 | ->onEnumerate(devId, msg->data.enumerated.finger.fid, 427 | msg->data.enumerated.finger.gid, 428 | msg->data.enumerated.remaining_templates) 429 | .isOk()) { 430 | ALOGE("failed to invoke fingerprint onEnumerate callback"); 431 | } 432 | break; 433 | } 434 | } 435 | 436 | } // namespace implementation 437 | } // namespace V2_3 438 | } // namespace fingerprint 439 | } // namespace biometrics 440 | } // namespace hardware 441 | } // namespace android 442 | -------------------------------------------------------------------------------- /hidl/fingerprint/BiometricsFingerprint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 2021-2022 The LineageOS Project 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | namespace android { 32 | namespace hardware { 33 | namespace biometrics { 34 | namespace fingerprint { 35 | namespace V2_3 { 36 | namespace implementation { 37 | 38 | using ::android::sp; 39 | using ::android::hardware::hidl_string; 40 | using ::android::hardware::hidl_vec; 41 | using ::android::hardware::Return; 42 | using ::android::hardware::Void; 43 | using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintAcquiredInfo; 44 | using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintError; 45 | using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback; 46 | using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus; 47 | using ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint; 48 | using ::vendor::oneplus::fingerprint::extension::V1_0::IVendorFingerprintExtensions; 49 | 50 | struct BiometricsFingerprint : public IBiometricsFingerprint { 51 | public: 52 | BiometricsFingerprint(); 53 | ~BiometricsFingerprint(); 54 | 55 | // Method to wrap legacy HAL with BiometricsFingerprint class 56 | static IBiometricsFingerprint* getInstance(); 57 | 58 | // Methods from ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint 59 | // follow. 60 | Return setNotify( 61 | const sp& clientCallback) override; 62 | Return preEnroll() override; 63 | Return enroll(const hidl_array& hat, uint32_t gid, 64 | uint32_t timeoutSec) override; 65 | Return postEnroll() override; 66 | Return getAuthenticatorId() override; 67 | Return cancel() override; 68 | Return enumerate() override; 69 | Return remove(uint32_t gid, uint32_t fid) override; 70 | Return setActiveGroup(uint32_t gid, const hidl_string& storePath) override; 71 | Return authenticate(uint64_t operationId, uint32_t gid) override; 72 | Return isUdfps(uint32_t sensorID) override; 73 | Return onFingerDown(uint32_t x, uint32_t y, float minor, float major) override; 74 | Return onFingerUp() override; 75 | 76 | private: 77 | static const char* getModuleId(); 78 | static fingerprint_device_t* openHal(); 79 | static void notify( 80 | const fingerprint_msg_t* msg); /* Static callback for legacy HAL implementation */ 81 | static Return ErrorFilter(int32_t error); 82 | static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode); 83 | static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode); 84 | static BiometricsFingerprint* sInstance; 85 | int isCancelled = 0; 86 | 87 | std::mutex mClientCallbackMutex; 88 | sp mClientCallback; 89 | fingerprint_device_t* mDevice; 90 | sp mVendorFpService; 91 | }; 92 | 93 | } // namespace implementation 94 | } // namespace V2_3 95 | } // namespace fingerprint 96 | } // namespace biometrics 97 | } // namespace hardware 98 | } // namespace android 99 | -------------------------------------------------------------------------------- /hidl/fingerprint/UdfpsExtension.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2024 The LineageOS Project 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | #include 7 | 8 | #if __has_include() 9 | #include 10 | #elif __has_include() 11 | #include 12 | #endif 13 | 14 | uint32_t getUdfpsDimZOrder(uint32_t z) { 15 | return z; 16 | } 17 | 18 | uint32_t getUdfpsZOrder(uint32_t z, bool touched) { 19 | #ifdef FOD_PRESSED_LAYER_ZORDER 20 | return touched ? z | FOD_PRESSED_LAYER_ZORDER : z; 21 | #else 22 | return touched ? 0xfc8 : z; 23 | #endif 24 | } 25 | 26 | uint64_t getUdfpsUsageBits(uint64_t usageBits, bool) { 27 | return usageBits; 28 | } 29 | -------------------------------------------------------------------------------- /hidl/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.oneplus.rc: -------------------------------------------------------------------------------- 1 | service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.3-service.oneplus 2 | # "class hal" causes a race condition on some devices due to files created 3 | # in /data. As a workaround, postpone startup until later in boot once 4 | # /data is mounted. 5 | class late_start 6 | user system 7 | group system input uhid 8 | 9 | on boot 10 | chown system system /sys/class/drm/card0-DSI-1/auth_status 11 | chmod 0666 /sys/class/drm/card0-DSI-1/auth_status 12 | chown system system /sys/class/drm/card0-DSI-1/notify_dim 13 | chmod 0666 /sys/class/drm/card0-DSI-1/notify_dim 14 | chown system system /sys/class/drm/card0-DSI-1/notify_fppress 15 | chmod 0666 /sys/class/drm/card0-DSI-1/notify_fppress 16 | chown system system /sys/class/drm/card0-DSI-1/power_status 17 | chmod 0666 /sys/class/drm/card0-DSI-1/power_status 18 | -------------------------------------------------------------------------------- /hidl/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.oneplus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.biometrics.fingerprint 4 | hwbinder 5 | 2.3 6 | 7 | IBiometricsFingerprint 8 | default 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hidl/fingerprint/properties.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.oneplus" 18 | #define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.3-service.oneplus" 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | extern "C" int property_get(const char* key, char* value, const char* default_value) { 26 | static auto property_get_orig = 27 | reinterpret_cast(dlsym(RTLD_NEXT, "property_get")); 28 | 29 | if (strcmp(key, "vendor.boot.verifiedbootstate") == 0) { 30 | ALOGV("Returning orange for vendor.boot.verifiedbootstate"); 31 | return strlen(strcpy(value, "orange")); 32 | } 33 | 34 | return property_get_orig(key, value, default_value); 35 | } 36 | -------------------------------------------------------------------------------- /hidl/fingerprint/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "BiometricsFingerprint.h" 25 | 26 | using android::sp; 27 | using android::hardware::configureRpcThreadpool; 28 | using android::hardware::joinRpcThreadpool; 29 | using android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint; 30 | using android::hardware::biometrics::fingerprint::V2_3::implementation::BiometricsFingerprint; 31 | 32 | int main() { 33 | android::sp bio = BiometricsFingerprint::getInstance(); 34 | 35 | configureRpcThreadpool(1, true /*callerWillJoin*/); 36 | 37 | if (bio != nullptr) { 38 | if (::android::OK != bio->registerAsService()) { 39 | return 1; 40 | } 41 | } else { 42 | ALOGE("Can't create instance of BiometricsFingerprint, nullptr"); 43 | } 44 | 45 | joinRpcThreadpool(); 46 | 47 | return 0; // should never get here 48 | } 49 | -------------------------------------------------------------------------------- /interfaces/Android.bp: -------------------------------------------------------------------------------- 1 | hidl_package_root { 2 | name: "vendor.goodix", 3 | path: "hardware/oneplus/interfaces/goodix", 4 | } 5 | 6 | hidl_package_root { 7 | name: "vendor.oneplus", 8 | path: "hardware/oneplus/interfaces/oneplus", 9 | } 10 | -------------------------------------------------------------------------------- /interfaces/goodix/hardware/biometrics/fingerprint/2.1/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.goodix.hardware.biometrics.fingerprint@2.1", 5 | root: "vendor.goodix", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IGoodixFingerprintDaemon.hal", 9 | "IGoodixFingerprintDaemonCallback.hal", 10 | ], 11 | interfaces: [ 12 | "android.hidl.base@1.0", 13 | ], 14 | gen_java: true, 15 | } 16 | -------------------------------------------------------------------------------- /interfaces/goodix/hardware/biometrics/fingerprint/2.1/IGoodixFingerprintDaemon.hal: -------------------------------------------------------------------------------- 1 | package vendor.goodix.hardware.biometrics.fingerprint@2.1; 2 | 3 | import vendor.goodix.hardware.biometrics.fingerprint@2.1::IGoodixFingerprintDaemonCallback; 4 | 5 | interface IGoodixFingerprintDaemon { 6 | setNotify(IGoodixFingerprintDaemonCallback Callback); 7 | sendCommand(int32_t cmd, vec data) generates (int32_t resultCode, vec data); 8 | }; 9 | -------------------------------------------------------------------------------- /interfaces/goodix/hardware/biometrics/fingerprint/2.1/IGoodixFingerprintDaemonCallback.hal: -------------------------------------------------------------------------------- 1 | package vendor.goodix.hardware.biometrics.fingerprint@2.1; 2 | 3 | interface IGoodixFingerprintDaemonCallback { 4 | onDaemonMessage(int64_t devId, int32_t msgId, int32_t cmdId, vec msgData); 5 | }; 6 | -------------------------------------------------------------------------------- /interfaces/oneplus/camera/CameraHIDL/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.oneplus.camera.CameraHIDL@1.0", 5 | root: "vendor.oneplus", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IOnePlusCameraProvider.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /interfaces/oneplus/camera/CameraHIDL/1.0/IOnePlusCameraProvider.hal: -------------------------------------------------------------------------------- 1 | package vendor.oneplus.camera.CameraHIDL@1.0; 2 | 3 | interface IOnePlusCameraProvider { 4 | setCameraId(int32_t name) generates (bool status); 5 | setPackageName(string name) generates (bool status); 6 | getPackageName() generates (string cameraDeviceNames); 7 | file_access(string path) generates (bool status); 8 | file_delete(string path) generates (bool status); 9 | file_open(string path) generates (int32_t fd); 10 | file_write(int32_t fd, vec buffer, int32_t size) generates (bool status2); 11 | file_read(int32_t fd, int32_t size) generates (bool status, vec buffer, int32_t size); 12 | file_close(int32_t fd) generates (bool status); 13 | }; 14 | -------------------------------------------------------------------------------- /interfaces/oneplus/fingerprint/extension/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.oneplus.fingerprint.extension@1.0", 5 | root: "vendor.oneplus", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "types.hal", 9 | "IVendorFingerprintExtensions.hal", 10 | "IVendorFingerprintExtensionsCallback.hal", 11 | ], 12 | interfaces: [ 13 | "android.hidl.base@1.0", 14 | ], 15 | gen_java: true, 16 | } 17 | -------------------------------------------------------------------------------- /interfaces/oneplus/fingerprint/extension/1.0/IVendorFingerprintExtensions.hal: -------------------------------------------------------------------------------- 1 | package vendor.oneplus.fingerprint.extension@1.0; 2 | 3 | import vendor.oneplus.fingerprint.extension@1.0::types; 4 | import vendor.oneplus.fingerprint.extension@1.0::IVendorFingerprintExtensionsCallback; 5 | 6 | interface IVendorFingerprintExtensions { 7 | updateStatus(int32_t status) generates (int32_t debugErrno); 8 | getStatus() generates (int32_t debugErrno2); 9 | getEngTest() generates (vec FpTests); 10 | setEngCallback(IVendorFingerprintExtensionsCallback Callback) generates (int32_t debugErrno); 11 | startEngTest(int32_t cmdId) generates (int32_t debugErrno); 12 | stopEngTest(int32_t cmdId) generates (int32_t debugErrno); 13 | stopAllEngTest() generates (int32_t debugErrno2); 14 | setParam(int32_t level) generates (int32_t debugErrno); 15 | }; 16 | -------------------------------------------------------------------------------- /interfaces/oneplus/fingerprint/extension/1.0/IVendorFingerprintExtensionsCallback.hal: -------------------------------------------------------------------------------- 1 | package vendor.oneplus.fingerprint.extension@1.0; 2 | 3 | interface IVendorFingerprintExtensionsCallback { 4 | oneway onResult(int32_t cmdId, int32_t result, string info); 5 | }; 6 | -------------------------------------------------------------------------------- /interfaces/oneplus/fingerprint/extension/1.0/types.hal: -------------------------------------------------------------------------------- 1 | package vendor.oneplus.fingerprint.extension@1.0; 2 | 3 | struct FpTest { 4 | string name; 5 | int32_t cmdId; 6 | }; 7 | -------------------------------------------------------------------------------- /interfaces/oneplus/hardware/drmkey/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.oneplus.hardware.drmkey@1.0", 5 | root: "vendor.oneplus", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IOneplusDrmKey.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /interfaces/oneplus/hardware/drmkey/1.0/IOneplusDrmKey.hal: -------------------------------------------------------------------------------- 1 | package vendor.oneplus.hardware.drmkey@1.0; 2 | 3 | interface IOneplusDrmKey { 4 | installKeybox(string keybox) generates (int32_t status); 5 | verifyKeybox() generates (int32_t status); 6 | sendCommand(string command, string value) generates (int32_t status, string value); 7 | }; 8 | -------------------------------------------------------------------------------- /interfaces/update-makefiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh 4 | 5 | do_makefiles_update \ 6 | "vendor.goodix:hardware/oneplus/interfaces/goodix" 7 | 8 | do_makefiles_update \ 9 | "vendor.oneplus:hardware/oneplus/interfaces/oneplus" 10 | -------------------------------------------------------------------------------- /oneplus-fwk/Android.bp: -------------------------------------------------------------------------------- 1 | java_library { 2 | name: "oneplus-fwk", 3 | installable: true, 4 | 5 | srcs: [ 6 | "src/**/*.java", 7 | ], 8 | } 9 | -------------------------------------------------------------------------------- /oneplus-fwk/src/android/os/OPDiagnoseManager.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public final class OPDiagnoseManager { 4 | 5 | private static String LOG_TAG = OPDiagnoseManager.class.getSimpleName(); 6 | 7 | public boolean addIssueCount(int type, int count) { 8 | return true; 9 | } 10 | 11 | public boolean setIssueNumber(int type, int count) { 12 | return true; 13 | } 14 | 15 | public boolean writeDiagData(int type, String issueDesc) { 16 | return true; 17 | } 18 | 19 | public boolean setDiagData(int type, String issueDesc, int count) { 20 | return true; 21 | } 22 | 23 | public boolean saveDiagLog(int type) { 24 | return true; 25 | } 26 | 27 | public boolean saveQxdmLog(int type, String mask_type) { 28 | return true; 29 | } 30 | 31 | public boolean readDiagData(int type) { 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /oneplus-fwk/src/android/util/OpFeatures.java: -------------------------------------------------------------------------------- 1 | package android.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.util.BitSet; 8 | 9 | public final class OpFeatures { 10 | 11 | private static String LOG_TAG = OpFeatures.class.getSimpleName(); 12 | 13 | private static final BitSet sFeatures = new BitSet(); 14 | 15 | static { 16 | File file = new File("/odm/etc/odm_feature_list"); 17 | 18 | try (BufferedReader br = new BufferedReader(new FileReader(file))) { 19 | for (String line = br.readLine(); line != null; line = br.readLine()) { 20 | String[] values = line.split(" "); 21 | if (values.length == 4 && values[3].equals("true")) { 22 | String id = values[0].replaceAll("[^0-9]", ""); 23 | if (id.length() != 0) { 24 | sFeatures.set(Integer.parseInt(id)); 25 | } 26 | } 27 | } 28 | } catch (IOException e) { 29 | Log.e(LOG_TAG, "Failed to read odm feature list file", e); 30 | } 31 | } 32 | 33 | public static boolean isSupport(int... features) { 34 | for (int feature : features) { 35 | if (feature < 0 || !sFeatures.get(feature)) { 36 | return false; 37 | } 38 | } 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /wifi-mac-generator/Android.bp: -------------------------------------------------------------------------------- 1 | sh_binary { 2 | name: "wifi-mac-generator", 3 | init_rc: ["wifi-mac-generator.rc"], 4 | src: "wifi-mac-generator.sh", 5 | vendor: true, 6 | } 7 | -------------------------------------------------------------------------------- /wifi-mac-generator/wifi-mac-generator.rc: -------------------------------------------------------------------------------- 1 | service vendor.wifi-mac-generator /vendor/bin/wifi-mac-generator 2 | class main 3 | user wifi 4 | group wifi 5 | oneshot 6 | disabled 7 | 8 | on post-fs-data 9 | start vendor.wifi-mac-generator 10 | -------------------------------------------------------------------------------- /wifi-mac-generator/wifi-mac-generator.sh: -------------------------------------------------------------------------------- 1 | #!/vendor/bin/sh 2 | WLAN_MAC_VENDOR_PREFIX="C0EEFB" 3 | WLAN_MAC_PERSIST_PATH="/mnt/vendor/persist/wlan_mac.bin" 4 | 5 | function wait_for_file() { 6 | retries=0 7 | 8 | while [ ! -f "${1}" ]; do 9 | retries=$((retries + 1)) 10 | 11 | if [ "${retries}" -eq 10 ]; then 12 | return 1 13 | fi 14 | 15 | sleep 1 16 | done 17 | 18 | return 0 19 | } 20 | 21 | if [[ ! -f "${WLAN_MAC_PERSIST_PATH}" ]] || [[ ! -s "${WLAN_MAC_PERSIST_PATH}" ]]; then 22 | MAC_0_PATH="/data/vendor/oemnvitems/4678_0" 23 | 24 | if ! wait_for_file "${MAC_0_PATH}"; then 25 | MAC_0="${WLAN_MAC_VENDOR_PREFIX}`xxd -l 3 -p /dev/urandom | tr '[:lower:]' '[:upper:]'`" 26 | else 27 | MAC_0=`xxd -p "${MAC_0_PATH}" | grep -o '..' | tac | tr -d '\n' | tr '[:lower:]' '[:upper:]'` 28 | fi 29 | 30 | MAC_1_PATH="/data/vendor/oemnvitems/4678_1" 31 | 32 | if ! wait_for_file "${MAC_1_PATH}"; then 33 | MAC_1="${WLAN_MAC_VENDOR_PREFIX}`xxd -l 3 -p /dev/urandom | tr '[:lower:]' '[:upper:]'`" 34 | else 35 | MAC_1=`xxd -p "${MAC_1_PATH}" | grep -o '..' | tac | tr -d '\n' | tr '[:lower:]' '[:upper:]'` 36 | fi 37 | 38 | echo "Intf0MacAddress=${MAC_0}" > "${WLAN_MAC_PERSIST_PATH}" 39 | echo "Intf1MacAddress=${MAC_1}" >> "${WLAN_MAC_PERSIST_PATH}" 40 | echo "Intf2MacAddress=000AF58989FD" >> "${WLAN_MAC_PERSIST_PATH}" 41 | echo "Intf3MacAddress=000AF58989FC" >> "${WLAN_MAC_PERSIST_PATH}" 42 | echo "END" >> "${WLAN_MAC_PERSIST_PATH}" 43 | fi 44 | --------------------------------------------------------------------------------