Improved check on prefix in assitant + fixed some logs missing assitant tag

This commit is contained in:
Sylvain Berfini 2023-07-20 13:27:11 +02:00
parent 7e694af88f
commit 35944bb3a1
16 changed files with 84 additions and 38 deletions

View file

@ -32,6 +32,7 @@ abstract class AbstractPhoneViewModel(accountCreator: AccountCreator) :
CountryPickerFragment.CountryPickedListener { CountryPickerFragment.CountryPickedListener {
val prefix = MutableLiveData<String>() val prefix = MutableLiveData<String>()
val prefixError = MutableLiveData<String>()
val phoneNumber = MutableLiveData<String>() val phoneNumber = MutableLiveData<String>()
val phoneNumberError = MutableLiveData<String>() val phoneNumberError = MutableLiveData<String>()
@ -48,7 +49,10 @@ abstract class AbstractPhoneViewModel(accountCreator: AccountCreator) :
} }
fun isPhoneNumberOk(): Boolean { fun isPhoneNumberOk(): Boolean {
return prefix.value.orEmpty().isNotEmpty() && phoneNumber.value.orEmpty().isNotEmpty() && phoneNumberError.value.orEmpty().isEmpty() return prefix.value.orEmpty().length > 1 && // Not just '+' character
prefixError.value.orEmpty().isEmpty() &&
phoneNumber.value.orEmpty().isNotEmpty() &&
phoneNumberError.value.orEmpty().isEmpty()
} }
fun updateFromPhoneNumberAndOrDialPlan(number: String?, dialPlan: DialPlan?) { fun updateFromPhoneNumberAndOrDialPlan(number: String?, dialPlan: DialPlan?) {

View file

@ -46,7 +46,7 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM
val password = MutableLiveData<String>() val password = MutableLiveData<String>()
val passwordError = MutableLiveData<String>() val passwordError = MutableLiveData<String>()
val loginEnabled: MediatorLiveData<Boolean> = MediatorLiveData() val loginEnabled = MediatorLiveData<Boolean>()
val waitForServerAnswer = MutableLiveData<Boolean>() val waitForServerAnswer = MutableLiveData<Boolean>()
@ -140,6 +140,9 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM
loginEnabled.addSource(phoneNumberError) { loginEnabled.addSource(phoneNumberError) {
loginEnabled.value = isLoginButtonEnabled() loginEnabled.value = isLoginButtonEnabled()
} }
loginEnabled.addSource(prefixError) {
loginEnabled.value = isLoginButtonEnabled()
}
} }
override fun onCleared() { override fun onCleared() {
@ -149,6 +152,7 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM
override fun onFlexiApiTokenReceived() { override fun onFlexiApiTokenReceived() {
Log.i("[Assistant] [Account Login] Using FlexiAPI auth token [${accountCreator.token}]") Log.i("[Assistant] [Account Login] Using FlexiAPI auth token [${accountCreator.token}]")
waitForServerAnswer.value = false
loginWithPhoneNumber() loginWithPhoneNumber()
} }

View file

@ -51,16 +51,16 @@ class EchoCancellerCalibrationViewModel : ViewModel() {
coreContext.core.removeListener(listener) coreContext.core.removeListener(listener)
when (status) { when (status) {
EcCalibratorStatus.DoneNoEcho -> { EcCalibratorStatus.DoneNoEcho -> {
Log.i("[Echo Canceller Calibration] Done, no echo") Log.i("[Assistant] [Echo Canceller Calibration] Done, no echo")
} }
EcCalibratorStatus.Done -> { EcCalibratorStatus.Done -> {
Log.i("[Echo Canceller Calibration] Done, delay is ${delay}ms") Log.i("[Assistant] [Echo Canceller Calibration] Done, delay is ${delay}ms")
} }
EcCalibratorStatus.Failed -> { EcCalibratorStatus.Failed -> {
Log.w("[Echo Canceller Calibration] Failed") Log.w("[Assistant] [Echo Canceller Calibration] Failed")
} }
EcCalibratorStatus.InProgress -> { EcCalibratorStatus.InProgress -> {
Log.i("[Echo Canceller Calibration] In progress") Log.i("[Assistant] [Echo Canceller Calibration] In progress")
} }
} }
echoCalibrationTerminated.value = Event(true) echoCalibrationTerminated.value = Event(true)

View file

@ -72,7 +72,7 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Account Creation] onIsAccountExist status is $status") Log.i("[Assistant] [Account Creation] onIsAccountExist status is $status")
when (status) { when (status) {
AccountCreator.Status.AccountExist, AccountCreator.Status.AccountExistWithAlias -> { AccountCreator.Status.AccountExist, AccountCreator.Status.AccountExistWithAlias -> {
waitForServerAnswer.value = false waitForServerAnswer.value = false
@ -99,7 +99,7 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Account Creation] onCreateAccount status is $status") Log.i("[Assistant] [Account Creation] onCreateAccount status is $status")
waitForServerAnswer.value = false waitForServerAnswer.value = false
when (status) { when (status) {
@ -149,11 +149,11 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu
} }
override fun onFlexiApiTokenReceived() { override fun onFlexiApiTokenReceived() {
Log.i("[Account Creation] Using FlexiAPI auth token [${accountCreator.token}]") Log.i("[Assistant] [Account Creation] Using FlexiAPI auth token [${accountCreator.token}]")
waitForServerAnswer.value = true waitForServerAnswer.value = true
val status = accountCreator.isAccountExist val status = accountCreator.isAccountExist
Log.i("[Account Creation] Account exists returned $status") Log.i("[Assistant] [Account Creation] Account exists returned $status")
if (status != AccountCreator.Status.RequestOk) { if (status != AccountCreator.Status.RequestOk) {
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: ${status.name}") onErrorEvent.value = Event("Error: ${status.name}")
@ -161,7 +161,7 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu
} }
override fun onFlexiApiTokenRequestError() { override fun onFlexiApiTokenRequestError() {
Log.e("[Account Creation] Failed to get an auth token from FlexiAPI") Log.e("[Assistant] [Account Creation] Failed to get an auth token from FlexiAPI")
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: Failed to get an auth token from account manager server") onErrorEvent.value = Event("Error: Failed to get an auth token from account manager server")
} }
@ -175,11 +175,11 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu
val token = accountCreator.token.orEmpty() val token = accountCreator.token.orEmpty()
if (token.isNotEmpty()) { if (token.isNotEmpty()) {
Log.i( Log.i(
"[Account Creation] We already have an auth token from FlexiAPI [$token], continue" "[Assistant] [Account Creation] We already have an auth token from FlexiAPI [$token], continue"
) )
onFlexiApiTokenReceived() onFlexiApiTokenReceived()
} else { } else {
Log.i("[Account Creation] Requesting an auth token from FlexiAPI") Log.i("[Assistant] [Account Creation] Requesting an auth token from FlexiAPI")
waitForServerAnswer.value = true waitForServerAnswer.value = true
requestFlexiApiToken() requestFlexiApiToken()
} }

View file

@ -57,7 +57,7 @@ class EmailAccountValidationViewModel(val accountCreator: AccountCreator) : View
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Account Validation] onIsAccountActivated status is $status") Log.i("[Assistant] [Account Validation] onIsAccountActivated status is $status")
waitForServerAnswer.value = false waitForServerAnswer.value = false
when (status) { when (status) {

View file

@ -152,6 +152,8 @@ class GenericLoginViewModel(private val accountCreator: AccountCreator) : ViewMo
} }
private fun isLoginButtonEnabled(): Boolean { private fun isLoginButtonEnabled(): Boolean {
return username.value.orEmpty().isNotEmpty() && domain.value.orEmpty().isNotEmpty() && password.value.orEmpty().isNotEmpty() return username.value.orEmpty().isNotEmpty() &&
domain.value.orEmpty().isNotEmpty() &&
password.value.orEmpty().isNotEmpty()
} }
} }

View file

@ -68,7 +68,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Phone Account Creation] onIsAccountExist status is $status") Log.i("[Assistant] [Phone Account Creation] onIsAccountExist status is $status")
when (status) { when (status) {
AccountCreator.Status.AccountExist, AccountCreator.Status.AccountExistWithAlias -> { AccountCreator.Status.AccountExist, AccountCreator.Status.AccountExistWithAlias -> {
waitForServerAnswer.value = false waitForServerAnswer.value = false
@ -92,7 +92,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Phone Account Creation] onIsAliasUsed status is $status") Log.i("[Assistant] [Phone Account Creation] onIsAliasUsed status is $status")
when (status) { when (status) {
AccountCreator.Status.AliasExist -> { AccountCreator.Status.AliasExist -> {
waitForServerAnswer.value = false waitForServerAnswer.value = false
@ -114,7 +114,9 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
} }
AccountCreator.Status.AliasNotExist -> { AccountCreator.Status.AliasNotExist -> {
val createAccountStatus = creator.createAccount() val createAccountStatus = creator.createAccount()
Log.i("[Phone Account Creation] createAccount returned $createAccountStatus") Log.i(
"[Assistant] [Phone Account Creation] createAccount returned $createAccountStatus"
)
if (createAccountStatus != AccountCreator.Status.RequestOk) { if (createAccountStatus != AccountCreator.Status.RequestOk) {
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: ${status.name}") onErrorEvent.value = Event("Error: ${status.name}")
@ -132,7 +134,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Phone Account Creation] onCreateAccount status is $status") Log.i("[Assistant] [Phone Account Creation] onCreateAccount status is $status")
waitForServerAnswer.value = false waitForServerAnswer.value = false
when (status) { when (status) {
AccountCreator.Status.AccountCreated -> { AccountCreator.Status.AccountCreated -> {
@ -173,6 +175,9 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
createEnabled.addSource(phoneNumberError) { createEnabled.addSource(phoneNumberError) {
createEnabled.value = isCreateButtonEnabled() createEnabled.value = isCreateButtonEnabled()
} }
createEnabled.addSource(prefixError) {
createEnabled.value = isCreateButtonEnabled()
}
} }
override fun onCleared() { override fun onCleared() {
@ -181,9 +186,22 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
} }
override fun onFlexiApiTokenReceived() { override fun onFlexiApiTokenReceived() {
Log.i("[Phone Account Creation] Using FlexiAPI auth token [${accountCreator.token}]") Log.i(
"[Assistant] [Phone Account Creation] Using FlexiAPI auth token [${accountCreator.token}]"
)
accountCreator.displayName = displayName.value accountCreator.displayName = displayName.value
accountCreator.setPhoneNumber(phoneNumber.value, prefix.value)
val result = AccountCreator.PhoneNumberStatus.fromInt(
accountCreator.setPhoneNumber(phoneNumber.value, prefix.value)
)
if (result != AccountCreator.PhoneNumberStatus.Ok) {
Log.e(
"[Assistant] [Phone Account Creation] Error [$result] setting the phone number: ${phoneNumber.value} with prefix: ${prefix.value}"
)
phoneNumberError.value = result.name
return
}
Log.i("[Assistant] [Phone Account Creation] Phone number is ${accountCreator.phoneNumber}")
if (useUsername.value == true) { if (useUsername.value == true) {
accountCreator.username = username.value accountCreator.username = username.value
@ -199,14 +217,14 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
} }
override fun onFlexiApiTokenRequestError() { override fun onFlexiApiTokenRequestError() {
Log.e("[Phone Account Creation] Failed to get an auth token from FlexiAPI") Log.e("[Assistant] [Phone Account Creation] Failed to get an auth token from FlexiAPI")
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: Failed to get an auth token from account manager server") onErrorEvent.value = Event("Error: Failed to get an auth token from account manager server")
} }
private fun checkUsername() { private fun checkUsername() {
val status = accountCreator.isAccountExist val status = accountCreator.isAccountExist
Log.i("[Phone Account Creation] isAccountExist returned $status") Log.i("[Assistant] [Phone Account Creation] isAccountExist returned $status")
if (status != AccountCreator.Status.RequestOk) { if (status != AccountCreator.Status.RequestOk) {
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: ${status.name}") onErrorEvent.value = Event("Error: ${status.name}")
@ -215,7 +233,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
private fun checkPhoneNumber() { private fun checkPhoneNumber() {
val status = accountCreator.isAliasUsed val status = accountCreator.isAliasUsed
Log.i("[Phone Account Creation] isAliasUsed returned $status") Log.i("[Assistant] [Phone Account Creation] isAliasUsed returned $status")
if (status != AccountCreator.Status.RequestOk) { if (status != AccountCreator.Status.RequestOk) {
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: ${status.name}") onErrorEvent.value = Event("Error: ${status.name}")
@ -226,11 +244,11 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
val token = accountCreator.token.orEmpty() val token = accountCreator.token.orEmpty()
if (token.isNotEmpty()) { if (token.isNotEmpty()) {
Log.i( Log.i(
"[Phone Account Creation] We already have an auth token from FlexiAPI [$token], continue" "[Assistant] [Phone Account Creation] We already have an auth token from FlexiAPI [$token], continue"
) )
onFlexiApiTokenReceived() onFlexiApiTokenReceived()
} else { } else {
Log.i("[Phone Account Creation] Requesting an auth token from FlexiAPI") Log.i("[Assistant] [Phone Account Creation] Requesting an auth token from FlexiAPI")
waitForServerAnswer.value = true waitForServerAnswer.value = true
requestFlexiApiToken() requestFlexiApiToken()
} }

View file

@ -60,12 +60,12 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Phone Account Linking] onIsAliasUsed status is $status") Log.i("[Assistant] [Phone Account Linking] onIsAliasUsed status is $status")
when (status) { when (status) {
AccountCreator.Status.AliasNotExist -> { AccountCreator.Status.AliasNotExist -> {
if (creator.linkAccount() != AccountCreator.Status.RequestOk) { if (creator.linkAccount() != AccountCreator.Status.RequestOk) {
Log.e("[Phone Account Linking] linkAccount status is $status") Log.e("[Assistant] [Phone Account Linking] linkAccount status is $status")
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: ${status.name}") onErrorEvent.value = Event("Error: ${status.name}")
} }
@ -86,7 +86,7 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho
status: AccountCreator.Status, status: AccountCreator.Status,
response: String? response: String?
) { ) {
Log.i("[Phone Account Linking] onLinkAccount status is $status") Log.i("[Assistant] [Phone Account Linking] onLinkAccount status is $status")
waitForServerAnswer.value = false waitForServerAnswer.value = false
when (status) { when (status) {
@ -113,6 +113,9 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho
linkEnabled.addSource(phoneNumberError) { linkEnabled.addSource(phoneNumberError) {
linkEnabled.value = isLinkButtonEnabled() linkEnabled.value = isLinkButtonEnabled()
} }
linkEnabled.addSource(prefixError) {
linkEnabled.value = isLinkButtonEnabled()
}
} }
override fun onCleared() { override fun onCleared() {
@ -123,10 +126,10 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho
override fun onFlexiApiTokenReceived() { override fun onFlexiApiTokenReceived() {
accountCreator.setPhoneNumber(phoneNumber.value, prefix.value) accountCreator.setPhoneNumber(phoneNumber.value, prefix.value)
accountCreator.username = username.value accountCreator.username = username.value
Log.i("[Phone Account Linking] Phone number is ${accountCreator.phoneNumber}") Log.i("[Assistant] [Phone Account Linking] Phone number is ${accountCreator.phoneNumber}")
val status: AccountCreator.Status = accountCreator.isAliasUsed val status: AccountCreator.Status = accountCreator.isAliasUsed
Log.i("[Phone Account Linking] isAliasUsed returned $status") Log.i("[Assistant] [Phone Account Linking] isAliasUsed returned $status")
if (status != AccountCreator.Status.RequestOk) { if (status != AccountCreator.Status.RequestOk) {
waitForServerAnswer.value = false waitForServerAnswer.value = false
onErrorEvent.value = Event("Error: ${status.name}") onErrorEvent.value = Event("Error: ${status.name}")
@ -134,12 +137,12 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho
} }
override fun onFlexiApiTokenRequestError() { override fun onFlexiApiTokenRequestError() {
Log.e("[Phone Account Linking] Failed to get an auth token from FlexiAPI") Log.e("[Assistant] [Phone Account Linking] Failed to get an auth token from FlexiAPI")
waitForServerAnswer.value = false waitForServerAnswer.value = false
} }
fun link() { fun link() {
Log.i("[Phone Account Linking] Requesting an auth token from FlexiAPI") Log.i("[Assistant] [Phone Account Linking] Requesting an auth token from FlexiAPI")
waitForServerAnswer.value = true waitForServerAnswer.value = true
requestFlexiApiToken() requestFlexiApiToken()
} }

View file

@ -34,7 +34,7 @@ class QrCodeViewModel : ViewModel() {
private val listener = object : CoreListenerStub() { private val listener = object : CoreListenerStub() {
override fun onQrcodeFound(core: Core, result: String?) { override fun onQrcodeFound(core: Core, result: String?) {
Log.i("[QR Code] Found [$result]") Log.i("[Assistant] [QR Code] Found [$result]")
if (result != null) qrCodeFoundEvent.postValue(Event(result)) if (result != null) qrCodeFoundEvent.postValue(Event(result))
} }
} }
@ -54,7 +54,7 @@ class QrCodeViewModel : ViewModel() {
for (camera in coreContext.core.videoDevicesList) { for (camera in coreContext.core.videoDevicesList) {
if (camera.contains("Back")) { if (camera.contains("Back")) {
Log.i("[QR Code] Found back facing camera: $camera") Log.i("[Assistant] [QR Code] Found back facing camera: $camera")
coreContext.core.videoDevice = camera coreContext.core.videoDevice = camera
return return
} }
@ -62,7 +62,7 @@ class QrCodeViewModel : ViewModel() {
val first = coreContext.core.videoDevicesList.firstOrNull() val first = coreContext.core.videoDevicesList.firstOrNull()
if (first != null) { if (first != null) {
Log.i("[QR Code] Using first camera found: $first") Log.i("[Assistant] [QR Code] Using first camera found: $first")
coreContext.core.videoDevice = first coreContext.core.videoDevice = first
} }
} }

View file

@ -73,7 +73,7 @@ class RemoteProvisioningViewModel : ViewModel() {
fun fetchAndApply() { fun fetchAndApply() {
val url = urlToFetch.value.orEmpty() val url = urlToFetch.value.orEmpty()
coreContext.core.provisioningUri = url coreContext.core.provisioningUri = url
Log.w("[Remote Provisioning] Url set to [$url], restarting Core") Log.w("[Assistant] [Remote Provisioning] Url set to [$url], restarting Core")
fetchInProgress.value = true fetchInProgress.value = true
coreContext.core.stop() coreContext.core.stop()
coreContext.core.start() coreContext.core.start()

View file

@ -593,7 +593,17 @@ fun addPhoneNumberEditTextValidation(editText: EditText, enabled: Boolean) {
fun addPrefixEditTextValidation(editText: EditText, enabled: Boolean) { fun addPrefixEditTextValidation(editText: EditText, enabled: Boolean) {
if (!enabled) return if (!enabled) return
editText.addTextChangedListener(object : TextWatcher { editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {} override fun afterTextChanged(s: Editable?) {
val dialPlan = PhoneNumberUtils.getDialPlanFromCountryCallingPrefix(
s.toString().substring(1)
)
if (dialPlan == null) {
editText.error =
editText.context.getString(
R.string.assistant_error_invalid_international_prefix
)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

View file

@ -119,6 +119,7 @@
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
assistantPhoneNumberPrefixValidation="@{true}" assistantPhoneNumberPrefixValidation="@{true}"
errorMessage="@={viewModel.prefixError}"
android:text="@={viewModel.prefix}" android:text="@={viewModel.prefix}"
android:imeOptions="actionNext" android:imeOptions="actionNext"
android:singleLine="true" android:singleLine="true"

View file

@ -116,6 +116,7 @@
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
assistantPhoneNumberPrefixValidation="@{true}" assistantPhoneNumberPrefixValidation="@{true}"
errorMessage="@={viewModel.prefixError}"
android:text="@={viewModel.prefix}" android:text="@={viewModel.prefix}"
android:imeOptions="actionNext" android:imeOptions="actionNext"
android:singleLine="true" android:singleLine="true"

View file

@ -126,6 +126,7 @@
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
assistantPhoneNumberPrefixValidation="@{true}" assistantPhoneNumberPrefixValidation="@{true}"
errorMessage="@={viewModel.prefixError}"
android:text="@={viewModel.prefix}" android:text="@={viewModel.prefix}"
android:imeOptions="actionNext" android:imeOptions="actionNext"
android:singleLine="true" android:singleLine="true"

View file

@ -790,4 +790,5 @@
<string name="content_description_emoji_picker">Change la visibilité du selectionneur d\'emoji</string> <string name="content_description_emoji_picker">Change la visibilité du selectionneur d\'emoji</string>
<string name="android_14_full_screen_intent_permission_not_granted">Permission requise pour afficher les appels entrant non accordée</string> <string name="android_14_full_screen_intent_permission_not_granted">Permission requise pour afficher les appels entrant non accordée</string>
<string name="android_14_go_to_full_screen_intent_permission_setting">Afficher</string> <string name="android_14_go_to_full_screen_intent_permission_setting">Afficher</string>
<string name="assistant_error_invalid_international_prefix">Préfixe international inconnu</string>
</resources> </resources>

View file

@ -422,6 +422,7 @@
<string name="assistant_error_invalid_email_address">Email address is invalid</string> <string name="assistant_error_invalid_email_address">Email address is invalid</string>
<string name="assistant_error_username_too_long">Username has too many characters</string> <string name="assistant_error_username_too_long">Username has too many characters</string>
<string name="assistant_error_invalid_credentials">Account does not exist or password does not match</string> <string name="assistant_error_invalid_credentials">Account does not exist or password does not match</string>
<string name="assistant_error_invalid_international_prefix">Wrong international prefix</string>
<!-- Assistant login --> <!-- Assistant login -->
<string name="assistant_linphone_account">Use your &appName; account</string> <string name="assistant_linphone_account">Use your &appName; account</string>