Compare commits

..

No commits in common. "lineage-21" and "lineage-18.0" have entirely different histories.

412 changed files with 6255 additions and 26041 deletions

1
.gitignore vendored
View File

@ -1 +0,0 @@
/nfc

View File

@ -1,23 +0,0 @@
//
// Copyright (C) 2020-2021 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
android_app {
name: "AdvancedDisplay",
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
certificate: "platform",
platform_apis: true,
static_libs: [
"org.lineageos.platform.internal",
"org.lineageos.settings.resources",
],
optimize: {
proguard_flags_files: ["proguard.flags"],
},
}

View File

@ -0,0 +1,33 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := AdvancedDisplay
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_CERTIFICATE := platform
LOCAL_USE_AAPT2 := true
LOCAL_STATIC_ANDROID_LIBRARIES := \
android-support-v4 \
android-support-v7-appcompat \
android-support-v7-preference \
android-support-v7-recyclerview \
android-support-v13 \
android-support-v14-preference
LOCAL_STATIC_JAVA_LIBRARIES := \
org.lineageos.platform.internal
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/res \
$(TOP)/packages/resources/devicesettings/res
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@ -7,10 +7,8 @@
<application
android:label="@string/app_name"
android:theme="@style/Theme.SubSettingsBase">
<receiver
android:name="org.lineageos.settings.device.BootCompletedReceiver"
android:exported="true">
android:theme="@style/Theme.Main">
<receiver android:name="org.lineageos.settings.device.BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
@ -19,8 +17,7 @@
<activity
android:name=".AdvancedDisplayActivity"
android:label="@string/app_name"
android:exported="true">
android:label="@string/app_name">
<intent-filter>
<action android:name="com.android.settings.action.EXTRA_SETTINGS" />
</intent-filter>

View File

@ -20,8 +20,8 @@
<string name="category_screen_title">Pantalla</string>
<string name="screen_colors_title">Colores</string>
<string name="mdnie_scenario_title_head">Escenariu</string>
<string name="mdnie_scenario_summary_head">Afita l\'escenariu de mDNIe</string>
<string name="mdnie_accessibility_title_head">Mou de l\'accesibilidá</string>
<string name="mdnie_scenario_summary_head">Afita l\'escenariu mDNIe</string>
<string name="mdnie_accessibility_title_head">Mou d\'accesibilidá</string>
<string name="mdnie_accessibility_summary_head">Afitar el mou d\'accesibilidá mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (por defeutu)</string>
<string name="mdnie_scenario_video">Videu</string>
@ -36,9 +36,9 @@
<string name="mdnie_scenario_email">Corréu electrónicu</string>
<string name="mdnie_scenario_tdmb">Televisión dixital</string>
<string name="mdnie_accessibility_normal">Normal</string>
<string name="mdnie_accessibility_inverse">Colores invertíos</string>
<string name="mdnie_accessibility_color_blind">Daltonismu</string>
<string name="mdnie_accessibility_screen_curtain">Cortina de la pantalla</string>
<string name="mdnie_accessibility_inverse">Invertíu</string>
<string name="mdnie_accessibility_color_blind">Daltónicu</string>
<string name="mdnie_accessibility_screen_curtain">Cortina de pantalla</string>
<string name="mdnie_accessibility_grayscale">Buxu</string>
<string name="mdnie_accessibility_gray_negative">Buxu invertío</string>
<string name="mdnie_accessibility_gray_negative">Gris invertíu</string>
</resources>

View File

@ -20,9 +20,9 @@
<string name="category_screen_title">Ekran</string>
<string name="screen_colors_title">Rənglər</string>
<string name="mdnie_scenario_title_head">Ekran rejimi</string>
<string name="mdnie_scenario_summary_head">mDNle ssenarisini ayarla</string>
<string name="mdnie_scenario_summary_head">mDNle ssenarisini tənzimlə</string>
<string name="mdnie_accessibility_title_head">Əlçatımlılıq rejimi</string>
<string name="mdnie_accessibility_summary_head">mDNIe əlçatımlılıq rejimini ayarla</string>
<string name="mdnie_accessibility_summary_head">mDNIe əlçatımlılıq rejimini tənzimlə</string>
<string name="mdnie_scenario_ui">LineageOS (ilkin)</string>
<string name="mdnie_scenario_video">Video</string>
<string name="mdnie_scenario_video_warm">Video - isti</string>
@ -31,7 +31,7 @@
<string name="mdnie_scenario_navigation">Hərəkət</string>
<string name="mdnie_scenario_gallery">Qalereya</string>
<string name="mdnie_scenario_vt">Görüntülü zəng</string>
<string name="mdnie_scenario_browser">Brauzer</string>
<string name="mdnie_scenario_browser">Səyyah</string>
<string name="mdnie_scenario_ebook">Elektron kitab</string>
<string name="mdnie_scenario_email">Elektron poçt</string>
<string name="mdnie_scenario_tdmb">Rəqəmsal televizor</string>

View File

@ -19,14 +19,6 @@
<string name="app_name">Налады экрана</string>
<string name="category_screen_title">Экран</string>
<string name="screen_colors_title">Колеры</string>
<string name="mdnie_scenario_video_warm">Відэа (цёплыя тоны)</string>
<string name="mdnie_scenario_camera">Камера</string>
<string name="mdnie_scenario_navigation">Навігацыя</string>
<string name="mdnie_scenario_gallery">Галерэя</string>
<string name="mdnie_scenario_vt">Відэавыклік</string>
<string name="mdnie_scenario_browser">Браўзер</string>
<string name="mdnie_scenario_tdmb">Лічбавае тэлебачанне</string>
<string name="mdnie_accessibility_inverse">Інвертаваны</string>
<string name="mdnie_accessibility_color_blind">Дальтанізм</string>
<string name="mdnie_accessibility_grayscale">Шэры</string>
<string name="mdnie_scenario_title_head">Сцэнар</string>
<string name="mdnie_scenario_summary_head">Усталёўка сцэнара mDNIe</string>
</resources>

View File

@ -22,17 +22,5 @@
<string name="mdnie_scenario_title_head">Scenarie</string>
<string name="mdnie_scenario_summary_head">Angiv mDNIe-scenariet</string>
<string name="mdnie_scenario_ui">LineageOS (standard)</string>
<string name="mdnie_scenario_video">Video</string>
<string name="mdnie_scenario_video_warm">Video varm</string>
<string name="mdnie_scenario_video_cold">Video kold</string>
<string name="mdnie_scenario_camera">Kamera</string>
<string name="mdnie_scenario_navigation">Navigation</string>
<string name="mdnie_scenario_gallery">Galleri</string>
<string name="mdnie_scenario_vt">Videoopkald</string>
<string name="mdnie_scenario_browser">Browser</string>
<string name="mdnie_scenario_email">E-mail</string>
<string name="mdnie_accessibility_normal">Normal</string>
<string name="mdnie_accessibility_inverse">Inverteret</string>
<string name="mdnie_accessibility_color_blind">Farve blind</string>
<string name="mdnie_accessibility_grayscale">Grå</string>
</resources>

View File

@ -20,7 +20,7 @@
<string name="category_screen_title">Bildschirm</string>
<string name="screen_colors_title">Farben</string>
<string name="mdnie_scenario_title_head">Szenario</string>
<string name="mdnie_scenario_summary_head">Wähle das mDNIe-Szenario</string>
<string name="mdnie_scenario_summary_head">Wählen Sie das mDNIe-Szenario</string>
<string name="mdnie_accessibility_title_head">Barrierefreier Modus</string>
<string name="mdnie_accessibility_summary_head">mDNIe-Modus festlegen</string>
<string name="mdnie_scenario_ui">LineageOS (Standard)</string>

View File

@ -16,7 +16,7 @@
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Pantalla avanzada</string>
<string name="app_name">Ajustes avanzados</string>
<string name="category_screen_title">Pantalla</string>
<string name="screen_colors_title">Colores</string>
<string name="mdnie_scenario_title_head">Escenario</string>

View File

@ -21,17 +21,4 @@
<string name="screen_colors_title">Colores</string>
<string name="mdnie_scenario_title_head">Escenario</string>
<string name="mdnie_scenario_summary_head">Establecer el escenario mDNIe</string>
<string name="mdnie_accessibility_title_head">Modo de accesibilidad</string>
<string name="mdnie_accessibility_summary_head">Definir el modo de accesibilidad mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (predefinido)</string>
<string name="mdnie_scenario_video">Vídeo</string>
<string name="mdnie_scenario_video_warm">Vídeo cálido</string>
<string name="mdnie_scenario_video_cold">Vídeo frío</string>
<string name="mdnie_scenario_camera">Cámara</string>
<string name="mdnie_scenario_navigation">Navegación</string>
<string name="mdnie_scenario_gallery">Galería</string>
<string name="mdnie_scenario_vt">Videollamada</string>
<string name="mdnie_scenario_browser">Navegador</string>
<string name="mdnie_scenario_ebook">Libro electrónico</string>
<string name="mdnie_accessibility_screen_curtain">Cortina de pantalla</string>
</resources>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2014 The CyanogenMod Project
Copyright (C) 2018 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Schermi avanzât</string>
<string name="category_screen_title">Schermi</string>
<string name="screen_colors_title">Colôrs</string>
<string name="mdnie_scenario_title_head">Senari</string>
<string name="mdnie_scenario_summary_head">Stabilìs il senari mDNIe</string>
<string name="mdnie_accessibility_title_head">Modalitât di acès facilitât</string>
<string name="mdnie_accessibility_summary_head">Stabilìs la modalitât di acès facilitât mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (predefinît)</string>
<string name="mdnie_scenario_video">Video</string>
<string name="mdnie_scenario_video_warm">Video cjalt</string>
<string name="mdnie_scenario_video_cold">Video frêt</string>
<string name="mdnie_scenario_camera">Fotocjamare</string>
<string name="mdnie_scenario_navigation">Navigazion</string>
<string name="mdnie_scenario_gallery">Galarie</string>
<string name="mdnie_scenario_vt">Video-clamade</string>
<string name="mdnie_scenario_browser">Navigadôr</string>
<string name="mdnie_scenario_ebook">eBook</string>
<string name="mdnie_scenario_email">E-mail</string>
<string name="mdnie_scenario_tdmb">Television digjitâl</string>
<string name="mdnie_accessibility_normal">Normâl</string>
<string name="mdnie_accessibility_inverse">Invertît</string>
<string name="mdnie_accessibility_color_blind">Daltonisim</string>
<string name="mdnie_accessibility_screen_curtain">Tende dal schermi</string>
<string name="mdnie_accessibility_grayscale">Grîs</string>
<string name="mdnie_accessibility_gray_negative">Grîs invertît</string>
</resources>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2014 The CyanogenMod Project
Copyright (C) 2018 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Ítarlegri skjástillingar</string>
<string name="category_screen_title">Skjár</string>
<string name="screen_colors_title">Litir</string>
<string name="mdnie_scenario_title_head">Atburðarás</string>
<string name="mdnie_scenario_summary_head">Veldu mDNIe-atburðarás</string>
<string name="mdnie_accessibility_title_head">Aukið aðgengi</string>
<string name="mdnie_accessibility_summary_head">Stilltu mDNIe \'aukið aðgengi\'-ham</string>
<string name="mdnie_scenario_ui">LineageOS (sjálfgefið)</string>
<string name="mdnie_scenario_video">Myndskeið</string>
<string name="mdnie_scenario_video_warm">Hlýlegt myndskeið</string>
<string name="mdnie_scenario_video_cold">Kuldalegt myndskeið</string>
<string name="mdnie_scenario_camera">Myndavél</string>
<string name="mdnie_scenario_navigation">Flakk</string>
<string name="mdnie_scenario_gallery">Myndasafn</string>
<string name="mdnie_scenario_vt">Myndsímtal</string>
<string name="mdnie_scenario_browser">Vafri</string>
<string name="mdnie_scenario_ebook">Rafbók</string>
<string name="mdnie_scenario_email">Tölvupóstur</string>
<string name="mdnie_scenario_tdmb">Stafrænt sjónvarp</string>
<string name="mdnie_accessibility_normal">Venjulegt</string>
<string name="mdnie_accessibility_inverse">Viðsnúið</string>
<string name="mdnie_accessibility_color_blind">Litblinda</string>
<string name="mdnie_accessibility_screen_curtain">Skjátjald</string>
<string name="mdnie_accessibility_grayscale">Grátt</string>
<string name="mdnie_accessibility_gray_negative">Viðsnúið grátt</string>
</resources>

View File

@ -16,29 +16,8 @@
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">ეკრანის პარამეტრები</string>
<string name="category_screen_title">ეკრანი</string>
<string name="screen_colors_title">ფერები</string>
<string name="mdnie_scenario_title_head">სცენარი</string>
<string name="mdnie_scenario_summary_head">mDNIe-ს სცენარის დაყენება</string>
<string name="mdnie_accessibility_title_head">ხელმისაწვდომობა</string>
<string name="mdnie_accessibility_summary_head">mDNIe-ხელმისაწვდომობის მითითება</string>
<string name="mdnie_scenario_ui">LineageOS (ნაგულისხმევი)</string>
<string name="mdnie_scenario_video">ვიდეო</string>
<string name="mdnie_scenario_video_warm">ვიდეო თბილი ფერებით</string>
<string name="mdnie_scenario_video_cold">ვიდეო ცივი ფერებით</string>
<string name="mdnie_scenario_camera">კამერა</string>
<string name="mdnie_scenario_navigation">სამოძრაო</string>
<string name="mdnie_scenario_gallery">გალერეა</string>
<string name="mdnie_scenario_vt">ვიდეოზარი</string>
<string name="mdnie_scenario_browser">ბრაუზერი</string>
<string name="mdnie_scenario_ebook">ელწიგნი</string>
<string name="mdnie_scenario_email">ელფოსტა</string>
<string name="mdnie_scenario_tdmb">ციფრული ტელევიზია</string>
<string name="mdnie_accessibility_normal">ჩვეულებრივი</string>
<string name="mdnie_accessibility_inverse">შებრუნებული</string>
<string name="mdnie_accessibility_color_blind">დალტონიზმი</string>
<string name="mdnie_accessibility_screen_curtain">ეკრანის დაფარვა</string>
<string name="mdnie_accessibility_grayscale">ნაცრისფერი</string>
<string name="mdnie_accessibility_gray_negative">ნაცრისფერი შებრუნებული</string>
</resources>

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2014 The CyanogenMod Project
Copyright (C) 2018 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Taskant leqqayen</string>
<string name="category_screen_title">Agdil</string>
<string name="screen_colors_title">Initen</string>
<string name="mdnie_scenario_title_head">Asinaṛyu</string>
<string name="mdnie_scenario_summary_head">Sbadu asinaṛyu mDNIe</string>
<string name="mdnie_accessibility_title_head">Askar n tnekcumt</string>
<string name="mdnie_scenario_ui">LineageOS (amezwer)</string>
<string name="mdnie_scenario_video">Tavidyut</string>
<string name="mdnie_scenario_video_warm">Tavidyut yeḥman</string>
<string name="mdnie_scenario_video_cold">Tavidyut tasemmaḍt</string>
<string name="mdnie_scenario_camera">Takamiṛat</string>
<string name="mdnie_scenario_navigation">Tunigin</string>
<string name="mdnie_scenario_gallery">Tamidelt</string>
<string name="mdnie_scenario_vt">Asiwel s tvidyut</string>
<string name="mdnie_scenario_browser">Iminig</string>
<string name="mdnie_scenario_email">Imayl</string>
<string name="mdnie_accessibility_normal">Amagnu</string>
<string name="mdnie_accessibility_inverse">Meqlub</string>
<string name="mdnie_accessibility_grayscale">Amumad</string>
</resources>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2014 The CyanogenMod Project
Copyright (C) 2018 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Erweiderte Schierm</string>
<string name="category_screen_title">Schierm</string>
<string name="screen_colors_title">Faarwen</string>
<string name="mdnie_scenario_title_head">Zeenario</string>
<string name="mdnie_scenario_summary_head">mDNIe-Zeenario auswielen</string>
</resources>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2014 The CyanogenMod Project
Copyright (C) 2018 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="category_screen_title">မျက်နှာပြင်</string>
<string name="screen_colors_title">အရောင်များ</string>
<string name="mdnie_scenario_title_head">ဇာတ်ညွှန်း</string>
</resources>

View File

@ -20,7 +20,7 @@
<string name="category_screen_title">Tela</string>
<string name="screen_colors_title">Cores</string>
<string name="mdnie_scenario_title_head">Cenário</string>
<string name="mdnie_scenario_summary_head">Defina o cenário mDNIe</string>
<string name="mdnie_scenario_summary_head">Define o cenário mDNIe</string>
<string name="mdnie_accessibility_title_head">Modo de acessibilidade</string>
<string name="mdnie_accessibility_summary_head">Definir o modo de acessibilidade do mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (padrão)</string>

View File

@ -18,5 +18,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="category_screen_title">Ischermu</string>
<string name="screen_colors_title">Colores</string>
<string name="mdnie_scenario_video_warm">Tonu vìdeu callente</string>
</resources>

View File

@ -21,24 +21,4 @@
<string name="screen_colors_title">Färger</string>
<string name="mdnie_scenario_title_head">Scenario</string>
<string name="mdnie_scenario_summary_head">Ställ in mDNIe-scenario</string>
<string name="mdnie_accessibility_title_head">Tillgänglighetsläge</string>
<string name="mdnie_accessibility_summary_head">Ange tillgänglighetsläget för mDNIe</string>
<string name="mdnie_scenario_ui">LineageOS (standard)</string>
<string name="mdnie_scenario_video">Video</string>
<string name="mdnie_scenario_video_warm">Varm video</string>
<string name="mdnie_scenario_video_cold">Kall video</string>
<string name="mdnie_scenario_camera">Kamera</string>
<string name="mdnie_scenario_navigation">Navigering</string>
<string name="mdnie_scenario_gallery">Galleri</string>
<string name="mdnie_scenario_vt">Videosamtal</string>
<string name="mdnie_scenario_browser">Webbläsare</string>
<string name="mdnie_scenario_ebook">E-bok</string>
<string name="mdnie_scenario_email">E-post</string>
<string name="mdnie_scenario_tdmb">Digital-TV</string>
<string name="mdnie_accessibility_normal">Normal</string>
<string name="mdnie_accessibility_inverse">Inverterad</string>
<string name="mdnie_accessibility_color_blind">Färgblind</string>
<string name="mdnie_accessibility_screen_curtain">Skärmridå</string>
<string name="mdnie_accessibility_grayscale">Grå</string>
<string name="mdnie_accessibility_gray_negative">Gråinverterad</string>
</resources>

View File

