diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 69399d84c..e72dd1667 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -55,10 +55,13 @@
android:theme="@style/Theme.Linphone"
tools:targetApi="35">
-
+
+
diff --git a/app/src/main/java/org/linphone/telecom/auto/AAScreen.kt b/app/src/main/java/org/linphone/telecom/auto/AAScreen.kt
new file mode 100644
index 000000000..20340f6c3
--- /dev/null
+++ b/app/src/main/java/org/linphone/telecom/auto/AAScreen.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2010-2024 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-android
+ * (see https://www.linphone.org).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.linphone.telecom.auto
+
+import androidx.car.app.CarContext
+import androidx.car.app.Screen
+import androidx.car.app.model.Action
+import androidx.car.app.model.CarIcon
+import androidx.car.app.model.GridItem
+import androidx.car.app.model.GridTemplate
+import androidx.car.app.model.Header
+import androidx.car.app.model.ItemList
+import androidx.car.app.model.Template
+import androidx.core.graphics.drawable.IconCompat
+import org.linphone.LinphoneApplication.Companion.coreContext
+import org.linphone.R
+import org.linphone.contacts.getNativeContactPictureUri
+import org.linphone.core.MagicSearch
+import org.linphone.core.tools.Log
+import org.linphone.utils.LinphoneUtils
+
+class AAScreen(context: CarContext) : Screen(context) {
+ companion object {
+ private const val TAG = "[Android Auto Screen]"
+ }
+
+ private val favoritesList = arrayListOf()
+
+ private var loading = true
+
+ init {
+ Log.i(
+ "$TAG Creating favorites contacts list template for host with API level [${carContext.carAppApiLevel}]"
+ )
+ coreContext.postOnCoreThread { core ->
+ val magicSearch = core.createMagicSearch()
+ val results = magicSearch.getContactsList(
+ "",
+ LinphoneUtils.getDefaultAccount()?.params?.domain.orEmpty(),
+ MagicSearch.Source.FavoriteFriends.toInt(),
+ MagicSearch.Aggregation.Friend
+ )
+ val favorites = arrayListOf()
+ for (result in results) {
+ val builder = GridItem.Builder()
+ val friend = result.friend ?: continue
+
+ builder.setTitle(friend.name)
+ val pictureUri = friend.getNativeContactPictureUri()
+ if (pictureUri != null) {
+ Log.i(
+ "$TAG Creating car icon for friend [${friend.name}] with URI [$pictureUri]"
+ )
+ try {
+ builder.setImage(
+ CarIcon.Builder(IconCompat.createWithContentUri(pictureUri))
+ .build(),
+ GridItem.IMAGE_TYPE_LARGE
+ )
+ } catch (e: Exception) {
+ Log.e("$TAG Exception trying to create CarIcon: $e")
+ }
+ }
+
+ builder.setOnClickListener {
+ val address = friend.address ?: friend.addresses.firstOrNull()
+ if (address != null) {
+ Log.i("$TAG Starting audio call to [${address.asStringUriOnly()}]")
+ coreContext.startAudioCall(address)
+ }
+ }
+ val item = builder.build()
+ favorites.add(item)
+ }
+ loading = false
+ Log.i("$TAG Processed [${favorites.size}] favorites")
+
+ coreContext.postOnMainThread {
+ favoritesList.addAll(favorites)
+ invalidate()
+ }
+ }
+ }
+
+ override fun onGetTemplate(): Template {
+ Log.i("$TAG onGetTemplate called, favorites are [${if (loading) "loading" else "loaded"}]")
+
+ val listBuilder = ItemList.Builder()
+ listBuilder.setNoItemsMessage(
+ carContext.getString(R.string.car_favorites_contacts_list_empty)
+ )
+ for (favorite in favoritesList) {
+ listBuilder.addItem(favorite)
+ }
+ val list = listBuilder.build()
+
+ val header = Header.Builder()
+ .setTitle(carContext.getString(R.string.car_favorites_contacts_title))
+ .setStartHeaderAction(Action.APP_ICON)
+ .build()
+
+ val gridBuilder = GridTemplate.Builder()
+ gridBuilder.setHeader(header)
+ gridBuilder.setLoading(loading)
+ if (!loading) {
+ Log.i("$TAG Added [${favoritesList.size}] favorites items to grid")
+ gridBuilder.setSingleList(list)
+ }
+ return gridBuilder.build()
+ }
+}
diff --git a/app/src/main/java/org/linphone/telecom/TelecomAndroidAutoService.kt b/app/src/main/java/org/linphone/telecom/auto/AAService.kt
similarity index 86%
rename from app/src/main/java/org/linphone/telecom/TelecomAndroidAutoService.kt
rename to app/src/main/java/org/linphone/telecom/auto/AAService.kt
index b75b13b59..81ffc6de9 100644
--- a/app/src/main/java/org/linphone/telecom/TelecomAndroidAutoService.kt
+++ b/app/src/main/java/org/linphone/telecom/auto/AAService.kt
@@ -17,17 +17,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.linphone.telecom
+package org.linphone.telecom.auto
import android.content.pm.ApplicationInfo
import androidx.car.app.CarAppService
+import androidx.car.app.Session
import androidx.car.app.validation.HostValidator
import org.linphone.R
import org.linphone.core.tools.Log
-class TelecomAndroidAutoService : CarAppService() {
+class AAService : CarAppService() {
companion object {
- private const val TAG = "[Telecom Android Auto Service]"
+ private const val TAG = "[Android Auto Service]"
}
override fun createHostValidator(): HostValidator {
@@ -51,4 +52,9 @@ class TelecomAndroidAutoService : CarAppService() {
validator
}
}
+
+ override fun onCreateSession(): Session {
+ Log.i("$TAG Creating Session object")
+ return AASession()
+ }
}
diff --git a/app/src/main/java/org/linphone/telecom/auto/AASession.kt b/app/src/main/java/org/linphone/telecom/auto/AASession.kt
new file mode 100644
index 000000000..cc3515617
--- /dev/null
+++ b/app/src/main/java/org/linphone/telecom/auto/AASession.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010-2024 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-android
+ * (see https://www.linphone.org).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.linphone.telecom.auto
+
+import android.content.Intent
+import androidx.car.app.Screen
+import androidx.car.app.Session
+import org.linphone.core.tools.Log
+
+class AASession : Session() {
+ companion object {
+ private const val TAG = "[Android Auto Session]"
+ }
+
+ override fun onCreateScreen(intent: Intent): Screen {
+ Log.i("$TAG Creating Screen object for host with API level [${carContext.carAppApiLevel}]")
+ return AAScreen(carContext)
+ }
+}
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 5250c2bb1..c02ab9fba 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -678,6 +678,10 @@
Enregistrements
Aucun appel enregistré…
+
+ Favoris
+ Aucun contact dans la liste des favoris
+
Ajouter aux contacts
Voir le contact
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 58aba061e..1d9154ece 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -716,6 +716,10 @@
Recordings
No recording for the moment…
+
+ Favorites
+ No favorite contact yet
+
Add to contacts
See contact