@ -21,11 +21,4 @@
<string name="screen_colors_title">Кольори</string>
<string name="mdnie_scenario_title_head">Сценарій</string>
<string name="mdnie_scenario_summary_head">Встановити сценарій mDNIe</string>
<string name="mdnie_scenario_video">Відео</string>
<string name="mdnie_scenario_video_warm">Відео (теплі тони)</string>
<string name="mdnie_scenario_video_cold">Відео (холодні тони)</string>
<string name="mdnie_scenario_camera">Камера</string>
<string name="mdnie_scenario_gallery">Галерея</string>
<string name="mdnie_scenario_vt">Відеовиклик</string>
<string name="mdnie_scenario_tdmb">Цифрове телебачення</string>
</resources>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 The CyanogenMod Project
2017 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<style name="Theme.Main" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="preferenceCategoryStyle">@style/Theme.Main.PreferenceCategoryStyle</item>
<item name="preferenceFragmentStyle">@style/Theme.Main.PreferenceFragmentStyle</item>
<item name="preferenceStyle">@style/Theme.Main.PreferenceStyle</item>
<item name="preferenceTheme">@style/Theme.Main.PreferenceTheme</item>
<item name="dialogPreferenceStyle">@style/Theme.Main.DialogPreferenceStyle</item>
<item name="switchPreferenceStyle">@style/Theme.Main.SwitchPreferenceStyle</item>
</style>
<style name="Theme.Main.PreferenceCategoryStyle" parent="@*android:style/Preference.DeviceDefault.Category">
<item name="allowDividerAbove">true</item>
<item name="android:layout">@layout/preference_category_material_settings</item>
</style>
<style name="Theme.Main.PreferenceFragmentStyle" parent="@*android:style/PreferenceFragment.Material">
<item name="allowDividerAfterLastItem">false</item>
</style>
<style name="Theme.Main.PreferenceStyle" parent="@*android:style/Preference.DeviceDefault">
<item name="allowDividerAbove">false</item>
<item name="allowDividerBelow">true</item>
<item name="singleLineTitle">false</item>
<item name="android:layout">@layout/preference_material_settings</item>
</style>
<style name="Theme.Main.PreferenceTheme">
</style>
<style name="Theme.Main.DialogPreferenceStyle" parent="@*android:style/Preference.DeviceDefault.DialogPreference">
<item name="allowDividerAbove">false</item>
<item name="allowDividerBelow">true</item>
<item name="singleLineTitle">false</item>
<item name="android:iconSpaceReserved">true</item>
</style>
<style name="Theme.Main.SwitchPreferenceStyle" parent="@style/Theme.Main.PreferenceStyle">
<item name="widgetLayout">@*android:layout/preference_widget_switch</item>
</style>
</resources>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018,2022 The LineageOS Project
* Copyright (C) 2017 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,16 +17,14 @@
package org.lineageos.settings.device;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
public class AdvancedDisplayActivity extends CollapsingToolbarBaseActivity {
public class AdvancedDisplayActivity extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(
com.android.settingslib.collapsingtoolbar.R.id.content_frame,
getFragmentManager().beginTransaction().replace(android.R.id.content,
new AdvancedDisplayFragment()).commit();
}
}

View File

@ -16,10 +16,11 @@
package org.lineageos.settings.device;
import android.app.ActionBar;
import android.content.res.Resources;
import android.os.Bundle;
import androidx.preference.PreferenceFragment;
import android.support.v14.preference.PreferenceFragment;
import android.view.MenuItem;
import org.lineageos.settings.device.R;
@ -34,6 +35,9 @@ public class AdvancedDisplayFragment extends PreferenceFragment {
addPreferencesFromResource(R.xml.screen_preferences);
Resources res = getResources();
final ActionBar actionBar = getActivity().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
/* mDNIe */
mmDNIeScenario = (mDNIeScenario) findPreference(Constants.KEY_MDNIE_SCENARIO);
mmDNIeScenario.setEnabled(
@ -43,4 +47,13 @@ public class AdvancedDisplayFragment extends PreferenceFragment {
mmDNIeAccessibility.setEnabled(
FileUtils.isFileWritable(res.getString(R.string.mdnie_accessibility_sysfs_file)));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
getActivity().onBackPressed();
return true;
}
return false;
}
}

View File

@ -19,15 +19,15 @@ package org.lineageos.settings.device;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.PreferenceManager;
import android.util.AttributeSet;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import org.lineageos.internal.util.FileUtils;
public class mDNIeAccessibility extends ListPreference implements Preference.OnPreferenceChangeListener {
public class mDNIeAccessibility extends ListPreference implements OnPreferenceChangeListener {
private static String FILE = null;

View File

@ -19,15 +19,15 @@ package org.lineageos.settings.device;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.PreferenceManager;
import android.util.AttributeSet;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import org.lineageos.internal.util.FileUtils;
public class mDNIeScenario extends ListPreference implements Preference.OnPreferenceChangeListener {
public class mDNIeScenario extends ListPreference implements OnPreferenceChangeListener {
private static String FILE = null;

View File

@ -1,23 +0,0 @@
soong_namespace {
imports: [
"hardware/google/pixel",
"hardware/google/interfaces",
],
}
soong_config_module_type {
name: "samsung_header_path",
module_type: "cc_defaults",
config_namespace: "samsungVars",
value_variables: ["target_specific_header_path"],
properties: ["include_dirs"],
}
samsung_header_path {
name: "samsung_header_path_defaults",
soong_config_variables: {
target_specific_header_path: {
include_dirs: ["%s"],
},
},
}

View File

@ -36,7 +36,9 @@ include $(SAM_ROOT)/wifiloader/Android.mk
endif
ifeq ($(BOARD_VENDOR),samsung)
include $(SAM_ROOT)/AdvancedDisplay/Android.mk
include $(SAM_ROOT)/audio/Android.mk
include $(SAM_ROOT)/doze/Android.mk
include $(SAM_ROOT)/hidl/Android.mk
include $(SAM_ROOT)/modemloader/Android.mk
include $(SAM_ROOT)/ril/Android.mk

View File

@ -1,43 +0,0 @@
cc_library_static {
name: "android.hardware.camera.common-helper.samsung",
vendor_available: true,
defaults: [
"hidl_defaults",
"samsung_camera3_defaults",
],
srcs: [
"CameraModule.cpp",
"CameraMetadata.cpp",
"CameraParameters.cpp",
"VendorTagDescriptor.cpp",
"HandleImporter.cpp",
"Exif.cpp",
"SamsungCameraModule.cpp",
"SimpleThread.cpp",
],
cflags: [
"-Werror",
"-Wextra",
"-Wall",
],
shared_libs: [
"liblog",
"libgralloctypes",
"libhardware",
"libcamera_metadata",
"libexif",
"libui",
],
include_dirs: ["system/media/private/camera/include"],
header_libs: ["libhardware_headers.camera3_samsung"],
export_include_dirs: ["include", "include_samsung"],
export_shared_lib_headers: ["libui"],
}
// NOTE: Deprecated module kept for compatibility reasons.
// Depend on "android.hardware.camera.common-helper.samsung" instead
cc_library_static {
name: "android.hardware.camera.common@1.0-helper.samsung",
vendor_available: true,
whole_static_libs: ["android.hardware.camera.common-helper.samsung"],
}

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/CameraMetadata.cpp

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/CameraModule.cpp

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/CameraParameters.cpp

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/Exif.cpp

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/HandleImporter.cpp

View File

@ -1,42 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "CamComm1.0-SamsungCamModule"
#define ATRACE_TAG ATRACE_TAG_CAMERA
#include <SamsungCameraModule.h>
#include <cutils/trace.h>
namespace android {
namespace hardware {
namespace camera {
namespace common {
namespace helper {
SamsungCameraModule::SamsungCameraModule(camera_module_t* module)
: CameraModule(module), mModule(module) {}
SamsungCameraModule::~SamsungCameraModule() {}
bool SamsungCameraModule::isSetTorchModeStrengthSupported() {
return isSetTorchModeSupported() && mModule->set_torch_mode_strength != NULL;
}
int SamsungCameraModule::setTorchModeStrength(const char* camera_id, bool enable, int strength) {
int res = INVALID_OPERATION;
if (mModule->set_torch_mode_strength != NULL) {
ATRACE_BEGIN("camera_module->set_torch_mode_strength");
res = mModule->set_torch_mode_strength(camera_id, enable, strength);
ATRACE_END();
}
return res;
}
} // namespace helper
} // namespace common
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/SimpleThread.cpp

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/VendorTagDescriptor.cpp

View File

@ -1 +0,0 @@
../../../../../hardware/interfaces/camera/common/default/include

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <CameraModule.h>
namespace android {
namespace hardware {
namespace camera {
namespace common {
namespace helper {
class SamsungCameraModule : public CameraModule {
public:
explicit SamsungCameraModule(camera_module_t* module);
virtual ~SamsungCameraModule();
bool isSetTorchModeStrengthSupported();
int setTorchModeStrength(const char* camera_id, bool enable, int strength);
private:
camera_module_t* mModule;
};
} // namespace helper
} // namespace common
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1,40 +0,0 @@
//
// Copyright (C) 2024 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
cc_library_shared {
name: "camera.device-impl.samsung",
defaults: [
"android.hardware.graphics.common-ndk_shared",
"samsung_camera3_defaults",
],
vendor: true,
srcs: [
"CameraDevice.cpp",
"CameraDeviceSession.cpp",
"convert.cpp",
],
shared_libs: [
"android.hardware.camera.common-V1-ndk",
"android.hardware.camera.device-V1-ndk",
"libbinder_ndk",
"libcamera_metadata",
"libcutils",
"libfmq",
"libgralloctypes",
"libhidlbase",
"liblog",
"libui",
"libutils",
],
static_libs: [
"android.hardware.camera.common-helper.samsung",
"libaidlcommonsupport",
],
header_libs: [
"libhardware_headers.camera3_samsung",
],
export_include_dirs: ["."],
}

View File

@ -1,412 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "CamDev-impl"
#include "CameraDevice.h"
#include "convert.h"
#include <cutils/trace.h>
namespace android {
namespace hardware {
namespace camera {
namespace device {
namespace implementation {
std::string CameraDevice::kDeviceVersion = "1.1";
CameraDevice::CameraDevice(
sp<SamsungCameraModule> module, const std::string& cameraId,
const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames)
: mModule(module),
mCameraId(cameraId),
mDisconnected(false),
mCameraDeviceNames(cameraDeviceNames) {
mCameraIdInt = atoi(mCameraId.c_str());
// Should not reach here as provider also validate ID
if (mCameraIdInt < 0) {
ALOGE("%s: Invalid camera id: %s", __FUNCTION__, mCameraId.c_str());
mInitFail = true;
} else if (mCameraIdInt >= mModule->getNumberOfCameras()) {
ALOGI("%s: Adding a new camera id: %s", __FUNCTION__, mCameraId.c_str());
}
mDeviceVersion = mModule->getDeviceVersion(mCameraIdInt);
if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
ALOGE("%s: Camera id %s does not support HAL3.2+", __FUNCTION__, mCameraId.c_str());
mInitFail = true;
}
}
CameraDevice::~CameraDevice() {}
Status CameraDevice::initStatus() const {
Mutex::Autolock _l(mLock);
Status status = Status::OK;
if (mInitFail) {
status = Status::INTERNAL_ERROR;
} else if (mDisconnected) {
status = Status::CAMERA_DISCONNECTED;
}
return status;
}
ndk::ScopedAStatus CameraDevice::getCameraCharacteristics(CameraMetadata* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
Status status = initStatus();
if (status == Status::OK) {
// Module 2.1+ codepath.
struct camera_info info;
int ret = mModule->getCameraInfo(mCameraIdInt, &info);
if (ret == OK && info.static_camera_characteristics != NULL) {
common::helper::CameraMetadata metadata = (camera_metadata_t*)info.static_camera_characteristics;
camera_metadata_entry_t entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
if (entry.count > 0 && *entry.data.u8 != 0 && mModule->isSetTorchModeStrengthSupported()) {
// Samsung always has 5 supported torch strength levels
int32_t defaultTorchStrength = 1;
int32_t torchStrengthLevels = 5;
metadata.update(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &defaultTorchStrength, 1);
metadata.update(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &torchStrengthLevels, 1);
}
convertToAidl(metadata.release(), _aidl_return);
} else {
ALOGE("%s: get camera info failed!", __FUNCTION__);
status = Status::INTERNAL_ERROR;
}
}
return fromStatus(status);
}
ndk::ScopedAStatus CameraDevice::getPhysicalCameraCharacteristics(
const std::string& in_physicalCameraId, CameraMetadata* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
Status status = initStatus();
if (status == Status::OK) {
// Require module 2.5+ version.
if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_5) {
ALOGE("%s: get_physical_camera_info must be called on camera module 2.5 or newer",
__FUNCTION__);
status = Status::INTERNAL_ERROR;
} else {
char* end;
errno = 0;
long id = strtol(in_physicalCameraId.c_str(), &end, 0);
if (id > INT_MAX || (errno == ERANGE && id == LONG_MAX) || id < INT_MIN ||
(errno == ERANGE && id == LONG_MIN) || *end != '\0') {
ALOGE("%s: Invalid physicalCameraId %s", __FUNCTION__, in_physicalCameraId.c_str());
status = Status::ILLEGAL_ARGUMENT;
} else {
camera_metadata_t* physicalInfo = nullptr;
int ret = mModule->getPhysicalCameraInfo((int)id, &physicalInfo);
if (ret == OK) {
convertToAidl(physicalInfo, _aidl_return);
} else if (ret == -EINVAL) {
ALOGE("%s: %s is not a valid physical camera Id outside of getCameraIdList()",
__FUNCTION__, in_physicalCameraId.c_str());
status = Status::ILLEGAL_ARGUMENT;
} else {
ALOGE("%s: Failed to get physical camera %s info: %s (%d)!", __FUNCTION__,
in_physicalCameraId.c_str(), strerror(-ret), ret);
status = Status::INTERNAL_ERROR;
}
}
}
}
return fromStatus(status);
}
void CameraDevice::setConnectionStatus(bool connected) {
Mutex::Autolock _l(mLock);
mDisconnected = !connected;
std::shared_ptr<CameraDeviceSession> session = mSession.lock();
if (session == nullptr) {
return;
}
// Only notify active session disconnect events.
// Users will need to re-open camera after disconnect event
if (!connected) {
session->disconnect();
}
return;
}
Status CameraDevice::getAidlStatus(int status) {
switch (status) {
case 0:
return Status::OK;
case -ENOSYS:
return Status::OPERATION_NOT_SUPPORTED;
case -EBUSY:
return Status::CAMERA_IN_USE;
case -EUSERS:
return Status::MAX_CAMERAS_IN_USE;
case -ENODEV:
return Status::INTERNAL_ERROR;
case -EINVAL:
return Status::ILLEGAL_ARGUMENT;
default:
ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
return Status::INTERNAL_ERROR;
}
}
ndk::ScopedAStatus CameraDevice::getResourceCost(CameraResourceCost* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
Status status = initStatus();
if (status == Status::OK) {
int cost = 100;
std::vector<std::string> conflicting_devices;
struct camera_info info;
// If using post-2.4 module version, query the cost + conflicting devices from the HAL
if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
int ret = mModule->getCameraInfo(mCameraIdInt, &info);
if (ret == OK) {
cost = info.resource_cost;
for (size_t i = 0; i < info.conflicting_devices_length; i++) {
std::string cameraId(info.conflicting_devices[i]);
for (const auto& pair : mCameraDeviceNames) {
if (cameraId == pair.first) {
conflicting_devices.push_back(pair.second);
}
}
}
} else {
status = Status::INTERNAL_ERROR;
}
}
if (status == Status::OK) {
_aidl_return->resourceCost = cost;
_aidl_return->conflictingDevices.resize(conflicting_devices.size());
for (size_t i = 0; i < conflicting_devices.size(); i++) {
_aidl_return->conflictingDevices[i] = conflicting_devices[i];
ALOGV("CamDevice %s is conflicting with camDevice %s", mCameraId.c_str(),
_aidl_return->conflictingDevices[i].c_str());
}
}
}
return fromStatus(status);
}
ndk::ScopedAStatus CameraDevice::isStreamCombinationSupported(const StreamConfiguration& in_streams,
bool* _aidl_return) {
Status status;
*_aidl_return = false;
// Require module 2.5+ version.
if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_5) {
ALOGE("%s: is_stream_combination_supported must be called on camera module 2.5 or "
"newer",
__FUNCTION__);
status = Status::INTERNAL_ERROR;
} else {
camera_stream_combination_t streamComb{};
streamComb.operation_mode = static_cast<uint32_t>(in_streams.operationMode);
streamComb.num_streams = in_streams.streams.size();
camera_stream_t* streamBuffer = new camera_stream_t[streamComb.num_streams];
size_t i = 0;
for (const auto& it : in_streams.streams) {
streamBuffer[i].stream_type = static_cast<int>(it.streamType);
streamBuffer[i].width = it.width;
streamBuffer[i].height = it.height;
streamBuffer[i].format = static_cast<int>(it.format);
streamBuffer[i].data_space = static_cast<android_dataspace_t>(it.dataSpace);
streamBuffer[i].usage = static_cast<uint32_t>(it.usage);
streamBuffer[i].physical_camera_id = it.physicalCameraId.c_str();
streamBuffer[i++].rotation = static_cast<int>(it.rotation);
}
streamComb.streams = streamBuffer;
auto res = mModule->isStreamCombinationSupported(mCameraIdInt, &streamComb);
switch (res) {
case NO_ERROR:
*_aidl_return = true;
status = Status::OK;
break;
case BAD_VALUE:
status = Status::OK;
break;
case INVALID_OPERATION:
status = Status::OPERATION_NOT_SUPPORTED;
break;
default:
ALOGE("%s: Unexpected error: %d", __FUNCTION__, res);
status = Status::INTERNAL_ERROR;
};
delete[] streamBuffer;
}
return fromStatus(status);
}
ndk::ScopedAStatus CameraDevice::open(const std::shared_ptr<ICameraDeviceCallback>& in_callback,
std::shared_ptr<ICameraDeviceSession>* _aidl_return) {
if (_aidl_return == nullptr) {
ALOGE("%s: cannot open camera %s. return session ptr is null!", __FUNCTION__,
mCameraId.c_str());
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
Status status = initStatus();
std::shared_ptr<CameraDeviceSession> session = nullptr;
if (in_callback == nullptr) {
ALOGE("%s: cannot open camera %s. callback is null!", __FUNCTION__, mCameraId.c_str());
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
if (status != Status::OK) {
// Provider will never pass initFailed device to client, so
// this must be a disconnected camera
ALOGE("%s: cannot open camera %s. camera is disconnected!", __FUNCTION__,
mCameraId.c_str());
return fromStatus(Status::CAMERA_DISCONNECTED);
} else {
mLock.lock();
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
session = mSession.lock();
if (session != nullptr && !session->isClosed()) {
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
mLock.unlock();
return fromStatus(Status::CAMERA_IN_USE);
}
/** Open HAL device */
status_t res;
camera3_device_t* device;
ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(), reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (res != OK) {
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
mLock.unlock();
return fromStatus(getAidlStatus(res));
}
/** Cross-check device version */
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
ALOGE("%s: Could not open camera: "
"Camera device should be at least %x, reports %x instead",
__FUNCTION__, CAMERA_DEVICE_API_VERSION_3_2, device->common.version);
device->common.close(&device->common);
mLock.unlock();
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
struct camera_info info;
res = mModule->getCameraInfo(mCameraIdInt, &info);
if (res != OK) {
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
device->common.close(&device->common);
mLock.unlock();
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
session = createSession(device, info.static_camera_characteristics, in_callback);
if (session == nullptr) {
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
mLock.unlock();
return fromStatus(Status::INTERNAL_ERROR);
}
if (session->isInitFailed()) {
ALOGE("%s: camera device session init failed", __FUNCTION__);
session = nullptr;
mLock.unlock();
return fromStatus(Status::INTERNAL_ERROR);
}
mSession = session;
mLock.unlock();
}
*_aidl_return = session;
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraDevice::openInjectionSession(const std::shared_ptr<ICameraDeviceCallback>&,
std::shared_ptr<ICameraInjectionSession>*) {
return fromStatus(Status::OPERATION_NOT_SUPPORTED);
}
ndk::ScopedAStatus CameraDevice::setTorchMode(bool in_on) {
if (!mModule->isSetTorchModeSupported()) {
return fromStatus(Status::OPERATION_NOT_SUPPORTED);
}
Status status = initStatus();
if (status == Status::OK) {
status = getAidlStatus(mModule->setTorchMode(mCameraId.c_str(), in_on));
if (status == Status::OK) {
mTorchStrengthLevel = 1;
}
}
return fromStatus(status);
}
ndk::ScopedAStatus CameraDevice::turnOnTorchWithStrengthLevel(int32_t in_torchStrength) {
if (!mModule->isSetTorchModeStrengthSupported()) {
return fromStatus(Status::OPERATION_NOT_SUPPORTED);
}
Status status = initStatus();
if (status == Status::OK) {
status = getAidlStatus(
mModule->setTorchModeStrength(mCameraId.c_str(), true, in_torchStrength));
if (status == Status::OK) {
mTorchStrengthLevel = in_torchStrength;
}
}
return fromStatus(status);
}
ndk::ScopedAStatus CameraDevice::getTorchStrengthLevel(int32_t* _aidl_return) {
if (!mModule->isSetTorchModeSupported()) {
return fromStatus(Status::OPERATION_NOT_SUPPORTED);
}
*_aidl_return = mTorchStrengthLevel;
return fromStatus(Status::OK);
}
std::shared_ptr<CameraDeviceSession> CameraDevice::createSession(
camera3_device_t* device, const camera_metadata_t* deviceInfo,
const std::shared_ptr<ICameraDeviceCallback>& callback) {
return ndk::SharedRefBase::make<CameraDeviceSession>(device, deviceInfo, callback);
}
binder_status_t CameraDevice::dump(int fd, const char** args, uint32_t numArgs) {
std::shared_ptr<CameraDeviceSession> session = mSession.lock();
if (session == nullptr) {
dprintf(fd, "No active camera device session instance\n");
return STATUS_OK;
}
return session->dump(fd, args, numArgs);
}
} // namespace implementation
} // namespace device
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1,99 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "CameraDeviceSession.h"
#include <SamsungCameraModule.h>
#include <aidl/android/hardware/camera/common/Status.h>
#include <aidl/android/hardware/camera/device/BnCameraDevice.h>
namespace android {
namespace hardware {
namespace camera {
namespace device {
namespace implementation {
using ::aidl::android::hardware::camera::common::CameraResourceCost;
using ::aidl::android::hardware::camera::common::Status;
using ::aidl::android::hardware::camera::device::BnCameraDevice;
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
using ::aidl::android::hardware::camera::device::ICameraDeviceSession;
using ::aidl::android::hardware::camera::device::ICameraInjectionSession;
using ::aidl::android::hardware::camera::device::StreamConfiguration;
using ::android::hardware::camera::common::helper::SamsungCameraModule;
class CameraDevice : public BnCameraDevice {
public:
// Called by provider HAL.
// Provider HAL must ensure the uniqueness of CameraDevice object per cameraId, or there could
// be multiple CameraDevice trying to access the same physical camera. Also, provider will have
// to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying
// camera is detached.
CameraDevice(sp<SamsungCameraModule> module, const std::string& cameraId,
const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames);
virtual ~CameraDevice();
ndk::ScopedAStatus getCameraCharacteristics(CameraMetadata* _aidl_return) override;
ndk::ScopedAStatus getPhysicalCameraCharacteristics(const std::string& in_physicalCameraId,
CameraMetadata* _aidl_return) override;
ndk::ScopedAStatus getResourceCost(CameraResourceCost* _aidl_return) override;
ndk::ScopedAStatus isStreamCombinationSupported(const StreamConfiguration& in_streams,
bool* _aidl_return) override;
ndk::ScopedAStatus open(const std::shared_ptr<ICameraDeviceCallback>& in_callback,
std::shared_ptr<ICameraDeviceSession>* _aidl_return) override;
ndk::ScopedAStatus openInjectionSession(
const std::shared_ptr<ICameraDeviceCallback>& in_callback,
std::shared_ptr<ICameraInjectionSession>* _aidl_return) override;
ndk::ScopedAStatus setTorchMode(bool in_on) override;
ndk::ScopedAStatus turnOnTorchWithStrengthLevel(int32_t in_torchStrength) override;
ndk::ScopedAStatus getTorchStrengthLevel(int32_t* _aidl_return) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
// Caller must use this method to check if CameraDevice ctor failed
bool isInitFailed() { return mInitFail; }
// Used by provider HAL to signal external camera disconnected
void setConnectionStatus(bool connected);
// Device version to be used by the external camera provider.
// Should be of the form <major>.<minor>
static std::string kDeviceVersion;
protected:
virtual std::shared_ptr<CameraDeviceSession> createSession(
camera3_device_t*, const camera_metadata_t* deviceInfo,
const std::shared_ptr<ICameraDeviceCallback>&);
const sp<SamsungCameraModule> mModule;
const std::string mCameraId;
// const after ctor
int mCameraIdInt;
int mDeviceVersion;
bool mInitFail = false;
// Set by provider (when external camera is connected/disconnected)
bool mDisconnected;
std::weak_ptr<CameraDeviceSession> mSession{};
int32_t mTorchStrengthLevel = 1;
const SortedVector<std::pair<std::string, std::string>>& mCameraDeviceNames;
// gating access to mSession and mDisconnected
mutable Mutex mLock;
// convert conventional HAL status to AIDL Status
static Status getAidlStatus(int);
Status initStatus() const;
};
} // namespace implementation
} // namespace device
} // namespace camera
} // namespace hardware
} // namespace android

File diff suppressed because it is too large Load Diff

View File

@ -1,388 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "convert.h"
#include <CameraMetadata.h>
#include <HandleImporter.h>
#include <aidl/android/hardware/camera/common/Status.h>
#include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
#include <aidl/android/hardware/camera/device/CaptureResult.h>
#include <aidl/android/hardware/camera/device/ICameraOfflineSession.h>
#include <aidl/android/hardware/camera/device/NotifyMsg.h>
#include <aidl/android/hardware/camera/device/StreamBuffer.h>
#include <fmq/AidlMessageQueue.h>
#include <hardware/camera3.h>
#include <utils/Mutex.h>
#include <deque>
#include <map>
#include <unordered_map>
#include <unordered_set>
namespace android {
namespace hardware {
namespace camera {
namespace device {
namespace implementation {
using ::aidl::android::hardware::camera::common::Status;
using ::aidl::android::hardware::camera::device::BnCameraDeviceSession;
using ::aidl::android::hardware::camera::device::BufferCache;
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
using ::aidl::android::hardware::camera::device::CaptureRequest;
using ::aidl::android::hardware::camera::device::CaptureResult;
using ::aidl::android::hardware::camera::device::HalStream;
using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
using ::aidl::android::hardware::camera::device::ICameraOfflineSession;
using ::aidl::android::hardware::camera::device::NotifyMsg;
using ::aidl::android::hardware::camera::device::RequestTemplate;
using ::aidl::android::hardware::camera::device::StreamBuffer;
using ::aidl::android::hardware::camera::device::StreamConfiguration;
using ::android::AidlMessageQueue;
using ::android::hardware::camera::common::helper::HandleImporter;
/**
* Function pointer types with C calling convention to
* use for HAL callback functions.
*/
extern "C" {
typedef void(callbacks_process_capture_result_t)(const struct camera3_callback_ops*,
const camera3_capture_result_t*);
typedef void(callbacks_notify_t)(const struct camera3_callback_ops*, const camera3_notify_msg_t*);
}
class CameraDeviceSession : public BnCameraDeviceSession, protected camera3_callback_ops {
public:
CameraDeviceSession(camera3_device_t*, const camera_metadata_t* deviceInfo,
const std::shared_ptr<ICameraDeviceCallback>&);
virtual ~CameraDeviceSession();
// Caller must use this method to check if CameraDeviceSession ctor failed
bool isInitFailed() { return mInitFail; }
// Used by CameraDevice to signal external camera disconnected
void disconnect();
bool isClosed();
ndk::ScopedAStatus close() override;
ndk::ScopedAStatus configureStreams(const StreamConfiguration& in_requestedConfiguration,
std::vector<HalStream>* _aidl_return) override;
ndk::ScopedAStatus constructDefaultRequestSettings(RequestTemplate in_type,
CameraMetadata* _aidl_return) override;
ndk::ScopedAStatus flush() override;
ndk::ScopedAStatus getCaptureRequestMetadataQueue(
MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
ndk::ScopedAStatus getCaptureResultMetadataQueue(
MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
ndk::ScopedAStatus isReconfigurationRequired(const CameraMetadata& in_oldSessionParams,
const CameraMetadata& in_newSessionParams,
bool* _aidl_return) override;
ndk::ScopedAStatus processCaptureRequest(const std::vector<CaptureRequest>& in_requests,
const std::vector<BufferCache>& in_cachesToRemove,
int32_t* _aidl_return) override;
ndk::ScopedAStatus signalStreamFlush(const std::vector<int32_t>& in_streamIds,
int32_t in_streamConfigCounter) override;
ndk::ScopedAStatus switchToOffline(
const std::vector<int32_t>& in_streamsToKeep,
CameraOfflineSessionInfo* out_offlineSessionInfo,
std::shared_ptr<ICameraOfflineSession>* _aidl_return) override;
ndk::ScopedAStatus repeatingRequestEnd(int32_t in_frameNumber,
const std::vector<int32_t>& in_streamIds) override;
protected:
// Helper methods
Status constructDefaultRequestSettingsRaw(int type, CameraMetadata* outMetadata);
bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration,
camera3_stream_configuration_t* stream_list /*out*/,
std::vector<camera3_stream_t*>* streams /*out*/);
void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration);
void postProcessConfigurationFailureLocked(const StreamConfiguration& requestedConfiguration);
Status processOneCaptureRequest(const CaptureRequest& request);
// Method to pop buffer's bufferId from mBufferIdMaps
// BUFFER_ID_NO_BUFFER is returned if no matching buffer is found
uint64_t popBufferId(const buffer_handle_t& buf, int streamId);
// By default camera service uses frameNumber/streamId pair to retrieve the buffer that
// was sent to HAL. Override this implementation if HAL is using buffers from buffer management
// APIs to send output buffer.
virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId);
status_t constructCaptureResult(CaptureResult& result,
const camera3_capture_result* hal_result);
// Static helper method to copy/shrink capture result metadata sent by HAL
// Temporarily allocated metadata copy will be hold in mds
static void sShrinkCaptureResult(
camera3_capture_result* dst, const camera3_capture_result* src,
std::vector<::android::hardware::camera::common::helper::CameraMetadata>* mds,
std::vector<const camera_metadata_t*>* physCamMdArray, bool handlePhysCam);
static bool sShouldShrink(const camera_metadata_t* md);
static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src);
// protecting mClosed/mDisconnected/mInitFail
mutable Mutex mStateLock;
// device is closed either
// - closed by user
// - init failed
// - camera disconnected
bool mClosed = false;
// Set by CameraDevice (when external camera is disconnected)
bool mDisconnected = false;
struct AETriggerCancelOverride {
bool applyAeLock;
uint8_t aeLock;
bool applyAePrecaptureTrigger;
uint8_t aePrecaptureTrigger;
};
camera3_device_t* mDevice;
const uint32_t mDeviceVersion;
const bool mFreeBufEarly;
bool mIsAELockAvailable;
bool mDerivePostRawSensKey;
uint32_t mNumPartialResults;
// Stream ID -> Camera3Stream cache
std::map<int, Camera3Stream> mStreamMap;
std::map<int, std::string> mPhysicalCameraIdMap;
// Physical camera ids for the logical multi-camera. Empty if this
// is not a logical multi-camera.
std::unordered_set<std::string> mPhysicalCameraIds;
Mutex mStreamConfigCounterLock;
uint32_t mStreamConfigCounter = 1;
mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
// (streamID, frameNumber) -> inflight buffer cache
std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers;
// (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
::android::hardware::camera::common::helper::CameraMetadata mOverridenResult;
std::map<uint32_t, bool> mInflightRawBoostPresent;
::android::hardware::camera::common::helper::CameraMetadata mOverridenRequest;
static const uint64_t BUFFER_ID_NO_BUFFER = 0;
// buffers currently ciculating between HAL and camera service
// key: bufferId sent via HIDL interface
// value: imported buffer_handle_t
// Buffer will be imported during process_capture_request and will be freed
// when the its stream is deleted or camera device session is closed
typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
// Stream ID -> circulating buffers map
std::map<int, CirculatingBuffers> mCirculatingBuffers;
static HandleImporter sHandleImporter;
static buffer_handle_t sEmptyBuffer;
bool mInitFail;
bool mFirstRequest = false;
struct BufferHasher {
size_t operator()(const buffer_handle_t& buf) const {
if (buf == nullptr) return 0;
size_t result = 1;
result = 31 * result + buf->numFds;
for (int i = 0; i < buf->numFds; i++) {
result = 31 * result + buf->data[i];
}
return result;
}
};
struct BufferComparator {
bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
if (buf1->numFds == buf2->numFds) {
for (int i = 0; i < buf1->numFds; i++) {
if (buf1->data[i] != buf2->data[i]) {
return false;
}
}
return true;
}
return false;
}
};
std::mutex mBufferIdMapLock; // protecting mBufferIdMaps and mNextBufferId
typedef std::unordered_map<const buffer_handle_t, uint64_t, BufferHasher, BufferComparator>
BufferIdMap;
// stream ID -> per stream buffer ID map for buffers coming from requestStreamBuffers API
// Entries are created during requestStreamBuffers when a stream first request a buffer, and
// deleted in returnStreamBuffers/processCaptureResult* when all buffers are returned
std::unordered_map<int, BufferIdMap> mBufferIdMaps;
::android::hardware::camera::common::helper::CameraMetadata mDeviceInfo;
using RequestMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
class ResultBatcher {
public:
ResultBatcher(const std::shared_ptr<ICameraDeviceCallback>& callback);
void setNumPartialResults(uint32_t n);
void setBatchedStreams(const std::vector<int>& streamsToBatch);
void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
void registerBatch(uint32_t frameNumber, uint32_t batchSize);
void notify(NotifyMsg& msg);
void processCaptureResult(CaptureResult& result);
protected:
struct InflightBatch {
// Protect access to entire struct. Acquire this lock before read/write any data or
// calling any methods. processCaptureResult and notify will compete for this lock
// HIDL IPCs might be issued while the lock is held
Mutex mLock;
bool allDelivered() const;
uint32_t mFirstFrame;
uint32_t mLastFrame;
uint32_t mBatchSize;
bool mShutterDelivered = false;
std::vector<NotifyMsg> mShutterMsgs;
struct BufferBatch {
BufferBatch(uint32_t batchSize) { mBuffers.reserve(batchSize); }
bool mDelivered = false;
// This currently assumes every batched request will output to the batched stream
// and since HAL must always send buffers in order, no frameNumber tracking is
// needed
std::vector<StreamBuffer> mBuffers;
};
// Stream ID -> VideoBatch
std::unordered_map<int, BufferBatch> mBatchBufs;
struct MetadataBatch {
// (frameNumber, metadata)
std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
};
// Partial result IDs that has been delivered to framework
uint32_t mNumPartialResults;
uint32_t mPartialResultProgress = 0;
// partialResult -> MetadataBatch
std::map<uint32_t, MetadataBatch> mResultMds;
// Set to true when batch is removed from mInflightBatches
// processCaptureResult and notify must check this flag after acquiring mLock to make
// sure this batch isn't removed while waiting for mLock
bool mRemoved = false;
};
// Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
// Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
// It's possible that the InflightBatch is removed from mInflightBatches before the
// InflightBatch::mLock is acquired (most likely caused by an error notification), so
// caller must check InflightBatch::mRemoved flag after the lock is acquried.
// This method will hold ResultBatcher::mLock briefly
std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
static const int NOT_BATCHED = -1;
// move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
// handle
void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
void sendBatchMetadataLocked(std::shared_ptr<InflightBatch> batch,
uint32_t lastPartialResultIdx);
// Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
// This method will hold ResultBatcher::mLock briefly
void checkAndRemoveFirstBatch();
// The following sendXXXX methods must be called while the InflightBatch::mLock is locked
// HIDL IPC methods will be called during these methods.
void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
// send buffers for all batched streams
void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
// send buffers for specified streams
void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch,
const std::vector<int>& streams);
// End of sendXXXX methods
// helper methods
void freeReleaseFences(std::vector<CaptureResult>&);
void notifySingleMsg(NotifyMsg& msg);
void processOneCaptureResult(CaptureResult& result);
void invokeProcessCaptureResultCallback(std::vector<CaptureResult>& results,
bool tryWriteFmq);
// Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
// processCaptureRequest, processCaptureResult, notify will compete for this lock
// Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
mutable Mutex mLock;
std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
uint32_t mNumPartialResults;
std::vector<int> mStreamsToBatch;
const std::shared_ptr<ICameraDeviceCallback> mCallback;
std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
// Protect against invokeProcessCaptureResultCallback()
Mutex mProcessCaptureResultLock;
} mResultBatcher;
std::vector<int> mVideoStreamIds;
bool initialize();
static bool shouldFreeBufEarly();
Status initStatus() const;
// Validate and import request's input buffer and acquire fence
virtual Status importRequest(const CaptureRequest& request,
std::vector<buffer_handle_t*>& allBufPtrs,
std::vector<int>& allFences);
Status importRequestImpl(const CaptureRequest& request,
std::vector<buffer_handle_t*>& allBufPtrs, std::vector<int>& allFences,
// Optional argument for ICameraDeviceSession@3.5 impl
bool allowEmptyBuf = false);
Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
/*out*/ buffer_handle_t** outBufPtr, bool allowEmptyBuf);
static void cleanupInflightFences(std::vector<int>& allFences, size_t numFences);
void cleanupBuffersLocked(int id);
void updateBufferCaches(const std::vector<BufferCache>& cachesToRemove);
bool handleAePrecaptureCancelRequestLocked(
const camera3_capture_request_t& halRequest,
android::hardware::camera::common::helper::CameraMetadata* settings /*out*/,
AETriggerCancelOverride* override /*out*/);
void overrideResultForPrecaptureCancelLocked(
const AETriggerCancelOverride& aeTriggerCancelOverride,
::android::hardware::camera::common::helper::CameraMetadata* settings /*out*/);
/**
* Static callback forwarding methods from HAL to instance
*/
static callbacks_process_capture_result_t sProcessCaptureResult;
static callbacks_notify_t sNotify;
};
} // namespace implementation
} // namespace device
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1,150 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.camera.device-convert-impl"
#include <log/log.h>
#include "convert.h"
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
#include <aidl/android/hardware/graphics/common/Dataspace.h>
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <hardware/camera_common.h>
namespace android {
namespace hardware {
namespace camera {
namespace device {
namespace implementation {
using ::aidl::android::hardware::camera::device::ErrorCode;
using ::aidl::android::hardware::camera::device::ErrorMsg;
using ::aidl::android::hardware::camera::device::ShutterMsg;
using ::aidl::android::hardware::graphics::common::BufferUsage;
using ::aidl::android::hardware::graphics::common::Dataspace;
using ::aidl::android::hardware::graphics::common::PixelFormat;
void convertToAidl(const camera_metadata_t* src, CameraMetadata* dest) {
if (src == nullptr) {
return;
}
size_t size = get_camera_metadata_size(src);
auto* src_start = (uint8_t*)src;
uint8_t* src_end = src_start + size;
dest->metadata.assign(src_start, src_end);
}
bool convertFromAidl(const CameraMetadata& src, const camera_metadata_t** dst) {
const std::vector<uint8_t>& metadata = src.metadata;
if (metadata.empty()) {
// Special case for null metadata
*dst = nullptr;
return true;
}
const uint8_t* data = metadata.data();
// check that the size of CameraMetadata match underlying camera_metadata_t
if (get_camera_metadata_size((camera_metadata_t*)data) != metadata.size()) {
ALOGE("%s: input CameraMetadata is corrupt!", __FUNCTION__);
return false;
}
*dst = (camera_metadata_t*)data;
return true;
}
void convertToAidl(const Camera3Stream* src, HalStream* dst) {
dst->overrideDataSpace = (Dataspace)src->data_space;
dst->id = src->mId;
dst->overrideFormat = (PixelFormat)src->format;
dst->maxBuffers = src->max_buffers;
dst->physicalCameraId = src->physical_camera_id;
if (src->stream_type == CAMERA3_STREAM_OUTPUT) {
dst->consumerUsage = (BufferUsage)0;
dst->producerUsage = (BufferUsage)src->usage;
} else if (src->stream_type == CAMERA3_STREAM_INPUT) {
dst->producerUsage = (BufferUsage)0;
dst->consumerUsage = (BufferUsage)src->usage;
} else {
// Should not reach here per current AIDL spec, but we might end up adding
// bi-directional stream to AIDL.
ALOGW("%s: Stream type %d is not currently supported!", __FUNCTION__, src->stream_type);
}
}
void convertToAidl(const camera3_stream_configuration_t& src, std::vector<HalStream>* dst) {
dst->resize(src.num_streams);
for (uint32_t i = 0; i < src.num_streams; i++) {
convertToAidl(static_cast<Camera3Stream*>(src.streams[i]), &dst->at(i));
}
}
void convertFromAidl(const Stream& src, Camera3Stream* dst) {
dst->mId = src.id;
dst->stream_type = (int)src.streamType;
dst->width = src.width;
dst->height = src.height;
dst->format = (int)src.format;
dst->data_space = (android_dataspace_t)src.dataSpace;
dst->rotation = (int)src.rotation;
dst->usage = (uint32_t)src.usage;
// Fields to be filled by HAL (max_buffers, priv) are initialized to 0
dst->max_buffers = 0;
dst->priv = 0;
// Initialize physical_camera_id
dst->physical_camera_id = nullptr;
}
void convertFromAidl(buffer_handle_t* bufPtr, BufferStatus status, camera3_stream_t* stream,
int acquireFence, camera3_stream_buffer_t* dst) {
dst->stream = stream;
dst->buffer = bufPtr;
dst->status = (int)status;
dst->acquire_fence = acquireFence;
dst->release_fence = -1; // meant for HAL to fill in
}
void convertToAidl(const camera3_notify_msg* src, NotifyMsg* dst) {
switch (src->type) {
case CAMERA3_MSG_ERROR: {
ErrorMsg error;
// The camera3_stream_t* must be the same as what wrapper HAL passed to conventional
// HAL, or the ID lookup will return garbage. Caller should validate the ID here is
// indeed one of active stream IDs
Camera3Stream* stream = static_cast<Camera3Stream*>(src->message.error.error_stream);
error.frameNumber = src->message.error.frame_number;
error.errorStreamId = (stream != nullptr) ? stream->mId : -1;
error.errorCode = (ErrorCode)src->message.error.error_code;
dst->set<NotifyMsg::Tag::error>(error);
} break;
case CAMERA3_MSG_SHUTTER: {
ShutterMsg shutter;
shutter.frameNumber = src->message.shutter.frame_number;
shutter.timestamp = src->message.shutter.timestamp;
dst->set<NotifyMsg::Tag::shutter>(shutter);
} break;
default:
ALOGE("%s: HIDL type converion failed. Unknown msg type 0x%x", __FUNCTION__, src->type);
}
return;
}
} // namespace implementation
} // namespace device
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1,84 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
#include <aidl/android/hardware/camera/common/Status.h>
#include <aidl/android/hardware/camera/device/BufferStatus.h>
#include <aidl/android/hardware/camera/device/CameraMetadata.h>
#include <aidl/android/hardware/camera/device/HalStream.h>
#include <aidl/android/hardware/camera/device/NotifyMsg.h>
#include <aidl/android/hardware/camera/device/Stream.h>
#include <aidlcommonsupport/NativeHandle.h>
#include <hardware/camera3.h>
#include <system/camera_metadata.h>
namespace android {
namespace hardware {
namespace camera {
namespace device {
namespace implementation {
// The camera3_stream_t sent to conventional HAL. Added mId fields to enable stream ID lookup
// fromt a downcasted camera3_stream
struct Camera3Stream : public camera3_stream {
int mId;
};
using ::aidl::android::hardware::camera::common::Status;
using ::aidl::android::hardware::camera::device::BufferStatus;
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::HalStream;
using ::aidl::android::hardware::camera::device::NotifyMsg;
using ::aidl::android::hardware::camera::device::Stream;
void convertToAidl(const camera_metadata_t* src, CameraMetadata* dest);
bool convertFromAidl(const CameraMetadata& src, const camera_metadata_t** dst);
void convertToAidl(const Camera3Stream* src, HalStream* dst);
void convertToAidl(const camera3_stream_configuration_t& src, std::vector<HalStream>* dst);
void convertFromAidl(const Stream& src, Camera3Stream* dst);
void convertFromAidl(buffer_handle_t*, BufferStatus, camera3_stream_t*, int acquireFence, // inputs
camera3_stream_buffer_t* dst);
void convertToAidl(const camera3_notify_msg* src, NotifyMsg* dst);
inline aidl::android::hardware::common::NativeHandle makeToAidlIfNotNull(
const native_handle_t* nh) {
if (nh == nullptr) {
return aidl::android::hardware::common::NativeHandle();
}
return makeToAidl(nh);
}
inline ndk::ScopedAStatus fromStatus(Status status) {
return status == Status::OK
? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
} // namespace implementation
} // namespace device
} // namespace camera
} // namespace hardware
} // namespace android
#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_

View File

@ -1,36 +0,0 @@
soong_config_module_type {
name: "samsung_camera3",
module_type: "cc_defaults",
config_namespace: "samsungCameraVars",
bool_variables: [
"needs_sec_get_cam_pos_v1",
"needs_sec_get_cam_pos_v2",
"needs_sec_reserved_field",
"usage_64bit",
],
properties: ["cflags"],
}
samsung_camera3 {
name: "samsung_camera3_defaults",
soong_config_variables: {
needs_sec_get_cam_pos_v1: {
cflags: ["-DCAMERA_NEEDS_SEC_GET_CAM_POS_V1"],
},
needs_sec_get_cam_pos_v2: {
cflags: ["-DCAMERA_NEEDS_SEC_GET_CAM_POS_V2"],
},
needs_sec_reserved_field: {
cflags: ["-DCAMERA_NEEDS_SEC_RESERVED_FIELD"],
},
usage_64bit: {
cflags: ["-DCAMERA_64BIT_USAGE"],
},
},
}
cc_library_headers {
name: "libhardware_headers.camera3_samsung",
export_include_dirs: ["include"],
vendor_available: true,
}

View File

@ -1 +0,0 @@
../../../../../../../hardware/libhardware/include/hardware/camera.h

File diff suppressed because it is too large Load Diff

View File

@ -1,71 +0,0 @@
//
// Copyright (C) 2024 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
soong_config_module_type {
name: "extra_ids",
module_type: "cc_defaults",
config_namespace: "samsungCameraVars",
value_variables: ["extra_ids"],
properties: ["cppflags"],
}
extra_ids {
name: "extra_id_defaults",
soong_config_variables: {
extra_ids: {
cppflags: ["-DEXTRA_IDS=%s"],
},
},
}
cc_defaults {
name: "camera_service_aidl_defaults.samsung",
defaults: [
"extra_id_defaults",
"samsung_camera3_defaults"
],
vintf_fragments: ["android.hardware.camera.provider-service.samsung.xml"],
vendor: true,
relative_install_path: "hw",
srcs: [
"service.cpp",
"CameraProvider.cpp",
],
shared_libs: [
"android.hardware.camera.common-V1-ndk",
"android.hardware.camera.device-V1-ndk",
"android.hardware.camera.provider-V1-ndk",
"camera.device-impl.samsung",
"libbinder_ndk",
"libcamera_metadata",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"liblog",
"libutils",
],
static_libs: [
"android.hardware.camera.common-helper.samsung",
"libaidlcommonsupport",
],
header_libs: [
"libhardware_headers.camera3_samsung",
],
}
cc_binary {
name: "android.hardware.camera.provider-service_32.samsung",
defaults: ["camera_service_aidl_defaults.samsung"],
compile_multilib: "32",
init_rc: ["android.hardware.camera.provider-service_32.samsung.rc"],
}
cc_binary {
name: "android.hardware.camera.provider-service.samsung",
defaults: ["camera_service_aidl_defaults.samsung"],
init_rc: ["android.hardware.camera.provider-service.samsung.rc"],
}

View File

@ -1,467 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "CamPrvdr"
#include "CameraProvider.h"
#include <CameraDevice.h>
#include <convert.h>
#include <utils/Trace.h>
#include <regex>
namespace android {
namespace hardware {
namespace camera {
namespace provider {
namespace implementation {
using ::aidl::android::hardware::camera::common::CameraMetadataType;
using ::aidl::android::hardware::camera::common::Status;
using ::aidl::android::hardware::camera::common::TorchModeStatus;
using ::aidl::android::hardware::camera::common::VendorTag;
using ::android::hardware::camera::common::helper::VendorTagDescriptor;
using ::android::hardware::camera::device::implementation::CameraDevice;
using ::android::hardware::camera::device::implementation::fromStatus;
namespace {
// "device@<version>/internal/<id>"
const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/internal/(.+)");
const int kMaxCameraDeviceNameLen = 128;
const int kMaxCameraIdLen = 16;
bool matchDeviceName(const std::string& deviceName, std::string* deviceVersion,
std::string* cameraId) {
std::string deviceNameStd(deviceName.c_str());
std::smatch sm;
if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
if (deviceVersion != nullptr) {
*deviceVersion = sm[1];
}
if (cameraId != nullptr) {
*cameraId = sm[2];
}
return true;
}
return false;
}
} // anonymous namespace
void CameraProvider::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new) {
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
std::string cameraIdStr(cameraId);
mCameraIds.add(cameraIdStr);
// initialize mCameraDeviceNames
int deviceVersion = mModule->getDeviceVersion(camera_id);
auto deviceNamePair = std::make_pair(cameraIdStr, getAidlDeviceName(cameraIdStr));
mCameraDeviceNames.add(deviceNamePair);
if (cam_new) {
mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
}
}
void CameraProvider::removeDeviceNames(int camera_id) {
std::string cameraIdStr = std::to_string(camera_id);
mCameraIds.remove(cameraIdStr);
int deviceVersion = mModule->getDeviceVersion(camera_id);
auto deviceNamePair = std::make_pair(cameraIdStr, getAidlDeviceName(cameraIdStr));
mCameraDeviceNames.remove(deviceNamePair);
mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, CameraDeviceStatus::NOT_PRESENT);
mModule->removeCamera(camera_id);
}
/**
* static callback forwarding methods from HAL to instance
*/
void CameraProvider::sCameraDeviceStatusChange(const struct camera_module_callbacks* callbacks,
int camera_id, int new_status) {
CameraProvider* cp = const_cast<CameraProvider*>(static_cast<const CameraProvider*>(callbacks));
if (cp == nullptr) {
ALOGE("%s: callback ops is null", __FUNCTION__);
return;
}
Mutex::Autolock _l(cp->mCbLock);
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
std::string cameraIdStr(cameraId);
cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t)new_status;
if (cp->mCallbacks == nullptr) {
// For camera connected before mCallbacks is set, the corresponding
// addDeviceNames() would be called later in setCallbacks().
return;
}
bool found = false;
CameraDeviceStatus status = (CameraDeviceStatus)new_status;
for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
if (cameraIdStr.compare(deviceNamePair.first) == 0) {
cp->mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
found = true;
}
}
switch (status) {
case CameraDeviceStatus::PRESENT:
case CameraDeviceStatus::ENUMERATING:
if (!found) {
cp->addDeviceNames(camera_id, status, true);
}
break;
case CameraDeviceStatus::NOT_PRESENT:
if (found) {
cp->removeDeviceNames(camera_id);
}
}
}
void CameraProvider::sTorchModeStatusChange(const struct camera_module_callbacks* callbacks,
const char* camera_id, int new_status) {
CameraProvider* cp = const_cast<CameraProvider*>(static_cast<const CameraProvider*>(callbacks));
if (cp == nullptr) {
ALOGE("%s: callback ops is null", __FUNCTION__);
return;
}
Mutex::Autolock _l(cp->mCbLock);
if (cp->mCallbacks != nullptr) {
std::string cameraIdStr(camera_id);
TorchModeStatus status = (TorchModeStatus)new_status;
for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
if (cameraIdStr.compare(deviceNamePair.first) == 0) {
cp->mCallbacks->torchModeStatusChange(deviceNamePair.second, status);
}
}
}
}
std::string CameraProvider::getAidlDeviceName(std::string cameraId) {
return "device@" + CameraDevice::kDeviceVersion + "/internal/" + cameraId;
}
CameraProvider::CameraProvider()
: camera_module_callbacks_t({sCameraDeviceStatusChange, sTorchModeStatusChange}) {
mInitFailed = initialize();
}
CameraProvider::~CameraProvider() {}
bool CameraProvider::initCamera(int id) {
struct camera_info info;
auto rc = mModule->getCameraInfo(id, &info);
if (rc != NO_ERROR) {
ALOGE("%s: Camera info query failed!", __func__);
return true;
}
if (checkCameraVersion(id, info) != OK) {
ALOGE("%s: Camera version check failed!", __func__);
return true;
}
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", id);
std::string cameraIdStr(cameraId);
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
addDeviceNames(id);
return false;
}
bool CameraProvider::initialize() {
camera_module_t* rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}
mModule = new SamsungCameraModule(rawModule);
err = mModule->init();
if (err != OK) {
ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
// Setup vendor tags here so HAL can setup vendor keys in camera characteristics
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
if (!setUpVendorTags()) {
ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
}
// Setup callback now because we are going to try openLegacy next
err = mModule->setCallbacks(this);
if (err != OK) {
ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
if (initCamera(i)) {
mModule.clear();
return true;
}
}
std::vector<int> extraIDs = {
#ifdef EXTRA_IDS
EXTRA_IDS
#endif
};
for (int i : extraIDs) {
if (initCamera(i)) {
mModule.clear();
return true;
} else {
mNumberOfLegacyCameras++;
}
}
return false; // mInitFailed
}
/**
* Check that the device HAL version is still in supported.
*/
int CameraProvider::checkCameraVersion(int id, camera_info info) {
if (mModule == nullptr) {
return NO_INIT;
}
// device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
// All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
uint16_t moduleVersion = mModule->getModuleApiVersion();
if (moduleVersion >= CAMERA_MODULE_API_VERSION_2_0) {
// Verify the device version is in the supported range
switch (info.device_version) {
case CAMERA_DEVICE_API_VERSION_1_0:
case CAMERA_DEVICE_API_VERSION_3_2:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_5:
// in support
break;
case CAMERA_DEVICE_API_VERSION_3_6:
/**
* ICameraDevice@3.5 contains APIs from both
* CAMERA_DEVICE_API_VERSION_3_6 and CAMERA_MODULE_API_VERSION_2_5
* so we require HALs to uprev both for simplified supported combinations.
* HAL can still opt in individual new APIs indepedently.
*/
if (moduleVersion < CAMERA_MODULE_API_VERSION_2_5) {
ALOGE("%s: Device %d has unsupported version combination:"
"HAL version %x and module version %x",
__FUNCTION__, id, info.device_version, moduleVersion);
return NO_INIT;
}
break;
case CAMERA_DEVICE_API_VERSION_2_0:
case CAMERA_DEVICE_API_VERSION_2_1:
case CAMERA_DEVICE_API_VERSION_3_0:
case CAMERA_DEVICE_API_VERSION_3_1:
// no longer supported
default:
ALOGE("%s: Device %d has HAL version %x, which is not supported", __FUNCTION__, id,
info.device_version);
return NO_INIT;
}
}
return OK;
}
bool CameraProvider::setUpVendorTags() {
ATRACE_CALL();
vendor_tag_ops_t vOps = vendor_tag_ops_t();
// Check if vendor operations have been implemented
if (!mModule->isVendorTagDefined()) {
ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
return true;
}
mModule->getVendorTagOps(&vOps);
// Ensure all vendor operations are present
if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
vOps.get_tag_type == nullptr) {
ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions.", __FUNCTION__);
return false;
}
// Read all vendor tag definitions into a descriptor
sp<VendorTagDescriptor> desc;
status_t res;
if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/ desc)) != OK) {
ALOGE("%s: Could not generate descriptor from vendor tag operations,"
"received error %s (%d). Camera clients will not be able to use"
"vendor tags",
__FUNCTION__, strerror(res), res);
return false;
}
// Set the global descriptor to use with camera metadata
VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
size_t numSections = sectionNames->size();
std::vector<std::vector<VendorTag>> tagsBySection(numSections);
int tagCount = desc->getTagCount();
std::vector<uint32_t> tags(tagCount);
desc->getTagArray(tags.data());
for (int i = 0; i < tagCount; i++) {
VendorTag vt;
vt.tagId = tags[i];
vt.tagName = desc->getTagName(tags[i]);
vt.tagType = (CameraMetadataType)desc->getTagType(tags[i]);
ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
tagsBySection[sectionIdx].push_back(vt);
}
mVendorTagSections.resize(numSections);
for (size_t s = 0; s < numSections; s++) {
mVendorTagSections[s].sectionName = (*sectionNames)[s].c_str();
mVendorTagSections[s].tags = tagsBySection[s];
}
return true;
}
ndk::ScopedAStatus CameraProvider::setCallback(
const std::shared_ptr<ICameraProviderCallback>& callback) {
Mutex::Autolock _l(mCbLock);
mCallbacks = callback;
if (callback == nullptr) {
return fromStatus(Status::OK);
}
// Add and report all presenting external cameras.
for (auto const& statusPair : mCameraStatusMap) {
int id = std::stoi(statusPair.first);
auto status = static_cast<CameraDeviceStatus>(statusPair.second);
if (id >= mNumberOfLegacyCameras && status != CameraDeviceStatus::NOT_PRESENT) {
addDeviceNames(id, status, true);
}
}
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraProvider::getVendorTags(std::vector<VendorTagSection>* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
_aidl_return->insert(_aidl_return->end(), mVendorTagSections.begin(), mVendorTagSections.end());
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraProvider::getCameraIdList(std::vector<std::string>* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
for (auto const& deviceNamePair : mCameraDeviceNames) {
if (std::stoi(deviceNamePair.first) >= mNumberOfLegacyCameras) {
// External camera devices must be reported through the device status change callback,
// not in this list.
continue;
}
if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
_aidl_return->push_back(deviceNamePair.second);
}
}
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraProvider::getCameraDeviceInterface(
const std::string& in_cameraDeviceName, std::shared_ptr<ICameraDevice>* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
std::string cameraId, deviceVersion;
bool match = matchDeviceName(in_cameraDeviceName, &deviceVersion, &cameraId);
if (!match) {
*_aidl_return = nullptr;
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, in_cameraDeviceName));
if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
Status status = Status::OK;
ssize_t idx = mCameraIds.indexOf(cameraId);
if (idx == NAME_NOT_FOUND) {
ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
status = Status::ILLEGAL_ARGUMENT;
} else { // invalid version
ALOGE("%s: camera device %s does not support version %s!", __FUNCTION__,
cameraId.c_str(), deviceVersion.c_str());
status = Status::OPERATION_NOT_SUPPORTED;
}
return fromStatus(status);
}
ALOGV("Constructing camera device");
std::shared_ptr<CameraDevice> deviceImpl =
ndk::SharedRefBase::make<CameraDevice>(mModule, cameraId, mCameraDeviceNames);
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
*_aidl_return = nullptr;
return fromStatus(Status::INTERNAL_ERROR);
}
IF_ALOGV() {
int interfaceVersion;
deviceImpl->getInterfaceVersion(&interfaceVersion);
ALOGV("%s: device interface version: %d", __FUNCTION__, interfaceVersion);
}
*_aidl_return = deviceImpl;
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraProvider::notifyDeviceStateChange(int64_t newState) {
ALOGD("%s: New device state: 0x%" PRIx64, __FUNCTION__, newState);
uint64_t state = static_cast<uint64_t>(newState);
mModule->notifyDeviceStateChange(state);
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraProvider::getConcurrentCameraIds(
std::vector<ConcurrentCameraIdCombination>* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
*_aidl_return = {};
return fromStatus(Status::OK);
}
ndk::ScopedAStatus CameraProvider::isConcurrentStreamCombinationSupported(
const std::vector<CameraIdAndStreamCombination>&, bool* _aidl_return) {
if (_aidl_return == nullptr) {
return fromStatus(Status::ILLEGAL_ARGUMENT);
}
// No concurrent stream combinations are supported
*_aidl_return = false;
return fromStatus(Status::OK);
}
} // namespace implementation
} // namespace provider
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1,93 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <SamsungCameraModule.h>
#include <VendorTagDescriptor.h>
#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <aidl/android/hardware/camera/provider/BnCameraProvider.h>
#include <map>
namespace android {
namespace hardware {
namespace camera {
namespace provider {
namespace implementation {
using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
using ::aidl::android::hardware::camera::common::VendorTagSection;
using ::aidl::android::hardware::camera::device::ICameraDevice;
using ::aidl::android::hardware::camera::provider::BnCameraProvider;
using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
using ::aidl::android::hardware::camera::provider::ICameraProviderCallback;
using ::android::hardware::camera::common::helper::SamsungCameraModule;
class CameraProvider : public BnCameraProvider, protected camera_module_callbacks_t {
public:
CameraProvider();
~CameraProvider() override;
// Caller must use this method to check if CameraProvider ctor failed
bool isInitFailed() { return mInitFailed; }
ndk::ScopedAStatus setCallback(
const std::shared_ptr<ICameraProviderCallback>& in_callback) override;
ndk::ScopedAStatus getVendorTags(std::vector<VendorTagSection>* _aidl_return) override;
ndk::ScopedAStatus getCameraIdList(std::vector<std::string>* _aidl_return) override;
ndk::ScopedAStatus getCameraDeviceInterface(
const std::string& in_cameraDeviceName,
std::shared_ptr<ICameraDevice>* _aidl_return) override;
ndk::ScopedAStatus notifyDeviceStateChange(int64_t in_deviceState) override;
ndk::ScopedAStatus getConcurrentCameraIds(
std::vector<ConcurrentCameraIdCombination>* _aidl_return) override;
ndk::ScopedAStatus isConcurrentStreamCombinationSupported(
const std::vector<CameraIdAndStreamCombination>& in_configs,
bool* _aidl_return) override;
protected:
Mutex mCbLock;
std::shared_ptr<ICameraProviderCallback> mCallbacks = nullptr;
sp<SamsungCameraModule> mModule;
int mNumberOfLegacyCameras;
std::map<std::string, camera_device_status_t> mCameraStatusMap; // camera id -> status
SortedVector<std::string> mCameraIds; // the "0"/"1" legacy camera Ids
// (cameraId string, hidl device name) pairs
SortedVector<std::pair<std::string, std::string>> mCameraDeviceNames;
// Must be queried before using any APIs.
// APIs will only work when this returns true
bool mInitFailed;
bool initCamera(int id);
bool initialize();
std::vector<VendorTagSection> mVendorTagSections;
bool setUpVendorTags();
int checkCameraVersion(int id, camera_info info);
// create AIDL device name from camera ID
std::string getAidlDeviceName(std::string cameraId);
// static callback forwarding methods
static void sCameraDeviceStatusChange(const struct camera_module_callbacks* callbacks,
int camera_id, int new_status);
static void sTorchModeStatusChange(const struct camera_module_callbacks* callbacks,
const char* camera_id, int new_status);
void addDeviceNames(int camera_id, CameraDeviceStatus status = CameraDeviceStatus::PRESENT,
bool cam_new = false);
void removeDeviceNames(int camera_id);
};
} // namespace implementation
} // namespace provider
} // namespace camera
} // namespace hardware
} // namespace android

View File

@ -1,8 +0,0 @@
service vendor.camera.provider /vendor/bin/hw/android.hardware.camera.provider-service.samsung
interface aidl android.hardware.camera.provider.ICameraProvider/internal/0
class hal
user cameraserver
group audio camera input drmrpc usb
ioprio rt 4
capabilities SYS_NICE
task_profiles CameraServiceCapacity MaxPerformance

View File

@ -1,6 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.camera.provider</name>
<fqname>ICameraProvider/internal/0</fqname>
</hal>
</manifest>

View File

@ -1,8 +0,0 @@
service vendor.camera.provider /vendor/bin/hw/android.hardware.camera.provider-service_32.samsung
interface aidl android.hardware.camera.provider.ICameraProvider/internal/0
class hal
user cameraserver
group audio camera input drmrpc usb
ioprio rt 4
capabilities SYS_NICE
task_profiles CameraServiceCapacity MaxPerformance

View File

@ -1,49 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.camera.provider-service.samsung"
#include "CameraProvider.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <log/log.h>
using ::android::hardware::camera::provider::implementation::CameraProvider;
namespace {
// Default recommended RPC thread count for camera provider implementations
const int HWBINDER_THREAD_COUNT = 6;
} // namespace
int main() {
ALOGI("CameraProvider: samsung service is starting.");
ABinderProcess_setThreadPoolMaxThreadCount(HWBINDER_THREAD_COUNT);
std::shared_ptr<CameraProvider> defaultProvider = ndk::SharedRefBase::make<CameraProvider>();
const std::string serviceName = std::string(CameraProvider::descriptor) + "/internal/0";
binder_exception_t ret =
AServiceManager_addService(defaultProvider->asBinder().get(), serviceName.c_str());
LOG_ALWAYS_FATAL_IF(ret != EX_NONE, "Error while registering camera provider service: %d",
ret);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@ -1,37 +0,0 @@
//
// Copyright (C) 2024 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "android.hardware.biometrics.fingerprint-service.samsung",
relative_install_path: "hw",
init_rc: ["android.hardware.biometrics.fingerprint-service.samsung.rc"],
vintf_fragments: ["android.hardware.biometrics.fingerprint-service.samsung.xml"],
srcs: [
"CancellationSignal.cpp",
"Fingerprint.cpp",
"LegacyHAL.cpp",
"LockoutTracker.cpp",
"Session.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"libhardware",
"android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.util",
],
static_libs: ["libandroid.hardware.biometrics.fingerprint.SamsungProps"],
vendor: true,
}
sysprop_library {
name: "android.hardware.biometrics.fingerprint.SamsungProps",
srcs: ["fingerprint.sysprop"],
property_owner: "Vendor",
vendor: true,
}

View File

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

View File

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

View File

@ -1,232 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Fingerprint.h"
#include "VendorConstants.h"
#include <fingerprint.sysprop.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <fcntl.h>
#include <linux/uinput.h>
using namespace ::android::fingerprint::samsung;
using ::android::base::ParseInt;
using ::android::base::Split;
namespace aidl {
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
namespace {
constexpr int SENSOR_ID = 0;
constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG;
constexpr int MAX_ENROLLMENTS_PER_USER = 4;
constexpr bool SUPPORTS_NAVIGATION_GESTURES = false;
constexpr char HW_COMPONENT_ID[] = "fingerprintSensor";
constexpr char HW_VERSION[] = "vendor/model/revision";
constexpr char FW_VERSION[] = "1.01";
constexpr char SERIAL_NUMBER[] = "00000001";
constexpr char SW_COMPONENT_ID[] = "matchingAlgorithm";
constexpr char SW_VERSION[] = "vendor/version/revision";
}
static Fingerprint* sInstance;
Fingerprint::Fingerprint() {
sInstance = this; // keep track of the most recent instance
if (!mHal.openHal(Fingerprint::notify)) {
LOG(ERROR) << "Can't open HAL module";
}
std::string sensorTypeProp = FingerprintHalProperties::type().value_or("");
if (sensorTypeProp == "" || sensorTypeProp == "default" || sensorTypeProp == "rear")
mSensorType = FingerprintSensorType::REAR;
else if (sensorTypeProp == "udfps")
mSensorType = FingerprintSensorType::UNDER_DISPLAY_ULTRASONIC;
else if (sensorTypeProp == "udfps_optical")
mSensorType = FingerprintSensorType::UNDER_DISPLAY_OPTICAL;
else if (sensorTypeProp == "side")
mSensorType = FingerprintSensorType::POWER_BUTTON;
else if (sensorTypeProp == "home")
mSensorType = FingerprintSensorType::HOME_BUTTON;
else
mSensorType = FingerprintSensorType::UNKNOWN;
mMaxEnrollmentsPerUser =
FingerprintHalProperties::max_enrollments_per_user().value_or(MAX_ENROLLMENTS_PER_USER);
mSupportsGestures =
FingerprintHalProperties::supports_gestures().value_or(SUPPORTS_NAVIGATION_GESTURES);
if (mSupportsGestures) {
mHal.request(FINGERPRINT_REQUEST_NAVIGATION_MODE_START, 1);
uinputFd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (uinputFd < 0) {
LOG(ERROR) << "Unable to open uinput node";
goto skip_uinput_setup;
}
int err = ioctl(uinputFd, UI_SET_EVBIT, EV_KEY) |
ioctl(uinputFd, UI_SET_KEYBIT, KEY_UP) |
ioctl(uinputFd, UI_SET_KEYBIT, KEY_DOWN);
if (err != 0) {
LOG(ERROR) << "Unable to enable key events";
goto skip_uinput_setup;
}
struct uinput_user_dev uidev;
sprintf(uidev.name, "uinput-sec-fp");
uidev.id.bustype = BUS_VIRTUAL;
err = write(uinputFd, &uidev, sizeof(uidev));
if (err < 0) {
LOG(ERROR) << "Write user device to uinput node failed";
goto skip_uinput_setup;
}
err = ioctl(uinputFd, UI_DEV_CREATE);
if (err < 0) {
LOG(ERROR) << "Unable to create uinput device";
goto skip_uinput_setup;
}
LOG(INFO) << "Successfully registered uinput-sec-fp for fingerprint gestures";
}
skip_uinput_setup:
return;
}
ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
std::vector<common::ComponentInfo> componentInfo = {
{HW_COMPONENT_ID, HW_VERSION, FW_VERSION, SERIAL_NUMBER, "" /* softwareVersion */},
{SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
"" /* serialNumber */, SW_VERSION}};
common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH,
mMaxEnrollmentsPerUser, componentInfo};
SensorLocation sensorLocation;
std::string loc = FingerprintHalProperties::sensor_location().value_or("");
std::vector<std::string> dim = Split(loc, "|");
if (dim.size() >= 3 && dim.size() <= 4) {
ParseInt(dim[0], &sensorLocation.sensorLocationX);
ParseInt(dim[1], &sensorLocation.sensorLocationY);
ParseInt(dim[2], &sensorLocation.sensorRadius);
if (dim.size() >= 4)
sensorLocation.display = dim[3];
} else if(loc.length() > 0) {
LOG(WARNING) << "Invalid sensor location input (x|y|radius|display): " << loc;
}
LOG(INFO) << "Sensor type: " << ::android::internal::ToString(mSensorType)
<< " location: " << sensorLocation.toString();
*out = {{commonProps,
mSensorType,
{sensorLocation},
mSupportsGestures,
false,
false,
false,
std::nullopt}};
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* out) {
CHECK(mSession == nullptr || mSession->isClosed()) << "Open session already exists!";
mSession = SharedRefBase::make<Session>(mHal, userId, cb, mLockoutTracker);
*out = mSession;
mSession->linkToDeath(cb->asBinder().get());
return ndk::ScopedAStatus::ok();
}
void Fingerprint::notify(const fingerprint_msg_t* msg) {
Fingerprint* thisPtr = sInstance;
if (msg->type == FINGERPRINT_ACQUIRED
&& msg->data.acquired.acquired_info > SEM_FINGERPRINT_EVENT_BASE) {
thisPtr->handleEvent(msg->data.acquired.acquired_info);
return;
}
if (thisPtr->mSession == nullptr || thisPtr->mSession->isClosed()) {
LOG(ERROR) << "Receiving callbacks before a session is opened.";
return;
}
thisPtr->mSession->notify(msg);
}
void Fingerprint::handleEvent(int eventCode) {
switch (eventCode) {
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN:
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP: {
if (!mSupportsGestures) return;
struct input_event event {};
int keycode = eventCode == SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP ?
KEY_UP : KEY_DOWN;
// Report the key
event.type = EV_KEY;
event.code = keycode;
event.value = 1;
if (write(uinputFd, &event, sizeof(event)) < 0) {
LOG(ERROR) << "Write EV_KEY to uinput node failed";
return;
}
// Force a flush with an EV_SYN
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
if (write(uinputFd, &event, sizeof(event)) < 0) {
LOG(ERROR) << "Write EV_SYN to uinput node failed";
return;
}
// Report the key
event.type = EV_KEY;
event.code = keycode;
event.value = 0;
if (write(uinputFd, &event, sizeof(event)) < 0) {
LOG(ERROR) << "Write EV_KEY to uinput node failed";
return;
}
// Force a flush with an EV_SYN
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
if (write(uinputFd, &event, sizeof(event)) < 0) {
LOG(ERROR) << "Write EV_SYN to uinput node failed";
return;
}
} break;
case SEM_FINGERPRINT_EVENT_CAPTURE_READY: {
if (mSession != nullptr && !mSession->isClosed()) {
mSession->onCaptureReady();
}
} break;
}
}
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,52 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/biometrics/fingerprint/BnFingerprint.h>
#include "LegacyHAL.h"
#include "LockoutTracker.h"
#include "Session.h"
using ::aidl::android::hardware::biometrics::fingerprint::ISession;
using ::aidl::android::hardware::biometrics::fingerprint::ISessionCallback;
using ::aidl::android::hardware::biometrics::fingerprint::SensorProps;
namespace aidl {
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
class Fingerprint : public BnFingerprint {
public:
Fingerprint();
ndk::ScopedAStatus getSensorProps(std::vector<SensorProps>* _aidl_return) override;
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* out) override;
private:
static void notify(
const fingerprint_msg_t* msg); /* Static callback for legacy HAL implementation */
void handleEvent(int eventCode);
LegacyHAL mHal;
LockoutTracker mLockoutTracker;
FingerprintSensorType mSensorType;
int mMaxEnrollmentsPerUser;
bool mSupportsGestures;
int uinputFd;
std::shared_ptr<Session> mSession;
};
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
} // namespace aidl

View File

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

View File

@ -1,83 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "Fingerprint.h"
#include <android-base/logging.h>
#include <dlfcn.h>
namespace aidl {
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
bool LegacyHAL::openHal(fingerprint_notify_t notify) {
void* handle = dlopen("libbauthserver.so", RTLD_NOW);
if (!handle)
handle = dlopen("libsfp_sensor.so", RTLD_NOW);
if (handle) {
int err;
ss_fingerprint_close =
reinterpret_cast<typeof(ss_fingerprint_close)>(dlsym(handle, "ss_fingerprint_close"));
ss_fingerprint_open =
reinterpret_cast<typeof(ss_fingerprint_open)>(dlsym(handle, "ss_fingerprint_open"));
ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>(
dlsym(handle, "ss_set_notify_callback"));
ss_fingerprint_pre_enroll = reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>(
dlsym(handle, "ss_fingerprint_pre_enroll"));
ss_fingerprint_enroll =
reinterpret_cast<typeof(ss_fingerprint_enroll)>(dlsym(handle, "ss_fingerprint_enroll"));
ss_fingerprint_post_enroll = reinterpret_cast<typeof(ss_fingerprint_post_enroll)>(
dlsym(handle, "ss_fingerprint_post_enroll"));
ss_fingerprint_get_auth_id = reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>(
dlsym(handle, "ss_fingerprint_get_auth_id"));
ss_fingerprint_cancel =
reinterpret_cast<typeof(ss_fingerprint_cancel)>(dlsym(handle, "ss_fingerprint_cancel"));
ss_fingerprint_enumerate = reinterpret_cast<typeof(ss_fingerprint_enumerate)>(
dlsym(handle, "ss_fingerprint_enumerate"));
ss_fingerprint_remove =
reinterpret_cast<typeof(ss_fingerprint_remove)>(dlsym(handle, "ss_fingerprint_remove"));
ss_fingerprint_set_active_group = reinterpret_cast<typeof(ss_fingerprint_set_active_group)>(
dlsym(handle, "ss_fingerprint_set_active_group"));
ss_fingerprint_authenticate = reinterpret_cast<typeof(ss_fingerprint_authenticate)>(
dlsym(handle, "ss_fingerprint_authenticate"));
ss_fingerprint_request = reinterpret_cast<typeof(ss_fingerprint_request)>(
dlsym(handle, "ss_fingerprint_request"));
if ((err = ss_fingerprint_open(nullptr)) != 0) {
LOG(ERROR) << "Can't open fingerprint, error: " << err;
return false;
}
if ((err = ss_set_notify_callback(notify)) != 0) {
LOG(ERROR) << "Can't register fingerprint module callback, error: " << err;
return false;
}
return true;
}
return false;
}
int LegacyHAL::request(int cmd, int param) {
// TO-DO: input, output handling not implemented
int result = ss_fingerprint_request(cmd, nullptr, 0, nullptr, 0, param);
LOG(INFO) << "request(cmd=" << cmd << ", param=" << param << ", result=" << result << ")";
return result;
}
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,42 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <hardware/fingerprint.h>
namespace aidl {
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
class LegacyHAL {
public:
bool openHal(fingerprint_notify_t notify);
int request(int cmd, int param);
int (*ss_fingerprint_close)();
int (*ss_fingerprint_open)(const char* id);
int (*ss_set_notify_callback)(fingerprint_notify_t notify);
uint64_t (*ss_fingerprint_pre_enroll)();
int (*ss_fingerprint_enroll)(const hw_auth_token_t* hat, uint32_t gid, uint32_t timeout_sec);
int (*ss_fingerprint_post_enroll)();
uint64_t (*ss_fingerprint_get_auth_id)();
int (*ss_fingerprint_cancel)();
int (*ss_fingerprint_enumerate)();
int (*ss_fingerprint_remove)(uint32_t gid, uint32_t fid);
int (*ss_fingerprint_set_active_group)(uint32_t gid, const char* store_path);
int (*ss_fingerprint_authenticate)(uint64_t operation_id, uint32_t gid);
int (*ss_fingerprint_request)(uint32_t cmd, char *inBuf, uint32_t inBuf_length, char *outBuf, uint32_t outBuf_length, uint32_t param);
};
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
} // namespace aidl

View File

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

View File

@ -1,42 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
namespace aidl {
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
#define LOCKOUT_TIMED_THRESHOLD 5
#define LOCKOUT_TIMED_DURATION 30 * 1000
#define LOCKOUT_PERMANENT_THRESHOLD 20
enum class LockoutMode {
NONE,
TIMED,
PERMANENT
};
class LockoutTracker {
public:
void reset(bool clearAttemptCounter);
LockoutMode getMode();
void addFailedAttempt();
int64_t getLockoutTimeLeft();
private:
int32_t mFailedCount = 0;
int64_t mLockoutTimedStart;
LockoutMode mCurrentMode;
};
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,465 +0,0 @@
/*
* Copyright (C) 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "CancellationSignal.h"
#include "Legacy2Aidl.h"
#include "Session.h"
#include "VendorConstants.h"
#include <fingerprint.sysprop.h>
#include <android-base/logging.h>
#include <dirent.h>
#include <endian.h>
#include <thread>
using namespace ::android::fingerprint::samsung;
using namespace ::std::chrono_literals;
namespace aidl {
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
void onClientDeath(void* cookie) {
LOG(INFO) << "FingerprintService has died";
Session* session = static_cast<Session*>(cookie);
if (session && !session->isClosed()) {
session->close();
}
}
Session::Session(LegacyHAL hal, int userId, std::shared_ptr<ISessionCallback> cb,
LockoutTracker lockoutTracker)
: mHal(hal),
mLockoutTracker(lockoutTracker),
mUserId(userId),
mCb(cb) {
mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
char filename[64];
snprintf(filename, sizeof(filename), FINGERPRINT_DATA_DIR, userId);
mHal.ss_fingerprint_set_active_group(userId, filename);
}
ndk::ScopedAStatus Session::generateChallenge() {
LOG(INFO) << "generateChallenge";
uint64_t challenge = mHal.ss_fingerprint_pre_enroll();
mCb->onChallengeGenerated(challenge);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) {
LOG(INFO) << "revokeChallenge";
mHal.ss_fingerprint_post_enroll();
mCb->onChallengeRevoked(challenge);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::enroll(const HardwareAuthToken& hat,
std::shared_ptr<ICancellationSignal>* out) {
LOG(INFO) << "enroll";
if (FingerprintHalProperties::force_calibrate().value_or(false)) {
mCaptureReady = false;
mHal.request(SEM_REQUEST_FORCE_CBGE, 1);
}
hw_auth_token_t authToken;
translate(hat, authToken);
int32_t error = mHal.ss_fingerprint_enroll(&authToken, mUserId, 0 /* timeoutSec */);
if (error) {
LOG(ERROR) << "ss_fingerprint_enroll failed: " << error;
mCb->onError(Error::UNABLE_TO_PROCESS, error);
}
if (FingerprintHalProperties::force_calibrate().value_or(false)) {
while (!mCaptureReady) {
std::this_thread::sleep_for(100ms);
}
}
*out = SharedRefBase::make<CancellationSignal>(this);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::authenticate(int64_t operationId,
std::shared_ptr<ICancellationSignal>* out) {
LOG(INFO) << "authenticate";
int32_t error = mHal.ss_fingerprint_authenticate(operationId, mUserId);
if (error) {
LOG(ERROR) << "ss_fingerprint_authenticate failed: " << error;
mCb->onError(Error::UNABLE_TO_PROCESS, error);
}
*out = SharedRefBase::make<CancellationSignal>(this);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::detectInteraction(std::shared_ptr<ICancellationSignal>* out) {
LOG(INFO) << "detectInteraction";
LOG(DEBUG) << "Detect interaction is not supported";
mCb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
*out = SharedRefBase::make<CancellationSignal>(this);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::enumerateEnrollments() {
LOG(INFO) << "enumerateEnrollments";
if (mHal.ss_fingerprint_enumerate) {
int32_t error = mHal.ss_fingerprint_enumerate();
if (error)
LOG(ERROR) << "ss_fingerprint_enumerate failed: " << error;
} else {
std::vector<int> enrollments;
char filename[64];
snprintf(filename, sizeof(filename), FINGERPRINT_DATA_DIR, mUserId);
DIR* directory = opendir(filename);
if (directory) {
struct dirent* entry;
while ((entry = readdir(directory))) {
int uid, fid;
if (sscanf(entry->d_name, "User_%d_%dtmpl.dat", &uid, &fid)) {
if (uid == mUserId)
enrollments.push_back(fid);
}
}
closedir(directory);
} else {
LOG(WARNING) << "Failed to open " << filename;
}
mCb->onEnrollmentsEnumerated(enrollments);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
LOG(INFO) << "removeEnrollments, size: " << enrollmentIds.size();
for (int32_t enrollment : enrollmentIds) {
int32_t error = mHal.ss_fingerprint_remove(mUserId, enrollment);
if (error)
LOG(ERROR) << "ss_fingerprint_remove failed: " << error;
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::getAuthenticatorId() {
LOG(INFO) << "getAuthenticatorId";
mCb->onAuthenticatorIdRetrieved(mHal.ss_fingerprint_get_auth_id());
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
LOG(INFO) << "invalidateAuthenticatorId";
mCb->onAuthenticatorIdInvalidated(mHal.ss_fingerprint_get_auth_id());
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::resetLockout(const HardwareAuthToken& /*hat*/) {
LOG(INFO) << "resetLockout";
clearLockout(true);
mIsLockoutTimerAborted = true;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::close() {
LOG(INFO) << "close";
mClosed = true;
mCb->onSessionClosed();
AIBinder_DeathRecipient_delete(mDeathRecipient);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/, float /*minor*/,
float /*major*/) {
LOG(INFO) << "onPointerDown";
if (FingerprintHalProperties::request_touch_event().value_or(false)) {
mHal.request(SEM_REQUEST_TOUCH_EVENT, 2);
}
checkSensorLockout();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) {
LOG(INFO) << "onPointerUp";
if (FingerprintHalProperties::request_touch_event().value_or(false)) {
mHal.request(SEM_REQUEST_TOUCH_EVENT, 1);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onUiReady() {
LOG(INFO) << "onUiReady";
// TODO: stub
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::authenticateWithContext(
int64_t operationId, const OperationContext& /*context*/,
std::shared_ptr<ICancellationSignal>* out) {
return authenticate(operationId, out);
}
ndk::ScopedAStatus Session::enrollWithContext(const HardwareAuthToken& hat,
const OperationContext& /*context*/,
std::shared_ptr<ICancellationSignal>* out) {
return enroll(hat, out);
}
ndk::ScopedAStatus Session::detectInteractionWithContext(const OperationContext& /*context*/,
std::shared_ptr<ICancellationSignal>* out) {
return detectInteraction(out);
}
ndk::ScopedAStatus Session::onPointerDownWithContext(const PointerContext& context) {
return onPointerDown(context.pointerId, context.x, context.y, context.minor, context.major);
}
ndk::ScopedAStatus Session::onPointerUpWithContext(const PointerContext& context) {
return onPointerUp(context.pointerId);
}
ndk::ScopedAStatus Session::onContextChanged(const OperationContext& /*context*/) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onPointerCancelWithContext(const PointerContext& /*context*/) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::setIgnoreDisplayTouches(bool /*shouldIgnore*/) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::cancel() {
int32_t ret = mHal.ss_fingerprint_cancel();
if (ret == 0) {
mCb->onError(Error::CANCELED, 0 /* vendorCode */);
return ndk::ScopedAStatus::ok();
} else {
return ndk::ScopedAStatus::fromServiceSpecificError(ret);
}
}
binder_status_t Session::linkToDeath(AIBinder* binder) {
return AIBinder_linkToDeath(binder, mDeathRecipient, this);
}
bool Session::isClosed() {
return mClosed;
}
// Translate from errors returned by traditional HAL (see fingerprint.h) to
// AIDL-compliant Error
Error Session::VendorErrorFilter(int32_t error, int32_t* vendorCode) {
*vendorCode = 0;
switch (error) {
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
return Error::HW_UNAVAILABLE;
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
return Error::UNABLE_TO_PROCESS;
case FINGERPRINT_ERROR_TIMEOUT:
return Error::TIMEOUT;
case FINGERPRINT_ERROR_NO_SPACE:
return Error::NO_SPACE;
case FINGERPRINT_ERROR_CANCELED:
return Error::CANCELED;
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
return Error::UNABLE_TO_REMOVE;
case FINGERPRINT_ERROR_LOCKOUT: {
*vendorCode = FINGERPRINT_ERROR_LOCKOUT;
return Error::VENDOR;
}
default:
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
// vendor specific code.
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
return Error::VENDOR;
}
}
LOG(ERROR) << "Unknown error from fingerprint vendor library: " << error;
return Error::UNABLE_TO_PROCESS;
}
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
// to AIDL-compliant AcquiredInfo
AcquiredInfo Session::VendorAcquiredFilter(int32_t info, int32_t* vendorCode) {
*vendorCode = 0;
switch (info) {
case FINGERPRINT_ACQUIRED_GOOD:
return AcquiredInfo::GOOD;
case FINGERPRINT_ACQUIRED_PARTIAL:
return AcquiredInfo::PARTIAL;
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
return AcquiredInfo::INSUFFICIENT;
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
return AcquiredInfo::SENSOR_DIRTY;
case FINGERPRINT_ACQUIRED_TOO_SLOW:
return AcquiredInfo::TOO_SLOW;
case FINGERPRINT_ACQUIRED_TOO_FAST:
return AcquiredInfo::TOO_FAST;
default:
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
// vendor specific code.
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
return AcquiredInfo::VENDOR;
}
}
LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info;
return AcquiredInfo::INSUFFICIENT;
}
bool Session::checkSensorLockout() {
LockoutMode lockoutMode = mLockoutTracker.getMode();
if (lockoutMode == LockoutMode::PERMANENT) {
LOG(ERROR) << "Fail: lockout permanent";
mCb->onLockoutPermanent();
mIsLockoutTimerAborted = true;
return true;
} else if (lockoutMode == LockoutMode::TIMED) {
int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
LOG(ERROR) << "Fail: lockout timed " << timeLeft;
mCb->onLockoutTimed(timeLeft);
if (!mIsLockoutTimerStarted) startLockoutTimer(timeLeft);
return true;
}
return false;
}
void Session::clearLockout(bool clearAttemptCounter) {
mLockoutTracker.reset(clearAttemptCounter);
mCb->onLockoutCleared();
}
void Session::startLockoutTimer(int64_t timeout) {
mIsLockoutTimerAborted = false;
std::function<void()> action =
std::bind(&Session::lockoutTimerExpired, this);
std::thread([timeout, action]() {
std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
action();
}).detach();
mIsLockoutTimerStarted = true;
}
void Session::lockoutTimerExpired() {
if (!mIsLockoutTimerAborted)
clearLockout(false);
mIsLockoutTimerStarted = false;
mIsLockoutTimerAborted = false;
}
void Session::notify(const fingerprint_msg_t* msg) {
switch (msg->type) {
case FINGERPRINT_ERROR: {
int32_t vendorCode = 0;
Error result = VendorErrorFilter(msg->data.error, &vendorCode);
LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")";
mCb->onError(result, vendorCode);
} break;
case FINGERPRINT_ACQUIRED: {
int32_t vendorCode = 0;
AcquiredInfo result =
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")";
mCb->onAcquired(result, vendorCode);
} break;
case FINGERPRINT_TEMPLATE_ENROLLING:
if (FingerprintHalProperties::uses_percentage_samples().value_or(false)) {
const_cast<fingerprint_msg_t*>(msg)->data.enroll.samples_remaining =
100 - msg->data.enroll.samples_remaining;
}
if (FingerprintHalProperties::cancel_on_enroll_completion().value_or(false)) {
if (msg->data.enroll.samples_remaining == 0)
mHal.ss_fingerprint_cancel();
}
LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid
<< ", gid=" << msg->data.enroll.finger.gid
<< ", rem=" << msg->data.enroll.samples_remaining << ")";
mCb->onEnrollmentProgress(msg->data.enroll.finger.fid,
msg->data.enroll.samples_remaining);
break;
case FINGERPRINT_TEMPLATE_REMOVED: {
LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid
<< ", gid=" << msg->data.removed.finger.gid
<< ", rem=" << msg->data.removed.remaining_templates << ")";
std::vector<int> enrollments;
enrollments.push_back(msg->data.removed.finger.fid);
mCb->onEnrollmentsRemoved(enrollments);
} break;
case FINGERPRINT_AUTHENTICATED: {
LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid
<< ", gid=" << msg->data.authenticated.finger.gid << ")";
if (msg->data.authenticated.finger.fid != 0) {
const hw_auth_token_t hat = msg->data.authenticated.hat;
HardwareAuthToken authToken;
translate(hat, authToken);
mCb->onAuthenticationSucceeded(msg->data.authenticated.finger.fid, authToken);
mLockoutTracker.reset(true);
} else {
mCb->onAuthenticationFailed();
mLockoutTracker.addFailedAttempt();
checkSensorLockout();
}
} break;
case FINGERPRINT_TEMPLATE_ENUMERATING: {
LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid
<< ", gid=" << msg->data.enumerated.finger.gid
<< ", rem=" << msg->data.enumerated.remaining_templates << ")";
static std::vector<int> enrollments;
enrollments.push_back(msg->data.enumerated.finger.fid);
if (msg->data.enumerated.remaining_templates == 0) {
mCb->onEnrollmentsEnumerated(enrollments);
enrollments.clear();
}
} break;
}
}
void Session::onCaptureReady() {
mCaptureReady = true;
}
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
} // namespace aidl

View File

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

View File

@ -1,101 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2020 The LineageOS Project
#pragma once
// Fingerprint requests
#define FINGERPRINT_REQUEST_ENROLL_SESSION 1002
#define FINGERPRINT_REQUEST_ENROLL_TYPE 18
#define FINGERPRINT_REQUEST_ENUMERATE 11
#define FINGERPRINT_REQUEST_GET_FP_IDS 1003
#define FINGERPRINT_REQUEST_GET_MAX_TEMPLATE_NUMBER 1004
#define FINGERPRINT_REQUEST_GET_SENSOR_INFO 5
#define FINGERPRINT_REQUEST_GET_SENSOR_STATUS 6
#define FINGERPRINT_REQUEST_GET_TOUCH_CNT 1007
#define FINGERPRINT_REQUEST_GET_UNIQUE_ID 7
#define FINGERPRINT_REQUEST_GET_USERIDS 12
#define FINGERPRINT_REQUEST_GET_VERSION 4
#define FINGERPRINT_REQUEST_HAS_FEATURE 1006
#define FINGERPRINT_REQUEST_LOCKOUT 1001
#define FINGERPRINT_REQUEST_NAVIGATION_LCD_ONOFF 17
#define FINGERPRINT_REQUEST_NAVIGATION_MODE_END 16
#define FINGERPRINT_REQUEST_NAVIGATION_MODE_START 15
#define FINGERPRINT_REQUEST_PAUSE 0
#define FINGERPRINT_REQUEST_PROCESS_FIDO 9
#define FINGERPRINT_REQUEST_REMOVE_FINGER 1000
#define FINGERPRINT_REQUEST_RESUME 1
#define FINGERPRINT_REQUEST_SENSOR_TEST_NORMALSCAN 3
#define FINGERPRINT_REQUEST_SESSION_OPEN 2
#define FINGERPRINT_REQUEST_SET_ACTIVE_GROUP 8
#define FINGERPRINT_REQUEST_UPDATE_SID 10
#define SEM_REQUEST_FORCE_CBGE 21
#define SEM_REQUEST_GET_FINGER_ICON_REMAIN_TIME 1010
#define SEM_REQUEST_GET_SECURITY_LEVEL 30
#define SEM_REQUEST_GET_SENSOR_TEST_RESULT 19
#define SEM_REQUEST_GET_TA_VERSION 10000
#define SEM_REQUEST_GET_TSP_BLOCK_STATUS 0x3F9
#define SEM_REQUEST_HIDE_INDISPLAY_AUTH_ANIMATION 0x3F4
#define SEM_REQUEST_INSTALL_TA 10001
#define SEM_REQUEST_IS_NEW_MATCHER 27
#define SEM_REQUEST_IS_TEMPLATE_CHANGED 25
#define SEM_REQUEST_MASK_CTL 0x3F5
#define SEM_REQUEST_MOVE_INDISPLAY_ICON 0x3F3
#define SEM_REQUEST_OPTICAL_CALIBRATION 0x3F8
#define SEM_REQUEST_REMOVE_ALL_USER 0x3F6
#define SEM_REQUEST_SET_ASP_LEVEL 20
#define SEM_REQUEST_SET_BOUNCER_SCREEN_STATUS 0x3FA
#define SEM_REQUEST_SET_SCREEN_STATUS 0x3F0
#define SEM_REQUEST_SHOW_INDISPLAY_AUTH_ANIMATION 1009
#define SEM_REQUEST_TOUCH_EVENT 22
#define SEM_REQUEST_TOUCH_SENSITIVE_CHANGE 0x3F7
#define SEM_REQUEST_UPDATE_MATCHER 28
#define SEM_REQUEST_VENDOR_EGIS_CALIBRATION 23
#define SEM_REQUEST_VENDOR_QCOM_REMOVE_CBGE 24
#define SEM_REQUEST_WIRELESS_CHARGER_STATUS 29
// Fingerprint aquired codes
#define SEM_FINGERPRINT_ACQUIRED_DUPLICATED_IMAGE 1002
#define SEM_FINGERPRINT_ACQUIRED_LIGHT_TOUCH 1003
#define SEM_FINGERPRINT_ACQUIRED_TSP_BLOCK 1004
#define SEM_FINGERPRINT_ACQUIRED_TSP_UNBLOCK 1005
#define SEM_FINGERPRINT_ACQUIRED_WET_FINGER 1001
// Fingerprint errors
#define SEM_FINGERPRINT_ERROR_CALIBRATION 1001
#define SEM_FINGERPRINT_ERROR_DISABLED_BIOMETRICS 5002
#define SEM_FINGERPRINT_ERROR_INVALID_HW 1005
#define SEM_FINGERPRINT_ERROR_NEED_TO_RETRY 5000
#define SEM_FINGERPRINT_ERROR_ONE_HAND_MODE 5001
#define SEM_FINGERPRINT_ERROR_PATTERN_DETECTED 1007
#define SEM_FINGERPRINT_ERROR_SERVICE_FAILURE 1003
#define SEM_FINGERPRINT_ERROR_SMART_VIEW 5003
#define SEM_FINGERPRINT_ERROR_SYSTEM_FAILURE 1002
#define SEM_FINGERPRINT_ERROR_TA_UPDATE -100
#define SEM_FINGERPRINT_ERROR_TEMPLATE_CORRUPTED 1004
#define SEM_FINGERPRINT_ERROR_TEMPLATE_FORMAT_CHANGED 1006
#define SEM_FINGERPRINT_ERROR_WIRELESS_CHARGING 5004
// Fingerprint events
#define SEM_FINGERPRINT_EVENT_BASE 10000
#define SEM_FINGERPRINT_EVENT_CAPTURE_COMPLETED 10003
#define SEM_FINGERPRINT_EVENT_CAPTURE_FAILED 10006
#define SEM_FINGERPRINT_EVENT_CAPTURE_READY 10001
#define SEM_FINGERPRINT_EVENT_CAPTURE_STARTED 10002
#define SEM_FINGERPRINT_EVENT_CAPTURE_SUCCESS 10005
#define SEM_FINGERPRINT_EVENT_FACTORY_SNSR_SCRIPT_END 10009
#define SEM_FINGERPRINT_EVENT_FACTORY_SNSR_SCRIPT_START 10008
#define SEM_FINGERPRINT_EVENT_FINGER_LEAVE 10004
#define SEM_FINGERPRINT_EVENT_FINGER_LEAVE_TIMEOUT 10007
#define SEM_FINGERPRINT_EVENT_GESTURE_DTAP 20003
#define SEM_FINGERPRINT_EVENT_GESTURE_LPRESS 20004
#define SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN 20002
#define SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP 20001
#define SEM_FINGERPRINT_EVENT_SPEN_CONTROL_OFF 30002
#define SEM_FINGERPRINT_EVENT_SPEN_CONTROL_ON 30001
// Fingerprint sensor status codes
#define SEM_SENSOR_STATUS_CALIBRATION_ERROR 100045
#define SEM_SENSOR_STATUS_ERROR 100042
#define SEM_SENSOR_STATUS_OK 100040
#define SEM_SENSOR_STATUS_WORKING 100041

View File

@ -1,5 +0,0 @@
service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.samsung
class hal
user system
group system input uhid
shutdown critical

View File

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

View File

@ -1,78 +0,0 @@
# fingerprint.sysprop
# module becomes static class (Java) / namespace (C++) for serving API
module: "android.fingerprint.samsung.FingerprintHalProperties"
owner: Vendor
# type of fingerprint sensor
prop {
prop_name: "ro.vendor.fingerprint.type"
type: String
scope: Internal
access: Readonly
enum_values: "default|rear|udfps|udfps_optical|side|home"
api_name: "type"
}
# max enrollments per user (default: 4)
prop {
prop_name: "ro.vendor.fingerprint.max_enrollments"
type: Integer
scope: Internal
access: Readonly
api_name: "max_enrollments_per_user"
}
# supports navigation gestures
prop {
prop_name: "ro.vendor.fingerprint.supports_gestures"
type: Boolean
scope: Internal
access: Readonly
api_name: "supports_gestures"
}
# sensor location
# <x>|<y>|<radius>|display in pixel
prop {
prop_name: "ro.vendor.fingerprint.sensor_location"
type: String
scope: Internal
access: Readonly
api_name: "sensor_location"
}
# force calibration on enroll
prop {
prop_name: "ro.vendor.fingerprint.force_calibrate"
type: Boolean
scope: Internal
access: Readonly
api_name: "force_calibrate"
}
# send touch events to HAL
prop {
prop_name: "ro.vendor.fingerprint.request_touch_event"
type: Boolean
scope: Internal
access: Readonly
api_name: "request_touch_event"
}
# uses percentage samples
prop {
prop_name: "ro.vendor.fingerprint.uses_percentage_samples"
type: Boolean
scope: Internal
access: Readonly
api_name: "uses_percentage_samples"
}
# cancel on completed enrollment
prop {
prop_name: "ro.vendor.fingerprint.cancel_on_enroll_completion"
type: Boolean
scope: Internal
access: Readonly
api_name: "cancel_on_enroll_completion"
}

View File

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

View File

@ -1,47 +0,0 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
cc_defaults {
name: "android.hardware.health-service.samsung-defaults",
defaults: [
"libhealth_aidl_impl_user",
"libhealth_aidl_charger_defaults",
],
relative_install_path: "hw",
vintf_fragments: ["android.hardware.health-service.samsung.xml"],
srcs: [
"Health.cpp",
],
static_libs: [
"libhealth_aidl_impl",
],
}
cc_binary {
name: "android.hardware.health-service.samsung",
defaults: ["android.hardware.health-service.samsung-defaults"],
vendor: true,
init_rc: ["android.hardware.health-service.samsung.rc"],
overrides: ["charger"],
}
cc_binary {
name: "android.hardware.health-service.samsung-recovery",
defaults: ["android.hardware.health-service.samsung-defaults"],
recovery: true,
init_rc: ["android.hardware.health-service.samsung-recovery.rc"],
overrides: ["charger.recovery"],
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android-base/logging.h>
#include <android/binder_interface_utils.h>
#include <health-impl/Health.h>
#include <health/utils.h>
#ifndef CHARGER_FORCE_NO_UI
#define CHARGER_FORCE_NO_UI 0
#endif
#if !CHARGER_FORCE_NO_UI
#include <health-impl/ChargerUtils.h>
#endif
using aidl::android::hardware::health::HalHealthLoop;
using aidl::android::hardware::health::Health;
#if !CHARGER_FORCE_NO_UI
using aidl::android::hardware::health::charger::ChargerCallback;
using aidl::android::hardware::health::charger::ChargerModeMain;
#endif
static constexpr const char* gInstanceName = "default";
static constexpr std::string_view gChargerArg{"--charger"};
#if !CHARGER_FORCE_NO_UI
namespace aidl::android::hardware::health {
class ChargerCallbackImpl : public ChargerCallback {
public:
using ChargerCallback::ChargerCallback;
bool ChargerEnableSuspend() override { return true; }
};
} // namespace aidl::android::hardware::health
#endif
int main(int argc, char** argv) {
#ifdef __ANDROID_RECOVERY__
android::base::InitLogging(argv, android::base::KernelLogger);
#endif
// make a default health service
auto config = std::make_unique<healthd_config>();
::android::hardware::health::InitHealthdConfig(config.get());
auto binder = ndk::SharedRefBase::make<Health>(gInstanceName, std::move(config));
if (argc >= 2 && argv[1] == gChargerArg) {
#if !CHARGER_FORCE_NO_UI
// If charger shouldn't have UI for your device, simply drop the line below
// for your service implementation. This corresponds to
// ro.charger.no_ui=true
return ChargerModeMain(binder, std::make_shared<aidl::android::hardware::health::ChargerCallbackImpl>(binder));
#endif
LOG(INFO) << "Starting charger mode without UI.";
} else {
LOG(INFO) << "Starting health HAL.";
}
auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
return hal_health_loop->StartLoop();
}

View File

@ -1,7 +0,0 @@
service vendor.health-samsung /system/bin/hw/android.hardware.health-service.samsung-recovery
class hal
seclabel u:r:hal_health_default:s0
user system
group system
capabilities WAKE_ALARM BLOCK_SUSPEND
file /dev/kmsg w

View File

@ -1,20 +0,0 @@
service vendor.health-samsung /vendor/bin/hw/android.hardware.health-service.samsung
class hal
user system
group system
capabilities WAKE_ALARM BLOCK_SUSPEND
file /dev/kmsg w
service vendor.charger /vendor/bin/hw/android.hardware.health-service.samsung --charger
class charger
seclabel u:r:charger_vendor:s0
user system
group system wakelock input
capabilities SYS_BOOT
file /dev/kmsg w
file /sys/fs/pstore/console-ramoops-0 r
file /sys/fs/pstore/console-ramoops r
file /proc/last_kmsg r
on charger
chown system system /dev/graphics/fb0

View File

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

View File

@ -1,23 +0,0 @@
//
// Copyright (C) 2021-2024 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "android.hardware.light-service.samsung",
defaults: ["samsung_header_path_defaults"],
relative_install_path: "hw",
init_rc: ["android.hardware.light-service.samsung.rc"],
vintf_fragments: ["android.hardware.light-service.samsung.xml"],
srcs: [
"Lights.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"android.hardware.light-V1-ndk",
],
vendor: true,
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2021 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/light/BnLights.h>
#include <samsung_lights.h>
#include <unordered_map>
using ::aidl::android::hardware::light::HwLightState;
using ::aidl::android::hardware::light::HwLight;
namespace aidl {
namespace android {
namespace hardware {
namespace light {
class Lights : public BnLights {
public:
Lights();
ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override;
ndk::ScopedAStatus getLights(std::vector<HwLight> *_aidl_return) override;
private:
void handleBacklight(const HwLightState& state);
#ifdef BUTTON_BRIGHTNESS_NODE
void handleButtons(const HwLightState& state);
#endif /* BUTTON_BRIGHTNESS_NODE */
#ifdef LED_BLINK_NODE
void handleBattery(const HwLightState& state);
void handleNotifications(const HwLightState& state);
void handleAttention(const HwLightState& state);
void setNotificationLED();
uint32_t calibrateColor(uint32_t color, int32_t brightness);
HwLightState mAttentionState;
HwLightState mBatteryState;
HwLightState mNotificationState;
#endif /* LED_BLINK_NODE */
uint32_t rgbToBrightness(const HwLightState& state);
std::mutex mLock;
std::unordered_map<LightType, std::function<void(const HwLightState&)>> mLights;
};
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,5 +0,0 @@
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.samsung
class hal
user system
group system
shutdown critical

View File

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

View File

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

View File

@ -1,19 +0,0 @@
cc_binary {
name: "android.hardware.memtrack-service.samsung-mali",
relative_install_path: "hw",
init_rc: ["memtrack.rc"],
vintf_fragments: ["memtrack.xml"],
vendor: true,
shared_libs: [
"android.hardware.memtrack-V1-ndk",
"libbase",
"libbinder_ndk",
"liblog",
],
srcs: [
"Memtrack.cpp",
"GpuSysfsReader.cpp",
"filesystem.cpp",
"main.cpp",
],
}

View File

@ -1,59 +0,0 @@
#include "GpuSysfsReader.h"
#include <log/log.h>
#include <fstream>
#include <sstream>
#include "filesystem.h"
#undef LOG_TAG
#define LOG_TAG "memtrack-gpusysfsreader"
using namespace GpuSysfsReader;
namespace {
uint64_t readNode(const std::string node, pid_t pid) {
std::stringstream ss;
if (pid)
ss << kSysfsDevicePath << "/" << kProcessDir << "/" << pid << "/" << node;
else
ss << kSysfsDevicePath << "/" << node;
const std::string path = ss.str();
if (!filesystem::exists(filesystem::path(path))) {
ALOGV("File not found: %s", path.c_str());
return 0;
}
std::ifstream file(path.c_str());
if (!file.is_open()) {
ALOGW("Failed to open %s path", path.c_str());
return 0;
}
uint64_t out;
file >> out;
file.close();
return out;
}
} // namespace
uint64_t GpuSysfsReader::getDmaBufGpuMem(pid_t pid) { return readNode(kDmaBufGpuMemNode, pid); }
uint64_t GpuSysfsReader::getGpuMemTotal(pid_t pid) { return readNode(kTotalGpuMemNode, pid); }
uint64_t GpuSysfsReader::getPrivateGpuMem(pid_t pid) {
auto dma_buf_size = getDmaBufGpuMem(pid);
auto gpu_total_size = getGpuMemTotal(pid);
if (dma_buf_size > gpu_total_size) {
ALOGE("Bug in reader, dma-buf size (%" PRIu64 ") is higher than total gpu size (%" PRIu64
")",
dma_buf_size, gpu_total_size);
return 0;
}
return gpu_total_size - dma_buf_size;
}

View File

@ -1,17 +0,0 @@
#pragma once
#include <inttypes.h>
#include <sys/types.h>
namespace GpuSysfsReader {
uint64_t getDmaBufGpuMem(pid_t pid = 0);
uint64_t getGpuMemTotal(pid_t pid = 0);
uint64_t getPrivateGpuMem(pid_t pid = 0);
constexpr char kSysfsDevicePath[] = "/sys/class/misc/mali0/device";
constexpr char kProcessDir[] = "kprcs";
constexpr char kMappedDmaBufsDir[] = "dma_bufs";
constexpr char kTotalGpuMemNode[] = "total_gpu_mem";
constexpr char kDmaBufGpuMemNode[] = "dma_buf_gpu_mem";
} // namespace GpuSysfsReader

View File

@ -1,79 +0,0 @@
#include <Memtrack.h>
#include <stdlib.h>
#include <sstream>
#include <string>
#include <vector>
#include "GpuSysfsReader.h"
#include "filesystem.h"
#undef LOG_TAG
#define LOG_TAG "memtrack-core"
namespace aidl {
namespace android {
namespace hardware {
namespace memtrack {
ndk::ScopedAStatus Memtrack::getMemory(int pid, MemtrackType type,
std::vector<MemtrackRecord>* _aidl_return) {
if (pid < 0)
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS &&
type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA)
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
_aidl_return->clear();
// Other types are retained only for backward compatibility
if (type != MemtrackType::GL && type != MemtrackType::GRAPHICS)
return ndk::ScopedAStatus::ok();
// pid 0 is only supported for GL type to report total private memory
if (pid == 0 && type != MemtrackType::GL)
return ndk::ScopedAStatus::ok();
uint64_t size = 0;
switch (type) {
case MemtrackType::GL:
size = GpuSysfsReader::getPrivateGpuMem(pid);
break;
case MemtrackType::GRAPHICS:
// TODO(b/194483693): This is not PSS as required by memtrack HAL
// but complete dmabuf allocations. Reporting PSS requires reading
// procfs. This HAL does not have that permission yet.
size = GpuSysfsReader::getDmaBufGpuMem(pid);
break;
default:
break;
}
MemtrackRecord record = {
.flags = MemtrackRecord::FLAG_SMAPS_UNACCOUNTED,
.sizeInBytes = static_cast<long>(size),
};
_aidl_return->emplace_back(record);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Memtrack::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) {
auto devPath = filesystem::path(GpuSysfsReader::kSysfsDevicePath);
std::string devName = "default-gpu";
if (filesystem::exists(devPath) && filesystem::is_symlink(devPath)) {
devName = filesystem::read_symlink(devPath).filename().string();
}
DeviceInfo dev_info = {.id = 0, .name = devName};
_aidl_return->clear();
_aidl_return->emplace_back(dev_info);
return ndk::ScopedAStatus::ok();
}
} // namespace memtrack
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,25 +0,0 @@
#pragma once
#include <aidl/android/hardware/memtrack/BnMemtrack.h>
#include <aidl/android/hardware/memtrack/DeviceInfo.h>
#include <aidl/android/hardware/memtrack/MemtrackRecord.h>
#include <aidl/android/hardware/memtrack/MemtrackType.h>
namespace aidl {
namespace android {
namespace hardware {
namespace memtrack {
class Memtrack : public BnMemtrack {
public:
ndk::ScopedAStatus getMemory(int pid, MemtrackType type,
std::vector<MemtrackRecord>* _aidl_return) override;
ndk::ScopedAStatus getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) override;
};
} // namespace memtrack
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,70 +0,0 @@
#include "filesystem.h"
#include <dirent.h>
#include <log/log.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sstream>
#include <string>
#include <vector>
namespace filesystem {
bool exists(const path& p) {
struct stat s;
return stat(p.string().c_str(), &s) == 0;
}
bool is_directory(const path& p) {
struct stat s;
if (stat(p.string().c_str(), &s))
return false;
return S_ISDIR(s.st_mode);
}
bool is_symlink(const path& p) {
struct stat s;
if (lstat(p.string().c_str(), &s))
return false;
return S_ISLNK(s.st_mode);
}
path read_symlink(const path& p) {
char* actualPath = realpath(p.string().c_str(), NULL);
if (!actualPath) {
return path(p.string());
}
path out(actualPath);
free(actualPath);
return out;
}
std::vector<directory_entry> directory_iterator(const path& p) {
if (!exists(p) || !is_directory(p))
return {};
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(p.string().c_str()), &closedir);
if (!dir) {
ALOGE("Failed to open %s directory", p.string().c_str());
}
std::vector<directory_entry> out;
struct dirent* dent;
while ((dent = readdir(dir.get()))) {
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
continue;
std::stringstream ss(p.string());
ss << "/" << dent->d_name;
out.emplace_back(ss.str());
}
return out;
}
} // namespace filesystem

View File

@ -1,60 +0,0 @@
// TODO(b/147469372): filesystem library in Android's libcxx is not available
// for vendors. It had an unstable ABI and libcxx isn't updated ever since.
// This simply implements some of the required functions in not-so-safe fashion.
#pragma once
#include <dirent.h>
#include <log/log.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
#include <vector>
namespace filesystem {
class path {
public:
path(const std::string _path) : strPath(_path) {}
path filename() const {
auto pos = strPath.rfind('/');
if (pos == std::string::npos)
return path(strPath);
pos++;
auto l = strPath.size();
return path(strPath.substr(pos, l - pos));
}
std::string string() const { return strPath; }
private:
std::string strPath;
};
class directory_entry {
public:
directory_entry(const std::string _path) : p(_path) {}
class path path() {
return p;
}
private:
class path p;
};
bool exists(const path& p);
bool is_directory(const path& p);
bool is_symlink(const path& p);
path read_symlink(const path& p);
// Vector is easier to create than an iterator and serves our purposes well
std::vector<directory_entry> directory_iterator(const path& p);
} // namespace filesystem

View File

@ -1,23 +0,0 @@
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include "Memtrack.h"
#undef LOG_TAG
#define LOG_TAG "memtrack-service"
using aidl::android::hardware::memtrack::Memtrack;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Memtrack> memtrack = ndk::SharedRefBase::make<Memtrack>();
const std::string instance = std::string() + Memtrack::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(memtrack->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // Unreachable
}

View File

@ -1,4 +0,0 @@
service vendor.memtrack-default /vendor/bin/hw/android.hardware.memtrack-service.samsung-mali
class hal
user graphics
group system

View File

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

View File

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

View File

@ -1,363 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ConvertUtils.h"
#include <android-base/logging.h>
#include <log/log.h>
using AidlSensorInfo = ::aidl::android::hardware::sensors::SensorInfo;
using AidlSensorType = ::aidl::android::hardware::sensors::SensorType;
using AidlEvent = ::aidl::android::hardware::sensors::Event;
using AidlSensorStatus = ::aidl::android::hardware::sensors::SensorStatus;
using ::aidl::android::hardware::sensors::AdditionalInfo;
using ::aidl::android::hardware::sensors::DynamicSensorInfo;
using ::android::hardware::sensors::V1_0::MetaDataEventType;
using V1_0SensorStatus = ::android::hardware::sensors::V1_0::SensorStatus;
using ::android::hardware::sensors::V1_0::AdditionalInfoType;
using V2_1SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo;
using V2_1Event = ::android::hardware::sensors::V2_1::Event;
using V2_1SensorType = ::android::hardware::sensors::V2_1::SensorType;
namespace aidl {
namespace android {
namespace hardware {
namespace sensors {
namespace implementation {
AidlSensorInfo convertSensorInfo(const V2_1SensorInfo& sensorInfo) {
AidlSensorInfo aidlSensorInfo;
aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle;
aidlSensorInfo.name = sensorInfo.name;
aidlSensorInfo.vendor = sensorInfo.vendor;
aidlSensorInfo.version = sensorInfo.version;
aidlSensorInfo.type = (AidlSensorType)sensorInfo.type;
aidlSensorInfo.typeAsString = sensorInfo.typeAsString;
aidlSensorInfo.maxRange = sensorInfo.maxRange;
aidlSensorInfo.resolution = sensorInfo.resolution;
aidlSensorInfo.power = sensorInfo.power;
aidlSensorInfo.minDelayUs = sensorInfo.minDelay;
aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount;
aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount;
aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission;
aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay;
aidlSensorInfo.flags = sensorInfo.flags;
return aidlSensorInfo;
}
void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) {
static_assert(decltype(hidlEvent->u.data)::elementCount() == 16);
hidlEvent->timestamp = aidlEvent.timestamp;
hidlEvent->sensorHandle = aidlEvent.sensorHandle;
hidlEvent->sensorType = (V2_1SensorType)aidlEvent.sensorType;
switch (aidlEvent.sensorType) {
case AidlSensorType::META_DATA:
hidlEvent->u.meta.what =
(MetaDataEventType)aidlEvent.payload.get<Event::EventPayload::meta>().what;
break;
case AidlSensorType::ACCELEROMETER:
case AidlSensorType::MAGNETIC_FIELD:
case AidlSensorType::ORIENTATION:
case AidlSensorType::GYROSCOPE:
case AidlSensorType::GRAVITY:
case AidlSensorType::LINEAR_ACCELERATION:
hidlEvent->u.vec3.x = aidlEvent.payload.get<Event::EventPayload::vec3>().x;
hidlEvent->u.vec3.y = aidlEvent.payload.get<Event::EventPayload::vec3>().y;
hidlEvent->u.vec3.z = aidlEvent.payload.get<Event::EventPayload::vec3>().z;
hidlEvent->u.vec3.status =
(V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::vec3>().status;
break;
case AidlSensorType::GAME_ROTATION_VECTOR:
hidlEvent->u.vec4.x = aidlEvent.payload.get<Event::EventPayload::vec4>().x;
hidlEvent->u.vec4.y = aidlEvent.payload.get<Event::EventPayload::vec4>().y;
hidlEvent->u.vec4.z = aidlEvent.payload.get<Event::EventPayload::vec4>().z;
hidlEvent->u.vec4.w = aidlEvent.payload.get<Event::EventPayload::vec4>().w;
break;
case AidlSensorType::ROTATION_VECTOR:
case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR:
std::copy(aidlEvent.payload.get<Event::EventPayload::data>().values.data(),
aidlEvent.payload.get<Event::EventPayload::data>().values.data() + 5,
hidlEvent->u.data.data());
break;
case AidlSensorType::ACCELEROMETER_UNCALIBRATED:
case AidlSensorType::MAGNETIC_FIELD_UNCALIBRATED:
case AidlSensorType::GYROSCOPE_UNCALIBRATED:
hidlEvent->u.uncal.x = aidlEvent.payload.get<Event::EventPayload::uncal>().x;
hidlEvent->u.uncal.y = aidlEvent.payload.get<Event::EventPayload::uncal>().y;
hidlEvent->u.uncal.z = aidlEvent.payload.get<Event::EventPayload::uncal>().z;
hidlEvent->u.uncal.x_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().xBias;
hidlEvent->u.uncal.y_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().yBias;
hidlEvent->u.uncal.z_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().zBias;
break;
case AidlSensorType::DEVICE_ORIENTATION:
case AidlSensorType::LIGHT:
case AidlSensorType::PRESSURE:
case AidlSensorType::PROXIMITY:
case AidlSensorType::RELATIVE_HUMIDITY:
case AidlSensorType::AMBIENT_TEMPERATURE:
case AidlSensorType::SIGNIFICANT_MOTION:
case AidlSensorType::STEP_DETECTOR:
case AidlSensorType::TILT_DETECTOR:
case AidlSensorType::WAKE_GESTURE:
case AidlSensorType::GLANCE_GESTURE:
case AidlSensorType::PICK_UP_GESTURE:
case AidlSensorType::WRIST_TILT_GESTURE:
case AidlSensorType::STATIONARY_DETECT:
case AidlSensorType::MOTION_DETECT:
case AidlSensorType::HEART_BEAT:
case AidlSensorType::LOW_LATENCY_OFFBODY_DETECT:
case AidlSensorType::HINGE_ANGLE:
hidlEvent->u.scalar = aidlEvent.payload.get<Event::EventPayload::scalar>();
break;
case AidlSensorType::STEP_COUNTER:
hidlEvent->u.stepCount = aidlEvent.payload.get<AidlEvent::EventPayload::stepCount>();
break;
case AidlSensorType::HEART_RATE:
hidlEvent->u.heartRate.bpm =
aidlEvent.payload.get<AidlEvent::EventPayload::heartRate>().bpm;
hidlEvent->u.heartRate.status =
(V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::heartRate>()
.status;
break;
case AidlSensorType::POSE_6DOF:
std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values),
std::end(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values),
hidlEvent->u.pose6DOF.data());
break;
case AidlSensorType::DYNAMIC_SENSOR_META:
hidlEvent->u.dynamic.connected =
aidlEvent.payload.get<Event::EventPayload::dynamic>().connected;
hidlEvent->u.dynamic.sensorHandle =
aidlEvent.payload.get<Event::EventPayload::dynamic>().sensorHandle;
std::copy(
std::begin(
aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values),
std::end(aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values),
hidlEvent->u.dynamic.uuid.data());
break;
case AidlSensorType::ADDITIONAL_INFO: {
const AdditionalInfo& additionalInfo =
aidlEvent.payload.get<AidlEvent::EventPayload::additional>();
hidlEvent->u.additional.type = (AdditionalInfoType)additionalInfo.type;
hidlEvent->u.additional.serial = additionalInfo.serial;
switch (additionalInfo.payload.getTag()) {
case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: {
const auto& aidlData =
additionalInfo.payload
.get<AdditionalInfo::AdditionalInfoPayload::dataInt32>()
.values;
std::copy(std::begin(aidlData), std::end(aidlData),
hidlEvent->u.additional.u.data_int32.data());
break;
}
case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: {
const auto& aidlData =
additionalInfo.payload
.get<AdditionalInfo::AdditionalInfoPayload::dataFloat>()
.values;
std::copy(std::begin(aidlData), std::end(aidlData),
hidlEvent->u.additional.u.data_float.data());
break;
}
default:
ALOGE("Invalid sensor additioanl info tag: %d",
static_cast<int32_t>(additionalInfo.payload.getTag()));
break;
}
break;
}
case AidlSensorType::HEAD_TRACKER: {
const auto& ht = aidlEvent.payload.get<Event::EventPayload::headTracker>();
hidlEvent->u.data[0] = ht.rx;
hidlEvent->u.data[1] = ht.ry;
hidlEvent->u.data[2] = ht.rz;
hidlEvent->u.data[3] = ht.vx;
hidlEvent->u.data[4] = ht.vy;
hidlEvent->u.data[5] = ht.vz;
// IMPORTANT: Because we want to preserve the data range of discontinuityCount,
// we assume the data can be interpreted as an int32_t directly (e.g. the underlying
// HIDL HAL must be using memcpy or equivalent to store this value).
*(reinterpret_cast<int32_t*>(&hidlEvent->u.data[6])) = ht.discontinuityCount;
break;
}
default: {
CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values),
std::end(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values),
hidlEvent->u.data.data());
break;
}
}
}
void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) {
static_assert(decltype(hidlEvent.u.data)::elementCount() == 16);
aidlEvent->timestamp = hidlEvent.timestamp;
aidlEvent->sensorHandle = hidlEvent.sensorHandle;
aidlEvent->sensorType = (AidlSensorType)hidlEvent.sensorType;
switch (hidlEvent.sensorType) {
case V2_1SensorType::META_DATA: {
AidlEvent::EventPayload::MetaData meta;
meta.what = (Event::EventPayload::MetaData::MetaDataEventType)hidlEvent.u.meta.what;
aidlEvent->payload.set<Event::EventPayload::meta>(meta);
break;
}
case V2_1SensorType::ACCELEROMETER:
case V2_1SensorType::MAGNETIC_FIELD:
case V2_1SensorType::ORIENTATION:
case V2_1SensorType::GYROSCOPE:
case V2_1SensorType::GRAVITY:
case V2_1SensorType::LINEAR_ACCELERATION: {
AidlEvent::EventPayload::Vec3 vec3;
vec3.x = hidlEvent.u.vec3.x;
vec3.y = hidlEvent.u.vec3.y;
vec3.z = hidlEvent.u.vec3.z;
vec3.status = (SensorStatus)hidlEvent.u.vec3.status;
aidlEvent->payload.set<Event::EventPayload::vec3>(vec3);
break;
}
case V2_1SensorType::GAME_ROTATION_VECTOR: {
AidlEvent::EventPayload::Vec4 vec4;
vec4.x = hidlEvent.u.vec4.x;
vec4.y = hidlEvent.u.vec4.y;
vec4.z = hidlEvent.u.vec4.z;
vec4.w = hidlEvent.u.vec4.w;
aidlEvent->payload.set<Event::EventPayload::vec4>(vec4);
break;
}
case V2_1SensorType::ROTATION_VECTOR:
case V2_1SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
AidlEvent::EventPayload::Data data;
std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5,
std::begin(data.values));
aidlEvent->payload.set<Event::EventPayload::data>(data);
break;
}
case V2_1SensorType::MAGNETIC_FIELD_UNCALIBRATED:
case V2_1SensorType::GYROSCOPE_UNCALIBRATED:
case V2_1SensorType::ACCELEROMETER_UNCALIBRATED: {
AidlEvent::EventPayload::Uncal uncal;
uncal.x = hidlEvent.u.uncal.x;
uncal.y = hidlEvent.u.uncal.y;
uncal.z = hidlEvent.u.uncal.z;
uncal.xBias = hidlEvent.u.uncal.x_bias;
uncal.yBias = hidlEvent.u.uncal.y_bias;
uncal.zBias = hidlEvent.u.uncal.z_bias;
aidlEvent->payload.set<Event::EventPayload::uncal>(uncal);
break;
}
case V2_1SensorType::DEVICE_ORIENTATION:
case V2_1SensorType::LIGHT:
case V2_1SensorType::PRESSURE:
case V2_1SensorType::PROXIMITY:
case V2_1SensorType::RELATIVE_HUMIDITY:
case V2_1SensorType::AMBIENT_TEMPERATURE:
case V2_1SensorType::SIGNIFICANT_MOTION:
case V2_1SensorType::STEP_DETECTOR:
case V2_1SensorType::TILT_DETECTOR:
case V2_1SensorType::WAKE_GESTURE:
case V2_1SensorType::GLANCE_GESTURE:
case V2_1SensorType::PICK_UP_GESTURE:
case V2_1SensorType::WRIST_TILT_GESTURE:
case V2_1SensorType::STATIONARY_DETECT:
case V2_1SensorType::MOTION_DETECT:
case V2_1SensorType::HEART_BEAT:
case V2_1SensorType::LOW_LATENCY_OFFBODY_DETECT:
case V2_1SensorType::HINGE_ANGLE:
aidlEvent->payload.set<Event::EventPayload::scalar>(hidlEvent.u.scalar);
break;
case V2_1SensorType::STEP_COUNTER:
aidlEvent->payload.set<Event::EventPayload::stepCount>(hidlEvent.u.stepCount);
break;
case V2_1SensorType::HEART_RATE: {
AidlEvent::EventPayload::HeartRate heartRate;
heartRate.bpm = hidlEvent.u.heartRate.bpm;
heartRate.status = (SensorStatus)hidlEvent.u.heartRate.status;
aidlEvent->payload.set<Event::EventPayload::heartRate>(heartRate);
break;
}
case V2_1SensorType::POSE_6DOF: {
AidlEvent::EventPayload::Pose6Dof pose6Dof;
std::copy(hidlEvent.u.pose6DOF.data(),
hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(),
std::begin(pose6Dof.values));
aidlEvent->payload.set<Event::EventPayload::pose6DOF>(pose6Dof);
break;
}
case V2_1SensorType::DYNAMIC_SENSOR_META: {
DynamicSensorInfo dynamicSensorInfo;
dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected;
dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle;
std::copy(hidlEvent.u.dynamic.uuid.data(),
hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(),
std::begin(dynamicSensorInfo.uuid.values));
aidlEvent->payload.set<Event::EventPayload::dynamic>(dynamicSensorInfo);
break;
}
case V2_1SensorType::ADDITIONAL_INFO: {
AdditionalInfo additionalInfo;
additionalInfo.type = (AdditionalInfo::AdditionalInfoType)hidlEvent.u.additional.type;
additionalInfo.serial = hidlEvent.u.additional.serial;
AdditionalInfo::AdditionalInfoPayload::Int32Values int32Values;
std::copy(hidlEvent.u.additional.u.data_int32.data(),
hidlEvent.u.additional.u.data_int32.data() +
hidlEvent.u.additional.u.data_int32.size(),
std::begin(int32Values.values));
additionalInfo.payload.set<AdditionalInfo::AdditionalInfoPayload::dataInt32>(
int32Values);
aidlEvent->payload.set<Event::EventPayload::additional>(additionalInfo);
break;
}
default: {
if (static_cast<int32_t>(hidlEvent.sensorType) ==
static_cast<int32_t>(AidlSensorType::HEAD_TRACKER)) {
Event::EventPayload::HeadTracker headTracker;
headTracker.rx = hidlEvent.u.data[0];
headTracker.ry = hidlEvent.u.data[1];
headTracker.rz = hidlEvent.u.data[2];
headTracker.vx = hidlEvent.u.data[3];
headTracker.vy = hidlEvent.u.data[4];
headTracker.vz = hidlEvent.u.data[5];
// IMPORTANT: Because we want to preserve the data range of discontinuityCount,
// we assume the data can be interpreted as an int32_t directly (e.g. the underlying
// HIDL HAL must be using memcpy or equivalent to store this value).
headTracker.discontinuityCount =
*(reinterpret_cast<const int32_t*>(&hidlEvent.u.data[6]));
aidlEvent->payload.set<Event::EventPayload::Tag::headTracker>(headTracker);
} else {
CHECK_GE((int32_t)hidlEvent.sensorType,
(int32_t)V2_1SensorType::DEVICE_PRIVATE_BASE);
AidlEvent::EventPayload::Data data;
std::copy(hidlEvent.u.data.data(),
hidlEvent.u.data.data() + hidlEvent.u.data.size(),
std::begin(data.values));
aidlEvent->payload.set<Event::EventPayload::data>(data);
}
break;
}
}
}
} // namespace implementation
} // namespace sensors
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@ -1,269 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define VERBOSE
#include "HalProxyAidl.h"
#include <aidlcommonsupport/NativeHandle.h>
#include <fmq/AidlMessageQueue.h>
#include <hidl/Status.h>
#include "ConvertUtils.h"
#include "EventMessageQueueWrapperAidl.h"
#include "ISensorsCallbackWrapperAidl.h"
#include "WakeLockMessageQueueWrapperAidl.h"
#include "convertV2_1.h"
using ::aidl::android::hardware::common::fmq::MQDescriptor;
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using ::aidl::android::hardware::sensors::ISensors;
using ::aidl::android::hardware::sensors::ISensorsCallback;
using ::aidl::android::hardware::sensors::SensorInfo;
using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent;
using ::ndk::ScopedAStatus;
namespace aidl {
namespace android {
namespace hardware {
namespace sensors {
namespace implementation {
static ScopedAStatus
resultToAStatus(::android::hardware::sensors::V1_0::Result result) {
switch (result) {
case ::android::hardware::sensors::V1_0::Result::OK:
return ScopedAStatus::ok();
case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED:
return ScopedAStatus::fromExceptionCode(EX_SECURITY);
case ::android::hardware::sensors::V1_0::Result::NO_MEMORY:
return ScopedAStatus::fromServiceSpecificError(ISensors::ERROR_NO_MEMORY);
case ::android::hardware::sensors::V1_0::Result::BAD_VALUE:
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION:
return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
default:
return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
}
}
static ::android::hardware::sensors::V1_0::RateLevel convertRateLevel(
ISensors::RateLevel rateLevel) {
switch (rateLevel) {
case ISensors::RateLevel::STOP:
return ::android::hardware::sensors::V1_0::RateLevel::STOP;
case ISensors::RateLevel::NORMAL:
return ::android::hardware::sensors::V1_0::RateLevel::NORMAL;
case ISensors::RateLevel::FAST:
return ::android::hardware::sensors::V1_0::RateLevel::FAST;
case ISensors::RateLevel::VERY_FAST:
return ::android::hardware::sensors::V1_0::RateLevel::VERY_FAST;
default:
assert(false);
}
}
static ::android::hardware::sensors::V1_0::OperationMode convertOperationMode(
ISensors::OperationMode operationMode) {
switch (operationMode) {
case ISensors::OperationMode::NORMAL:
return ::android::hardware::sensors::V1_0::OperationMode::NORMAL;
case ISensors::OperationMode::DATA_INJECTION:
return ::android::hardware::sensors::V1_0::OperationMode::DATA_INJECTION;
default:
assert(false);
}
}
static ::android::hardware::sensors::V1_0::SharedMemType convertSharedMemType(
ISensors::SharedMemInfo::SharedMemType sharedMemType) {
switch (sharedMemType) {
case ISensors::SharedMemInfo::SharedMemType::ASHMEM:
return ::android::hardware::sensors::V1_0::SharedMemType::ASHMEM;
case ISensors::SharedMemInfo::SharedMemType::GRALLOC:
return ::android::hardware::sensors::V1_0::SharedMemType::GRALLOC;
default:
assert(false);
}
}
static ::android::hardware::sensors::V1_0::SharedMemFormat convertSharedMemFormat(
ISensors::SharedMemInfo::SharedMemFormat sharedMemFormat) {
switch (sharedMemFormat) {
case ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT:
return ::android::hardware::sensors::V1_0::SharedMemFormat::SENSORS_EVENT;
default:
assert(false);
}
}
static ::android::hardware::sensors::V1_0::SharedMemInfo convertSharedMemInfo(
const ISensors::SharedMemInfo& sharedMemInfo) {
::android::hardware::sensors::V1_0::SharedMemInfo v1SharedMemInfo;
v1SharedMemInfo.type = convertSharedMemType(sharedMemInfo.type);
v1SharedMemInfo.format = convertSharedMemFormat(sharedMemInfo.format);
v1SharedMemInfo.size = sharedMemInfo.size;
v1SharedMemInfo.memoryHandle =
::android::hardware::hidl_handle(::android::makeFromAidl(sharedMemInfo.memoryHandle));
return v1SharedMemInfo;
}
ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) {
return resultToAStatus(HalProxy::activate(in_sensorHandle, in_enabled));
}
ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle,
int64_t in_samplingPeriodNs,
int64_t in_maxReportLatencyNs) {
return resultToAStatus(HalProxy::batch(in_sensorHandle, in_samplingPeriodNs,
in_maxReportLatencyNs));
}
ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle,
int32_t in_channelHandle,
ISensors::RateLevel in_rate,
int32_t *_aidl_return) {
ScopedAStatus status =
ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
HalProxy::configDirectReport(
in_sensorHandle, in_channelHandle, convertRateLevel(in_rate),
[&status, _aidl_return](::android::hardware::sensors::V1_0::Result result,
int32_t reportToken) {
status = resultToAStatus(result);
*_aidl_return = reportToken;
});
return status;
}
ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) {
return resultToAStatus(HalProxy::flush(in_sensorHandle));
}
ScopedAStatus HalProxyAidl::getSensorsList(
std::vector<::aidl::android::hardware::sensors::SensorInfo> *_aidl_return) {
for (const auto &sensor : HalProxy::getSensors()) {
SensorInfo dst = sensor.second;
if (dst.requiredPermission == "com.samsung.permission.SSENSOR") {
dst.requiredPermission = "";
}
if (dst.typeAsString == "com.samsung.sensor.physical_proximity" ||
dst.typeAsString == "com.samsung.sensor.hover_proximity") {
ALOGI("Fixing %s", dst.typeAsString.c_str());
dst.type = ::android::hardware::sensors::V2_1::SensorType::PROXIMITY;
dst.typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
dst.maxRange = 1;
}
#ifdef VERBOSE
ALOGI( "SENSOR NAME:%s ", dst.name.c_str());
ALOGI( " VENDOR:%s ", dst.name.c_str());
ALOGI( " TYPE:%d ", (uint32_t)dst.type);
ALOGI( " TYPE_AS_STRING:%s ", dst.typeAsString.c_str());
#endif
_aidl_return->push_back(convertSensorInfo(dst));
}
return ScopedAStatus::ok();
}
ScopedAStatus HalProxyAidl::initialize(
const MQDescriptor<::aidl::android::hardware::sensors::Event,
SynchronizedReadWrite> &in_eventQueueDescriptor,
const MQDescriptor<int32_t, SynchronizedReadWrite> &in_wakeLockDescriptor,
const std::shared_ptr<ISensorsCallback> &in_sensorsCallback) {
::android::sp<::android::hardware::sensors::V2_1::implementation::
ISensorsCallbackWrapperBase>
dynamicCallback = new ISensorsCallbackWrapperAidl(in_sensorsCallback);
auto aidlEventQueue = std::make_unique<::android::AidlMessageQueue<
::aidl::android::hardware::sensors::Event, SynchronizedReadWrite>>(
in_eventQueueDescriptor, true /* resetPointers */);
std::unique_ptr<::android::hardware::sensors::V2_1::implementation::
EventMessageQueueWrapperBase>
eventQueue =
std::make_unique<EventMessageQueueWrapperAidl>(aidlEventQueue);
auto aidlWakeLockQueue = std::make_unique<
::android::AidlMessageQueue<int32_t, SynchronizedReadWrite>>(
in_wakeLockDescriptor, true /* resetPointers */);
std::unique_ptr<::android::hardware::sensors::V2_1::implementation::
WakeLockMessageQueueWrapperBase>
wakeLockQueue =
std::make_unique<WakeLockMessageQueueWrapperAidl>(aidlWakeLockQueue);
return resultToAStatus(
initializeCommon(eventQueue, wakeLockQueue, dynamicCallback));
}
ScopedAStatus HalProxyAidl::injectSensorData(
const ::aidl::android::hardware::sensors::Event &in_event) {
::android::hardware::sensors::V2_1::Event hidlEvent;
convertToHidlEvent(in_event, &hidlEvent);
return resultToAStatus(
HalProxy::injectSensorData(convertToOldEvent(hidlEvent)));
}
ScopedAStatus
HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo &in_mem,
int32_t *_aidl_return) {
ScopedAStatus status =
ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo =
convertSharedMemInfo(in_mem);
HalProxy::registerDirectChannel(
sharedMemInfo,
[&status, _aidl_return](::android::hardware::sensors::V1_0::Result result,
int32_t reportToken) {
status = resultToAStatus(result);
*_aidl_return = reportToken;
});
native_handle_delete(const_cast<native_handle_t *>(
sharedMemInfo.memoryHandle.getNativeHandle()));
return status;
}
ScopedAStatus HalProxyAidl::setOperationMode(
::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) {
return resultToAStatus(
HalProxy::setOperationMode(convertOperationMode(in_mode)));
}
ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) {
return resultToAStatus(HalProxy::unregisterDirectChannel(in_channelHandle));
}
binder_status_t HalProxyAidl::dump(int fd, const char ** /* args */,
uint32_t /* numArgs */) {
native_handle_t *nativeHandle =
native_handle_create(1 /* numFds */, 0 /* numInts */);
nativeHandle->data[0] = fd;
HalProxy::debug(nativeHandle, {} /* args */);
native_handle_delete(nativeHandle);
return STATUS_OK;
}
} // namespace implementation
} // namespace sensors
} // namespace hardware
} // namespace android
} // namespace aidl

View File

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

View File

@ -1,7 +0,0 @@
service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.samsung-multihal
class hal
user system
group system wakelock context_hub input
task_profiles ServiceCapacityLow
capabilities BLOCK_SUSPEND
rlimit rtprio 10 10

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <aidl/android/hardware/sensors/BnSensors.h>
#include <android/hardware/sensors/2.1/types.h>
namespace aidl {
namespace android {
namespace hardware {
namespace sensors {
namespace implementation {
/**
* Generates an AIDL SensorInfo instance from the passed HIDL V2.1 SensorInfo instance.
*/
::aidl::android::hardware::sensors::SensorInfo convertSensorInfo(
const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo);
/**
* Populates a HIDL V2.1 Event instance based on an AIDL Event instance.
*/
void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent,
::android::hardware::sensors::V2_1::Event* hidlEvent);
/**
* Populates an AIDL Event instance based on a HIDL V2.1 Event instance.
*/
void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent,
::aidl::android::hardware::sensors::Event* aidlEvent);
} // namespace implementation
} // namespace sensors
} // namespace hardware
} // namespace android
} // namespace aidl

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