[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 0baf26c03a -s ours
am skip reason: subject contains skip directive
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telecomm/+/13842301
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: Icf0213d8f499ab5ce3d3da5a3d2604bfaef56e51
diff --git a/Android.bp b/Android.bp
index 0d89b00..b7eb450 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
genrule {
name: "statslog-telecom-java-gen",
tools: ["stats-log-api-gen"],
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7c57599..327d0a2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,80 +15,75 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- package="com.android.server.telecom"
- coreApp="true"
- android:sharedUserId="android.uid.system">
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ package="com.android.server.telecom"
+ coreApp="true"
+ android:sharedUserId="android.uid.system">
- <protected-broadcast android:name="android.intent.action.SHOW_MISSED_CALLS_NOTIFICATION" />
- <protected-broadcast android:name="com.android.server.telecom.MESSAGE_SENT" />
+ <protected-broadcast android:name="android.intent.action.SHOW_MISSED_CALLS_NOTIFICATION"/>
+ <protected-broadcast android:name="com.android.server.telecom.MESSAGE_SENT"/>
<!-- Prevents the activity manager from delaying any activity-start
requests by this package, including requests immediately after
the user presses "home". -->
- <uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE" />
- <uses-permission android:name="android.permission.BIND_INCALL_SERVICE" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO" />
- <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION" />
- <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
- <uses-permission android:name="android.permission.HANDLE_CALL_INTENT" />
- <uses-permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
- <uses-permission android:name="android.permission.MANAGE_USERS" />
- <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE"/>
+ <uses-permission android:name="android.permission.BIND_INCALL_SERVICE"/>
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+ <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO"/>
+ <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION"/>
+ <uses-permission android:name="android.permission.CALL_PRIVILEGED"/>
+ <uses-permission android:name="android.permission.HANDLE_CALL_INTENT"/>
+ <uses-permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
+ <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS"/>
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<!-- Required to determine source of ongoing audio recordings. -->
- <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- <uses-permission android:name="android.permission.READ_CALL_LOG" />
- <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.SEND_SMS" />
- <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
- <uses-permission android:name="android.permission.VIBRATE" />
- <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="android.permission.READ_BLOCKED_NUMBERS" />
- <uses-permission android:name="android.permission.WRITE_BLOCKED_NUMBERS" />
- <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING"/>
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.SEND_SMS"/>
+ <uses-permission android:name="android.permission.STOP_APP_SWITCHES"/>
+ <uses-permission android:name="android.permission.VIBRATE"/>
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
+ <uses-permission android:name="android.permission.READ_BLOCKED_NUMBERS"/>
+ <uses-permission android:name="android.permission.WRITE_BLOCKED_NUMBERS"/>
+ <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
- <permission
- android:name="android.permission.BROADCAST_CALLLOG_INFO"
- android:label="Broadcast the call type/duration information"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.BROADCAST_CALLLOG_INFO"
+ android:label="Broadcast the call type/duration information"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.PROCESS_CALLLOG_INFO"
- android:label="Register to handle the broadcasted call type/duration information"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.PROCESS_CALLLOG_INFO"
+ android:label="Register to handle the broadcasted call type/duration information"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION"
- android:label="Broadcast phone account registration"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION"
+ android:label="Broadcast phone account registration"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"
- android:label="Process phone account registration"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"
+ android:label="Process phone account registration"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.HANDLE_CALL_INTENT"
- android:label="Protects handling the call intent via the TelecomManager API."
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.HANDLE_CALL_INTENT"
+ android:label="Protects handling the call intent via the TelecomManager API."
+ android:protectionLevel="signature|system"/>
<application android:label="@string/telecommAppLabel"
- android:icon="@mipmap/ic_launcher_phone"
- android:allowBackup="false"
- android:supportsRtl="true"
- android:process="system"
- android:usesCleartextTraffic="false"
- android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true">
+ android:icon="@mipmap/ic_launcher_phone"
+ android:allowBackup="false"
+ android:supportsRtl="true"
+ android:process="system"
+ android:usesCleartextTraffic="false"
+ android:defaultToDeviceProtectedStorage="true"
+ android:directBootAware="true">
<!-- CALL vs CALL_PRIVILEGED vs CALL_EMERGENCY
We have three different intents through which a call can be initiated each with its
@@ -104,60 +99,61 @@
<!-- Activity that displays UI for managing blocked numbers. -->
<activity android:name=".settings.BlockedNumbersActivity"
- android:label="@string/blocked_numbers"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Telecom.BlockedNumbers"
- android:process=":ui"
- android:exported="true">
+ android:label="@string/blocked_numbers"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.BlockedNumbers"
+ android:process=":ui"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.action.MANAGE_BLOCKED_NUMBERS" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.action.MANAGE_BLOCKED_NUMBERS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".settings.CallBlockDisabledActivity"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="keyboardHidden|orientation|screenSize"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<!-- Activity that starts the outgoing call process by listening to CALL intent which
- contain contact information in the intent's data. CallActivity handles any data
- URL with the schemes "tel", "sip", and "voicemail". It also handles URLs linked to
- contacts provider entries. Any data not fitting the schema described is ignored. -->
+ contain contact information in the intent's data. CallActivity handles any data
+ URL with the schemes "tel", "sip", and "voicemail". It also handles URLs linked to
+ contacts provider entries. Any data not fitting the schema described is ignored. -->
<activity android:name=".components.UserCallActivity"
- android:label="@string/userCallActivityLabel"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:permission="android.permission.CALL_PHONE"
- android:excludeFromRecents="true"
- android:process=":ui">
+ android:label="@string/userCallActivityLabel"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:permission="android.permission.CALL_PHONE"
+ android:excludeFromRecents="true"
+ android:process=":ui"
+ android:exported="true">
<!-- CALL action intent filters for the various ways of initiating an outgoing call. -->
<intent-filter>
- <action android:name="android.intent.action.CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<!-- Specify an icon for SIP calls so that quick contacts widget shows a special SIP
- icon for calls to SIP addresses. -->
+ icon for calls to SIP addresses. -->
<intent-filter android:icon="@drawable/ic_launcher_sip_call">
- <action android:name="android.intent.action.CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="sip" />
+ <action android:name="android.intent.action.CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<!-- Omit default category below so that all Intents sent to this filter must be
- explicit. -->
+ explicit. -->
<intent-filter>
- <action android:name="android.intent.action.CALL" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/phone_v2" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.CALL"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/phone_v2"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
</activity>
@@ -167,30 +163,30 @@
processed. High priority of 1000 is used in all intent filters to prevent anything but
the system from processing this intent (b/8871505). -->
<activity-alias android:name="PrivilegedCallActivity"
- android:targetActivity=".components.UserCallActivity"
- android:permission="android.permission.CALL_PRIVILEGED"
- android:process=":ui">
+ android:targetActivity=".components.UserCallActivity"
+ android:permission="android.permission.CALL_PRIVILEGED"
+ android:process=":ui">
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter android:priority="1000"
- android:icon="@drawable/ic_launcher_sip_call">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="sip" />
+ android:icon="@drawable/ic_launcher_sip_call">
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/phone_v2" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/phone_v2"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
</activity-alias>
@@ -200,123 +196,129 @@
1000 is used in all intent filters to prevent anything but the system from processing
this intent (b/8871505). -->
<!-- TODO: Is there really a notion of an emergency SIP number? If not, can
- that scheme be removed from this activity? -->
+ that scheme be removed from this activity? -->
<activity-alias android:name="EmergencyCallActivity"
- android:targetActivity=".components.UserCallActivity"
- android:permission="android.permission.CALL_PRIVILEGED"
- android:process=":ui">
+ android:targetActivity=".components.UserCallActivity"
+ android:permission="android.permission.CALL_PRIVILEGED"
+ android:process=":ui">
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter android:priority="1000"
- android:icon="@drawable/ic_launcher_sip_call">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="sip" />
+ android:icon="@drawable/ic_launcher_sip_call">
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/phone_v2" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/phone_v2"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
</activity-alias>
- <receiver android:name=".components.TelecomBroadcastReceiver" android:exported="false"
- android:process="system">
+ <receiver android:name=".components.TelecomBroadcastReceiver"
+ android:exported="false"
+ android:process="system">
<intent-filter>
- <action android:name="com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS" />
- <action android:name="com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.ACTION_ANSWER_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.PROCEED_WITH_CALL" />
- <action android:name="com.android.server.telecom.CANCEL_CALL" />
- <action android:name="com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL" />
- <action android:name="com.android.server.telecom.CANCEL_REDIRECTED_CALL" />
+ <action android:name="com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS"/>
+ <action android:name="com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.ACTION_ANSWER_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.PROCEED_WITH_CALL"/>
+ <action android:name="com.android.server.telecom.CANCEL_CALL"/>
+ <action android:name="com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL"/>
+ <action android:name="com.android.server.telecom.CANCEL_REDIRECTED_CALL"/>
</intent-filter>
</receiver>
<receiver android:name=".components.AppUninstallBroadcastReceiver"
- android:process="system">
+ android:process="system"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
- <data android:scheme="package" />
+ <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED"/>
+ <data android:scheme="package"/>
</intent-filter>
</receiver>
<activity android:name=".RespondViaSmsSettings"
- android:label="@string/respond_via_sms_setting_title"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Telecom.DialerSettings"
- android:process=":ui">
+ android:label="@string/respond_via_sms_setting_title"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.DialerSettings"
+ android:process=":ui"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <action android:name="android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".settings.EnableAccountPreferenceActivity"
- android:label="@string/enable_account_preference_title"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Telecom.DialerSettings"
- android:process=":ui">
+ android:label="@string/enable_account_preference_title"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.DialerSettings"
+ android:process=":ui"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".components.ErrorDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<activity android:name=".ui.ConfirmCallDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<activity android:name=".ui.CallRedirectionTimeoutDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<activity android:name=".ui.TelecomDeveloperMenu"
- android:label="@string/developer_title"
- android:exported="false"
- android:process=":ui" />
+ android:label="@string/developer_title"
+ android:exported="false"
+ android:process=":ui"/>
<service android:name=".components.BluetoothPhoneService"
- android:singleUser="true"
- android:process="system">
+ android:singleUser="true"
+ android:process="system"
+ android:exported="true">
<intent-filter>
- <action android:name="android.bluetooth.IBluetoothHeadsetPhone" />
+ <action android:name="android.bluetooth.IBluetoothHeadsetPhone"/>
</intent-filter>
</service>
<service android:name=".components.TelecomService"
- android:singleUser="true"
- android:process="system">
+ android:singleUser="true"
+ android:process="system"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ITelecomService" />
+ <action android:name="android.telecom.ITelecomService"/>
</intent-filter>
</service>
diff --git a/OWNERS b/OWNERS
index 94409ef..39be2c1 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,6 @@
breadley@google.com
hallliu@google.com
tgunn@google.com
-paulye@google.com
+xiaotonj@google.com
+shuoq@google.com
+rgreenwalt@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 75feeb6..2e14650 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -16,5 +16,15 @@
}
]
}
+ ],
+ "presubmit-large": [
+ {
+ "name": "CtsTelecomTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
]
}
diff --git a/res/raw/InCallQualityNotification.ogg b/res/raw/InCallQualityNotification.ogg
new file mode 100644
index 0000000..84c029a
--- /dev/null
+++ b/res/raw/InCallQualityNotification.ogg
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 2857be3..ac2140b 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Boodskap"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Oproep is ontkoppel"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Die oproep na <xliff:g id="CALLER">%s</xliff:g> is ontkoppel as gevolg van \'n noodoproep wat gemaak word."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Jou oproep is ontkoppel as gevolg van \'n noodoproep wat gemaak word."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Agtergrondoproep"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> het \'n oproep in die agtergrond geplaas. Hierdie program kan dalk toegang tot oudio kry en dit oor die oproep speel."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> het opgehou reageer"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Jou oproep het die foonprogram gebruik wat saam met jou toestel gekom het"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Omgevalde foonprogram"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Jou foonprogram <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> het omgeval. Jou oproep is voortgesit deur die foonprogram te gebruik wat jy saam met jou toestel gekry het."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Oproep stilgemaak."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Luidsprekerfoon geaktiveer."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kan nie nou praat nie. Hoe\'s dit?"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index df8215c..1c2d161 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"መልዕክት"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"የተቋረጠ ጥሪ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"የአደጋ ጊዜ ጥሪ እየተደረገ ስለሆነ ወደ <xliff:g id="CALLER">%s</xliff:g> የሚደረገው ጥሪ ተቋርጧል።"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"የአደጋ ጊዜ ጥሪ እየተደረገ ስለሆነ የእርስዎ ጥሪ ተቋርጧል።"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"የጀርባ ጥሪ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ጥሪን ወደ ጀርባ አስቀምጧል። ይህ መተግበሪያ ጥሪው ላይ ኦዲዮ ላይ እየደረሰ ወይም እያጫወተ ሊሆን ይችላል።"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ምላሽ መስጠት አቁሟል"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ጥሪዎ ከእርስዎ መሣሪያ ጋር የመጣውን የስልክ መተግበሪያ ተጠቅሟል"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"የተበላሸ የስልክ መተግበሪያ"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ጥሪ ፀጥ ብሏል"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"የስልክ ድምፅ ማጉያ ነቅቷል።"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"አሁን ማውራት አልችልም። ሰላም ነው?"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 7e204d0..70d2334 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"رسالة"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"تم قطع الاتصال"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"تم قطع اتصالك بجهة الاتصال <xliff:g id="CALLER">%s</xliff:g> بسبب إجراء مكالمة طوارئ."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"تم قطع مكالمتك بسبب إجراء مكالمة طوارئ."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"مكالمة في الخلفية"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"وضَع <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> مكالمة في الخلفية. يمكن لهذا التطبيق الوصول إلى الصوت وتشغيله عبر المكالمة."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"توقّف <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> عن الاستجابة"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"تمت مكالمتك باستخدام تطبيق \"الهاتف\" الذي أتى مع جهازك."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"لقد تعطّل تطبيق الهاتف"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"تم كتم صوت المكالمة."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"تم تفعيل مكبر صوت الهاتف."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"لا يمكنني التحدث الآن. ما الأمر؟"</string>
@@ -73,10 +73,10 @@
<string name="non_primary_user" msgid="315564589279622098">"يمكن لمالك الجهاز فقط الاطّلاع على الأرقام المحظورة وإدارتها."</string>
<string name="delete_icon_description" msgid="5335959254954774373">"إلغاء الحظر"</string>
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"تم إيقاف الحظر مؤقتًا"</string>
- <string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"بعد الاتصال الهاتفي أو إرسال رسالة نصية إلى رقم طوارئ، يتم إيقاف الحظر لضمان تمكن خدمات الطوارئ من الاتصال بك."</string>
+ <string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"بعد الاتصال الهاتفي أو إرسال رسالة نصية إلى رقم طوارئ، يتم إيقاف تفعيل الحظر لضمان تمكن خدمات الطوارئ من الاتصال بك."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"إعادة تفعيل الآن"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"تم حظر <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"تمت إزالة حظر <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"تم إلغاء حظر <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"غير قادر على حظر رقم الطوارئ."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"تم حظر <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> بالفعل."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"يتم استخدام أداة الاتصال الشخصي لإجراء الاتصال"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 2f5de68..5f123f9 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"বাৰ্তা"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"সংযোগ বিচ্ছিন্ন কৰা কল"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"এট জৰুৰীকালীন কল কৰাৰ কাৰণে <xliff:g id="CALLER">%s</xliff:g>লৈ কৰা কলটোৰ সংযোগ বিচ্ছিন্ন কৰা হৈছে।"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"এট জৰুৰীকালীন কল কৰাৰ কাৰণে আপোনাৰ কলটোৰ সংযোগ বিচ্ছিন্ন কৰা হৈছে।"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"নেপথ্যৰ কল"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>এ নেপথ্যত এটা কল কৰিছে। এই এপ্টোৱে কলটোত অডিঅ’ এক্সেছ আৰু প্লে’ কৰি থাকিব পাৰে।"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>এ সঁহাৰি দিয়া বন্ধ কৰিছে"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"আপোনাৰ কলটোৱে আপোনাৰ ডিভাইচটোৰ লগত অহা ফ’ন এপ্টো ব্যৱহাৰ কৰিছে"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ক্ৰেশ্ব হোৱা ফ\'ন এপ্"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"আপোনাৰ ফ\'ন এপ্ <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ক্ৰেশ্ব হৈছে। আপোনাৰ ডিভাইচটোৰ লগত অহা ফ\'ন এপ্টো ব্যৱহাৰ কৰি আপোনাৰ কলটো অব্যাহত ৰখা হৈছিল।"</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"কল মিউট কৰা হৈছে।"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"স্পীকাৰফ\'ন সক্ষম কৰা হৈছে।"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"এতিয়া কথা পাতিব নোৱাৰোঁ। কি খবৰ?"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index d79343f..aa176e7 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mesaj"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Əlaqəsi kəsilmiş zəng"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Hazırda təcili zəng edildiyi üçün <xliff:g id="CALLER">%s</xliff:g> ilə zəng kəsilib."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Təcili zəng edildiyinə görə zənginizin əlaqəsi kəsildi."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Arxa fon zəngi"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> arxa fonda zəng edib. Bu tətbiq zəng ilə daxil ola və oxuda bilər."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> tətbiqində xəta baş verdi"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Zəng üçün cihazda əvvəlcədən quraşdırılan telefon tətbiqindən istifadə edildi"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Xəta baş verən telefon tətbiqi"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> tətbiqində xəta baş verdi. Zənginiz cihazda əvvəlcədən quraşdırılmış telefon tətbiqindən davam etdirildi."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Səssiz zəng edin."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Spikerfon aktivdir."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"İndi danışmaq olmur. Nə olub?"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index eba8c5c..03225e5 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Nepoznato"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Propušten poziv"</string>
- <string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"Propušten poslovni poziv"</string>
+ <string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"Propušten poziv za Work"</string>
<string name="notification_missedCallsTitle" msgid="3910479625507893809">"Propušteni pozivi"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"Broj propuštenih poziva: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"Propušten poziv od: <xliff:g id="MISSED_CALL_FROM">%s</xliff:g>"</string>
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Poruka"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Poziv je prekinut"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Poziv sa <xliff:g id="CALLER">%s</xliff:g> je prekinut jer se upućuje hitni poziv."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Poziv je prekinut jer se upućuje hitni poziv."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Poziv u pozadini"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikacija <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> je uputila poziv u pozadini. Ona može da pristupa zvuku i pušta ga tokom poziva."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> više ne reaguje"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Poziv je koristio aplikaciju za telefoniranje koju ste dobili uz uređaj"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikacija za telefoniranje koja je otkazala"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Aplikacija za telefoniranje <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> je otkazala. Poziv je nastavljen pomoću aplikacije za telefoniranje koju ste dobili uz uređaj."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Zvuk poziva je isključen."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Spikerfon je omogućen."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"U gužvi sam. O čemu se radi?"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index b6dd707..3668e38 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -27,17 +27,17 @@
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"Адказаць"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"Паведамленне"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Выклік перарваны"</string>
- <string name="notification_disconnectedCall_body" msgid="600491714584417536">"Выклік да абанента <xliff:g id="CALLER">%s</xliff:g> перарваны, бо выконваецца экстранны выклік."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Бягучы выклік перарваны, бо выконваецца экстранны выклік."</string>
+ <string name="notification_disconnectedCall_body" msgid="600491714584417536">"Выклік абанента <xliff:g id="CALLER">%s</xliff:g> быў перарваны з-за ажыццяўлення экстраннага выкліку."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Фонавы выклік"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Праграма \"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>\" перавяла выклік у фонавы рэжым і можа прайграваць аўдыя падчас выкліку."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Праграма \"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>\" не адказвае"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Выклік зроблены ў стандартнай праграме \"Тэлефон\" на прыладзе"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Збой у праграме \"Тэлефон\""</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Гук выключаны."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Уключаная гучная сувязь."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Не магу гаварыць. У чым справа?"</string>
- <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Я зараз перазваню."</string>
- <string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Перазваню пазней."</string>
+ <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Я выклікаю цябе праз момант."</string>
+ <string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Я выклікаю цябе пазней."</string>
<string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"Не магу адказаць. Пагаворым пазней?"</string>
<string name="respond_via_sms_setting_title" msgid="4762275482898830160">"Хуткія адказы"</string>
<string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"Рэдагаваць хуткія адказы"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 7afddc2..cfb9c12 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Съобщение"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Прекъснато обаждане"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Обаждането до <xliff:g id="CALLER">%s</xliff:g> бе прекъснато, тъй като се извършва спешно обаждане."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Обаждането ви бе прекъснато, тъй като се извършва спешно обаждане."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Обаждане: заден план"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> постави обаждане на заден план. Приложението може да има достъп до обаждането и да възпроизвежда звук върху него."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> престана да реагира"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Обаждането ви бе извършено с приложението за телефон, което сте получили с устройството си"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Приложение за телефон с прекъсната работа"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Обаждането бе спряно."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Високоговорителят бе активиран."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Сега не мога да говоря. Какво има?"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index cf04d40..7bdbcf7 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"মেসেজ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"ডিসকানেক্ট করা কল"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"জরুরি কল করার জন্য <xliff:g id="CALLER">%s</xliff:g>-কে করা কল ডিসকানেক্ট করা হয়েছে।"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"জরুরী কল করার জন্য আপনার কল ডিসকানেক্ট করা হয়েছে।"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"ব্যাকগ্রাউন্ডের কল"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ব্যাকগ্রাউন্ডে কল রেখেছে। এই অ্যাপটি হয়ত কলের মাধ্যমে অডিও অ্যাক্সেস করে চালাচ্ছে।"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> কাজ করছে না"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"আপনার ডিভাইসের ফোন অ্যাপ ব্যবহার করে কল করা হত"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ক্র্যাশ হওয়া ফোন অ্যাপ"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"কল মিউট করা আছে৷"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"স্পীকারফোন সক্ষম করা আছে৷"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"এখন কথা বলতে পারছি না৷ কি খবর?"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 1968357..f6619e5 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Poruka"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Poziv je prekinut"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Poziv upućen kontaktu <xliff:g id="CALLER">%s</xliff:g> je prekinut zbog upućivanja hitnog poziva."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Poziv je prekinut zbog upućivanja hitnog poziva."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Poziv u pozadini"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikacija <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> je uputila poziv u pozadini. Ova aplikacija može pristupati zvuku i reproducirati ga tokom poziva."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Aplikacija <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> je prestala reagirati"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Za poziv se koristila aplikacija za telefon koju ste dobili uz uređaj"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Pad aplikacije za telefon"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Zvuk poziva je isključen."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Zvučnik je omogućen."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Ne mogu sada pričati. O čemu se radi?"</string>
@@ -113,7 +113,7 @@
<string name="phone_settings_payphone_txt" msgid="5003987966052543965">"Telefonska govornica"</string>
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"Blokirajte pozive s telefonskih govornica"</string>
<string name="phone_settings_unknown_txt" msgid="3577926178354772728">"Nepoznato"</string>
- <string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"Blokiraj pozive neidentificiranih pozivaoca"</string>
+ <string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"Blokirajte pozive neidentificiranih pozivalaca"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"Blokiranje poziva"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"Blokiranje poziva je onemogućeno"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"Upućen je hitni poziv"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 69a7b6e..b098bbb 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Missatge"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Trucada desconnectada"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"La trucada a <xliff:g id="CALLER">%s</xliff:g> s\'ha desconnectat perquè s\'ha fet una trucada d\'emergència."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"La teva trucada s\'ha desconnectat perquè s\'ha fet una trucada d\'emergència."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Trucada en segon pla"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ha fet una trucada en segon pla. És possible que aquesta aplicació estigui accedint a l\'àudio i reproduint-lo a través de la trucada."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ha deixat de respondre"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"A la trucada s\'ha fet servir l\'aplicació de telèfon que hi ha al dispositiu"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplicació del telèfon que s\'ha bloquejat"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"L\'aplicació per a telèfons <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> s\'ha bloquejat. La trucada ha continuat amb l\'aplicació que hi ha al dispositiu."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Trucada silenciada."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Altaveu activat."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Ara no puc parlar. Què passa?"</string>
@@ -45,7 +44,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Resposta ràpida"</string>
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Missatge enviat a <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"No s\'ha pogut enviar el missatge a <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
- <string name="enable_account_preference_title" msgid="6949224486748457976">"Comptes de trucada"</string>
+ <string name="enable_account_preference_title" msgid="6949224486748457976">"Comptes de trucades"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Només es permeten les trucades d\'emergència."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Aquesta aplicació no pot fer trucades sortints sense el permís del telèfon."</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"Per realitzar una trucada, introdueix un número vàlid."</string>
@@ -99,7 +98,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Bloqueig de trucades"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Trucades en segon pla"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Trucades desconnectades"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplicacions del telèfon que han fallat"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplicacions del telèfon que s\'han bloquejat"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"En fer aquesta trucada, finalitzarà la de l\'aplicació <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Tria com vols fer aquesta trucada"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Desvia la trucada amb <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 1730a30..7683e9f 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Zpráva"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Hovor byl odpojen"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Hovor s volajícím <xliff:g id="CALLER">%s</xliff:g> byl odpojen, protože začalo být prováděno tísňové volání."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Váš hovor byl odpojen, protože bylo zahájeno tísňové volání."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Hovor na pozadí"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikace <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> přesunula hovor na pozadí. Tato aplikace může v hovoru používat a přehrávat zvuk."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Aplikace <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> přestala reagovat"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Při hovoru byla použita předinstalovaná telefonní aplikace"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikace na telefonování spadla"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Vaše aplikace na telefonování <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> spadla. Hovor pokračoval přes aplikaci, která byla na vašem zařízení předinstalovaná."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Hovor ztlumen."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Reproduktor je zapnutý."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Teď nemůžu mluvit, o co jde?"</string>
@@ -99,7 +98,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blokování hovorů"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Hovory na pozadí"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Odpojené hovory"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplikace, které spadly"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplikace na telefonování spadly"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Uskutečněním tohoto hovoru ukončíte hovor <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Vyberte, jak chcete tento hovor provést"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Přesměrovat hovor přes aplikaci <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 6a208c4..5819f2b 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -19,7 +19,7 @@
<string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Opkaldsstyring"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Opkald"</string>
<string name="unknown" msgid="6993977514360123431">"Ukendt"</string>
- <string name="notification_missedCallTitle" msgid="5060387047205532974">"Ubesvaret opkald"</string>
+ <string name="notification_missedCallTitle" msgid="5060387047205532974">"Ubesvarede opkald"</string>
<string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"Ubesvaret arbejdsopkald"</string>
<string name="notification_missedCallsTitle" msgid="3910479625507893809">"Ubesvarede opkald"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> ubesvarede opkald"</string>
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Besked"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Afbrudt opkald"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Opkaldet til <xliff:g id="CALLER">%s</xliff:g> er blevet afbrudt, fordi der foretages et nødopkald."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Dit opkald er blevet afbrudt, fordi der foretages et nødopkald."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Opkald i baggrunden"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> har foretaget et opkald i baggrunden. Denne app har muligvis adgang til og afspiller lyd i opkaldet."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> svarer ikke"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Dit opkald brugte den opkaldsapp, din enhed er født med"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Opkaldsapp, der er gået ned"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Opkaldsappen <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> er gået ned. Dit opkald fortsatte ved hjælp af den opkaldsapp, din enhed er født med."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Lyd slået fra opkald."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Højttalertelefon aktiveret."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kan ikke tale nu. Hvad sker der?"</string>
@@ -66,7 +65,7 @@
<string name="blocked_numbers_msg" msgid="2797422132329662697">"Du modtager ikke opkald og sms-beskeder fra blokerede numre."</string>
<string name="block_number" msgid="3784343046852802722">"Tilføj et nummer"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"Vil du fjerne blokeringen af <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
- <string name="unblock_button" msgid="8732021675729981781">"Fjern blokering"</string>
+ <string name="unblock_button" msgid="8732021675729981781">"Fjern blokeringen"</string>
<string name="add_blocked_dialog_body" msgid="8599974422407139255">"Bloker opkald og sms-beskeder fra"</string>
<string name="add_blocked_number_hint" msgid="8769422085658041097">"Telefonnummer"</string>
<string name="block_button" msgid="485080149164258770">"Bloker"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c434ecc..16e7901 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -21,18 +21,17 @@
<string name="unknown" msgid="6993977514360123431">"Unbekannt"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Entgangener Anruf"</string>
<string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"Verpasster geschäftlicher Anruf"</string>
- <string name="notification_missedCallsTitle" msgid="3910479625507893809">"Verpasste Anrufe"</string>
- <string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> verpasste Anrufe"</string>
+ <string name="notification_missedCallsTitle" msgid="3910479625507893809">"Entgangene Anrufe"</string>
+ <string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> entgangene Anrufe"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"Entgangener Anruf von <xliff:g id="MISSED_CALL_FROM">%s</xliff:g>"</string>
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"Zurückrufen"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"Nachricht"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Anruf beendet"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Der Anruf mit <xliff:g id="CALLER">%s</xliff:g> wurde beendet, weil ein Notruf getätigt wurde."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Der Anruf wurde beendet, weil ein Notruf getätigt wurde."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Anruf im Hintergrund"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> hat einen Anruf in den Hintergrund verschoben. Diese App greift möglicherweise auf den Anruf zu und spielt Audio darüber ab."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> reagiert nicht mehr"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Für den Anruf wurde die auf deinem Gerät vorinstallierte App verwendet"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Abgestürzte Telefon-App"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Deine Telefon-App \"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>\" ist abgestürzt. Der Anruf wurde mit der auf deinem Gerät vorinstallierten App fortgesetzt."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Anruf stummgeschaltet"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Freisprechfunktion aktiviert"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kann jetzt nicht sprechen. Was gibt\'s?"</string>
@@ -47,7 +46,7 @@
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Fehler beim Senden der Nachricht an <xliff:g id="PHONE_NUMBER">%s</xliff:g>"</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Anrufkonten"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Es sind nur Notrufe erlaubt."</string>
- <string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Diese App darf ohne die Berechtigung \"Telefon-App\" keine ausgehenden Anrufe tätigen."</string>
+ <string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Diese App darf ohne die Berechtigung \"Standard-App für Telefonie\" keine ausgehenden Anrufe tätigen."</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"Gib eine gültige Nummer ein."</string>
<string name="duplicate_video_call_not_allowed" msgid="5754746140185781159">"Der Anruf kann momentan nicht hinzugefügt werden."</string>
<string name="no_vm_number" msgid="2179959110602180844">"Fehlende Mailbox-Nummer"</string>
@@ -63,7 +62,7 @@
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"Als Standard festlegen"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"Abbrechen"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"Blockierte Nummern"</string>
- <string name="blocked_numbers_msg" msgid="2797422132329662697">"Du erhältst von blockierten Nummern keine Anrufe oder SMS."</string>
+ <string name="blocked_numbers_msg" msgid="2797422132329662697">"Du erhältst keine Anrufe oder SMS von blockierten Nummern."</string>
<string name="block_number" msgid="3784343046852802722">"Nummer hinzufügen"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"Blockierung von <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> aufheben?"</string>
<string name="unblock_button" msgid="8732021675729981781">"Blockierung aufheben"</string>
@@ -95,7 +94,7 @@
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"Dieser Anruf kann aufgrund deiner Anrufe in <xliff:g id="OTHER_CALL">%1$s</xliff:g> nicht getätigt werden."</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"Dieser Anruf kann aufgrund eines Anrufs in einer anderen App nicht getätigt werden."</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"Eingehende Anrufe"</string>
- <string name="notification_channel_missed_call" msgid="7168893015283909012">"Verpasste Anrufe"</string>
+ <string name="notification_channel_missed_call" msgid="7168893015283909012">"Entgangene Anrufe"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Anrufblockierung"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Anrufe im Hintergrund"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Beendete Anrufe"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index ab523c1..2d856b1 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Μήνυμα"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Αποσύνδεση κλήσης"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Η κλήση προς <xliff:g id="CALLER">%s</xliff:g> αποσυνδέθηκε λόγω πραγματοποίησης κλήσης έκτακτης ανάγκης."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Η κλήση σας αποσυνδέθηκε λόγω πραγματοποίησης κλήσης έκτακτης ανάγκης."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Κλήση στο παρασκήνιο"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Η εφαρμογή <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> πραγματοποίησε μια κλήση στο παρασκήνιο. Η εφαρμογή αυτή ενδέχεται να έχει δικαίωμα προσπέλασης και αναπαραγωγής ήχου κατά τη διάρκεια της κλήσης."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Η εφαρμογή <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> έπαψε να αποκρίνεται"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Η κλήση σας πραγματοποιήθηκε μέσω της αρχικής εφαρμογής τηλεφώνου της συσκευής σας."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Εφαρμογή τηλεφώνου που αντιμετώπισε σφάλμα λειτουργίας"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Η κλήση τέθηκε σε σίγαση."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Η ανοικτή συνομιλία ενεργοποιήθηκε."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Δεν μπορώ τώρα. Συμβαίνει κάτι;"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 4de7584..afda868 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Disconnected call"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"The call to <xliff:g id="CALLER">%s</xliff:g> has been disconnected due to an emergency call being placed."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Your call has been disconnected due to an emergency call being placed."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Background call"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> has placed a call into the background. This app may be accessing and playing audio over the call."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> stopped responding"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Your call used the phone app that came with your device"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Crashed Phone app"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Your phone app <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> has crashed. You call was continued using the phone app that came with your device."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Call muted."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Speakerphone enabled."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Can\'t talk now. What\'s going on?"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 4de7584..afda868 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Disconnected call"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"The call to <xliff:g id="CALLER">%s</xliff:g> has been disconnected due to an emergency call being placed."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Your call has been disconnected due to an emergency call being placed."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Background call"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> has placed a call into the background. This app may be accessing and playing audio over the call."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> stopped responding"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Your call used the phone app that came with your device"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Crashed Phone app"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Your phone app <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> has crashed. You call was continued using the phone app that came with your device."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Call muted."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Speakerphone enabled."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Can\'t talk now. What\'s going on?"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 4de7584..afda868 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Disconnected call"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"The call to <xliff:g id="CALLER">%s</xliff:g> has been disconnected due to an emergency call being placed."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Your call has been disconnected due to an emergency call being placed."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Background call"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> has placed a call into the background. This app may be accessing and playing audio over the call."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> stopped responding"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Your call used the phone app that came with your device"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Crashed Phone app"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Your phone app <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> has crashed. You call was continued using the phone app that came with your device."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Call muted."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Speakerphone enabled."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Can\'t talk now. What\'s going on?"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 4de7584..afda868 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Disconnected call"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"The call to <xliff:g id="CALLER">%s</xliff:g> has been disconnected due to an emergency call being placed."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Your call has been disconnected due to an emergency call being placed."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Background call"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> has placed a call into the background. This app may be accessing and playing audio over the call."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> stopped responding"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Your call used the phone app that came with your device"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Crashed Phone app"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Your phone app <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> has crashed. You call was continued using the phone app that came with your device."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Call muted."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Speakerphone enabled."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Can\'t talk now. What\'s going on?"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 3b3a983..e1edced 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Disconnected call"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"The call to <xliff:g id="CALLER">%s</xliff:g> has been disconnected due to an emergency call being placed."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Your call has been disconnected due to an emergency call being placed."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Background call"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> has placed a call into the background. This app may be accessing and playing audio over the call."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> stopped responding"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Your call used the phone app that came with your device"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Crashed phone app"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Your phone app <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> has crashed. You call was continued using the phone app that came with your device."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Call muted."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Speakerphone enabled."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Can\'t talk now. What\'s up?"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 826b877..89ba06f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mensaje"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Se desconectó la llamada"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Se desconectó la llamada a <xliff:g id="CALLER">%s</xliff:g> porque se está realizando una llamada de emergencia."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Se desconectó tu llamada porque se está haciendo una llamada de emergencia."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Llamada en 2.° plano"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> movió una a segundo plano. Es posible que esta app acceda a la llamada y reproduzca audio."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> dejó de responder"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Tu llamada se hizo con la app de teléfono que venía en tu dispositivo"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"App de teléfono con fallas"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Llamada silenciada"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Altavoz habilitado"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"No puedo hablar ahora. ¿Todo bien?"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index e124de4..5860766 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mensaje"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Llamada interrumpida"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Se ha interrumpido la llamada a <xliff:g id="CALLER">%s</xliff:g> debido a una llamada de emergencia."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Se ha interrumpido tu llamada debido a una llamada de emergencia."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Llamada en segundo plano"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ha llamado en segundo plano. Puede que esta aplicación acceda al audio y lo reproduzca durante la llamada."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ha dejado de responder"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"La llamada se utilizó la aplicación para teléfonos que venía con tu dispositivo"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplicación para teléfonos bloqueada"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Tu aplicación para teléfonos <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> se ha bloqueado. La llamada continuó con la aplicación para teléfonos de tu dispositivo."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Llamada silenciada"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Altavoz habilitado"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"No puedo hablar. ¿Es importante?"</string>
@@ -45,7 +44,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Respuesta rápida"</string>
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Mensaje enviado a <xliff:g id="PHONE_NUMBER">%s</xliff:g>"</string>
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"No se ha podido enviar el mensaje al <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
- <string name="enable_account_preference_title" msgid="6949224486748457976">"Cuentas de llamada"</string>
+ <string name="enable_account_preference_title" msgid="6949224486748457976">"Cuentas de llamadas"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Solo se permiten llamadas de emergencia."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Esta aplicación no puede hacer llamadas sin permiso del teléfono."</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"Para realizar una llamada, introduce un número válido."</string>
@@ -99,7 +98,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Bloqueo de llamadas"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Llamadas en segundo plano"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Llamadas interrumpidas"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplicaciones para teléfonos con bloqueos"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplicaciones para teléfonos bloqueadas"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Si haces esta llamada, se finalizará la de <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Elige cómo quieres hacer esta llamada"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Redirigir llamada con <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index bb291ad..71531f1 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Sõnum"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Kõne on katkestatud"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Kõne helistajaga <xliff:g id="CALLER">%s</xliff:g> on katkestatud, kuna alustati hädaabikõnet."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Teie kõne katkestati, kuna alustati hädaabikõnet."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Taustal olev kõne"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> lülitas kõne taustale. See rakendus võib helile juurde pääseda ja seda kõne ajal esitada."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> lõpetas reageerimise"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Teie kõne kasutas teie seadmega kaasas olnud telefonirakendust"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Kokkujooksnud telefonirakendus"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Kõne on summutatud."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Valjuhääldi on sisse lülitatud."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Ei saa praegu rääkida. Milles asi?"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index c8956cd..9649ab6 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mezua"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Deia deskonektatu egin da"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"<xliff:g id="CALLER">%s</xliff:g> deitzaileari egiten ari zinen deia deskonektatu da larrialdi-dei bat egiten ari zarelako."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Deia deskonektatu egin da, larrialdi-dei bat egiten ari zarelako."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Atzeko planoko deia"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> aplikazioak atzeko planoan jarri du deia. Baliteke aplikazioak audioa atzitzea eta erreproduzitzea deian zehar."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Erantzuteari utzi dio <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> aplikazioak"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Gailuaren telefono-aplikazioarekin egin da deia"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Telefonoko aplikazioak huts egin du"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> telefono-aplikazioak huts egin du. Gailuaren telefono-aplikazioa erabilita jarraitu da deia egiten."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Deiaren audioa desaktibatu da."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Bozgorailua gaitu da."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Ezin dut hitz egin. Arazoren bat al dago?"</string>
@@ -98,7 +97,7 @@
<string name="notification_channel_missed_call" msgid="7168893015283909012">"Dei galduak"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Deiak blokeatzeko aukera"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Atzeko planoko deiak"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Deskonektatutako deiak"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Deiak deskonektatu egin dira"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Huts egin duten telefonoko aplikazioak"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Dei hau egiten baduzu, amaitu egingo da <xliff:g id="OTHER_APP">%1$s</xliff:g> aplikazioko deia."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Aukeratu dei hau egiteko modua"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index c873159..3cc5bb6 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -28,15 +28,14 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"پیام"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"تماس قطعشده"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"بهدلیل انجام تماسی اضطراری، تماس با <xliff:g id="CALLER">%s</xliff:g> قطع شده است."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"بهدلیل برقراری تماس اضطراری، تماس شما قطع شده است."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"تماس پسزمینه"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> تماسی را در پسزمینه قرار داد. ممکن است این برنامه درحین تماس به صدا دسترسی پیدا کند و آن را پخش کند."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> متوقف شد"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"تماستان بااستفاده از برنامه تلفن ارائهشده در دستگاهتان برقرار شد"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"برنامه خراب تلفن"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"«برنامه تلفن» <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> خراب شده است. تماستان بااستفاده از «برنامه تلفن» ارائهشده در دستگاه ادامه پیدا کرد."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"تماس نادیده گرفته شد."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"تلفن آیفوندار فعال شد."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"الآن نمیتوانم صحبت کنم. موضوع چیست؟"</string>
- <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"همین حالا با شما تماس میگیرم."</string>
+ <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"همین حالا با شما تماس میگیرم.."</string>
<string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"بعداً با شما تماس میگیرم."</string>
<string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"اکنون نمیتوانم صحبت کنم. بعداً به من زنگ میزنید؟"</string>
<string name="respond_via_sms_setting_title" msgid="4762275482898830160">"پاسخهای سریع"</string>
@@ -81,13 +80,13 @@
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> قبلاً مسدود شده است."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"استفاده از شمارهگیر شخصی برای گرفتن تماس"</string>
<string name="notification_incoming_call" msgid="1233481138362230894">"<xliff:g id="CALL_VIA">%1$s</xliff:g> تماس از <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
- <string name="notification_incoming_video_call" msgid="5795968314037063900">"<xliff:g id="CALL_VIA">%1$s</xliff:g> تماس تصویری از <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
+ <string name="notification_incoming_video_call" msgid="5795968314037063900">"<xliff:g id="CALL_VIA">%1$s</xliff:g> تماس ویدیویی از <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
<string name="answering_ends_other_call" msgid="8653544281903986641">"پاسخگویی به تماس <xliff:g id="CALL_VIA">%1$s</xliff:g> پایان میدهد"</string>
<string name="answering_ends_other_calls" msgid="3702302838456922535">"پاسخگویی به تماسهای <xliff:g id="CALL_VIA">%1$s</xliff:g> شما پاسخ میدهد"</string>
- <string name="answering_ends_other_video_call" msgid="8572022039304239958">"پاسخگویی به تماس تصویری <xliff:g id="CALL_VIA">%1$s</xliff:g> شما پایان میدهد"</string>
+ <string name="answering_ends_other_video_call" msgid="8572022039304239958">"پاسخگویی به تماس ویدیویی <xliff:g id="CALL_VIA">%1$s</xliff:g> شما پایان میدهد"</string>
<string name="answering_ends_other_managed_call" msgid="4031778317409881805">"پاسخگویی به تماس درحال انجامتان پایان میدهد"</string>
<string name="answering_ends_other_managed_calls" msgid="3974069768615307659">"پاسخگویی به تماسهای درحال انجامتان پایان میدهد"</string>
- <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"پاسخگویی به تماس تصویری درحال انجامتان پایان میدهد"</string>
+ <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"پاسخگویی به تماس ویدیویی درحال انجامتان پایان میدهد"</string>
<string name="answer_incoming_call" msgid="2045888814782215326">"پاسخگویی"</string>
<string name="decline_incoming_call" msgid="922147089348451310">"نپذیرفتن"</string>
<string name="cant_call_due_to_no_supported_service" msgid="1635626384149947077">"بهدلیل اینکه هیچ حساب تماسی وجود ندارد که از این نوع تماس پشتیبانی کند، تماس برقرار نشد."</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index cf57d62..ab0830c 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Viesti"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Puhelu katkaistu"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Puhelu vastaanottajalle <xliff:g id="CALLER">%s</xliff:g> on katkaistu hätäpuhelun soittamisen vuoksi."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Puhelusi on katkaistu hätäpuhelun soittamisen vuoksi."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Taustapuhelu"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> on asettanut puhelun taustalle. Tämä sovellus voi käyttää ja toistaa ääntä puhelun päällä."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> lakkasi vastaamasta"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Puhelu soitettiin laitteen mukana tulleella puhelinsovelluksella"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Kaatunut puhelinsovellus"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Puhelu mykistetty."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Kaiutin käytössä."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"En voi vastata. Mitä asiaa?"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 74faab9..24c2eff 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Appel déconnecté"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"L\'appel à <xliff:g id="CALLER">%s</xliff:g> a été déconnecté en raison d\'un appel d\'urgence qui a été passé."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Votre appel a été déconnecté en raison d\'un appel d\'urgence en cours de lancement."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Appel en arrière-plan"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> a passé un appel en arrière-plan. Cette application peut accéder à l\'audio de l\'appel et faire jouer un contenu audio par l\'intermédiaire de l\'appel."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> a arrêté de répondre"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Votre appel a utilisé l\'application Téléphone intégrée à votre appareil"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"L\'application téléphonique a planté"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Son coupé"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Haut-parleur activé"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Peux pas parler. Quoi de neuf?"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"Lorsque vous communiquez avec les services d\'urgence par téléphone ou par message texte, la fonctionnalité de blocage est désactivée pour que ceux-ci puissent vous joindre."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"Réactiver le blocage maintenant"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"Le numéro <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> a été bloqué."</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"Le numéro <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> a été débloqué"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"Le numéro <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> a été débloqué."</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"Impossible de bloquer le numéro d\'urgence."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"Le numéro <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> a déjà été bloqué."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"Utilisation du clavier personnel pour faire l\'appel…"</string>
@@ -99,7 +99,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blocage des appels"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Appels en arrière-plan"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Appels déconnectés"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Applications téléphoniques qui ont planté"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Les applications téléphoniques ont planté"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Si vous passez cet appel, vous mettrez fin à l\'appel <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Choisissez comment passer cet appel"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Rediriger l\'appel en utilisant <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index c2a95a2..071f208 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -28,17 +28,17 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Message"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Appel interrompu"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"L\'appel avec <xliff:g id="CALLER">%s</xliff:g> a été interrompu en raison d\'un appel d\'urgence."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Votre appel a été interrompu en raison d\'un appel d\'urgence."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Appel en arrière-plan"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> a placé un appel en arrière-plan. Il est possible que cette application lise des fichiers audio pendant l\'appel."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> a cessé de répondre"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"L\'appel s\'est poursuivi dans l\'application d\'appel préinstallée sur votre appareil"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Une application d\'appel a planté"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Son coupé"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Haut-parleur activé"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Je ne peux pas répondre. Ça va ?"</string>
<string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Je te rappelle tout de suite."</string>
<string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Je t\'appelle plus tard."</string>
- <string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"Je ne peux pas répondre. On se rappelle ?"</string>
+ <string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"Peux pas répondre. On se rappelle ?"</string>
<string name="respond_via_sms_setting_title" msgid="4762275482898830160">"Réponses rapides"</string>
<string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"Modifier les réponses rapides"</string>
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
@@ -99,7 +99,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blocage d\'appels"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Appels en arrière-plan"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Appels interrompus"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Applications téléphoniques ayant planté"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Des applications d\'appel ont planté"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Si vous passez cet appel, vous mettrez fin à celui qui est en cours dans l\'application <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Choisissez comment passer cet appel"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Rediriger l\'appel avec <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
@@ -113,7 +113,7 @@
<string name="phone_settings_payphone_txt" msgid="5003987966052543965">"Cabines téléphoniques"</string>
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"Bloquez les appels provenant de cabines téléphoniques"</string>
<string name="phone_settings_unknown_txt" msgid="3577926178354772728">"Numéros inconnus"</string>
- <string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"Bloquer les appels provenant de personnes non identifiées"</string>
+ <string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"Bloquez les appels provenant de personnes non identifiées"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"Blocage d\'appels"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"Blocage d\'appels désactivé"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"Appel d\'urgence"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 42c55d6..d558f99 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mensaxe"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Chamada desconectada"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Desconectouse a chamada a <xliff:g id="CALLER">%s</xliff:g> porque se realizou unha chamada de emerxencia."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Desconectouse a chamada porque se realizou unha chamada de emerxencia."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Chamada seg. plano"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> chamou en segundo plano. Pode que esta aplicación acceda ao audio e o reproduza durante a chamada."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> deixou de responder"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Usouse a aplicación para teléfonos que ven co teu dispositivo na chamada"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Fallou a aplicación de teléfono"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Chamada silenciada"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Altofalante activado"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Non podo falar agora. Que pasa?"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 7455080..c20fb1b 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -19,7 +19,7 @@
<string name="telecommAppLabel" product="default" msgid="3077225713817780583">"કૉલ સંચાલન"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"ફોન"</string>
<string name="unknown" msgid="6993977514360123431">"અજાણ્યું"</string>
- <string name="notification_missedCallTitle" msgid="5060387047205532974">"ચૂકી ગયેલો કૉલ"</string>
+ <string name="notification_missedCallTitle" msgid="5060387047205532974">"છૂટેલો કૉલ"</string>
<string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"ચૂકી ગયેલ કાર્ય કૉલ"</string>
<string name="notification_missedCallsTitle" msgid="3910479625507893809">"છૂટેલા કૉલ્સ"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> છૂટેલા કૉલ્સ"</string>
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"સંદેશ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"ડિસ્કનેક્ટ કરેલો કૉલ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ઇમર્જન્સી કૉલને કારણે <xliff:g id="CALLER">%s</xliff:g>નો કૉલ ડિસ્કનેક્ટ કરવામાં આવ્યો છે."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ઇમર્જન્સી કૉલને કારણે તમારો કૉલ ડિસ્કનેક્ટ કરવામાં આવ્યો છે."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"બૅકગ્રાઉન્ડ કૉલ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>એ કૉલ બેકગ્રાઉન્ડમાં રાખ્યો છે. આ ઍપ કૉલ પરથી ઑડિયો ઍક્સેસ કરીને તેને ચલાવી શકે છે."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ઍપ પ્રતિસાદ આપી રહી નથી"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"તમારા કૉલ માટે તમારા ડિવાઇસમાં પહેલેથી ઇન્સ્ટૉલ કરેલી ફોન ઍપનો ઉપયોગ કરવામાં આવ્યો"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ફોન ઍપ ક્રૅશ થઈ"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"કૉલ મ્યૂટ કરેલ છે."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"સ્પીકરફોન પસંદ કરેલ છે."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"હમણાં વાત નહીં કરી શકું. શું હતું?"</string>
@@ -45,7 +45,7 @@
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"ઝડપી પ્રતિસાદ"</string>
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> પર સંદેશ મોકલ્યો."</string>
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g>ને સંદેશ મોકલવામાં નિષ્ફળ રહ્યાં."</string>
- <string name="enable_account_preference_title" msgid="6949224486748457976">"કૉલ કરવા માટેના એકાઉન્ટ"</string>
+ <string name="enable_account_preference_title" msgid="6949224486748457976">"કૉલિંગ એકાઉન્ટ્સ"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"ફક્ત કટોકટીના કૉલ્સને મંજૂરી છે."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"ફોન પરવાનગી વિના આ ઍપ્લિકેશન આઉટગોઇંગ કૉલ્સ કરી શકતી નથી."</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"કૉલ કરવા માટે, માન્ય નંબર દાખલ કરો."</string>
@@ -65,8 +65,8 @@
<string name="blocked_numbers" msgid="8322134197039865180">"અવરોધિત નંબરો"</string>
<string name="blocked_numbers_msg" msgid="2797422132329662697">"બ્લૉક કરેલા નંબર પરથી કૉલ અથવા ટેક્સ્ટ તમને આવશે નહિ."</string>
<string name="block_number" msgid="3784343046852802722">"એક નંબર ઉમેરો"</string>
- <string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> ને અનબ્લૉક કરીએ?"</string>
- <string name="unblock_button" msgid="8732021675729981781">"અનબ્લૉક કરો"</string>
+ <string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> ને બ્લૉક કરીએ?"</string>
+ <string name="unblock_button" msgid="8732021675729981781">"અનાવરોધિત કરો"</string>
<string name="add_blocked_dialog_body" msgid="8599974422407139255">"આ નંબરના કૉલ અને ટેક્સ્ટને અવરોધિત કરો"</string>
<string name="add_blocked_number_hint" msgid="8769422085658041097">"ફોન નંબર"</string>
<string name="block_button" msgid="485080149164258770">"અવરોધિત કરો"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"તમે કોઈ કટોકટીનો નંબર ડાયલ કરો કે ટેક્સ્ટ કરો તે પછી, કટોકટીની સેવાઓ તમારો સંપર્ક કરી શકે તેની ખાતરી કરવા માટે અવરોધિત કરવું બંધ કરવામાં આવે છે."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"હવે ફરીથી સક્ષમ કરો"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> અવરોધિત કર્યો"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> અનબ્લૉક કર્યો"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> અનાવરોધિત કર્યો"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"કટોકટીના નંબરને અવરોધિત કરવામાં અસમર્થ."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>, પહેલાંથી અવરોધિત કરવામાં આવ્યો છે."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"કૉલ કરવા માટે વ્યક્તિગત ડાયલરનો ઉપયોગ કરી રહ્યાં છે"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index ed623b8..cfea7a5 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"मैसेज"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"कॉल डिसकनेक्ट किया गया"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"<xliff:g id="CALLER">%s</xliff:g> के साथ चल रहे कॉल को डिसकनेक्ट किया गया क्योंकि एक आपातकालीन कॉल किया जा रहा है."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"एक आपातकालीन कॉल किया जा रहा है, इसलिए आपका कॉल डिसकनेक्ट कर दिया गया है."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"बैकग्राउंड कॉल"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ने कॉल को बैकग्राउंड में रखा है हो सकता है कि यह ऐप्लिकेशन आपके कॉल से ऑडियो ऐक्सेस करके उसे चला रहा हो."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ऐप्लिकेशन बंद हो गया है"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"कॉल करने के लिए, आपके डिवाइस में पहले से मौजूद फ़ोन ऐप्लिकेशन का इस्तेमाल किया गया"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"फ़ोन ऐप्लिकेशन जो बंद हो गया"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"कॉल म्यूट की गई."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"स्पीकरफ़ोन सक्षम."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"अभी बात नहीं हो सकती. क्या हो रहा है?"</string>
@@ -66,7 +66,7 @@
<string name="blocked_numbers_msg" msgid="2797422132329662697">"ब्लॉक किए गए नंबर से आपको कॉल या मैसेज नहीं मिलेंगे."</string>
<string name="block_number" msgid="3784343046852802722">"नंबर जोड़ें"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> को अनब्लॉक करें?"</string>
- <string name="unblock_button" msgid="8732021675729981781">"अनब्लॉक करें"</string>
+ <string name="unblock_button" msgid="8732021675729981781">"अनवरोधित करें"</string>
<string name="add_blocked_dialog_body" msgid="8599974422407139255">"इसके कॉल और मैसेज रोकें"</string>
<string name="add_blocked_number_hint" msgid="8769422085658041097">"फ़ोन नंबर"</string>
<string name="block_button" msgid="485080149164258770">"ब्लॉक करें"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"आपातकालीन नंबर डायल करने या उस पर लेख संदेश भेजने के बाद, अवरोधन बंद हो जाता है ताकि आपातकालीन सेवाएं आपसे संपर्क कर सकें."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"अभी फिर से सक्षम करें"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> अवरोधित है"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> अनब्लॉक किया गया"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> अनवरोधित है"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"आपातकालीन नंबर ब्लॉक करने में असमर्थ."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> पहले से अवरोधित है."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"कॉल करने के लिए व्यक्तिगत डायलर का उपयोग करना"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index ff38e54..184ebfb 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Poruka"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Prekinuti poziv"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Poziv upućen <xliff:g id="CALLER">%s</xliff:g> prekinut je zbog uspostavljanja hitnog poziva."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Poziv je prekinut zbog hitnog poziva."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Poziv u pozadini"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikacija <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> prebacila je poziv u pozadinu. Ta aplikacija možda pristupa zvuku i reproducira ga putem poziva."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> više ne odgovara"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Vaš je poziv upotrijebio aplikaciju telefona koju ste dobili na uređaju"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikacija telefona srušila se"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Zvuk poziva isključen."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Zvučnik je omogućen."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Sada ne mogu razgovarati. Što ima?"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"Nakon što nazovete broj hitne službe ili pošaljete poruku na njega, blokada će se isključiti kako bi vam se hitna služba mogla javiti."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"Ponovno omogući sada"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"Broj <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> blokiran je"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"Broj <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> je deblokiran"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"Broj <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> deblokiran je"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"Broj hitne službe ne može se blokirati."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"Broj <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> već je blokiran."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"Za upućivanje poziva upotrebljava se osobni program za biranje"</string>
@@ -99,7 +99,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blokiranje poziva"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Pozivi u pozadini"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Prekinuti pozivi"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Rušenja aplikacija telefona"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplikacije telefona su se srušile"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Upućivanjem ovog poziva prekinut ćete poziv u aplikaciji <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Odaberite kako ćete uputiti poziv"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Preusmjeri poziv putem aplikacije <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 55e5535..d0cf42f 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Üzenet"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Bontott hívás"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Az Ön és <xliff:g id="CALLER">%s</xliff:g> közötti hívást a szolgáltató egy segélyhívás kezdeményezése miatt bontotta."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Segélyhívást kezdeményeztek, ezért az Ön hívását megszakítottuk."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Háttérbeli hívás"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"A(z) <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> a háttérbe helyezett egy hívást. Ez az alkalmazás hozzáférhet a híváshoz, és hangot játszhat le benne."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"A(z) <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> lefagyott"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"A hívása a készülékhez mellékelt telefonalkalmazást használta"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Telefonalkalmazás összeomlása"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> nevű telefonalkalmazása összeomlott. A hívása a készülékéhez mellékelt telefonalkalmazásban folyatódott."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Hívás némítva."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Kihangosítás engedélyezve."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Most nem alkalmas. Mi újság?"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 6987dab..6ce8dc9 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Գրել"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Զանգն ընդհատվեց"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"<xliff:g id="CALLER">%s</xliff:g>-ի հետ ընթացիկ զանգն ընդհատվեց շտապ կանչի պատճառով։"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Ձեր զանգն ընդհատվեց շտապ կանչի պատճառով։"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Ֆոնային զանգ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> հավելվածը տեղափոխեց զանգը ֆոնային ռեժիմ և կարող է զանգի ընթացքում աուդիո ֆայլ նվագարկել:"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> հավելվածը չի արձագանքում"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Զանգն իրականացվեց արտադրողի կողմից ձեր սարքում տեղադրված հեռախոսի հավելվածով։"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Հեռախոսի հավելվածի աշխատանքը խափանվեց"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Սխալի պատճառով հեռախոսի ձեր հավելվածի (<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>) աշխատանքը խափանվեց։ Զանգը շարունակվեց արտադրողի կողմից ձեր սարքում տեղադրված հեռախոսի հավելվածով։"</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Զանգը խլացված է:"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Բարձրախոսը միացված է:"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Հիմա չեմ կարող խոսել: Ի՞նչ կա:"</string>
@@ -98,7 +97,7 @@
<string name="notification_channel_missed_call" msgid="7168893015283909012">"Բաց թողնված զանգեր"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Զանգերի արգելափակում"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Ֆոնային զանգեր"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Անջատված զանգեր"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Ընդհատված զանգեր"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Հեռախոսի հավելվածներ, որոնց աշխատանքը սխալի պատճառով խափանվել է"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Այս զանգը կատարելու դեպքում <xliff:g id="OTHER_APP">%1$s</xliff:g>-ի ընթացիկ զանգը կընդհատվի"</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Ընտրեք, թե ինչպես եք ուզում կատարել այս զանգը"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 23ebb73..47bda07 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Pesan"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Panggilan terputus"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Panggilan kepada <xliff:g id="CALLER">%s</xliff:g> terputus karena ada panggilan darurat."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Panggilan Anda terputus karena ada panggilan darurat."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Panggilan latar belakang"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> telah menempatkan panggilan telepon ke latar belakang. Aplikasi ini mungkin mengakses dan memutar audio melalui panggilan telepon."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> berhenti merespons"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Panggilan Anda menggunakan aplikasi telepon bawaan perangkat Anda"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikasi telepon error"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Aplikasi telepon <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> mengalami error. Panggilan Anda dilanjutkan menggunakan aplikasi telepon yang disertakan dengan perangkat."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Panggilan disenyapkan."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Pengeras suara ponsel diaktifkan."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Tak bisa bicara sekarang. Ada apa?"</string>
@@ -81,13 +80,13 @@
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> sudah diblokir."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"Menggunakan telepon pribadi untuk melakukan panggilan"</string>
<string name="notification_incoming_call" msgid="1233481138362230894">"<xliff:g id="CALL_VIA">%1$s</xliff:g> panggilan dari <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
- <string name="notification_incoming_video_call" msgid="5795968314037063900">"<xliff:g id="CALL_VIA">%1$s</xliff:g> panggilan video dari <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
+ <string name="notification_incoming_video_call" msgid="5795968314037063900">"<xliff:g id="CALL_VIA">%1$s</xliff:g> video call dari <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
<string name="answering_ends_other_call" msgid="8653544281903986641">"Menjawab panggilan akan mengakhiri panggilan <xliff:g id="CALL_VIA">%1$s</xliff:g> Anda"</string>
<string name="answering_ends_other_calls" msgid="3702302838456922535">"Menjawab panggilan akan mengakhiri panggilan <xliff:g id="CALL_VIA">%1$s</xliff:g> Anda"</string>
- <string name="answering_ends_other_video_call" msgid="8572022039304239958">"Menjawab panggilan akan mengakhiri panggilan video <xliff:g id="CALL_VIA">%1$s</xliff:g> Anda"</string>
+ <string name="answering_ends_other_video_call" msgid="8572022039304239958">"Menjawab panggilan akan mengakhiri video call <xliff:g id="CALL_VIA">%1$s</xliff:g> Anda"</string>
<string name="answering_ends_other_managed_call" msgid="4031778317409881805">"Menjawab panggilan akan mengakhiri panggilan yang sedang berlangsung"</string>
<string name="answering_ends_other_managed_calls" msgid="3974069768615307659">"Menjawab panggilan akan mengakhiri panggilan yang sedang berlangsung"</string>
- <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"Menjawab panggilan akan mengakhiri panggilan video yang sedang berlangsung"</string>
+ <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"Menjawab panggilan akan mengakhiri video call yang sedang berlangsung"</string>
<string name="answer_incoming_call" msgid="2045888814782215326">"Jawab"</string>
<string name="decline_incoming_call" msgid="922147089348451310">"Tolak"</string>
<string name="cant_call_due_to_no_supported_service" msgid="1635626384149947077">"Panggilan tidak dapat dilakukan karena tidak ada akun panggilan yang mendukung jenis panggilan ini."</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 442b9d5..a7037cc 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Skilaboð"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Aftengt símtal"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Símtalið til <xliff:g id="CALLER">%s</xliff:g> hefur verið aftengt vegna þess að neyðarsímtal var hringt."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Símtalið var aftengt vegna þess að neyðarsímtal var hringt."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Bakgrunnssímtal"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> hefur sett símtal í bakgrunn. Hugsanlega fær þetta forrit aðgang að hljóði yfir símtalið og spilar það."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> hætti að svara"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Símtalið þitt notaði símaforritið sem fylgdi tækinu"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Hrun í símaforriti"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Símtal þaggað."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Kveikt á hátalara."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kemst ekki í símann. Eitthvað títt?"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 60f32d7..ba34c94 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Messaggio"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Chiamata disconnessa"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"La chiamata a <xliff:g id="CALLER">%s</xliff:g> è stata disconnessa per dare priorità a una chiamata di emergenza."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"La tua chiamata è stata disconnessa per dare priorità a una chiamata di emergenza."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"In sottofondo"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ha spostato una chiamata in sottofondo. L\'app potrà accedere all\'audio e riprodurlo in sovrapposizione alla chiamata."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> non risponde più"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Per la tua chiamata è stata utilizzata l\'app per telefono integrata nel tuo dispositivo"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"App per telefono arrestata in modo anomalo"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Chiamata disattivata."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Vivavoce attivo."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Non posso parlare ora. Che succede?"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 30a909b..841d482 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"שליחת הודעה"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"השיחה נותקה"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"השיחה עם <xliff:g id="CALLER">%s</xliff:g> נותקה בגלל שיחת חירום."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"השיחה נותקה בגלל שיחת חירום."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"שיחה ברקע"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"האפליקציה <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> התחילה שיחה ברקע. ייתכן שלאפליקציה יש גישה לאודיו או שהיא משמיעה אודיו בשיחה."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"אפליקציית <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> הפסיקה להגיב"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"השיחה הייתה דרך אפליקציית הטלפון המקורית של המכשיר"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"אפליקציית טלפון קרסה"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"אפליקציית השיחות <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> קרסה. השיחה נמשכה באפליקציית השיחות של המכשיר."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"שיחה מושתקת."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"רמקול מופעל."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"לא נוח לי עכשיו. מה קורה?"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index bd87d66..1937bf4 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"メッセージ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"通話が切断されました"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"緊急通報番号宛に発信中のため、<xliff:g id="CALLER">%s</xliff:g> さんとの通話が切断されました。"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"緊急通報番号宛に発信中のため、通話が切断されました。"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"バックグラウンド通話"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> が通話をバックグラウンドに切り替えました。これで、このアプリは通話を通じて音声にアクセスして再生できます。"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> が応答しなくなりました"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"通話には、ご利用のデバイスにプリインストールされていた通話アプリが使用されていました"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"スマートフォン アプリがクラッシュしました"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"通話がミュートされています。"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"スピーカーが有効です。"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ただいま電話に出られません。ご用件をお知らせください。"</string>
@@ -57,9 +57,9 @@
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"デフォルトに設定"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"キャンセル"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> はすべての通話の発信や制御を行えるようになります。デフォルトの電話アプリに設定するのは信頼できるアプリだけにしてください。"</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトの通話スクリーニング アプリにしますか?"</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトのコール スクリーニング アプリにしますか?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> では通話をスクリーニングできなくなります。"</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトにすると、連絡先に登録されていない発信者の情報を確認したり、そのような発信者からの通話をブロックしたりできるようになります。デフォルトの通話スクリーニング アプリに設定するのは信頼できるアプリだけにしてください。"</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトにすると、連絡先に登録されていない発信者の情報を確認したり、そのような発信者からの通話をブロックしたりできるようになります。デフォルトのコール スクリーニング アプリに設定するのは信頼できるアプリだけにしてください。"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"デフォルトに設定"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"キャンセル"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"ブロックした番号"</string>
@@ -112,7 +112,7 @@
<string name="phone_settings_private_num_summary_txt" msgid="6755758240544021037">"番号非通知の発信者をブロック"</string>
<string name="phone_settings_payphone_txt" msgid="5003987966052543965">"公衆電話"</string>
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"公衆電話からの着信をブロック"</string>
- <string name="phone_settings_unknown_txt" msgid="3577926178354772728">"不明な発信者"</string>
+ <string name="phone_settings_unknown_txt" msgid="3577926178354772728">"不明"</string>
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"不明な発信者からの着信をブロック"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"着信のブロック"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"着信のブロックを無効にしました"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index be27e8b..442f54a 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"შეტყობინების გაგზავნა"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"გათიშული ზარი"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ზარი <xliff:g id="CALLER">%s</xliff:g>-თან გაითიშა გადაუდებელი ზარის განთავსების გამო."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"თქვენი ზარი გაითიშა, რადგან ხორციელდება გადაუდებელი ზარი."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"ზარი ფონში"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>-მა განათავსა ზარი ფონში. ამ აპმა შეიძლება წვდომა იქონიოს აუდიოზე ზარიდან და დაუკრას ის."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>-მა რეაგირება შეწყვიტა"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"თქვენმა ზარმა გამოიყენა ტელეფონის აპი, რომელიც თქვენს მოწყობილობას მოჰყვა"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ავარიულად გათიშული ტელეფონის აპი"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ზარი დადუმებულია."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"სპიკერები ჩართულია."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ვერ ვპასუხობ. რა ხდება?"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 0bab244..6155604 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Хабар"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Қоңырау ажыратылды"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Құтқару қызметіне қоңырау шалғандықтан, сіз бен <xliff:g id="CALLER">%s</xliff:g> арасындағы қоңырау ажыратылды."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Құтқару қызметіне қоңырау шалғандықтан, қоңырауыңыз ажыратылды."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Фондық қоңырау"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> қоңырауды фондық режимге ауыстырды. Бұл қолданба қоңырау барысында аудионы пайдалана және ойната алады."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> жауап бермейді"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Қоңырау құрылғының әдепкі телефон қолданбасы арқылы шалынды."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Бұзылған телефон қолданбасы"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Қоңырау үнсіздендірілген."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Үндеткішті телефон қосылды."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Қазір сөйлесе алмаймын. Не болды?"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"Төтенше жағдай нөмірін терген немесе мәтіндік хабар жіберген соң, төтенше жағдай қызметтері сізге хабарласа алуы үшін тыйым алынады."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"Қазір қайта қосу"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> бөгелген"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> бөгеуден шығарылды"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> бөгеуден шығарылған"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"Жедел қызмет нөмірін бөгеу мүмкін емес."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> бұрыннан бөгелген."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"Қоңырау шалу үшін жеке нөмір тергішті пайдалану"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 58b2abf..6818583 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"សារ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"បានផ្ដាច់ការហៅទូរសព្ទ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ការហៅទូរសព្ទទៅ <xliff:g id="CALLER">%s</xliff:g> ត្រូវបានផ្ដាច់ ដោយសារកំពុងហៅទៅលេខសង្គ្រោះបន្ទាន់។"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ការហៅទូរសព្ទរបស់អ្នកត្រូវបានផ្ដាច់ ដោយសារតែកំពុងធ្វើការហៅទៅលេខសង្គ្រោះបន្ទាន់។"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"ការហៅនៅផ្ទៃខាងក្រោយ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> បានធ្វើការហៅទូរសព្ទនៅផ្ទៃខាងក្រោយ។ កម្មវិធីនេះអាចកំពុងចូលប្រើប្រាស់ និងចាក់សំឡេងតាមការហៅទូរសព្ទ។"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> បានគាំង"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ការហៅទូរសព្ទរបស់អ្នកបានប្រើប្រាស់កម្មវិធីទូរសព្ទដែលភ្ជាប់មកជាមួយឧបករណ៍របស់អ្នក"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"កម្មវិធីទូរសព្ទគាំង"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"កម្មវិធីទូរសព្ទ <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> របស់អ្នកបានគាំង។ ការហៅទូរសព្ទរបស់អ្នកត្រូវបានបន្តដោយប្រើប្រាស់កម្មវិធីទូរសព្ទដែលមានភ្ជាប់មកជាមួយឧបករណ៍របស់អ្នក។"</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"ការហៅបិទសំឡេង។"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"បានបើកអូប៉ាល័រទូរស័ព្ទ។"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"មិនអាចនិយាយបានទេ ឥឡូវនេះ។ មានការអីដែរ?"</string>
@@ -98,7 +97,7 @@
<string name="notification_channel_missed_call" msgid="7168893015283909012">"ការហៅដែលមិនបានទទួល"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"ការទប់ស្កាត់ការហៅ"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"ការហៅនៅផ្ទៃខាងក្រោយ"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"ការហៅទូរសព្ទដែលបានផ្ដាច់"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"បានផ្ដាច់ការហៅទូរសព្ទ"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"កម្មវិធីទូរសព្ទគាំង"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"ការហៅទូរសព្ទនេះ នឹងបញ្ចប់ការហៅ <xliff:g id="OTHER_APP">%1$s</xliff:g> របស់អ្នក។"</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"ជ្រើសរើសរបៀបធ្វើការហៅទូរសព្ទនេះ"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 6e0bb59..c7873f5 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -21,18 +21,18 @@
<string name="unknown" msgid="6993977514360123431">"ಅಪರಿಚಿತ"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"ಮಿಸ್ಡ್ ಕಾಲ್"</string>
<string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"ಮಿಸ್ಡ್ ಕೆಲಸದ ಕರೆ"</string>
- <string name="notification_missedCallsTitle" msgid="3910479625507893809">"ಮಿಸ್ಡ್ ಕಾಲ್ಗಳು"</string>
- <string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> ಮಿಸ್ಡ್ ಕಾಲ್ಗಳು"</string>
+ <string name="notification_missedCallsTitle" msgid="3910479625507893809">"ಮಿಸ್ಡ್ ಕರೆಗಳು"</string>
+ <string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> ಮಿಸ್ಡ್ ಕರೆಗಳು"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"<xliff:g id="MISSED_CALL_FROM">%s</xliff:g> ಅವರಿಂದ ಮಿಸ್ಡ್ ಕಾಲ್"</string>
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"ಮರಳಿ ಕರೆ ಮಾಡಿ"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"ಸಂದೇಶ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"ಕರೆಯ ಕನೆಕ್ಷನ್ ಅನ್ನು ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ತುರ್ತು ಕರೆಯನ್ನು ಮಾಡುತ್ತಿರುವ ಕಾರಣ <xliff:g id="CALLER">%s</xliff:g> ಗೆ ಕರೆಯ ಕನೆಕ್ಷನ್ ಅನ್ನು ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ತುರ್ತು ಕರೆಯನ್ನು ಮಾಡುತ್ತಿರುವ ಕಾರಣ ನಿಮ್ಮ ಕರೆಯನ್ನು ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"ಹಿನ್ನೆಲೆ ಕರೆ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ಆ್ಯಪ್, ಕರೆಯನ್ನು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಇರಿಸಿದೆ. ಈ ಆ್ಯಪ್ ಕರೆಯ ಮೂಲಕ ಆಡಿಯೊವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು ಮತ್ತು ಪ್ಲೇ ಮಾಡಬಹುದು."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ಪ್ರತಿಕ್ರಿಯಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿದೆ"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ನಿಮ್ಮ ಕರೆಯು ಸಾಧನದ ಜೊತೆಗೆ ನೀಡಲಾದ ಫೋನ್ ಆ್ಯಪ್ ಅನ್ನು ಬಳಸಿದೆ."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ಕ್ರ್ಯಾಶ್ ಆಗಿರುವ ಫೋನ್ ಆ್ಯಪ್"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ಕರೆಯನ್ನು ಮ್ಯೂಟ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"ಸ್ಪೀಕರ್ಫೋನ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ಕ್ಷಮಿಸಿ, ಈಗ ಮಾತನಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಸಮಾಚಾರವೇನು?"</string>
@@ -95,7 +95,7 @@
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"ನಿಮ್ಮ <xliff:g id="OTHER_CALL">%1$s</xliff:g> ಕರೆಗಳ ಕಾರಣ ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ."</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"ಬೇರೊಂದು ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಕರೆಯಲ್ಲಿರುವುದರಿಂದ ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"ಒಳಬರುವ ಕರೆಗಳು"</string>
- <string name="notification_channel_missed_call" msgid="7168893015283909012">"ಮಿಸ್ಡ್ ಕಾಲ್ಗಳು"</string>
+ <string name="notification_channel_missed_call" msgid="7168893015283909012">"ಮಿಸ್ಡ್ ಕರೆಗಳು"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"ಕರೆ ನಿರ್ಬಂಧಿಸುವಿಕೆ"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"ಹಿನ್ನೆಲೆ ಕರೆಗಳು"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"ಕರೆಗಳ ಕನೆಕ್ಷನ್ ಅನ್ನು ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 1a29b2e..03a89d6 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"문자 메시지"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"연결 해제된 통화"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"긴급 전화 연결로 인해 <xliff:g id="CALLER">%s</xliff:g>님에게 건 통화가 연결 해제되었습니다."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"긴급 전화 연결로 인해 통화가 연결 해제되었습니다."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"백그라운드 통화"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>에서 통화를 백그라운드로 전환했습니다. 앱이 통화에 사용되는 오디오에 액세스하거나 재생 중일 수 있습니다."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>의 응답이 중지됨"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"기기의 기본 전화 앱을 사용하여 통화했습니다."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"다운된 전화 앱"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"통화가 음소거되었습니다."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"스피커폰이 사용 설정되었습니다."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"통화 불가. 용무를 남겨주세요."</string>
@@ -63,7 +63,7 @@
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"기본으로 설정"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"취소"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"차단된 번호"</string>
- <string name="blocked_numbers_msg" msgid="2797422132329662697">"차단된 번호에서 걸려오는 전화나 문자는 더 이상 수신되지 않습니다."</string>
+ <string name="blocked_numbers_msg" msgid="2797422132329662697">"차단한 번호에서 걸려오는 전화나 문자는 더 이상 수신되지 않습니다."</string>
<string name="block_number" msgid="3784343046852802722">"번호 추가"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>번을 차단 해제하시겠습니까?"</string>
<string name="unblock_button" msgid="8732021675729981781">"차단 해제"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 83e498e..82e7b61 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Билдирүү"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Ажыратылган чалуу"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Учурда шашылыш чалуудан улам, <xliff:g id="CALLER">%s</xliff:g> чалуу ажыратылган."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Учурда шашылыш чалуудан улам, чалууңуз ажыратылган."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Фондогу чалуу"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> чалууну фонго койгон. Бул колдонмо чалуу аркылуу аудиого кирип, ойното алат."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> жооп берүүнү токтотту"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Чалууңуз түзмөгүңүз менен келген телефон колдонмосун пайдаланды"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Телефондун колдонмосунда ката кетти"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> телефон колдонмоңузда ката кеткен. Чалууңуз түзмөгүңүз менен келген телефон колдонмосу пайдаланып улантылган."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Чалуу үнсүз тартипте."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Динамик иштеп жатат."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Азыр сүйлөшө албайм. Эмне болду?"</string>
@@ -99,7 +98,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Чалууну бөгөттөө"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Фондогу чалуулар"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Ажыратылган чалуулар"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Катадан улам иштебей калган телефон колдонмолору"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Телефондун колдонмолорунда ката кетти"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Эгер чалып баштасаңыз, <xliff:g id="OTHER_APP">%1$s</xliff:g> чалууңуз аяктайт."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Чалуу жолун тандаңыз"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> аркылуу чалуу багытын буруу"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 64142ca..d5c2e6c 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"ຂໍ້ຄວາມ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"ສາຍຖືກຕັດແລ້ວ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ສາຍໂທຫາ <xliff:g id="CALLER">%s</xliff:g> ຖືກຕັດແລ້ວ ເນື່ອງຈາກກຳລັງມີການໂທສຸກເສີນຢູ່."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ສາຍໂທຂອງທ່ານໄດ້ຖືກຕັດແລ້ວ ເນື່ອງຈາກກຳລັງມີການໂທສຸກເສີນຢູ່."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"ການໂທໃນພື້ນຫຼັງ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ວາງການໂທໄວ້ພື້ນຫຼັງແລ້ວ. ແອັບນີ້ອາດເຂົ້າເຖິງ ແລະ ຫຼິ້ນສຽງຜ່ານການໂທໄດ້."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ໄດ້ຢຸດການຕອບສະໜອງແລ້ວ"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ການໂທຂອງທ່ານໃຊ້ແອັບໂທລະສັບທີ່ມາພ້ອມກັບອຸປະກອນຂອງທ່ານ"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ແອັບໂທລະສັບຂັດຂ້ອງ"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ປິດສຽງການໂທແລ້ວ."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"ເປີດລຳໂພງແລ້ວ."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ບໍ່ສາມາດລົມໄດ້ໃນຕອນນີ້. ມີຫຍັງບໍ່?"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 29090d1..7acbc58 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Pranešimas"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Skambutis atjungtas"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Skambutis kontaktui <xliff:g id="CALLER">%s</xliff:g> buvo atjungtas dėl atliekamo skambučio pagalbos numeriu."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Skambutis buvo atjungtas dėl atliekamo skambučio pagalbos numeriu."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Skambutis fone"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Programa „<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>“ perkėlė skambutį į foną. Ši programa gali pasiekti ir leisti garsą vykstant skambučiui."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Programa „<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>“ nebereaguoja"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Atliekant skambutį buvo naudojama telefono programa, kuri buvo įrenginyje jį įsigijus"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Užstrigusi telefono programa"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Skambutis nutildytas."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Garsiakalbis įgalintas."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Dabar negaliu kalbėti. Kas nutiko?"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 782777d..1e88d48 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Ziņojums"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Pārtraukts zvans"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Zvans lietotājam <xliff:g id="CALLER">%s</xliff:g> ir pārtraukts, jo tiek veikts ārkārtas izsaukums."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Jūsu zvans ir pārtraukts, jo tiek veikts ārkārtas izsaukums."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Saruna fonā"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> pārcēla sarunu uz darbību fonā. Sarunas laikā šī lietotne var piekļūt audio saturam un to atskaņot."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> pārtrauca reaģēt"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Zvanam tika izmantota jūsu ierīcē iebūvētā tālruņa lietotne"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Avarējusī tālruņa lietotne"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Zvana skaņa ir izslēgta."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Skaļrunis ir iespējots."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Nevaru runāt. Kas gadījās?"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 99e211f..4cc54b1 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Управување со повици"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Управување со повик"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Телефон"</string>
<string name="unknown" msgid="6993977514360123431">"Непознато"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Пропуштен повик"</string>
@@ -24,15 +24,15 @@
<string name="notification_missedCallsTitle" msgid="3910479625507893809">"Пропуштени повици"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> пропуштени повици"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"Пропуштен повик од <xliff:g id="MISSED_CALL_FROM">%s</xliff:g>"</string>
- <string name="notification_missedCall_call_back" msgid="7900333283939789732">"Повикај го"</string>
+ <string name="notification_missedCall_call_back" msgid="7900333283939789732">"Повикува назад"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"Порака"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Исклучен повик"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Повикот до <xliff:g id="CALLER">%s</xliff:g> се исклучи поради воспоставувањето итен повик."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Повикот ќе се исклучи поради воспоставувањето итен повик."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Повик во заднина"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> воспостави повик во заднината. Апликацијава можеби пристапува до и пушта аудио во повикот."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> падна"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Повикот се обави на апликацијата за телефон што дојде со уредот"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Падната апликација за телефон"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Повикот е со исклучен звук"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Интерфонот е овозможен."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Не можам да зборувам сега. Што има?"</string>
@@ -44,7 +44,7 @@
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Брз одговор"</string>
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Порака е испратена на <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
- <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Пораката не може да се испрати на <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
+ <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Пораката не можеше да се испрати на <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Сметки за повици"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Дозволени се само итни повици."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Оваа апликација не може да прави појдовни повици без дозволата Телефон."</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 5c64034..de08a5b 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"കോൾ മാനേജ്മെന്റ്"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"കോൾ മാനേജുമെന്റ്"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"ഫോണ്"</string>
<string name="unknown" msgid="6993977514360123431">"അജ്ഞാതം"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"മിസ്ഡ് കോൾ"</string>
@@ -24,15 +24,15 @@
<string name="notification_missedCallsTitle" msgid="3910479625507893809">"മിസ്ഡ് കോളുകൾ"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> മിസ്ഡ് കോളുകൾ"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"<xliff:g id="MISSED_CALL_FROM">%s</xliff:g> എന്നതിൽ നിന്നുള്ള മിസ്ഡ് കോൾ"</string>
- <string name="notification_missedCall_call_back" msgid="7900333283939789732">"തിരിച്ചുവിളിക്കുക"</string>
+ <string name="notification_missedCall_call_back" msgid="7900333283939789732">"കോൾബാക്ക്"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"സന്ദേശം"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"വിച്ഛേദിക്കപ്പെട്ട കോൾ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ഒരു അടിയന്തര കോൾ നടക്കുന്നതിനാൽ <xliff:g id="CALLER">%s</xliff:g> എന്നയാൾക്ക് ചെയ്യുന്ന കോൾ വിച്ഛേദിക്കപ്പെട്ടിരിക്കുന്നു."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ഒരു അടിയന്തര കോൾ നടക്കുന്നതിനാൽ നിങ്ങളുടെ കോൾ വിച്ഛേദിക്കപ്പെട്ടിരിക്കുന്നു."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"പശ്ചാത്തല കോൾ"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> കോൾ പശ്ചാത്തലത്തിലേക്ക് മാറ്റി. കോൾ ചെയ്യുമ്പോൾ ഈ ആപ്പിന് ഓഡിയോ ആക്സസ് ചെയ്യാനും പ്ലേ ചെയ്യാനും കഴിഞ്ഞേക്കാം."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ആപ്പ് പ്രതികരിക്കുന്നത് നിർത്തി"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"നിങ്ങളുടെ കോൾ, നിങ്ങളുടെ ഉപകരണത്തിനൊപ്പം ലഭ്യമായ ഫോൺ ആപ്പ് ഉപയോഗിച്ചു"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ക്രാഷായ ഫോൺ ആപ്പ്"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"കോൾ നിശബ്ദമാക്കി."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"സ്പീക്കർഫോൺ പ്രവർത്തനക്ഷമമാക്കി."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ഇപ്പോൾ സംസാരിക്കാനാകില്ല. എന്താ വിളിച്ചത്?"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"നിങ്ങൾ ഒരു എമർജൻസി നമ്പർ ഡയൽ ചെയ്ത് കഴിയുമ്പോഴോ അതിലേക്ക് സന്ദേശമയച്ചുകഴിയുമ്പോഴോ, എമർജൻസി സേവനങ്ങൾ നിങ്ങളിലേക്ക് എത്തുമെന്ന് ഉറപ്പാക്കാൻ കോൾ ബ്ലോക്കിംഗ് ഓഫാക്കും."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"ഇപ്പോൾ വീണ്ടും പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> ബ്ലോക്ക് ചെയ്തു"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> അൺബ്ലോക്ക് ചെയ്തു"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> അൺബ്ലോക്കുചെയ്തു"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"അടിയന്തര നമ്പർ ബ്ലോക്കുചെയ്യാനാകുന്നില്ല."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> മുമ്പേതന്നെ ബ്ലോക്കുചെയ്തതാണ്."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"കോൾ ചെയ്യുന്നതിന് സ്വകാര്യ ഡയലർ ഉപയോഗിക്കുന്നു"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index cdef26b..86f55d4 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -25,26 +25,25 @@
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> аваагүй дуудлага"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"<xliff:g id="MISSED_CALL_FROM">%s</xliff:g>-н аваагүй дуудлага"</string>
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"Буцааж залгах"</string>
- <string name="notification_missedCall_message" msgid="4054698824390076431">"Мессеж"</string>
+ <string name="notification_missedCall_message" msgid="4054698824390076431">"Мессэж"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Дуудлага саллаа"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Яаралтай дуудлага ирсэн тул <xliff:g id="CALLER">%s</xliff:g> руу хийсэн дуудлагыг салгалаа."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Яаралтай дуудлага ирсэн тул таны дуудлагыг салгалаа."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Арын дуудлага"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> дуудлагыг ард оруулсан байна. Энэхүү апп нь дуудлагаар аудиод хандаж, тоглуулж байна."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> хариу өгөхөө больсон"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Таны дуудлагыг таны төхөөрөмжтэй хамт ирсэн гар утасны аппаар хийсэн"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Гэмтсэн гар утасны апп"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Таны гар утасны апп болох <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> гэмтсэн байна. Таны дуудлагыг таны төхөөрөмжтэй хамт ирсэн гар утасны аппаар үргэлжлүүлсэн."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Дууг хаасан."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Чанга яригчийг идэвхжүүлсэн."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Ярих боломжгүй байна. Сонин юу байна?"</string>
- <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Би тань руу одоохон эргээд залгая."</string>
+ <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Би тань руу одоо буцаагаад залгая."</string>
<string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Би тань руу дараа залгая."</string>
<string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"Ярих боломжгүй байна. Дараа залгах уу?"</string>
<string name="respond_via_sms_setting_title" msgid="4762275482898830160">"Шуурхай хариунууд"</string>
<string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"Шуурхай хариуг засах"</string>
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Шуурхай хариу"</string>
- <string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Мессежийг <xliff:g id="PHONE_NUMBER">%s</xliff:g> руу илгээв."</string>
- <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> руу мессеж илгээж чадсангүй."</string>
+ <string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Зурвасыг <xliff:g id="PHONE_NUMBER">%s</xliff:g> руу илгээв."</string>
+ <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> руу зурвас илгээж чадсангүй."</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Дуудлагын эрхтэй бүртгэлүүд"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Зөвхөн яаралтай тусламжийн дуудлага хийх боломжтой."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Энэ апп нь утасны зөвшөөрөлгүйгээр дуудлага хийх боломжгүй."</string>
@@ -71,12 +70,12 @@
<string name="add_blocked_number_hint" msgid="8769422085658041097">"Утасны дугаар"</string>
<string name="block_button" msgid="485080149164258770">"Блоклох"</string>
<string name="non_primary_user" msgid="315564589279622098">"Зөвхөн энэ төхөөрөмжийн эзэн блоклосон дугаарыг харж, өөрчлөх боломжтой."</string>
- <string name="delete_icon_description" msgid="5335959254954774373">"Блокоос гаргах"</string>
+ <string name="delete_icon_description" msgid="5335959254954774373">"Хоригийг тайлах"</string>
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"Дугаар хориглох түр хугацаанд идэвхгүй болсон"</string>
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"Түргэн тусламжийн дугаар руу залгах буюу мессеж бичсэний дараа түргэн тусламжаас тантай холбогдох боломжтой байлгахын тулд дугаар хориглохыг идэвхгүй болгоно."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"Одоо дахин идэвхжүүлэх"</string>
- <string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>-г блоклосон"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>-г блокоос гаргасан"</string>
+ <string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>-г хориглосон"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>-н хоригийг авсан"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"Яаралтай дугаарыг хориглох боломжгүй."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>-г аль хэдийн хориглосон байна."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"Дуудлага хийхийн тулд хувийн залгагчийг ашиглаж байна"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 331cf5c..5230356 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"मेसेज"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"डिस्कनेक्ट केलेला कॉल"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"आणीबाणी कॉल केल्यामुळे <xliff:g id="CALLER">%s</xliff:g> ला केलेला कॉल डिस्कनेक्ट केला गेला."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"आणीबाणी कॉल केल्यामुळे तुमचा कॉल डिस्कनेक्ट केला गेला आहे."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"बॅकग्राउंड कॉल"</string>
- <string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> यांनी कॉल बॅकग्राउंडवर ठेवला आहे हे अॅप कदाचित कॉलद्वारे ऑडिओ ॲक्सेस आणि प्ले करत आहे."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ने प्रतिसाद देणे थांबवले आहे"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"तुमच्या कॉलने डिव्हाइससोबत दिलेले फोन अॅप वापरले आहे"</string>
+ <string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> यांनी कॉल बॅकग्राउंडवर ठेवला आहे हे ॲप कदाचित कॉलद्वारे ऑडिओ ॲक्सेस आणि प्ले करत आहे."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"क्रॅश झालेले फोन ॲप"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"कॉल नि.शब्द केला."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"स्पीकरफोन सक्षम केला."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"आत्ता बोलू शकत नाही. कशासाठी कॉल केला होता?"</string>
@@ -85,9 +85,9 @@
<string name="answering_ends_other_call" msgid="8653544281903986641">"उत्तर देण्यामुळे तुमचा <xliff:g id="CALL_VIA">%1$s</xliff:g> कॉल समाप्त होईल"</string>
<string name="answering_ends_other_calls" msgid="3702302838456922535">"उत्तर देण्यामुळे तुमचे <xliff:g id="CALL_VIA">%1$s</xliff:g> कॉल समाप्त होतील"</string>
<string name="answering_ends_other_video_call" msgid="8572022039304239958">"उत्तर देण्यामुळे तुमचा <xliff:g id="CALL_VIA">%1$s</xliff:g> व्हिडिओ कॉल समाप्त होईल"</string>
- <string name="answering_ends_other_managed_call" msgid="4031778317409881805">"उत्तर देण्यामुळे तुमचा सुरू असलेला कॉल समाप्त होईल"</string>
- <string name="answering_ends_other_managed_calls" msgid="3974069768615307659">"उत्तर देण्यामुळे तुमचे सुरू असलेले कॉल समाप्त होतील"</string>
- <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"उत्तर देण्यामुळे तुमचा सुरू असलेला व्हिडिओ कॉल समाप्त होईल"</string>
+ <string name="answering_ends_other_managed_call" msgid="4031778317409881805">"उत्तर देण्यामुळे तुमचा सुरु असलेला कॉल समाप्त होईल"</string>
+ <string name="answering_ends_other_managed_calls" msgid="3974069768615307659">"उत्तर देण्यामुळे तुमचे सुरु असलेले कॉल समाप्त होतील"</string>
+ <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"उत्तर देण्यामुळे तुमचा सुरु असलेला व्हिडिओ कॉल समाप्त होईल"</string>
<string name="answer_incoming_call" msgid="2045888814782215326">"उत्तर द्या"</string>
<string name="decline_incoming_call" msgid="922147089348451310">"नकार द्या"</string>
<string name="cant_call_due_to_no_supported_service" msgid="1635626384149947077">"कॉल करू शकत नाही कारण अशाप्रकारच्या कॉलला सपोर्ट करतील अशी कोणतीही कॉलिंग खाती नाहीत."</string>
@@ -95,11 +95,11 @@
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"आपल्या <xliff:g id="OTHER_CALL">%1$s</xliff:g> कॉलमुळे कॉल केला जाऊ शकत नाही."</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"दुसर्या ॲपमधील कॉलमुळे कॉल केला जाऊ शकत नाही."</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"येणारे कॉल"</string>
- <string name="notification_channel_missed_call" msgid="7168893015283909012">"मिस्ड कॉल"</string>
+ <string name="notification_channel_missed_call" msgid="7168893015283909012">"सुटलेले कॉल"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"कॉल ब्लॉक करणे"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"बॅकग्राउंड कॉल"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"डिस्कनेक्ट केलेले कॉल"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"क्रॅश झालेली फोन ॲप्स"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"क्रॅश झालेले फोन ॲप्स"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"हा कॉल केल्याने तुमचा <xliff:g id="OTHER_APP">%1$s</xliff:g> कॉल समाप्त होईल."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"हा कॉल कसा करायचा ते निवडा"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> वापरून कॉल रीडिरेक्ट करा"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index b43b554..9d2bad2 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mesej"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Panggilan diputuskan sambungan"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Panggilan kepada <xliff:g id="CALLER">%s</xliff:g> telah diputuskan sambungannya kerana panggilan kecemasan sedang dibuat."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Panggilan anda telah diputuskan sambungan kerana panggilan kecemasan sedang dibuat."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Panggilan latar blkg"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> telah meletakkan panggilan dalam latar belakang Apl ini mungkin mengakses dan memainkan audio mengatasi panggilan."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> telah berhenti memberikan respons"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Panggilan anda telah menggunakan aplikasi telefon yang disertakan bersama peranti anda"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikasi telefon yang ranap"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Apl telefon anda, <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> telah ranap. Panggilan anda telah diteruskan menggunakan apl telefon yang disertakan dengan peranti anda."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Panggilan diredam."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Telefon pembesar suara didayakan."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Sedang sibuk. Ada apa?"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index c1b3124..fe724dc 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"စာတို"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"ခေါ်ဆိုမှုကို ဖြတ်တောက်လိုက်သည်"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"အရေးပေါ်ဖုန်းခေါ်ဆိုမှု ပြုလုပ်နေသောကြောင့် <xliff:g id="CALLER">%s</xliff:g> ထံသို့ ခေါ်ဆိုမှုကို ဖြတ်တောက်လိုက်သည်။"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"အရေးပေါ်ဖုန်းခေါ်ဆိုမှု ပြုလုပ်နေသောကြောင့် သင်၏ ခေါ်ဆိုမှုကို ဖြတ်တောက်လိုက်သည်။"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"နောက်ခံမှ ခေါ်ဆိုမှု"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> သည် ခေါ်ဆိုမှုကို နောက်ခံသို့ ထည့်လိုက်ပါသည်။ ဤအက်ပ်သည် ခေါ်ဆိုမှုမှတစ်ဆင့် အသံများကို သုံးခြင်းနှင့် ဖွင့်ခြင်းတို့ ပြုလုပ်နိုင်ပါသည်။"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> က တုံ့ပြန်ခြင်းကို ရပ်လိုက်သည်"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"သင့်စက်ပစ္စည်းနှင့် အတူပါလာသော ဖုန်းအက်ပ်သုံးပြီး ခေါ်ဆိုမှုကို ပြုလုပ်ထားသည်"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ရပ်တန့်သွားသော ဖုန်းအက်ပ်"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"နားထောင်ရုံသာ (စကားပြောပိတ်ထားသည်)"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"စပီကာဖုန်း သုံးလို့ရသည်"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"အခုပြောလို့မရဘူး။ အကြောင်းထူးရှိလား။"</string>
@@ -65,18 +65,18 @@
<string name="blocked_numbers" msgid="8322134197039865180">"ပိတ်ထားသည့် နံပါတ်များ"</string>
<string name="blocked_numbers_msg" msgid="2797422132329662697">"ပိတ်ထားသော နံပါတ်များမှ ဖုန်းခေါ်ခြင်း (သို့) စာသားပို့ခြင်းတို့ကို သင်လက်ခံရရှိမည် မဟုတ်ပါ။"</string>
<string name="block_number" msgid="3784343046852802722">"နံပါတ်တစ်ခု ထည့်ပါ"</string>
- <string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> ကို ပြန်ဖွင့်မလား။"</string>
- <string name="unblock_button" msgid="8732021675729981781">"ပြန်ဖွင့်ရန်"</string>
+ <string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> ကို ပိတ်ဆို့မှုပြန်ဖွင့်မလား။"</string>
+ <string name="unblock_button" msgid="8732021675729981781">"ပိတ်ဆို့မှုပြန်ဖွင့်ပါ"</string>
<string name="add_blocked_dialog_body" msgid="8599974422407139255">"ဤနံပါတ်မှ ခေါ်ဆိုမှုနှင့် စာများကို ပိတ်ဆို့ပါ"</string>
<string name="add_blocked_number_hint" msgid="8769422085658041097">"ဖုန်းနံပါတ်"</string>
<string name="block_button" msgid="485080149164258770">"ပိတ်ဆို့ပါ"</string>
<string name="non_primary_user" msgid="315564589279622098">"ပိတ်ဆို့ထားသည့် နံပါတ်များကို စက်ပစ္စည်းပိုင်ရှင်သာလျှင် ကြည့်ရှု၍ စီမံခန့်ခွဲနိုင်ပါသည်။"</string>
- <string name="delete_icon_description" msgid="5335959254954774373">"ပြန်ဖွင့်ရန်"</string>
+ <string name="delete_icon_description" msgid="5335959254954774373">"မပိတ်ဆို့တော့ပါ"</string>
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"ဘလော့ခ်လုပ်ခြင်းကို ပိတ်ထားပါသည်"</string>
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"သင် အရေးပေါ်နံပါတ်တစ်ခုကို ဖုန်းခေါ် (သို့) စာသားပို့ပြီးနောက် အရေးပေါ်ဝန်ဆောင်မှုများက သင့်ကို ဆက်သွယ်နိုင်ကြောင်း သေချာစေရန် ဘလော့ခ်လုပ်ခြင်းကို ပိတ်ထားပါသည်။"</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"ယခု ပြန်ဖွင့်လိုက်ပါ"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> ကို ပိတ်ဆို့ပြီးပါပြီ"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> ကို ပြန်ဖွင့်လိုက်သည်"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> ကို မပိတ်ဆို့တော့ပါ"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"အရေးပေါ်နံပါတ်ကို ပိတ်ဆို့၍ မရပါ။"</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> ကို ပိတ်ဆို့ထားပြီး ဖြစ်သည်။"</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"ဖုန်းခေါ်ဆိုမှုပြုလုပ်ရန် ကိုယ်ရေးကိုယ်တာ ဖုန်းခေါ်ဆိုမှုစနစ်ကို အသုံးပြုခြင်း"</string>
@@ -96,7 +96,7 @@
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"အခြားအက်ပ်သုံးပြီးပြောနေသည့်အတွက် အထွက်ခေါ်ဆိုမှုကို မပြုလုပ်နိုင်ပါ။"</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"အဝင်ဖုန်းခေါ်ဆိုမှုများ"</string>
<string name="notification_channel_missed_call" msgid="7168893015283909012">"လွတ်သွားသော ဖုန်းခေါ်ဆိုမှုများ"</string>
- <string name="notification_channel_call_blocking" msgid="2028807677868598710">"ခေါ်ဆိုမှု ပိတ်ထားခြင်း"</string>
+ <string name="notification_channel_call_blocking" msgid="2028807677868598710">"ခေါ်ဆိုမှု ပိတ်ခြင်း"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"နောက်ခံမှ ခေါ်ဆိုမှုများ"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"ခေါ်ဆိုမှုများကို ဖြတ်တောက်လိုက်သည်"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"ရပ်တန့်သွားသော ဖုန်းအက်ပ်များ"</string>
@@ -105,7 +105,7 @@
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"ခေါ်ဆိုမှုကို <xliff:g id="OTHER_APP">%1$s</xliff:g> ဖြင့် တစ်ဆင့်ပြန်ညွှန်ရန်"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"ကျွန်ုပ်၏ ဖုန်းနံပါတ်ဖြင့် ဖုန်းခေါ်ရန်"</string>
<string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> ဖြင့်ဖုန်းခေါ်ဆို၍မရပါ။ ဖုန်းခေါ်ဆိုမှု တစ်ဆင့်ပြန်ညွှန်ပြသည့် အခြားအက်ပ်ကို အသုံးပြုပါ (သို့) အကူအညီအတွက် ဆော့ဖ်ဝဲအင်ဂျင်နီယာကို ဆက်သွယ်ပါ။"</string>
- <string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"ခေါ်ဆိုမှု ပိတ်ထားခြင်း"</string>
+ <string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"ခေါ်ဆိုမှု ပိတ်ခြင်း"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"\'အဆက်အသွယ်များ\' ထဲတွင် မရှိသော နံပါတ်များ"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"သင်၏ \'အဆက်အသွယ်များ\' ထဲတွင် မပါဝင်သော နံပါတ်များကို ပိတ်ပါ"</string>
<string name="phone_settings_private_num_txt" msgid="6339272760338475619">"သီးသန့်"</string>
@@ -114,7 +114,7 @@
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"အများသုံးဖုန်းများမှ ခေါ်ဆိုမှုများကို ပိတ်ပါ"</string>
<string name="phone_settings_unknown_txt" msgid="3577926178354772728">"အမည်မသိ"</string>
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"အမည်မသိသော ခေါ်ဆိုသူများကို ပိတ်ပါ"</string>
- <string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"ခေါ်ဆိုမှု ပိတ်ထားခြင်း"</string>
+ <string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"ခေါ်ဆိုမှု ပိတ်ခြင်း"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"\'ခေါ်ဆိုမှု ပိတ်ခြင်း\' ကို ရပ်ထားပါသည်"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"အရေးပေါ် ခေါ်ဆိုမှု ပြုလုပ်ထားပါသည်"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"အရေးပေါ်တုံ့ပြန်သူများက သင့်အား ဆက်သွယ်နိုင်စေရန် \'ခေါ်ဆိုမှု ပိတ်ခြင်း\' ကို ရပ်ထားပါသည်။"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 3f65c62..915c37b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Melding"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Koblet fra anropet"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Anropet til <xliff:g id="CALLER">%s</xliff:g> er koblet fra fordi et nødanrop ble utført."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Samtalen din ble brutt fordi et nødanrop ble utført."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Bakgrunnsanrop"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> har flyttet et anrop til bakgrunnen. Det kan hende denne appen bruker og spiller av lyd over anropet."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> sluttet å svare"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Anropet ble gjort med telefonappen som fulgte med enheten din"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Krasjet telefonapp"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Samtalelyd er kuttet."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Høyttaler er aktivert."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kan ikke snakke nå. Hva skjer?"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 1e2b32f..9acbdcf 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -27,12 +27,12 @@
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"फेरि कल गर्नुहोस्"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"सन्देश"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"विच्छेद गरिएको कल"</string>
- <string name="notification_disconnectedCall_body" msgid="600491714584417536">"आपत्कालीन कल गरिएको हुनाले <xliff:g id="CALLER">%s</xliff:g> लाई गरिएको कल विच्छेद गरियो।"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"आपत्कालीन कल जारी रहेको हुनाले तपाईंको कल विच्छेद गरिएको छ।"</string>
+ <string name="notification_disconnectedCall_body" msgid="600491714584417536">"आपत्कालीन कल गरिएको हुनाले <xliff:g id="CALLER">%s</xliff:g> लाई गरिएको कल विच्छेद गरियो।"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"पृष्ठभूमिको कल"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ले एउटा कल पृष्ठभूमिमा राखेको छ। कल गरेको बेला यो अनुप्रयोगले अडियोमाथि पहुँच राखेर प्ले गरिरहेको हुन सक्छ।"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ले काम गर्न छाड्यो"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"कल गर्नका लागि तपाईंको यन्त्रमा पहिल्यैदेखि रहेको फोन एप प्रयोग गरियो"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"क्र्यास भएको फोन एप"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"कल म्युट भयो।"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"स्पिकरफोन सक्षम भयो।"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"अहिले कुरा गर्न मिल्दैन। के भइरहेको छ?"</string>
@@ -46,24 +46,24 @@
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> लाई सन्देश पठाइयो।"</string>
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> मा सन्देश पठाउन सकिएन।"</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"कलिङ खाताहरू"</string>
- <string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"आपत्कालीन कलहरूलाई मात्र अनुमति दिइएको छ।"</string>
+ <string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"आपतकालीन कलहरूलाई मात्र अनुमति दिइएको छ।"</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"यो अनुप्रयोगले फोनको अनुमति बिना बहिर्गमन कलहरू गर्न सक्दैन।"</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"एक कल गर्नको लागि, एक वैध नम्बर प्रविष्टि गर्नुहोस्।"</string>
<string name="duplicate_video_call_not_allowed" msgid="5754746140185781159">"यस समयमा कल थप गर्न सकिँदैन।"</string>
<string name="no_vm_number" msgid="2179959110602180844">"भ्वाइसमेल नम्बर हराइरहेको छ"</string>
<string name="no_vm_number_msg" msgid="1339245731058529388">"SIM कार्डमा कुनै पनि भ्वाइसमेल नम्बर भण्डारण भएको छैन।"</string>
<string name="add_vm_number_str" msgid="5179510133063168998">"नम्बर थप्नुहोस्"</string>
- <string name="change_default_dialer_dialog_title" msgid="5861469279421508060">"तपाईंको पूर्वनिर्धारित फोन एप <xliff:g id="NEW_APP">%s</xliff:g> बनाउने हो?"</string>
+ <string name="change_default_dialer_dialog_title" msgid="5861469279421508060">"तपाईंको पूर्वनिर्धारित फोन अनुप्रयोग <xliff:g id="NEW_APP">%s</xliff:g> बनाउने हो?"</string>
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"पूर्वनिर्धारित रूपमा सेट गर्नुहोस्"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"रद्द गर्नुहोस्"</string>
- <string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> कलका सबै पक्षहरूलाई स्थापित गर्न र नियन्त्रण गर्न सक्षम हुने छ। तपाईंलाई विश्वास लाग्ने एपहरूलाई मात्र फोनमा पूर्वनिर्धारित एपका रूपमा सेट गर्नुपर्छ।"</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"तपाईंको पूर्वनिर्धारित कल स्क्रिन एप <xliff:g id="NEW_APP">%s</xliff:g> बनाउने हो?"</string>
+ <string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> कलका सबै पक्षहरूलाई स्थापित गर्न र नियन्त्रण गर्न सक्षम हुने छ। तपाईंलाई विश्वास लाग्ने अनुप्रयोगहरूलाई मात्र फोनमा पूर्वनिर्धारित अनुप्रयोगका रूपमा सेट गर्नुपर्छ।"</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"तपाईंको पूर्वनिर्धारित कल स्क्रिन अनुप्रयोग <xliff:g id="NEW_APP">%s</xliff:g> बनाउने हो?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> ले अब उप्रान्त कलहरू स्क्रिन गर्न सक्ने छैनन्।"</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> ले तपाईंको सम्पर्कमा नभएका कल गर्ने व्यक्तिका जानकारी हेर्न सक्छ र तिनीहरूमाथि रोक लगाउन सक्छ। तपाईंलाई विश्वास लाग्ने एपहरूलाई मात्र कल स्क्रिन पूर्वनिर्धारित एपका रूपमा सेट गर्नुपर्छ।"</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> ले तपाईंको सम्पर्कमा नभएका कल गर्ने व्यक्तिका जानकारी हेर्न सक्छ र तिनीहरूमाथि रोक लगाउन सक्छ। तपाईंलाई विश्वास लाग्ने अनुप्रयोगहरूलाई मात्र कल स्क्रिन पूर्वनिर्धारित अनुप्रयोगका रूपमा सेट गर्नुपर्छ।"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"पूर्वनिर्धारित रूपमा सेट गर्नुहोस्"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"रद्द गर्नुहोस्"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"रोकिएका नम्बरहरू"</string>
- <string name="blocked_numbers_msg" msgid="2797422132329662697">"तपाईँले रोक लगाइएका नम्बरहरूबाट फोन वा टेक्स्ट म्यासेजहरू प्राप्त गर्नुहुने छैन।"</string>
+ <string name="blocked_numbers_msg" msgid="2797422132329662697">"तपाईँले रोक लगाइएका नम्बरहरूबाट फोन वा पाठ सन्देशहरू प्राप्त गर्नुहुने छैन।"</string>
<string name="block_number" msgid="3784343046852802722">"नम्बर थप्नुहोस्"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> लाई अनब्लक गर्ने हो?"</string>
<string name="unblock_button" msgid="8732021675729981781">"अनब्लक गर्नुहोस्"</string>
@@ -73,11 +73,11 @@
<string name="non_primary_user" msgid="315564589279622098">"यन्त्रको मालिकले रोकिएका नम्बरहरूलाई हेर्न र व्यवस्थापन गर्न सक्छ।"</string>
<string name="delete_icon_description" msgid="5335959254954774373">"अनब्लक गर्नुहोस्"</string>
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"रोक लगाउने काम अस्थायी रूपमा निष्क्रिय छ"</string>
- <string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"तपाईँले आपत्कालीन नम्बरमा डायल गरेपछि वा पाठ सन्देश पठाएपछि आपत्कालीन सेवाहरूले तपाईँलाई सम्पर्क गर्न सकून् भन्ने कुरा सुनिश्चित गर्न कलमाथिको अवरोध निष्क्रिय गरिन्छ।"</string>
+ <string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"तपाईँले आपतकालीन नम्बरमा डायल गरेपछि वा पाठ सन्देश पठाएपछि आपतकालीन सेवाहरूले तपाईँलाई सम्पर्क गर्न सकून् भन्ने कुरा सुनिश्चित गर्न कलमाथिको अवरोध निष्क्रिय गरिन्छ।"</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"अब पुन:-सक्रिय गर्नुहोस्"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> माथि रोक लगाइयो"</string>
<string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> माथिको रोक हटाइयो"</string>
- <string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"आपत्कालीन नम्बरमाथि रोक लगाउन सकिएन।"</string>
+ <string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"आपतकालीन नम्बरमाथि रोक लगाउन सकिएन।"</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> लाई पहिले नै रोकिएको छ।"</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"कल गर्न व्यक्तिगत डायलर प्रयोग गर्दै"</string>
<string name="notification_incoming_call" msgid="1233481138362230894">"<xliff:g id="CALL_FROM">%2$s</xliff:g> ले गरेको <xliff:g id="CALL_VIA">%1$s</xliff:g> कल"</string>
@@ -97,14 +97,14 @@
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"आगमन कलहरू"</string>
<string name="notification_channel_missed_call" msgid="7168893015283909012">"छुटेका कलहरू"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"कलमाथि रोक लगाउने सुविधा"</string>
- <string name="notification_channel_background_calls" msgid="7785659903711350506">"ब्याकग्राउन्डका कलहरू"</string>
+ <string name="notification_channel_background_calls" msgid="7785659903711350506">"पृष्ठभूमिका कलहरू"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"विच्छेद गरिएका कल"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"क्र्यास भएका फोन एपहरू"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"यो कल गर्नुले तपाईंको <xliff:g id="OTHER_APP">%1$s</xliff:g> कल अन्त्य गर्दछ।"</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"यो कल गर्ने तरिका छनौट गर्नुहोस्"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> प्रयोग गरी कल रिडाइरेक्ट गर्नुहोस्"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"फोन नम्बर प्रयोग गरी कल गर्नुहोस्"</string>
- <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> प्रयोग गरेर कल गर्न सकिएन। कुनै अर्को रिडिरेक्टिङ एपको प्रयोग वा मद्दतका लागि विकासकर्तासँग सम्पर्क गरी हेर्नुहोस्।"</string>
+ <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> प्रयोग गरेर कल गर्न सकिएन। कुनै अर्को रिडिरेक्टिङ अनुप्रयोगको प्रयोग वा मद्दतका लागि विकासकर्तासँग सम्पर्क गरी हेर्नुहोस्।"</string>
<string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"कलमाथि रोक लगाउने सुविधा"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"सम्पर्क सूचीहरूमा नरहेका नम्बरहरू"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"आफ्नो सम्पर्क सूचीहरूमा सूचीबद्ध नगरिएका नम्बरहरूमाथि रोक लगाउनुहोस्"</string>
@@ -116,8 +116,8 @@
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"अज्ञात कल गर्ने व्यक्तिहरूको कलमाथि रोक लगाउनुहोस्"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"कलमाथि रोक लगाउने सुविधा"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"कलमाथि रोक लगाउने सुविधालाई असक्षम पारियो"</string>
- <string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"आपत्कालीन कल गरियो"</string>
- <string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"आपत्कालीन अवस्थामा उद्दार गर्ने मान्छेहरूलाई तपाईंलाई सम्पर्क गर्न दिन कलमाथि रोक लगाउने सुविधा असक्षम पारिएको छ।"</string>
+ <string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"आपतकालीन कल गरियो"</string>
+ <string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"आपतकालीन अवस्थामा उद्दार गर्ने मान्छेहरूलाई तपाईंलाई सम्पर्क गर्न दिन कलमाथि रोक लगाउने सुविधा असक्षम पारिएको छ।"</string>
<string name="developer_title" msgid="9146088855661672353">"टेलिकमको विकासकर्ताको मेनु"</string>
- <string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"आपत्कालीन कल चलिराखेको बेलामा अरु कल स्वीकार गर्न सकिँदैन।"</string>
+ <string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"आपत्कालीन कल चलिराखेको बेलामा अरु कल स्वीकार गर्न सकिँदैन।"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 166e95d..10b8d82 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Bericht"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Beëindigd gesprek"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Het gesprek met <xliff:g id="CALLER">%s</xliff:g> is beëindigd omdat er een noodoproep is geplaatst."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Je gesprek is beëindigd omdat er een noodoproep is geplaatst."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Achtergrondgesprek"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> heeft een gesprek op de achtergrond geplaatst. Deze app kan audio openen en afspelen over het gesprek."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> reageert niet meer"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Voor je gesprek is de telefoon-app van je apparaat gebruikt"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Gecrashte telefoon-app"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Gesprek gedempt."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Luidspreker is aan."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kan nu niet opnemen. Alles goed?"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index e3ca712..40f513c 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -21,18 +21,18 @@
<string name="unknown" msgid="6993977514360123431">"ଅଜଣା"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"ମିସଡ୍ କଲ୍"</string>
<string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"କାର୍ଯ୍ୟସ୍ଥଳୀରୁ ଆସିଥିବା ମିସଡ୍ କଲ୍"</string>
- <string name="notification_missedCallsTitle" msgid="3910479625507893809">"ମିସ୍ଡ କଲ୍"</string>
- <string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>ଟି ମିସ୍ଡ କଲ୍"</string>
+ <string name="notification_missedCallsTitle" msgid="3910479625507893809">"ମିସଡ୍ କଲ୍"</string>
+ <string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>ଟି ମିସଡ୍ କଲ୍"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"<xliff:g id="MISSED_CALL_FROM">%s</xliff:g>ଙ୍କ ଠାରୁ ମିସ୍-କଲ୍ ମିଳିଛି"</string>
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"କଲବ୍ୟାକ୍ କରନ୍ତୁ"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"ମେସେଜ୍ ଦିଅନ୍ତୁ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"କଲ୍ ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ଏକ ଜରୁରୀକାଳୀନ କଲ୍ କରାଯାଇଥିବାରୁ <xliff:g id="CALLER">%s</xliff:g>ଙ୍କୁ କରାଯାଇଥିବା କଲ୍ ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି।"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ଏକ ଜରୁରୀକାଳୀନ କଲ୍ କରାଯାଉଥିବା ଯୋଗୁଁ ଆପଣଙ୍କ କଲ୍ ବିଚ୍ଛିନ୍ନ ହୋଇଯାଇଛି।"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡ କଲ୍"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡରେ ଏକ କଲ୍ କରିଛି। ଏହା ଆପ୍ କଲ୍ ସମୟରେ ଅଡିଓ ଆକ୍ସେସ୍ କରିପାରେ ଏବଂ ଚଲେଇପାରେ।"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ଉତ୍ତର ଦେଉନାହିଁ"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ଆପଣଙ୍କ କଲ୍ ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସରେ ଥିବା ଫୋନ୍ ଆପ୍ ବ୍ୟବହାର କରାଯାଇଥିଲା"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"କ୍ରାଶ୍ ହୋଇଥିବା ଫୋନ୍ ଆପ୍"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"କଲ୍ ମ୍ୟୁଟ୍ କରାଯାଇଛି।"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"ସ୍ପିକରଫୋନ୍କୁ ସକ୍ଷମ କରାଯାଇଛି ।"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ବର୍ତ୍ତମାନ କଥା ହୋଇପାରିବ ନାହିଁ। କଥା କ’ଣ?"</string>
@@ -55,7 +55,7 @@
<string name="add_vm_number_str" msgid="5179510133063168998">"ନମ୍ବର୍ ଯୋଡ଼ନ୍ତୁ"</string>
<string name="change_default_dialer_dialog_title" msgid="5861469279421508060">"<xliff:g id="NEW_APP">%s</xliff:g>କୁ ଆପଣଙ୍କ ଫୋନ୍ର ଡିଫଲ୍ଟ ଆପ୍ କରିବେ?"</string>
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"ଡିଫଲ୍ଟ ସେଟ୍ କରନ୍ତୁ"</string>
- <string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+ <string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"କ୍ୟାନ୍ସଲ୍ କରନ୍ତୁ"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> କଲ୍ କରିବା ଏବଂ କଲ୍ର ସମସ୍ତ ଦିଗକୁ ନିୟନ୍ତ୍ରଣ କରିବାରେ ସକ୍ଷମ ହେବ। କେବଳ ନିଜର ଭରସାଯୋଗ୍ୟ ଆପ୍କୁ ଡିଫଲ୍ଟ ଫୋନ୍ ଆପ୍ ଭାବେ ସେଟ୍ କରିବା ଉଚିତ୍।"</string>
<string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"<xliff:g id="NEW_APP">%s</xliff:g>କୁ ଆପଣଙ୍କ ଡିଫଲ୍ଟ କଲ୍ ସ୍କ୍ରିନିଂ ଆପ୍ କରିବେ?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> କଲ୍ ସ୍କ୍ରିନ୍ କରିପାରିରିବେ ନାହିଁ।"</string>
@@ -65,8 +65,8 @@
<string name="blocked_numbers" msgid="8322134197039865180">"ବ୍ଲକ୍ କରାଯାଇଥିବା ନମ୍ବର୍"</string>
<string name="blocked_numbers_msg" msgid="2797422132329662697">"ବ୍ଲକ୍ କରାଯାଇଥିବା ନମ୍ବର୍ରୁ ଆପଣ କଲ୍ କିମ୍ବା ଟେକ୍ସଟ୍ ଗ୍ରହଣ କରିପାରିବେ ନାହିଁ।"</string>
<string name="block_number" msgid="3784343046852802722">"ଗୋଟିଏ ନମ୍ବର୍ ଯୋଡ଼ନ୍ତୁ"</string>
- <string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>କୁ ଅନବ୍ଲକ୍ କରିବେ?"</string>
- <string name="unblock_button" msgid="8732021675729981781">"ଅନବ୍ଲକ୍ କରନ୍ତୁ"</string>
+ <string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>ରୁ ବ୍ଲକ୍ ହଟାଇବେ?"</string>
+ <string name="unblock_button" msgid="8732021675729981781">"ଅବରୋଧ ହଟାନ୍ତୁ"</string>
<string name="add_blocked_dialog_body" msgid="8599974422407139255">"ଏହାର କଲ୍ ଓ ଟେକ୍ସଟ୍କୁ ବ୍ଲକ୍ କରନ୍ତୁ"</string>
<string name="add_blocked_number_hint" msgid="8769422085658041097">"ଫୋନ୍ ନମ୍ଵର୍"</string>
<string name="block_button" msgid="485080149164258770">"ବ୍ଲକ୍ କରନ୍ତୁ"</string>
@@ -76,7 +76,7 @@
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"ଆପଣ ଗୋଟିଏ ଜରୁରିକାଳୀନ ନମ୍ବର୍କୁ ଡାଏଲ୍ କିମ୍ବା ଟେକ୍ସଟ୍ କରିବା ପରେ, ଜରୁରିକାଳୀନ ସେବା ଆପଣଙ୍କୁ ଯୋଗାଯୋଗ କରିବାକୁ ସୁନିଶ୍ଚିତ କରିବା ପାଇଁ ଅବରୋଧକୁ ବନ୍ଦ କରିଦିଆଯାଇଥାଏ।"</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"ବର୍ତ୍ତମାନ ପୁନଃସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> ବ୍ଲକ୍ କରାଯାଇଛି"</string>
- <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> ଅନବ୍ଲକ୍ କରାଯାଇଛି"</string>
+ <string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> ଅବରୋଧ ହଟାଇଦିଆଯାଇଛି"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"ଜରୁରିକାଳୀନ ନମ୍ବର୍କୁ ଅବରୋଧ କରିବାରେ ଅକ୍ଷମ।"</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>କୁ ଅବରୋଧ କରାଯାଇସରିଛି।"</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"କଲ୍ କରିବା ପାଇଁ ବ୍ୟକ୍ତିଗତ ଡାଏଲର୍କୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -95,17 +95,17 @@
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"ଆପଣଙ୍କର <xliff:g id="OTHER_CALL">%1$s</xliff:g> କଲ୍ ହେତୁ କଲ୍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"ଅନ୍ୟ ଆପ୍ରେ କରାଯାଇଥିବା କଲ୍ ହେତୁ କଲ୍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"ଇନ୍କମିଙ୍ଗ କଲ୍"</string>
- <string name="notification_channel_missed_call" msgid="7168893015283909012">"ମିସ୍ଡ କଲ୍"</string>
- <string name="notification_channel_call_blocking" msgid="2028807677868598710">"କଲ୍ ବ୍ଲକିଂ"</string>
+ <string name="notification_channel_missed_call" msgid="7168893015283909012">"ମିସଡ୍ କଲ୍"</string>
+ <string name="notification_channel_call_blocking" msgid="2028807677868598710">"କଲ୍କୁ ଅବରୋଧ କରନ୍ତୁ"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡ କଲ୍ଗୁଡ଼ିକ"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"ବିଚ୍ଛିନ୍ନ କରାଯାଇଥିବା କଲ୍ଗୁଡ଼ିକ"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"କ୍ରାସ୍ ହୋଇଥିବା ଫୋନ୍ ଆପ୍ସ"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"କ୍ରାଶ୍ ହୋଇଥିବା ଫୋନ୍ ଆପ୍ସ"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"ଏହି କଲ୍କୁ ସ୍ଥାପନ କରିବା ଦ୍ଵାରା ଆପଣଙ୍କର <xliff:g id="OTHER_APP">%1$s</xliff:g> କଲ୍ ସମାପ୍ତ ହୋଇଯିବ।"</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"ଏହି କଲ୍ କିପରି କରିବାକୁ ଚାହାନ୍ତି ବାଛନ୍ତୁ"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> ବ୍ୟବହାର କରି କଲ୍ ରିଡାଇରେକ୍ଟ କରନ୍ତୁ"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"ମୋ ଫୋନ୍ ନମ୍ବର ବ୍ୟବହାର କରି କଲ୍ କରନ୍ତୁ"</string>
<string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> କଲ୍ କରିପାରିବ ନାହିଁ। ଏକ ଭିନ୍ନ କଲ୍ ପୁନଃନିର୍ଦ୍ଦେଶିତ ଆପ୍ ବ୍ୟବହାର କରି ଚେଷ୍ଟା କରନ୍ତୁ କିମ୍ବା ସାହାଯ୍ୟ ପାଇଁ ଡେଭେଲପ୍ରଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
- <string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"କଲ୍ ବ୍ଲକିଂ"</string>
+ <string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"କଲ୍କୁ ଅବରୋଧ କରନ୍ତୁ"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"ଯୋଗାଯୋଗରେ ନଥିବା ନମ୍ବର୍"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"ଆପଣଙ୍କ ଯୋଗାଯୋଗରେ ତାଲିକାଭୁକ୍ତ ହୋଇନଥିବା ନମ୍ବର୍କୁ ଅବରୋଧ କରନ୍ତୁ"</string>
<string name="phone_settings_private_num_txt" msgid="6339272760338475619">"ଗୋପନୀୟ"</string>
@@ -113,9 +113,9 @@
<string name="phone_settings_payphone_txt" msgid="5003987966052543965">"ପେ-ଫୋନ୍"</string>
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"ପେ-ଫୋନ୍ରୁ କଲ୍କୁ ଅବରୋଧ କରନ୍ତୁ"</string>
<string name="phone_settings_unknown_txt" msgid="3577926178354772728">"ଅଜଣା"</string>
- <string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"ଅଜଣା କଲରର କଲ୍କୁ ବ୍ଲକ୍ କରନ୍ତୁ"</string>
- <string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"କଲ୍ ବ୍ଲକିଂ"</string>
- <string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"କଲ୍ ବ୍ଲକିଂକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"ଅଜଣା କଲକର୍ତ୍ତାଙ୍କର କଲ୍କୁ ବ୍ଲକ୍ କରନ୍ତୁ"</string>
+ <string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"କଲ୍କୁ ଅବରୋଧ କରନ୍ତୁ"</string>
+ <string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"କଲ୍ ଅବରୋଧ ସୁବିଧାକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"ଜରୁରିକାଳୀନ କଲ୍ କରାଗଲା"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"ଜରୁରିକାଳୀନ ସହାୟତା କର୍ମଚାରୀମାନେ ଆପଣଙ୍କୁ ଯୋଗଯୋଗ କରିବା ପାଇଁ କଲ୍ ଅବରୋଧକୁ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="developer_title" msgid="9146088855661672353">"ଟେଲେକମ୍ ଡେଭେଲପର୍ ମେନୁ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 2b94316..5a5bc35 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"ਸੁਨੇਹਾ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"ਕਾਲ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"<xliff:g id="CALLER">%s</xliff:g> ਦੀ ਕਾਲ ਨੂੰ ਕਿਸੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲ ਦੇ ਚਲਦੇ ਕੱਟ ਦਿੱਤਾ ਗਿਆ ਹੈ।"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ਕਿਸੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲ ਕਰਕੇ ਤੁਹਾਡੀ ਕਾਲ ਕੱਟ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Background call"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> has placed a call into the background. This app may be accessing and playing audio over the call."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ਨੇ ਕੰਮ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ਤੁਹਾਡੀ ਕਾਲ ਨੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਪਹਿਲਾਂ ਤੋਂ ਸਥਾਪਤ ਫ਼ੋਨ ਐਪ ਦੀ ਵਰਤੋਂ ਕੀਤੀ"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"ਕ੍ਰੈਸ਼ ਹੋਈ ਫ਼ੋਨ ਐਪ"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ਕਾਲ ਮਿਊਟ ਕੀਤੀ।"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"ਸਪੀਕਰਫੋਨ ਸਮਰਥਿਤ।"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ਹੁਣੇ ਗੱਲ ਨਹੀਂ ਹੋ ਸਕਦੀ। ਕੀ ਹੋਇਆ?"</string>
@@ -95,17 +95,17 @@
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"ਤੁਹਾਡੀਆਂ <xliff:g id="OTHER_CALL">%1$s</xliff:g> ਕਾਲਾਂ ਦੇ ਕਾਰਨ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"ਕਿਸੇ ਹੋਰ ਐਪ ਵਿੱਚ ਇੱਕ ਕਾਲ ਹੋਣ ਦੇ ਕਾਰਨ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"ਇਨਕਮਿੰਗ ਕਾਲਾਂ"</string>
- <string name="notification_channel_missed_call" msgid="7168893015283909012">"ਮਿਸ ਕਾਲਾਂ"</string>
- <string name="notification_channel_call_blocking" msgid="2028807677868598710">"ਕਾਲ ਬਲਾਕ ਕਰਨਾ"</string>
- <string name="notification_channel_background_calls" msgid="7785659903711350506">"ਬੈਕਗ੍ਰਾਊਂਡ ਕਾਲਾਂ"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"ਡਿਸਕਨੈਕਟ ਕੀਤੀਆਂ ਕਾਲਾਂ"</string>
+ <string name="notification_channel_missed_call" msgid="7168893015283909012">"ਖੁੰਝੀਆਂ ਕਾਲਾਂ"</string>
+ <string name="notification_channel_call_blocking" msgid="2028807677868598710">"ਕਾਲ ਬਲਾਕਿੰਗ"</string>
+ <string name="notification_channel_background_calls" msgid="7785659903711350506">"Background calls"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"ਕਾਲਾਂ ਡਿਸਕਨੈਕਟ ਹੋ ਗਈਆਂ"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"ਕ੍ਰੈਸ਼ ਹੋਈਆਂ ਫ਼ੋਨ ਐਪਾਂ"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"ਇਹ ਕਾਲ ਕਰਨ ਨਾਲ ਤੁਹਾਡੀ <xliff:g id="OTHER_APP">%1$s</xliff:g> ਕਾਲ ਸਮਾਪਤ ਹੋ ਜਾਵੇਗੀ।"</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"ਚੁਣੋ ਕਿ ਕਾਲ ਕਿਵੇਂ ਕਰਨੀ ਹੈ"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਕਾਲ ਰੀਡਾਇਰੈਕਟ ਕਰੋ"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"ਮੇਰਾ ਫ਼ੋਨ ਨੰਬਰ ਵਰਤ ਕੇ ਕਾਲ ਕਰੋ"</string>
<string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> ਤੋਂ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਕਾਲ ਨੂੰ ਰੀਡਾਇਰੈਕਟ ਕਰਨ ਲਈ ਕੋਈ ਵੱਖਰੀ ਐਪ ਵਰਤ ਕੇ ਦੇਖੋ ਜਾਂ ਮਦਦ ਲਈ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸੰਪਰਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
- <string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"ਕਾਲ ਬਲਾਕ ਕਰਨਾ"</string>
+ <string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"ਕਾਲ ਬਲਾਕਿੰਗ"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"ਨੰਬਰ ਜੋ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਵਿੱਚ ਨਹੀਂ ਹਨ"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"ਉਹ ਨੰਬਰ ਬਲਾਕ ਕਰੋ ਜੋ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਵਿੱਚ ਨਹੀਂ ਹਨ"</string>
<string name="phone_settings_private_num_txt" msgid="6339272760338475619">"ਨਿੱਜੀ"</string>
@@ -114,7 +114,7 @@
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"ਜਨਤਕ ਫ਼ੋਨਾਂ ਵਾਲੀਆਂ ਕਾਲਾਂ ਬਲਾਕ ਕਰੋ"</string>
<string name="phone_settings_unknown_txt" msgid="3577926178354772728">"ਅਗਿਆਤ"</string>
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"ਅਣਪਛਾਤੇ ਕਾਲਰਾਂ ਵਾਲੀਆਂ ਕਾਲਾਂ ਬਲਾਕ ਕਰੋ"</string>
- <string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"ਕਾਲ ਬਲਾਕ ਕਰਨਾ"</string>
+ <string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"ਕਾਲ ਬਲਾਕਿੰਗ"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"ਕਾਲ ਬਲਾਕਿੰਗ ਵਿਕਲਪ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"ਸੰਕਟਕਾਲੀਨ ਕਾਲ ਕੀਤੀ ਗਈ"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"ਸੰਕਟਕਾਲੀਨ ਸਥਿਤੀ ਵਿੱਚ ਮਦਦ ਕਰਨ ਵਾਲੇ ਵਿਅਕਤੀ ਨੂੰ ਤੁਹਾਨੂੰ ਸੰਪਰਕ ਕਰਨ ਦੇਣ ਲਈ ਕਾਲ ਬਲਾਕਿੰਗ ਵਿਕਲਪ ਬੰਦ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ।"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 9cb1980..d103958 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Wiadomość"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Przerwane połączenie"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Połączenie z rozmówcą <xliff:g id="CALLER">%s</xliff:g> zostało przerwane z powodu nawiązania połączenia alarmowego."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Połączenie zostało przerwane z powodu nawiązania połączenia alarmowego."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Połączenie w tle"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikacja <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> umieściła połączenie w tle. Może ona uzyskiwać dostęp do dźwięku i odtwarzać go podczas połączenia."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Aplikacja <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> nie odpowiada"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Połączenie zostało zrealizowane za pomocą aplikacji do obsługi telefonu zainstalowanej na urządzeniu"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikacja telefoniczna uległa awarii"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Połączenie wyciszone."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Głośnik włączony."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Nie mogę rozmawiać. Co słychać?"</string>
@@ -99,7 +99,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blokowanie połączeń"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Połączenia w tle"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Przerwane połączenia"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplikacje telefoniczne po awarii"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplikacje telefoniczne, które uległy awarii"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Jeśli zadzwonisz, połączenie w aplikacji <xliff:g id="OTHER_APP">%1$s</xliff:g> zostanie zakończone."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Wybierz, jak chcesz zadzwonić"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Przekieruj połączenie za pomocą aplikacji <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index bb5213e..e91ac83 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mensagem"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Chamada desligada"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"A chamada para <xliff:g id="CALLER">%s</xliff:g> foi desligada porque foi efetuada uma chamada de emergência."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"A chamada foi desligada porque foi efetuada uma chamada de emergência."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Cham. segundo plano"</string>
- <string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> colocou uma chamada em segundo plano. Esta app pode estar a aceder e a reproduzir áudio sobre a chamada."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> deixou de responder."</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"A chamada utilizou a app de telefone incluída com o dispositivo."</string>
+ <string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> colocou uma chamada em segundo plano. Esta aplicação pode estar a aceder e a reproduzir áudio sobre a chamada."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplicação Telefone com falha"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Chamada sem som."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Alta voz ativada."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Não posso falar agora. Que se passa?"</string>
@@ -47,19 +47,19 @@
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Falha ao enviar a mensagem para <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Contas de chamadas"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Apenas são permitidas chamadas de emergência."</string>
- <string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Esta app não pode fazer chamadas sem a autorização do telefone."</string>
+ <string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Esta aplicação não pode fazer chamadas sem a autorização do telefone."</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"Para telefonar, introduza um número válido."</string>
<string name="duplicate_video_call_not_allowed" msgid="5754746140185781159">"Não é possível adicionar a chamada neste momento."</string>
<string name="no_vm_number" msgid="2179959110602180844">"Número do correio de voz em falta"</string>
<string name="no_vm_number_msg" msgid="1339245731058529388">"Não existe um número de correio de voz armazenado no cartão SIM."</string>
<string name="add_vm_number_str" msgid="5179510133063168998">"Adicionar número"</string>
- <string name="change_default_dialer_dialog_title" msgid="5861469279421508060">"Predefinir <xliff:g id="NEW_APP">%s</xliff:g> como a sua app Telefone?"</string>
+ <string name="change_default_dialer_dialog_title" msgid="5861469279421508060">"Predefinir <xliff:g id="NEW_APP">%s</xliff:g> como a sua aplicação Telefone?"</string>
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"Predefinir"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"Cancelar"</string>
- <string name="change_default_dialer_warning_message" msgid="8461963987376916114">"A app <xliff:g id="NEW_APP">%s</xliff:g> poderá efetuar chamadas e controlar todos os aspetos das mesmas. Apenas as aplicações em que confia devem ser escolhidas como a app de telefone predefinida."</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"Predefinir <xliff:g id="NEW_APP">%s</xliff:g> como a sua app Telefone?"</string>
+ <string name="change_default_dialer_warning_message" msgid="8461963987376916114">"A aplicação <xliff:g id="NEW_APP">%s</xliff:g> poderá efetuar chamadas e controlar todos os aspetos das mesmas. Apenas as aplicações em que confia devem ser escolhidas como a aplicação de telefone predefinida."</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"Predefinir <xliff:g id="NEW_APP">%s</xliff:g> como a sua aplicação Telefone?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> deixará de poder filtrar as chamadas."</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> poderá ver informações sobre os autores das chamadas que não se encontrem nos seus contactos e poderá bloquear estas chamadas. Apenas deve predefinir como app de filtro de chamadas as aplicações nas quais confia."</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> poderá ver informações sobre os autores das chamadas que não se encontrem nos seus contactos e poderá bloquear estas chamadas. Apenas deve predefinir como aplicação de filtro de chamadas as aplicações nas quais confia."</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"Predefinir"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"Cancelar"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"Números bloqueados"</string>
@@ -93,18 +93,18 @@
<string name="cant_call_due_to_no_supported_service" msgid="1635626384149947077">"Não é possível efetuar a chamada porque não existem contas de chamadas que suportem chamadas deste tipo."</string>
<string name="cant_call_due_to_ongoing_call" msgid="8004235328451385493">"Não é possível efetuar a chamada devido à sua chamada do <xliff:g id="OTHER_CALL">%1$s</xliff:g>."</string>
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"Não é possível efetuar a chamada devido às suas chamadas do <xliff:g id="OTHER_CALL">%1$s</xliff:g>."</string>
- <string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"Não é possível efetuar a chamada devido a uma chamada noutra app."</string>
+ <string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"Não é possível efetuar a chamada devido a uma chamada noutra aplicação."</string>
<string name="notification_channel_incoming_call" msgid="5245550964701715662">"Chamadas recebidas"</string>
<string name="notification_channel_missed_call" msgid="7168893015283909012">"Chamadas não atendidas"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Bloqueio de chamadas"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Chamadas em segundo plano"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Chamadas desligadas"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Apps Telefone com falhas"</string>
- <string name="alert_outgoing_call" msgid="5319895109298927431">"Ao efetuar esta chamada, irá terminar a chamada na app <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplicações Telefone com falhas"</string>
+ <string name="alert_outgoing_call" msgid="5319895109298927431">"Ao efetuar esta chamada, irá terminar a chamada na aplicação <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Escolha como pretende efetuar esta chamada"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Redirecionar chamada através de <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"Ligar com o meu número de telefone"</string>
- <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"Não é possível efetuar uma chamada através da app <xliff:g id="OTHER_APP">%1$s</xliff:g>. Experimente utilizar uma app de redirecionamento de chamadas diferente ou contactar o programador para obter ajuda."</string>
+ <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"Não é possível efetuar uma chamada através da aplicação <xliff:g id="OTHER_APP">%1$s</xliff:g>. Experimente utilizar uma aplicação de redirecionamento de chamadas diferente ou contactar o programador para obter ajuda."</string>
<string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"Bloqueio de chamadas"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"Números não incluídos nos Contactos"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"Bloquear números que não estejam na sua lista de Contactos"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 5d88619..135abd2 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mensagem"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Chamada desconectada"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"A chamada para <xliff:g id="CALLER">%s</xliff:g> foi desconectada porque uma chamada de emergência está sendo realizada."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Sua chamada foi desconectada porque uma chamada de emergência está sendo feita."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Chamada em 2º plano"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"O app <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> colocou uma chamada em segundo plano. Talvez ele esteja acessando e tocando o áudio durante a chamada."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"O app <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> parou de responder"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"A chamada usou o aplicativo de telefone que veio com seu dispositivo"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Falha com o app de telefone"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Seu app de telefone <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> falhou. A chamada continuou usando o app de telefone que veio com seu dispositivo."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Chamada sem áudio."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Viva-voz ativado."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Não posso falar agora. Manda um SMS, por favor?"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index a95d4a4..b0e569e 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mesaj"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Apel deconectat"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Apelul către <xliff:g id="CALLER">%s</xliff:g> a fost deconectat deoarece a fost inițiat un apel de urgență."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Apelul a fost deconectat deoarece a fost inițiat un apel de urgență."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Apel în fundal"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> a inițiat un apel în fundal. Este posibil ca această aplicație să acceseze și să redea mesaje audio peste apel."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> nu mai răspunde"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Apelul dvs. a folosit aplicația Telefon instalată pe dispozitiv"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplicație pentru telefon blocată"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Aplicația dvs. pentru telefon <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> s-a blocat. Apelul dvs. a fost continuat cu aplicația Telefon instalată pe dispozitiv."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Apel cu sunet dezactivat."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Difuzor activat."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Nu pot acum. Despre ce e vorba?"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index a50907a..808da40 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -28,16 +28,16 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Написать"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Вызов прекращен"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Вызов абонента <xliff:g id="CALLER">%s</xliff:g> был прекращен, так как осуществляется экстренный вызов."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Ваш вызов прекращен, так как осуществляется экстренный вызов."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Фоновый вызов"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Приложение <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> перевело вызов в фоновый режим. Это приложение может получать доступ к аудио вызова или воспроизводить в нем свое аудио."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> не отвечает"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Вызов был сделан с использованием приложения, которое установлено на ваше устройство производителем."</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Прекращена работа приложения телефона"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Звук выключен."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Громкая связь включена."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Не могу говорить. Что случилось?"</string>
- <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Я сейчас перезвоню."</string>
- <string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Я перезвоню позже."</string>
+ <string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Я сейчас вам перезвоню."</string>
+ <string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Я перезвоню вам позже."</string>
<string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"Не могу говорить. Позвоните позже."</string>
<string name="respond_via_sms_setting_title" msgid="4762275482898830160">"Быстрые ответы"</string>
<string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"Быстрые ответы"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index b73272b..9ce63d4 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"පණිවිඩය"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"විසන්ධි කළ ඇමතුම"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"<xliff:g id="CALLER">%s</xliff:g> වෙත ඇමතුම හදිසි ඇමතුමක් ගනිමින් ඇති නිසා විසන්ධි කර ඇත."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"හදිසි ඇමතුමක් ගනිමින් පැවතීම හේතුවෙන් ඔබේ ඇමතුම විසන්ධි කර ඇත."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"පසුබිම් ඇමතුම"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> පසුබිම තුළට ඇමතුමක් ගෙන ඇත. මෙම යෙදුම ඇමතුම හරහා ඕඩියෝ වෙත ප්රවේශ වෙමින් සහ වාදනය කරමින් සිටිය හැකිය."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ප්රතිචාර දැක්වීම නතර කළේය"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"ඔබේ ඇමතුම ඔබේ උපාංගය සමග පැමිණි දුරකථන යෙදුම භාවිත කළේය"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"බිඳ වැටුණු දුරකථන යෙදුම"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ඇමතුම නිශ්ශබ්දයි."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"ස්පිකර්ෆෝන් සබලයි."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"දැන් කතාකරන්න බැහැ. මොකද වෙලා තියෙන්නෙ?"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 0d79f1a..af4dedf 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Napísať"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Zrušený hovor"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Hovor kontaktu <xliff:g id="CALLER">%s</xliff:g> bol zrušený, aby mohlo prebehnúť tiesňové volanie."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Váš hovor bol zrušený, aby mohlo prebehnúť tiesňové volanie."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Hovor na pozadí"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikácia <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> umiestnila hovor do pozadia. Táto aplikácia môže mať počas hovoru prístup k zvuku a prehrávať ho."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Aplikácia <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> prestala reagovať"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Na hovor bola použitá telefónna aplikácia, ktorá bola vopred nainštalovaná vo vašom zariadení"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Telefónna aplikácia sa zrútila"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Zvuk hovoru bol vypnutý."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Reproduktor je povolený."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Teraz nemôžem hovoriť, o čo ide?"</string>
@@ -99,7 +99,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blokovanie hovorov"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Hovory na pozadí"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Zrušené hovory"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Zrútené telefónne aplikácie"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Telefónne aplikácie sa zrútili"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Ak uskutočníte tento hovor, hovor cez <xliff:g id="OTHER_APP">%1$s</xliff:g> bude ukončený."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Vyberte, ako chcete tento hovor uskutočniť"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Presmerovať hovor cez aplikáciu <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 5595c40..7cb871e 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Sporočilo"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Klic je prekinjen"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Klic za stik <xliff:g id="CALLER">%s</xliff:g> je prekinjen zaradi vzpostavljanja klica v sili."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Klic je prekinjen zaradi vzpostavljanja klica v sili."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Klic v ozadju"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Aplikacija <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> je klic premaknila v ozadje. Ta aplikacija morda dostopa do zvoka in ga predvaja prek klica."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Aplikacija <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> se ne odziva več"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Klic je bil opravljen prek aplikacije za klicanje, ki jo je v napravo namestil proizvajalec"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikacija za klicanje se je zrušila"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Klic izključen."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Zvočnik omogočen."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Zdaj ne morem govoriti. Za kaj gre?"</string>
@@ -98,8 +98,8 @@
<string name="notification_channel_missed_call" msgid="7168893015283909012">"Neodgovorjeni klici"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Blokiranje klicev"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Klici v ozadju"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Prekinjeni klici"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Zrušene aplikacije za klicanje"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Klici so prekinjeni"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Aplikacije za klicanje so se zrušile"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Če opravite ta klic, bo končan klic prek aplikacije <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Izberite, kako želite opraviti klic"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Preusmeri klic z aplikacijo <xliff:g id="OTHER_APP">%1$s</xliff:g>"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 53f4efc..859cc05 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mesazh"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Telefonatë e shkëputur"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Telefonata me <xliff:g id="CALLER">%s</xliff:g> është shkëputur sepse është kryer një telefonatë urgjence."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Telefonata jote është shkëputur sepse është kryer një telefonatë urgjence."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Telefonatë në sfond"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> e ka vendosur një telefonatë në sfond. Ky aplikacion mund të ketë qasje dhe të luajë audio mbi telefonatë."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> nuk përgjigjet më"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Telefonata jote ka përdorur aplikacionin e telefonit që ke marrë me pajisjen tënde"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Aplikacioni i telefonit që ka pësuar një ndërprerje aksidentale"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Telefonata kaloi në heshtje."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Altoparlanti u aktivizua."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Nuk flas dot tani. Si është puna?"</string>
@@ -65,7 +65,7 @@
<string name="blocked_numbers" msgid="8322134197039865180">"Numrat e bllokuar"</string>
<string name="blocked_numbers_msg" msgid="2797422132329662697">"Nuk do të marrësh telefonata ose mesazhe me tekst nga numrat e bllokuar."</string>
<string name="block_number" msgid="3784343046852802722">"Shto një numër"</string>
- <string name="unblock_dialog_body" msgid="2723393535797217261">"Të zhbllokohet <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
+ <string name="unblock_dialog_body" msgid="2723393535797217261">"Zhblloko <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
<string name="unblock_button" msgid="8732021675729981781">"Zhblloko"</string>
<string name="add_blocked_dialog_body" msgid="8599974422407139255">"Blloko telefonatat dhe mesazhet me tekst nga"</string>
<string name="add_blocked_number_hint" msgid="8769422085658041097">"Numri i telefonit"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index adfece0..5a7ef47 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -20,7 +20,7 @@
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Телефон"</string>
<string name="unknown" msgid="6993977514360123431">"Непознато"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Пропуштен позив"</string>
- <string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"Пропуштен пословни позив"</string>
+ <string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"Пропуштен позив за Work"</string>
<string name="notification_missedCallsTitle" msgid="3910479625507893809">"Пропуштени позиви"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"Број пропуштених позива: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"Пропуштен позив од: <xliff:g id="MISSED_CALL_FROM">%s</xliff:g>"</string>
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Порука"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Позив је прекинут"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Позив са <xliff:g id="CALLER">%s</xliff:g> је прекинут јер се упућује хитни позив."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Позив је прекинут јер се упућује хитни позив."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Позив у позадини"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Апликација <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> је упутила позив у позадини. Она може да приступа звуку и пушта га током позива."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> више не реагује"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Позив је користио апликацију за телефонирање коју сте добили уз уређај"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Апликација за телефонирање која је отказала"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Апликација за телефонирање <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> је отказала. Позив је настављен помоћу апликације за телефонирање коју сте добили уз уређај."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Звук позива је искључен."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Спикерфон је омогућен."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"У гужви сам. О чему се ради?"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index b646cbb..8b11861 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Sms:a"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Samtalet kopplades från"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Samtalet <xliff:g id="CALLER">%s</xliff:g> kopplades från eftersom ett nödsamtal ringdes."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Samtalets kopplades bort på grund av ett nödsamtal."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Bakgrundssamtal"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> har ringt ett samtal i bakgrunden. Denna app kan få åtkomst till och spela upp ljud från samtalet."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> slutade svara"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Samtalet använde telefonappen som medföljer enheten"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Kraschad telefonapp"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Telefonappen <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> har kraschat. Samtalet fortsatte med appen Telefon som medföljer enheten."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Samtalets ljud avstängt."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Högtalartelefon aktiverad."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Kan inte prata nu. Läget?"</string>
@@ -57,9 +56,9 @@
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"Ange standard"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"Avbryt"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> kan ringa och styra allt omkring samtal. Endast appar du litar på bör ställas in som standardtelefonapp."</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"Vill du göra <xliff:g id="NEW_APP">%s</xliff:g> till din standardapp för samtalsfiltrering?"</string>
- <string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> kommer inte längre att användas för samtalsfiltrering."</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> kommer att kunna se information om uppringare som inte finns i dina kontakter och blockera dessa samtal. Endast appar du litar på bör ställas in som standardapp för samtalsfiltrering."</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"Vill du göra <xliff:g id="NEW_APP">%s</xliff:g> till din standardapp för samtalsspärr?"</string>
+ <string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> kommer inte längre att användas för samtalsspärr."</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> kommer att kunna se information om uppringare som inte finns i dina kontakter och blockera dessa samtal. Endast appar du litar på bör ställas in som standardapp för samtalsspärr."</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"Ange standard"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"Avbryt"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"Blockerade nummer"</string>
@@ -75,7 +74,7 @@
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"Blockeringen har inaktiverats tillfälligt"</string>
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"När du ringer eller sms:ar ett nödnummer inaktiveras blockering för att säkerställa att räddningstjänsten kan kontakta dig."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"Återaktivera nu"</string>
- <string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> har blockerats"</string>
+ <string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> blockerade"</string>
<string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> avblockerat"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"Det går inte att blockera nödnummer."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> är redan blockerat."</string>
@@ -98,7 +97,7 @@
<string name="notification_channel_missed_call" msgid="7168893015283909012">"Missade samtal"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Samtalsblockering"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Bakgrundssamtal"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Frånkopplade samtal"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Samtalen kopplades från"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Kraschade telefonappar"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Ringer du det här samtalet avslutas samtalet i <xliff:g id="OTHER_APP">%1$s</xliff:g>."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Välj hur du vill ringa samtalet"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index d1142f7..90becc5 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Ujumbe"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Simu imekatwa"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Simu uliyompigia <xliff:g id="CALLER">%s</xliff:g> imekatwa kwa sababu kuna simu ya dharura inayopigwa."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Simu yako imekatwa kwa sababu kuna simu ya dharura inayopigwa."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Simu ya chinichini"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> inapiga simu chinichini. Huenda programu hii inafikia na kucheza sauti huku simu ikiendelea."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> imeacha kufanya kazi"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Ulipiga simu kwa kutumia Programu ya simu iliyokuja na kifaa chako"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Programu ya simu iliyoacha kufanya kazi"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Simu imezimwa."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Spika za simu zimewezeshwa"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Siwezi kuongea sasa. Kuna nini?"</string>
@@ -43,7 +43,7 @@
<string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"Hariri majibu ya haraka"</string>
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Majibu ya haraka"</string>
- <string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Ujumbe umetumwa kwa <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
+ <string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Ujumbe uliotumwa kwa <xliff:g id="PHONE_NUMBER">%s</xliff:g> ."</string>
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Imeshindwa kutuma SMS kwa <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Akaunti za simu"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Piga simu za dharura pekee."</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index ee48214..0bf91b4 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"செய்தி"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"அழைப்பு துண்டிக்கப்பட்டது"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"அவசர அழைப்பு மேற்கொள்ளப்பட்டதால் <xliff:g id="CALLER">%s</xliff:g> உடனான அழைப்பு துண்டிக்கப்பட்டது."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"அவசர அழைப்பு மேற்கொள்ளப்படுவதால் உங்கள் அழைப்பு துண்டிக்கப்பட்டுள்ளது."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"பின்னணி அழைப்பு"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"அழைப்பை பின்னணியில் செயல்படும் வகையில் <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> மாற்றியுள்ளது. அழைப்பின் மூலமாக இந்த ஆப்ஸ் ஆடியோவை அணுகி இயக்கக்கூடும்."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> செயலிழந்துவிட்டது"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"உங்கள் சாதனத்துடன் கிடைக்கும் மொபைல் ஆப்ஸ் மூலம் அழைப்பு மேற்கொள்ளப்பட்டது"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"சிதைவடைந்த மொபைல் ஆப்ஸ்"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"உங்கள் மொபைல் ஆப்ஸான <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> சிதைவடைந்துள்ளது. உங்கள் சாதனத்துடன் கிடைக்கும் மொபைல் ஆப்ஸ் மூலமே உங்கள் அழைப்பு தொடரப்பட்டது."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"அழைப்பு முடக்கப்பட்டது."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"ஸ்பீக்கர்ஃபோன் இயக்கப்பட்டது."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"இப்போது பேசமுடியாது. என்ன விஷயம்?"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 58eb225..1837ef3 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -21,18 +21,18 @@
<string name="unknown" msgid="6993977514360123431">"తెలియదు"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"సమాధానం ఇవ్వని కాల్"</string>
<string name="notification_missedWorkCallTitle" msgid="6965463282259034953">"మిస్డ్ కార్యాలయ కాల్"</string>
- <string name="notification_missedCallsTitle" msgid="3910479625507893809">"సమాధానం ఇవ్వని కాల్స్"</string>
+ <string name="notification_missedCallsTitle" msgid="3910479625507893809">"సమాధానం ఇవ్వని కాల్లు"</string>
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> సమాధానం ఇవ్వని కాల్లు"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"<xliff:g id="MISSED_CALL_FROM">%s</xliff:g> నుండి సమాధానం ఇవ్వని కాల్"</string>
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"కాల్ చేయి"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"సందేశం"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"కాల్ డిస్కనెక్ట్ చేయబడింది"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"అత్యవసర కాల్ చేయబడినందున <xliff:g id="CALLER">%s</xliff:g>తో కాల్ డిస్కనెక్ట్ చేయబడింది."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"అత్యవసర కాల్ చేయబడినందున మీ కాల్ డిస్కనెక్ట్ చేయబడింది."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"నేపథ్యం కాల్"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> కాల్ను నేపథ్యంలోకి పంపింది. కాల్ ద్వారా ఈ యాప్, ఆడియోను యాక్సెస్ ఇంకా ప్లే చేస్తుండవచ్చు."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> స్పందించడం ఆగిపోయింది"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"మీ కాల్, మీ పరికరంతో వచ్చిన ఫోన్ యాప్ను ఉపయోగించింది"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"క్రాష్ అయిన ఫోన్ యాప్"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"కాల్ మ్యూట్ చేయబడింది."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"స్పీకర్ ఫోన్ ప్రారంభించబడింది."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ఇప్పుడు మాట్లాడలేను. విషయం ఏమిటి?"</string>
@@ -94,11 +94,11 @@
<string name="cant_call_due_to_ongoing_call" msgid="8004235328451385493">"మీ <xliff:g id="OTHER_CALL">%1$s</xliff:g> కాల్ కొనసాగుతున్నందున కాల్ చేయడం సాధ్యపడదు."</string>
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"మీ <xliff:g id="OTHER_CALL">%1$s</xliff:g> కాల్లు కొనసాగుతున్నందున కాల్ చేయడం సాధ్యపడదు."</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"వేరొక అనువర్తనంలో కాల్ కొనసాగుతున్నందున కాల్ చేయడం సాధ్యపడదు."</string>
- <string name="notification_channel_incoming_call" msgid="5245550964701715662">"ఇన్కమింగ్ కాల్స్"</string>
- <string name="notification_channel_missed_call" msgid="7168893015283909012">"సమాధానం ఇవ్వని కాల్స్"</string>
+ <string name="notification_channel_incoming_call" msgid="5245550964701715662">"ఇన్కమింగ్ కాల్లు"</string>
+ <string name="notification_channel_missed_call" msgid="7168893015283909012">"సమాధానం ఇవ్వని కాల్లు"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"కాల్ బ్లాక్ చేయడం"</string>
- <string name="notification_channel_background_calls" msgid="7785659903711350506">"బ్యాక్గ్రౌండ్ కాల్స్"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"డిస్కనెక్ట్ చేసిన కాల్స్"</string>
+ <string name="notification_channel_background_calls" msgid="7785659903711350506">"నేపథ్యం కాల్లు"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"డిస్కనెక్ట్ చేసిన కాల్లు"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"క్రాష్ అయిన ఫోన్ యాప్స్"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"ఈ కాల్ చేయడం వలన మీ <xliff:g id="OTHER_APP">%1$s</xliff:g> కాల్ ముగుస్తుంది."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"ఈ కాల్ ఎలా చేయాలో ఎంచుకోండి"</string>
@@ -118,6 +118,6 @@
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"కాల్ బ్లాక్ చేయడం నిలిపివేయబడింది"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"అత్యవసర కాల్ చేయబడింది"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"మిమ్మల్ని సంప్రదించడానికి అత్యవసర ప్రతిస్పందనదారులను అనుమతించడానికి కాల్ బ్లాక్ చేయడం నిలిపివేయబడింది."</string>
- <string name="developer_title" msgid="9146088855661672353">"టెలికామ్ డెవలపర్ మెనూ"</string>
+ <string name="developer_title" msgid="9146088855661672353">"టెలికామ్ డెవలపర్ మెను"</string>
<string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"అత్యవసర కాల్లో వున్నప్పుడు కాల్లను స్వీకరించడానికి వీలుపడదు."</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 615abb9..1dfb513 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"ข้อความ"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"สายถูกตัด"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"สายที่โทรหา <xliff:g id="CALLER">%s</xliff:g> ถูกตัดเนื่องจากมีการโทรหาหมายเลขฉุกเฉิน"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"สายของคุณถูกตัดเพราะมีการโทรหาหมายเลขฉุกเฉิน"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"การโทรในเบื้องหลัง"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ได้ทำการโทรในเบื้องหลัง แอปนี้อาจกำลังเข้าถึงและเล่นเสียงผ่านการโทร"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> หยุดตอบสนอง"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"สายของคุณใช้แอปโทรศัพท์ที่มาพร้อมกับอุปกรณ์"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"แอปโทรศัพท์ขัดข้อง"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"ปิดเสียงการโทร"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"เปิดใช้งานลำโพงแล้ว"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ตอนนี้คุยไม่ได้ มีอะไรหรือเปล่า"</string>
@@ -62,7 +62,7 @@
<string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> จะดูข้อมูลเกี่ยวกับผู้โทรที่ไม่ได้อยู่ในรายชื่อติดต่อของคุณและจะบล็อกการโทรเหล่านี้ได้ คุณควรตั้งเฉพาะแอปที่คุณเชื่อถือเป็นแอปสกรีนสายเรียกเข้าเริ่มต้นเท่านั้น"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"ตั้งเป็นค่าเริ่มต้น"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"ยกเลิก"</string>
- <string name="blocked_numbers" msgid="8322134197039865180">"หมายเลขที่บล็อก"</string>
+ <string name="blocked_numbers" msgid="8322134197039865180">"หมายเลขที่ถูกบล็อก"</string>
<string name="blocked_numbers_msg" msgid="2797422132329662697">"คุณจะไม่สามารถรับสายหรือข้อความจากหมายเลขที่บล็อก"</string>
<string name="block_number" msgid="3784343046852802722">"เพิ่มหมายเลข"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"เลิกบล็อก <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> ใช่ไหม"</string>
@@ -94,7 +94,7 @@
<string name="cant_call_due_to_ongoing_call" msgid="8004235328451385493">"ไม่สามารถโทรออกได้เนื่องจากกำลังใช้สายอยู่ใน <xliff:g id="OTHER_CALL">%1$s</xliff:g>"</string>
<string name="cant_call_due_to_ongoing_calls" msgid="6379163795277824868">"ไม่สามารถโทรออกได้เนื่องจากกำลังใช้สายอยู่ใน <xliff:g id="OTHER_CALL">%1$s</xliff:g>"</string>
<string name="cant_call_due_to_ongoing_unknown_call" msgid="8243532328969433172">"ไม่สามารถโทรออกได้เนื่องจากกำลังใช้สายอยู่ในแอปอื่น"</string>
- <string name="notification_channel_incoming_call" msgid="5245550964701715662">"สายเรียกเข้า"</string>
+ <string name="notification_channel_incoming_call" msgid="5245550964701715662">"สายโทรเข้า"</string>
<string name="notification_channel_missed_call" msgid="7168893015283909012">"สายที่ไม่ได้รับ"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"การบล็อกสาย"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"การโทรในเบื้องหลัง"</string>
@@ -112,7 +112,7 @@
<string name="phone_settings_private_num_summary_txt" msgid="6755758240544021037">"บล็อกผู้โทรที่ไม่เปิดเผยหมายเลขโทรศัพท์"</string>
<string name="phone_settings_payphone_txt" msgid="5003987966052543965">"โทรศัพท์สาธารณะ"</string>
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"บล็อกสายจากโทรศัพท์สาธารณะ"</string>
- <string name="phone_settings_unknown_txt" msgid="3577926178354772728">"ไม่รู้จัก"</string>
+ <string name="phone_settings_unknown_txt" msgid="3577926178354772728">"ไม่ทราบ"</string>
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"บล็อกสายจากผู้โทรที่ไม่สามารถระบุได้"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"การบล็อกสาย"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"ปิดใช้การบล็อกสาย"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 998abef..06cd979 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -28,19 +28,19 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Padalhan ng mensahe"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Nadiskonektang tawag"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Nadiskonekta ang tawag kay <xliff:g id="CALLER">%s</xliff:g> dahil sa ginagawang pang-emergency na tawag."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Nadiskonekta ang iyong tawag dahil sa ginagawang pang-emergency na tawag."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Tawag sa background"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Naglagay ng tawag ang <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> sa background. Posibleng ina-access at pine-play ng app na ito ang audio sa tawag."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Huminto ang <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> sa pagtugon"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Ginamit ng tawag mo ang app na telepono na kasama sa iyong device"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Nag-crash ang phone app"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Naka-mute ang tawag."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Pinapagana ang speakerphone."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Di masagot ngayon. Ano\'ng meron?"</string>
<string name="respond_via_sms_canned_response_2" msgid="2052951316129952406">"Ako na lang ang tatawag sa \'yo."</string>
<string name="respond_via_sms_canned_response_3" msgid="6656147963478092035">"Tawagan kita mamaya."</string>
<string name="respond_via_sms_canned_response_4" msgid="9141132488345561047">"Di masagot ngayon. Tawag ka mamaya?"</string>
- <string name="respond_via_sms_setting_title" msgid="4762275482898830160">"Mga mabilis na sagot"</string>
- <string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"I-edit ang mabilis na sagot"</string>
+ <string name="respond_via_sms_setting_title" msgid="4762275482898830160">"Mga mabilisang tugon"</string>
+ <string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"I-edit ang mga quick response"</string>
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Mabilisang tugon"</string>
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Naipadala ang mensahe sa <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 2e02f8c..8f93ff1 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Mesaj gönder"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Aramanın bağlantısı kesildi"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Bir acil durum araması yapıldığı için <xliff:g id="CALLER">%s</xliff:g> ile olan görüşmenin bağlantısı kesildi."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Bir acil durum araması yapıldığı için görüşmenizin bağlantısı kesildi."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Arka plandaki arama"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> arka plana bir arama yerleştirdi. Bu uygulama arama üzerinden sese erişiyor ve ses çalıyor olabilir."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> yanıt vermeyi durdurdu"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Görüşmeniz için, cihazınızla gelen telefon uygulaması kullanıldı"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Kilitlenen telefon uygulaması"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Çağrı sesi kapatıldı."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Hoparlör etkin."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Şimdi konuşamam. Konu nedir?"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index d86b3eb..95b21f0 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Повідомлення"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Виклик припинено"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Виклик абонента <xliff:g id="CALLER">%s</xliff:g> припинено, оскільки здійснюється екстрений виклик."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Виклик перервано, оскільки здійснюється екстрений виклик."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"У фоновий режим"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"Додаток <xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> перевів виклик у фоновий режим і може відтворювати аудіо під час виклику."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"Додаток <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> не відповідає"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Поточний дзвінок було перенаправлено в додаток, що постачається разом із пристроєм"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Збій у додатку для дзвінків"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Додаток для дзвінків <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> аварійно завершив роботу. Поточний дзвінок було перенаправлено в додаток, що постачається разом із пристроєм."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Звук виклику вимкнено."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Гучний зв’язок увімкнено."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Не можу говорити. У чому справа?"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 20cca1b..b0c622e 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"پیغام"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"کال غیر منسلک کر دیا گیا"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"ہنگامی کال کی وجہ سے <xliff:g id="CALLER">%s</xliff:g> کی کال کو غیر منسلک کر دیا گیا ہے۔"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"ہنگامی کال لگائے جانے کی وجہ سے آپ کی کال غیر منسلک ہوگئی ہے۔"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"پس منظر کی کال"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> نے پس منظر میں کال لگا دیا ہے۔ یہ ایپ کال کے دوران آواز تک رسائی حاصل اور چلا سکتی ہے۔"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> نے جواب دینا بند کر دیا"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"آپ کی کال نے آپ کے آلہ کے ساتھ آئی ہوئی فون ایپ کا استعمال کیا"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"کریشڈ فون ایپ"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"کال خاموش کر دی گئی۔"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"اسپیکر فون فعال ہوگیا۔"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"ابھی بات نہیں کرسکتے۔ کیا ہو رہا ہے؟"</string>
@@ -98,13 +98,13 @@
<string name="notification_channel_missed_call" msgid="7168893015283909012">"چھوٹی ہوئی کالیں"</string>
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"کال مسدود کرنا"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"پس منظر کی کالز"</string>
- <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"منقطع کالز"</string>
+ <string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"کالز غیر منسلک کر دیے گئے"</string>
<string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"کریشڈ فون ایپس"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"یہ کال کرنے سے <xliff:g id="OTHER_APP">%1$s</xliff:g> کال ختم ہو جائے گی۔"</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"یہ کال کرنے کا طریقہ منتخب کریں"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> کے ذریعے کال کو ریڈائریکٹ کریں"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"میرا فون نمبر استعمال کر کے کال کريں"</string>
- <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> کے ذریعے کال نہیں کی جا سکتی۔ کال آگے بڑھانے والی کوئی دوسری ایپ آزما کر یا مدد کے لیے ڈویلپر سے رابطہ کر کے دیکھیں۔"</string>
+ <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> کے ذریعے کال نہیں کی جا سکتی۔ کال آگے بڑھانے والی کوئی دوسری ایپ آزما کر یا مدد کے لیے ڈیولپر سے رابطہ کر کے دیکھیں۔"</string>
<string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"کال مسدود کرنا"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"وہ نمبرز جو رابطوں میں نہیں ہیں"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"ان نمبرز کو مسدود کریں جو آپ کے رابطوں میں مندرج نہیں ہیں"</string>
@@ -118,6 +118,6 @@
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"کال مسدود کرنا غیر فعال ہو گیا ہے"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"ہنگامی کال کی گئی"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"ہنگامی حالت میں جواب دہندگان کو آپ سے رابطہ کرنے کی اجازت دینے کیلئے کال مسدود کرنا غیر فعال ہو گیا ہے۔"</string>
- <string name="developer_title" msgid="9146088855661672353">"ٹیلی کام ڈویلپر مینو"</string>
+ <string name="developer_title" msgid="9146088855661672353">"ٹیلی کام ڈیولپر مینو"</string>
<string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"ہنگامی کال کے دوران کالز نہیں لی جائیں گی۔"</string>
</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 3271245..253734b 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Chaqiruvlar boshqaruvi"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Qo‘ng‘iroqlar boshqaruvi"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Noma’lum"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Javobsiz chaqiruv"</string>
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"SMS"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Chaqiruv tugatildi"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Favqulodda chaqiruv amalga oshirilayotgani uchun <xliff:g id="CALLER">%s</xliff:g> bilan suhbatingiz tugatildi."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Favqulodda chaqiruv amalga oshirilayotgani uchun joriy chaqiruvingiz to‘xtatildi."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Orqa fondagi chaqiruv"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ilovasi chaqiruvni orqa fonga joyladi. Bu ilova ovozli chaqiruvga kirishi yoki unda audio ijro etishi mumkin."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> javob bermayapti"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Chaqiruv qurilmangizga avvaldan o‘rnatilgan ilova orqali amalga oshirildi"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Telefon ilovasi ishi xatolik tufayli to‘xtatildi"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Qo‘ng‘iroq ovozi o‘chirildi."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Karnaychalar yoqildi."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Hozir gaplasholmayman. Tinchlikmi?"</string>
@@ -99,7 +99,7 @@
<string name="notification_channel_call_blocking" msgid="2028807677868598710">"Chaqiruvlarni bloklash"</string>
<string name="notification_channel_background_calls" msgid="7785659903711350506">"Orqa fondagi chaqiruvlar"</string>
<string name="notification_channel_disconnected_calls" msgid="8228636543997645757">"Tugatilgan chaqiruvlar"</string>
- <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Ishdan chiqqan telefon ilovalari"</string>
+ <string name="notification_channel_in_call_service_crash" msgid="7313237519166984267">"Xatolik tufayli ishi to‘xtatilgan telefon ilovalari"</string>
<string name="alert_outgoing_call" msgid="5319895109298927431">"Bu qo‘ng‘iroqni amalga oshirsangiz, <xliff:g id="OTHER_APP">%1$s</xliff:g> qo‘ng‘irog‘i tugatiladi."</string>
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"Telefon qilish usulini tanlang"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"Chaqiruv <xliff:g id="OTHER_APP">%1$s</xliff:g> orqali qayta uzatilsin"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index c6fe44a..79b16bf 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Tin nhắn"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Cuộc gọi bị ngắt kết nối"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Cuộc gọi đến <xliff:g id="CALLER">%s</xliff:g> đã bị ngắt kết nối do một cuộc gọi khẩn cấp được thực hiện."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Cuộc gọi của bạn đã bị ngắt kết nối do một cuộc gọi khẩn cấp đang được thực hiện."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Cuộc gọi trong nền"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> đã gọi điện ở chế độ nền. Ứng dụng này có thể đang truy cập và phát âm thanh qua cuộc gọi."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> đã dừng phản hồi"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Cuộc gọi của bạn đã dùng ứng dụng dành cho điện thoại đi kèm với thiết bị"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Ứng dụng điện thoại bị lỗi"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"Ứng dụng điện thoại <xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> của bạn bị lỗi. Cuộc gọi của bạn đã được tiếp tục trên ứng dụng điện thoại đi kèm với thiết bị."</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"Đã tắt tiếng cuộc gọi."</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Đã bật loa ngoài."</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Giờ tôi không nói chuyện được. Có việc gì không?"</string>
@@ -81,13 +80,13 @@
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> đã bị chặn."</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"Sử dụng trình quay số cá nhân để gọi điện"</string>
<string name="notification_incoming_call" msgid="1233481138362230894">"Cuộc gọi <xliff:g id="CALL_VIA">%1$s</xliff:g> từ <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
- <string name="notification_incoming_video_call" msgid="5795968314037063900">"Cuộc gọi video <xliff:g id="CALL_VIA">%1$s</xliff:g> từ <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
+ <string name="notification_incoming_video_call" msgid="5795968314037063900">"Cuộc gọi điện video <xliff:g id="CALL_VIA">%1$s</xliff:g> từ <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
<string name="answering_ends_other_call" msgid="8653544281903986641">"Trả lời sẽ kết thúc cuộc gọi <xliff:g id="CALL_VIA">%1$s</xliff:g> của bạn"</string>
<string name="answering_ends_other_calls" msgid="3702302838456922535">"Trả lời sẽ kết thúc cuộc gọi <xliff:g id="CALL_VIA">%1$s</xliff:g> của bạn"</string>
- <string name="answering_ends_other_video_call" msgid="8572022039304239958">"Trả lời sẽ kết thúc cuộc gọi video <xliff:g id="CALL_VIA">%1$s</xliff:g> của bạn"</string>
+ <string name="answering_ends_other_video_call" msgid="8572022039304239958">"Trả lời sẽ kết thúc cuộc gọi điện video <xliff:g id="CALL_VIA">%1$s</xliff:g> của bạn"</string>
<string name="answering_ends_other_managed_call" msgid="4031778317409881805">"Trả lời sẽ kết thúc cuộc gọi đang diễn ra của bạn"</string>
<string name="answering_ends_other_managed_calls" msgid="3974069768615307659">"Trả lời sẽ kết thúc cuộc gọi đang diễn ra của bạn"</string>
- <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"Trả lời sẽ kết thúc cuộc gọi video đang diễn ra của bạn"</string>
+ <string name="answering_ends_other_managed_video_call" msgid="1988508241432031327">"Trả lời sẽ kết thúc cuộc gọi điện video đang diễn ra của bạn"</string>
<string name="answer_incoming_call" msgid="2045888814782215326">"Trả lời"</string>
<string name="decline_incoming_call" msgid="922147089348451310">"Từ chối"</string>
<string name="cant_call_due_to_no_supported_service" msgid="1635626384149947077">"Không thể thực hiện cuộc gọi do không có tài khoản hỗ trợ loại cuộc gọi này."</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index bbda818..e3c7f31 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"发短信"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"已中断的通话"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"由于要进行紧急呼叫,与 <xliff:g id="CALLER">%s</xliff:g> 的通话已中断。"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"由于要进行紧急呼叫,您的通话已中断。"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"后台通话"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> 已将通话切换到后台进行。此应用可以接入通话,并播放通话音频。"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>已停止响应"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"系统使用您设备自带的电话应用拨打了电话"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"崩溃的手机应用"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"通话已静音。"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"扬声器已启用。"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"现在无法接听。有什么事吗?"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 0f26c9d..c191fe0 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"短訊"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"已中斷的通話"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"因撥打緊急電話緣故,與<xliff:g id="CALLER">%s</xliff:g>的通話已中斷。"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"因撥打緊急電話緣故,您的通話已中斷。"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"背景通話"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"「<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>」已將通話放到背景。這個應用程式可以存取該通話,並透過該通話播放音訊。"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>已停止回應"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"您使用了裝置隨付的手機應用程式來通話"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"當機的手機應用程式"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"您的手機應用程式「<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>」已當機。您使用了裝置隨付的手機應用程式來繼續通話。"</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"通話已靜音。"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"擴音器已啟用"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"我現在不方便通話,有什麼事呢?"</string>
@@ -57,9 +56,9 @@
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"設為預設"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"取消"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"「<xliff:g id="NEW_APP">%s</xliff:g>」將可撥打電話並控制所有相關功能。只有您信任的應用程式,才應設為預設手機應用程式。"</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"要將「<xliff:g id="NEW_APP">%s</xliff:g>」設為預設來電過濾應用程式嗎?"</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"要將「<xliff:g id="NEW_APP">%s</xliff:g>」設為預設來電篩選應用程式嗎?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"「<xliff:g id="OLD_APP">%s</xliff:g>」無法再篩選來電。"</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"「<xliff:g id="NEW_APP">%s</xliff:g>」將可查看通訊錄以外來電者的相關資訊,並封鎖這些來電。只有您信任的應用程式才適合設為預設來電過濾應用程式。"</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"「<xliff:g id="NEW_APP">%s</xliff:g>」將可查看通訊錄以外來電者的相關資訊,並封鎖這些來電。只有您信任的應用程式才適合設為預設來電篩選應用程式。"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"設為預設"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"取消"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"已封鎖的號碼"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 7c98928..312386a 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -28,11 +28,10 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"簡訊"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"通話中斷"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"由於你正在撥打緊急電話,因此你與<xliff:g id="CALLER">%s</xliff:g>的通話已中斷。"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"你撥出了緊急電話,因此目前的通話已中斷。"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"背景通話"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"「<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g>」已將通話切換到在背景進行。這個應用程式可能會在通話期間存取及播放音訊。"</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"「<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>」已停止回應"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"目前是透過裝置內建的電話應用程式進行通話"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"通話應用程式異常終止"</string>
+ <string name="notification_crashedInCallService_body" msgid="7821729360036047995">"你的通話應用程式「<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g>」已異常終止。系統目前已使用裝置內建的通話應用程式繼續進行通話。"</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"通話已靜音。"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"喇叭已啟用"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"我現在不方便講話,有什麼事?"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 30c147d..674af06 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -28,11 +28,11 @@
<string name="notification_missedCall_message" msgid="4054698824390076431">"Umlayezo"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Ikholi enqanyuliwe"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Ikholi eya ku-<xliff:g id="CALLER">%s</xliff:g> inqanyuliwe ngenxa yekholi yesimo esiphuthumayo efakwayo."</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Ikholi yakho inqanyuliwe ngenxa yekholi yesimo esiphuthumayo eyenziwe."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"Ikholi engemuva"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> yenze ikholi ngemuva. Kungenzeka ukuthi lolu hlelo lokusebenza lufinyelela futhi ludlala okulalelwayo ngaphezu kwekholi."</string>
- <string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> iyeke ukuphendula"</string>
- <string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"Ikholi yakho isebenzise uhlelo lokusebenza lefoni elize nedivayisi yakho"</string>
+ <string name="notification_crashedInCallService_title" msgid="7440244344965656743">"Uhlelo lokusebenza lwefoni olukhubazekile"</string>
+ <!-- no translation found for notification_crashedInCallService_body (7821729360036047995) -->
+ <skip />
<string name="accessibility_call_muted" msgid="2968461092554300779">"Ikholu ithulisiwe"</string>
<string name="accessibility_speakerphone_enabled" msgid="555386652061614267">"Isipikha sefoni sinikwe amandla"</string>
<string name="respond_via_sms_canned_response_1" msgid="6332561460870382561">"Angikwazi ukukhuluma okwamanje. Kwenzenjani?"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 9cbbf46..b0e50b0 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -69,4 +69,8 @@
<!-- When true, the options in the call blocking settings to block restricted and unknown
callers are combined into a single toggle. -->
<bool name="combine_options_to_block_restricted_and_unknown_callers">true</bool>
+
+ <!-- When set, Telecom will attempt to bind to the {@link CallDiagnosticService} implementation
+ defined by the app with this package name. -->
+ <string name="call_diagnostic_service_package_name"></string>
</resources>
diff --git a/res/xml/activity_blocked_numbers.xml b/res/xml/activity_blocked_numbers.xml
index f884ec9..df1a759 100644
--- a/res/xml/activity_blocked_numbers.xml
+++ b/res/xml/activity_blocked_numbers.xml
@@ -75,7 +75,7 @@
<TextView
android:id="@+id/add_blocked"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="48dp"
android:text="@string/block_number"
android:layout_marginBottom="@dimen/blocked_numbers_button_bottom_margin"
android:paddingTop="@dimen/blocked_numbers_button_large_padding"
diff --git a/res/xml/enhanced_call_blocking_settings.xml b/res/xml/enhanced_call_blocking_settings.xml
index 32c4c5d..73ed2af 100644
--- a/res/xml/enhanced_call_blocking_settings.xml
+++ b/res/xml/enhanced_call_blocking_settings.xml
@@ -41,8 +41,4 @@
android:persistent="false"
android:defaultValue="false"/>
<!--Add divider to separate this enhanced call blocking settings from other settings-->
- <Preference
- android:key="enhanced_call_blocking_divider"
- android:persistent="false"
- android:layout="@xml/layout_divider"/>
</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/layout_blocked_number.xml b/res/xml/layout_blocked_number.xml
index 3cdd771..9dbfc2f 100644
--- a/res/xml/layout_blocked_number.xml
+++ b/res/xml/layout_blocked_number.xml
@@ -28,9 +28,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
+ android:layout_toStartOf="@+id/delete_blocked_number"
android:paddingTop="@dimen/blocked_numbers_delete_icon_padding"
- android:layout_alignParentLeft="true"
- android:layout_toLeftOf="@+id/delete_blocked_number"
android:textDirection="ltr" />
<ImageView
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index 9c227a6..d6780ed 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -208,6 +208,9 @@
public void setCallSource(int callSource) {
}
+
+ public void setMissedReason(long missedReason) {
+ }
}
/**
@@ -242,6 +245,7 @@
public List<TelecomLogClass.InCallServiceInfo> inCallServiceInfos;
public int callProperties = 0;
public int callSource = CALL_SOURCE_UNSPECIFIED;
+ public long missedReason;
private long mTimeOfLastVideoEvent = -1;
@@ -254,6 +258,7 @@
connectionService = "";
videoEvents = new LinkedList<>();
inCallServiceInfos = new LinkedList<>();
+ missedReason = 0;
}
CallInfoImpl(CallInfoImpl other) {
@@ -272,6 +277,7 @@
this.videoEvents = other.videoEvents;
this.callProperties = other.callProperties;
this.callSource = other.callSource;
+ this.missedReason = other.missedReason;
if (other.callTerminationReason != null) {
this.callTerminationReason = new DisconnectCause(
@@ -342,6 +348,13 @@
}
@Override
+ public void setMissedReason(long missedReason) {
+ Log.d(TAG, "setting missedReason for call " + callId + ": "
+ + missedReason);
+ this.missedReason = missedReason;
+ }
+
+ @Override
public void setCallEvents(EventManager.EventRecord records) {
this.callEvents = records;
}
@@ -399,6 +412,7 @@
+ " isEmergency: " + isEmergency + '\n'
+ " callTechnologies: " + getCallTechnologiesAsString() + '\n'
+ " callTerminationReason: " + getCallDisconnectReasonString() + '\n'
+ + " missedReason: " + getMissedReasonString() + '\n'
+ " connectionService: " + connectionService + '\n'
+ " isVideoCall: " + isVideo + '\n'
+ " inCallServices: " + getInCallServicesString() + '\n'
@@ -526,20 +540,27 @@
}
}
+ private String getMissedReasonString() {
+ //TODO: Implement this
+ return null;
+ }
+
private String getInCallServicesString() {
StringBuilder s = new StringBuilder();
s.append("[\n");
- for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) {
- s.append(" ");
- s.append("name: ");
- s.append(service.getInCallServiceName());
- s.append(" type: ");
- s.append(service.getInCallServiceType());
- s.append(" is crashed: ");
- s.append(service.getIsNullBinding());
- s.append(" service last time in ms: ");
- s.append(service.getBoundDurationMillis());
- s.append("\n");
+ if (inCallServiceInfos != null) {
+ for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) {
+ s.append(" ");
+ s.append("name: ");
+ s.append(service.getInCallServiceName());
+ s.append(" type: ");
+ s.append(service.getInCallServiceType());
+ s.append(" is crashed: ");
+ s.append(service.getIsNullBinding());
+ s.append(" service last time in ms: ");
+ s.append(service.getBoundDurationMillis());
+ s.append("\n");
+ }
}
s.append("]");
return s.toString();
@@ -612,7 +633,7 @@
}
public static CallInfo initiateCallAnalytics(String callId, int direction) {
- Log.d(TAG, "Starting analytics for call " + callId);
+ Log.i(TAG, "Starting analytics for call " + callId);
CallInfoImpl callInfo = new CallInfoImpl(callId, direction);
synchronized (sLock) {
while (sActiveCallIds.size() >= MAX_NUM_CALLS_TO_STORE) {
diff --git a/src/com/android/server/telecom/BluetoothHeadsetProxy.java b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
index a43b3cd..e4eed87 100644
--- a/src/com/android/server/telecom/BluetoothHeadsetProxy.java
+++ b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
@@ -36,19 +36,6 @@
mBluetoothHeadset = headset;
}
- public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
- String number, int type) {
-
- mBluetoothHeadset.clccResponse(index, direction, status, mode, mpty, number, type);
- }
-
- public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
- int type, String name) {
-
- mBluetoothHeadset.phoneStateChanged(numActive, numHeld, callState, number, type,
- name);
- }
-
public List<BluetoothDevice> getConnectedDevices() {
return mBluetoothHeadset.getConnectedDevices();
}
diff --git a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
deleted file mode 100644
index f2ea950..0000000
--- a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothHeadsetPhone;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.telecom.Connection;
-import android.telecom.Log;
-import android.telecom.PhoneAccount;
-import android.telecom.VideoProfile;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.telecom.CallsManager.CallsManagerListener;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Bluetooth headset manager for Telecom. This class shares the call state with the bluetooth device
- * and accepts call-related commands to perform on behalf of the BT device.
- */
-public class BluetoothPhoneServiceImpl {
-
- public interface BluetoothPhoneServiceImplFactory {
- BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(Context context,
- TelecomSystem.SyncRoot lock, CallsManager callsManager,
- PhoneAccountRegistrar phoneAccountRegistrar);
- }
-
- private static final String TAG = "BluetoothPhoneService";
-
- // match up with bthf_call_state_t of bt_hf.h
- private static final int CALL_STATE_ACTIVE = 0;
- private static final int CALL_STATE_HELD = 1;
- private static final int CALL_STATE_DIALING = 2;
- private static final int CALL_STATE_ALERTING = 3;
- private static final int CALL_STATE_INCOMING = 4;
- private static final int CALL_STATE_WAITING = 5;
- private static final int CALL_STATE_IDLE = 6;
- private static final int CALL_STATE_DISCONNECTED = 7;
-
- // match up with bthf_call_state_t of bt_hf.h
- // Terminate all held or set UDUB("busy") to a waiting call
- private static final int CHLD_TYPE_RELEASEHELD = 0;
- // Terminate all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
- // Hold all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
- // Add all held calls to a conference
- private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
-
- // Indicates that no call is ringing
- private static final int DEFAULT_RINGING_ADDRESS_TYPE = 128;
-
- private int mNumActiveCalls = 0;
- private int mNumHeldCalls = 0;
- private int mNumChildrenOfActiveCall = 0;
- private int mBluetoothCallState = CALL_STATE_IDLE;
- private String mRingingAddress = "";
- private int mRingingAddressType = DEFAULT_RINGING_ADDRESS_TYPE;
- private Call mOldHeldCall = null;
- private boolean mIsDisconnectedTonePlaying = false;
-
- /**
- * Binder implementation of IBluetoothHeadsetPhone. Implements the command interface that the
- * bluetooth headset code uses to control call.
- */
- @VisibleForTesting
- public final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
- @Override
- public boolean answerCall() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.aC");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "BT - answering call");
- Call call = mCallsManager.getRingingOrSimulatedRingingCall();
- if (call != null) {
- mCallsManager.answerCall(call, VideoProfile.STATE_AUDIO_ONLY);
- return true;
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
-
- }
- }
-
- @Override
- public boolean hangupCall() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.hC");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "BT - hanging up call");
- Call call = mCallsManager.getForegroundCall();
- if (call != null) {
- mCallsManager.disconnectCall(call);
- return true;
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean sendDtmf(int dtmf) throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.sD");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "BT - sendDtmf %c", Log.DEBUG ? dtmf : '.');
- Call call = mCallsManager.getForegroundCall();
- if (call != null) {
- // TODO: Consider making this a queue instead of starting/stopping
- // in quick succession.
- mCallsManager.playDtmfTone(call, (char) dtmf);
- mCallsManager.stopDtmfTone(call);
- return true;
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public String getNetworkOperator() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.gNO");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "getNetworkOperator");
- PhoneAccount account = getBestPhoneAccount();
- if (account != null && account.getLabel() != null) {
- return account.getLabel().toString();
- } else {
- // Finally, just get the network name from telephony.
- return mContext.getSystemService(TelephonyManager.class)
- .getNetworkOperatorName();
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public String getSubscriberNumber() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.gSN");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "getSubscriberNumber");
- String address = null;
- PhoneAccount account = getBestPhoneAccount();
- if (account != null) {
- Uri addressUri = account.getAddress();
- if (addressUri != null) {
- address = addressUri.getSchemeSpecificPart();
- }
- }
- if (TextUtils.isEmpty(address)) {
- address = mContext.getSystemService(TelephonyManager.class)
- .getLine1Number();
- if (address == null) address = "";
- }
- return address;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean listCurrentCalls() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.lCC");
- long token = Binder.clearCallingIdentity();
- try {
- // only log if it is after we recently updated the headset state or else it can
- // clog the android log since this can be queried every second.
- boolean logQuery = mHeadsetUpdatedRecently;
- mHeadsetUpdatedRecently = false;
-
- if (logQuery) {
- Log.i(TAG, "listcurrentCalls");
- }
-
- sendListOfCalls(logQuery);
- return true;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean queryPhoneState() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.qPS");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "queryPhoneState");
- updateHeadsetWithCallState(true /* force */);
- return true;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean processChld(int chld) throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.pC");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "processChld %d", chld);
- return BluetoothPhoneServiceImpl.this.processChld(chld);
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public void updateBtHandsfreeAfterRadioTechnologyChange() throws RemoteException {
- Log.d(TAG, "RAT change - deprecated");
- // deprecated
- }
-
- @Override
- public void cdmaSetSecondCallState(boolean state) throws RemoteException {
- Log.d(TAG, "cdma 1 - deprecated");
- // deprecated
- }
-
- @Override
- public void cdmaSwapSecondCallState() throws RemoteException {
- Log.d(TAG, "cdma 2 - deprecated");
- // deprecated
- }
- };
-
- /**
- * Listens to call changes from the CallsManager and calls into methods to update the bluetooth
- * headset with the new states.
- */
- @VisibleForTesting
- public CallsManagerListener mCallsManagerListener = new CallsManagerListenerBase() {
- @Override
- public void onCallAdded(Call call) {
- if (call.isExternalCall()) {
- return;
- }
- updateHeadsetWithCallState(false /* force */);
- }
-
- @Override
- public void onCallRemoved(Call call) {
- if (call.isExternalCall()) {
- return;
- }
- mClccIndexMap.remove(call);
- updateHeadsetWithCallState(false /* force */);
- }
-
- /**
- * Where a call which was external becomes a regular call, or a regular call becomes
- * external, treat as an add or remove, respectively.
- *
- * @param call The call.
- * @param isExternalCall {@code True} if the call became external, {@code false} otherwise.
- */
- @Override
- public void onExternalCallChanged(Call call, boolean isExternalCall) {
- if (isExternalCall) {
- onCallRemoved(call);
- } else {
- onCallAdded(call);
- }
- }
-
- @Override
- public void onCallStateChanged(Call call, int oldState, int newState) {
- if (call.isExternalCall()) {
- return;
- }
- // If a call is being put on hold because of a new connecting call, ignore the
- // CONNECTING since the BT state update needs to send out the numHeld = 1 + dialing
- // state atomically.
- // When the call later transitions to DIALING/DISCONNECTED we will then send out the
- // aggregated update.
- if (oldState == CallState.ACTIVE && newState == CallState.ON_HOLD) {
- for (Call otherCall : mCallsManager.getCalls()) {
- if (otherCall.getState() == CallState.CONNECTING) {
- return;
- }
- }
- }
-
- // To have an active call and another dialing at the same time is an invalid BT
- // state. We can assume that the active call will be automatically held which will
- // send another update at which point we will be in the right state.
- if (mCallsManager.getActiveCall() != null
- && oldState == CallState.CONNECTING &&
- (newState == CallState.DIALING || newState == CallState.PULLING)) {
- return;
- }
- updateHeadsetWithCallState(false /* force */);
- }
-
- @Override
- public void onIsConferencedChanged(Call call) {
- if (call.isExternalCall()) {
- return;
- }
- /*
- * Filter certain onIsConferencedChanged callbacks. Unfortunately this needs to be done
- * because conference change events are not atomic and multiple callbacks get fired
- * when two calls are conferenced together. This confuses updateHeadsetWithCallState
- * if it runs in the middle of two calls being conferenced and can cause spurious and
- * incorrect headset state updates. One of the scenarios is described below for CDMA
- * conference calls.
- *
- * 1) Call 1 and Call 2 are being merged into conference Call 3.
- * 2) Call 1 has its parent set to Call 3, but Call 2 does not have a parent yet.
- * 3) updateHeadsetWithCallState now thinks that there are two active calls (Call 2 and
- * Call 3) when there is actually only one active call (Call 3).
- */
- if (call.getParentCall() != null) {
- // If this call is newly conferenced, ignore the callback. We only care about the
- // one sent for the parent conference call.
- Log.d(this, "Ignoring onIsConferenceChanged from child call with new parent");
- return;
- }
- if (call.getChildCalls().size() == 1) {
- // If this is a parent call with only one child, ignore the callback as well since
- // the minimum number of child calls to start a conference call is 2. We expect
- // this to be called again when the parent call has another child call added.
- Log.d(this, "Ignoring onIsConferenceChanged from parent with only one child call");
- return;
- }
- updateHeadsetWithCallState(false /* force */);
- }
-
- @Override
- public void onDisconnectedTonePlaying(boolean isTonePlaying) {
- mIsDisconnectedTonePlaying = isTonePlaying;
- updateHeadsetWithCallState(false /* force */);
- }
- };
-
- /**
- * Listens to connections and disconnections of bluetooth headsets. We need to save the current
- * bluetooth headset so that we know where to send call updates.
- */
- @VisibleForTesting
- public BluetoothProfile.ServiceListener mProfileListener =
- new BluetoothProfile.ServiceListener() {
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- synchronized (mLock) {
- setBluetoothHeadset(new BluetoothHeadsetProxy((BluetoothHeadset) proxy));
- updateHeadsetWithCallState(true /* force */);
- }
- }
-
- @Override
- public void onServiceDisconnected(int profile) {
- synchronized (mLock) {
- mBluetoothHeadset = null;
- }
- }
- };
-
- /**
- * Receives events for global state changes of the bluetooth adapter.
- */
- @VisibleForTesting
- public final BroadcastReceiver mBluetoothAdapterReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (mLock) {
- int state = intent
- .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- Log.d(TAG, "Bluetooth Adapter state: %d", state);
- if (state == BluetoothAdapter.STATE_ON) {
- try {
- mBinder.queryPhoneState();
- } catch (RemoteException e) {
- // Remote exception not expected
- }
- }
- }
- }
- };
-
- private BluetoothAdapterProxy mBluetoothAdapter;
- private BluetoothHeadsetProxy mBluetoothHeadset;
-
- // A map from Calls to indexes used to identify calls for CLCC (C* List Current Calls).
- private Map<Call, Integer> mClccIndexMap = new HashMap<>();
-
- private boolean mHeadsetUpdatedRecently = false;
-
- private final Context mContext;
- private final TelecomSystem.SyncRoot mLock;
- private final CallsManager mCallsManager;
- private final PhoneAccountRegistrar mPhoneAccountRegistrar;
-
- public IBinder getBinder() {
- return mBinder;
- }
-
- public BluetoothPhoneServiceImpl(
- Context context,
- TelecomSystem.SyncRoot lock,
- CallsManager callsManager,
- BluetoothAdapterProxy bluetoothAdapter,
- PhoneAccountRegistrar phoneAccountRegistrar) {
- Log.d(this, "onCreate");
-
- mContext = context;
- mLock = lock;
- mCallsManager = callsManager;
- mPhoneAccountRegistrar = phoneAccountRegistrar;
-
- mBluetoothAdapter = bluetoothAdapter;
- if (mBluetoothAdapter == null) {
- Log.d(this, "BluetoothPhoneService shutting down, no BT Adapter found.");
- return;
- }
- mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
-
- IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
- context.registerReceiver(mBluetoothAdapterReceiver, intentFilter);
-
- mCallsManager.addListener(mCallsManagerListener);
- updateHeadsetWithCallState(false /* force */);
- }
-
- @VisibleForTesting
- public void setBluetoothHeadset(BluetoothHeadsetProxy bluetoothHeadset) {
- mBluetoothHeadset = bluetoothHeadset;
- }
-
- private boolean processChld(int chld) {
- Call activeCall = mCallsManager.getActiveCall();
- Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
- Call heldCall = mCallsManager.getHeldCall();
-
- // TODO: Keeping as Log.i for now. Move to Log.d after L release if BT proves stable.
- Log.i(TAG, "Active: %s\nRinging: %s\nHeld: %s", activeCall, ringingCall, heldCall);
-
- if (chld == CHLD_TYPE_RELEASEHELD) {
- if (ringingCall != null) {
- mCallsManager.rejectCall(ringingCall, false, null);
- return true;
- } else if (heldCall != null) {
- mCallsManager.disconnectCall(heldCall);
- return true;
- }
- } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
- if (activeCall == null && ringingCall == null && heldCall == null)
- return false;
- if (activeCall != null) {
- mCallsManager.disconnectCall(activeCall);
- if (ringingCall != null) {
- mCallsManager.answerCall(ringingCall, VideoProfile.STATE_AUDIO_ONLY);
- }
- return true;
- }
- if (ringingCall != null) {
- mCallsManager.answerCall(ringingCall, ringingCall.getVideoState());
- } else if (heldCall != null) {
- mCallsManager.unholdCall(heldCall);
- }
- return true;
- } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
- if (activeCall != null && activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
- activeCall.swapConference();
- Log.i(TAG, "CDMA calls in conference swapped, updating headset");
- updateHeadsetWithCallState(true /* force */);
- return true;
- } else if (ringingCall != null) {
- mCallsManager.answerCall(ringingCall, VideoProfile.STATE_AUDIO_ONLY);
- return true;
- } else if (heldCall != null) {
- // CallsManager will hold any active calls when unhold() is called on a
- // currently-held call.
- mCallsManager.unholdCall(heldCall);
- return true;
- } else if (activeCall != null && activeCall.can(Connection.CAPABILITY_HOLD)) {
- mCallsManager.holdCall(activeCall);
- return true;
- }
- } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
- if (activeCall != null) {
- if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
- activeCall.mergeConference();
- return true;
- } else {
- List<Call> conferenceable = activeCall.getConferenceableCalls();
- if (!conferenceable.isEmpty()) {
- mCallsManager.conference(activeCall, conferenceable.get(0));
- return true;
- }
- }
- }
- }
- return false;
- }
-
- private void enforceModifyPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MODIFY_PHONE_STATE, null);
- }
-
- private void sendListOfCalls(boolean shouldLog) {
- Collection<Call> mCalls = mCallsManager.getCalls();
- for (Call call : mCalls) {
- // We don't send the parent conference call to the bluetooth device.
- // We do, however want to send conferences that have no children to the bluetooth
- // device (e.g. IMS Conference).
- if (!call.isConference() ||
- (call.isConference() && call
- .can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN))) {
- sendClccForCall(call, shouldLog);
- }
- }
- sendClccEndMarker();
- }
-
- /**
- * Sends a single clcc (C* List Current Calls) event for the specified call.
- */
- private void sendClccForCall(Call call, boolean shouldLog) {
- boolean isForeground = mCallsManager.getForegroundCall() == call;
- int state = getBtCallState(call, isForeground);
- boolean isPartOfConference = false;
- boolean isConferenceWithNoChildren = call.isConference() && call
- .can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
-
- if (state == CALL_STATE_IDLE) {
- return;
- }
-
- Call conferenceCall = call.getParentCall();
- if (conferenceCall != null) {
- isPartOfConference = true;
-
- // Run some alternative states for Conference-level merge/swap support.
- // Basically, if call supports swapping or merging at the conference-level, then we need
- // to expose the calls as having distinct states (ACTIVE vs CAPABILITY_HOLD) or the
- // functionality won't show up on the bluetooth device.
-
- // Before doing any special logic, ensure that we are dealing with an ACTIVE call and
- // that the conference itself has a notion of the current "active" child call.
- Call activeChild = conferenceCall.getConferenceLevelActiveCall();
- if (state == CALL_STATE_ACTIVE && activeChild != null) {
- // Reevaluate state if we can MERGE or if we can SWAP without previously having
- // MERGED.
- boolean shouldReevaluateState =
- conferenceCall.can(Connection.CAPABILITY_MERGE_CONFERENCE) ||
- (conferenceCall.can(Connection.CAPABILITY_SWAP_CONFERENCE) &&
- !conferenceCall.wasConferencePreviouslyMerged());
-
- if (shouldReevaluateState) {
- isPartOfConference = false;
- if (call == activeChild) {
- state = CALL_STATE_ACTIVE;
- } else {
- // At this point we know there is an "active" child and we know that it is
- // not this call, so set it to HELD instead.
- state = CALL_STATE_HELD;
- }
- }
- }
- if (conferenceCall.getState() == CallState.ON_HOLD &&
- conferenceCall.can(Connection.CAPABILITY_MANAGE_CONFERENCE)) {
- // If the parent IMS CEP conference call is on hold, we should mark this call as
- // being on hold regardless of what the other children are doing.
- state = CALL_STATE_HELD;
- }
- } else if (isConferenceWithNoChildren) {
- // Handle the special case of an IMS conference call without conference event package
- // support. The call will be marked as a conference, but the conference will not have
- // child calls where conference event packages are not used by the carrier.
- isPartOfConference = true;
- }
-
- int index = getIndexForCall(call);
- int direction = call.isIncoming() ? 1 : 0;
- final Uri addressUri;
- if (call.getGatewayInfo() != null) {
- addressUri = call.getGatewayInfo().getOriginalAddress();
- } else {
- addressUri = call.getHandle();
- }
-
- String address = addressUri == null ? null : addressUri.getSchemeSpecificPart();
- if (address != null) {
- address = PhoneNumberUtils.stripSeparators(address);
- }
-
- int addressType = address == null ? -1 : PhoneNumberUtils.toaFromString(address);
-
- if (shouldLog) {
- Log.i(this, "sending clcc for call %d, %d, %d, %b, %s, %d",
- index, direction, state, isPartOfConference, Log.piiHandle(address),
- addressType);
- }
-
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(
- index, direction, state, 0, isPartOfConference, address, addressType);
- }
- }
-
- private void sendClccEndMarker() {
- // End marker is recognized with an index value of 0. All other parameters are ignored.
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(0 /* index */, 0, 0, 0, false, null, 0);
- }
- }
-
- /**
- * Returns the caches index for the specified call. If no such index exists, then an index is
- * given (smallest number starting from 1 that isn't already taken).
- */
- private int getIndexForCall(Call call) {
- if (mClccIndexMap.containsKey(call)) {
- return mClccIndexMap.get(call);
- }
-
- int i = 1; // Indexes for bluetooth clcc are 1-based.
- while (mClccIndexMap.containsValue(i)) {
- i++;
- }
-
- // NOTE: Indexes are removed in {@link #onCallRemoved}.
- mClccIndexMap.put(call, i);
- return i;
- }
-
- /**
- * Sends an update of the current call state to the current Headset.
- *
- * @param force {@code true} if the headset state should be sent regardless if no changes to the
- * state have occurred, {@code false} if the state should only be sent if the state has
- * changed.
- */
- private void updateHeadsetWithCallState(boolean force) {
- Call activeCall = mCallsManager.getActiveCall();
- Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
- Call heldCall = mCallsManager.getHeldCall();
-
- int bluetoothCallState = getBluetoothCallStateForUpdate();
-
- String ringingAddress = null;
- int ringingAddressType = DEFAULT_RINGING_ADDRESS_TYPE;
- String ringingName = null;
- if (ringingCall != null && ringingCall.getHandle() != null
- && !ringingCall.isSilentRingingRequested()) {
- ringingAddress = ringingCall.getHandle().getSchemeSpecificPart();
- if (ringingAddress != null) {
- ringingAddressType = PhoneNumberUtils.toaFromString(ringingAddress);
- }
- ringingName = ringingCall.getCallerDisplayName();
- if (TextUtils.isEmpty(ringingName)) {
- ringingName = ringingCall.getName();
- }
- }
- if (ringingAddress == null) {
- ringingAddress = "";
- }
-
- int numActiveCalls = activeCall == null ? 0 : 1;
- int numHeldCalls = mCallsManager.getNumHeldCalls();
- int numChildrenOfActiveCall = activeCall == null ? 0 : activeCall.getChildCalls().size();
-
- // Intermediate state for GSM calls which are in the process of being swapped.
- // TODO: Should we be hardcoding this value to 2 or should we check if all top level calls
- // are held?
- boolean callsPendingSwitch = (numHeldCalls == 2);
-
- // For conference calls which support swapping the active call within the conference
- // (namely CDMA calls) we need to expose that as a held call in order for the BT device
- // to show "swap" and "merge" functionality.
- boolean ignoreHeldCallChange = false;
- if (activeCall != null && activeCall.isConference() &&
- !activeCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) {
- if (activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
- // Indicate that BT device should show SWAP command by indicating that there is a
- // call on hold, but only if the conference wasn't previously merged.
- numHeldCalls = activeCall.wasConferencePreviouslyMerged() ? 0 : 1;
- } else if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
- numHeldCalls = 1; // Merge is available, so expose via numHeldCalls.
- }
-
- for (Call childCall : activeCall.getChildCalls()) {
- // Held call has changed due to it being combined into a CDMA conference. Keep
- // track of this and ignore any future update since it doesn't really count as
- // a call change.
- if (mOldHeldCall == childCall) {
- ignoreHeldCallChange = true;
- break;
- }
- }
- }
-
- if (mBluetoothHeadset != null &&
- (force ||
- (!callsPendingSwitch &&
- (numActiveCalls != mNumActiveCalls ||
- numChildrenOfActiveCall != mNumChildrenOfActiveCall ||
- numHeldCalls != mNumHeldCalls ||
- bluetoothCallState != mBluetoothCallState ||
- !TextUtils.equals(ringingAddress, mRingingAddress) ||
- ringingAddressType != mRingingAddressType ||
- (heldCall != mOldHeldCall && !ignoreHeldCallChange))))) {
-
- // If the call is transitioning into the alerting state, send DIALING first.
- // Some devices expect to see a DIALING state prior to seeing an ALERTING state
- // so we need to send it first.
- boolean sendDialingFirst = mBluetoothCallState != bluetoothCallState &&
- bluetoothCallState == CALL_STATE_ALERTING;
-
- mOldHeldCall = heldCall;
- mNumActiveCalls = numActiveCalls;
- mNumChildrenOfActiveCall = numChildrenOfActiveCall;
- mNumHeldCalls = numHeldCalls;
- mBluetoothCallState = bluetoothCallState;
- mRingingAddress = ringingAddress;
- mRingingAddressType = ringingAddressType;
-
- if (sendDialingFirst) {
- // Log in full to make logs easier to debug.
- Log.i(TAG, "updateHeadsetWithCallState " +
- "numActive %s, " +
- "numHeld %s, " +
- "callState %s, " +
- "ringing number %s, " +
- "ringing type %s, " +
- "ringing name %s",
- mNumActiveCalls,
- mNumHeldCalls,
- CALL_STATE_DIALING,
- Log.pii(mRingingAddress),
- mRingingAddressType,
- Log.pii(ringingName));
- mBluetoothHeadset.phoneStateChanged(
- mNumActiveCalls,
- mNumHeldCalls,
- CALL_STATE_DIALING,
- mRingingAddress,
- mRingingAddressType,
- ringingName);
- }
-
- Log.i(TAG, "updateHeadsetWithCallState " +
- "numActive %s, " +
- "numHeld %s, " +
- "callState %s, " +
- "ringing number %s, " +
- "ringing type %s, " +
- "ringing name %s",
- mNumActiveCalls,
- mNumHeldCalls,
- mBluetoothCallState,
- Log.pii(mRingingAddress),
- mRingingAddressType,
- Log.pii(ringingName));
-
- mBluetoothHeadset.phoneStateChanged(
- mNumActiveCalls,
- mNumHeldCalls,
- mBluetoothCallState,
- mRingingAddress,
- mRingingAddressType,
- ringingName);
-
- mHeadsetUpdatedRecently = true;
- }
- }
-
- private int getBluetoothCallStateForUpdate() {
- Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
- Call dialingCall = mCallsManager.getOutgoingCall();
- boolean hasOnlyDisconnectedCalls = mCallsManager.hasOnlyDisconnectedCalls();
-
- //
- // !! WARNING !!
- // You will note that CALL_STATE_WAITING, CALL_STATE_HELD, and CALL_STATE_ACTIVE are not
- // used in this version of the call state mappings. This is on purpose.
- // phone_state_change() in btif_hf.c is not written to handle these states. Only with the
- // listCalls*() method are WAITING and ACTIVE used.
- // Using the unsupported states here caused problems with inconsistent state in some
- // bluetooth devices (like not getting out of ringing state after answering a call).
- //
- int bluetoothCallState = CALL_STATE_IDLE;
- if (ringingCall != null && !ringingCall.isSilentRingingRequested()) {
- bluetoothCallState = CALL_STATE_INCOMING;
- } else if (dialingCall != null) {
- bluetoothCallState = CALL_STATE_ALERTING;
- } else if (hasOnlyDisconnectedCalls || mIsDisconnectedTonePlaying) {
- // Keep the DISCONNECTED state until the disconnect tone's playback is done
- bluetoothCallState = CALL_STATE_DISCONNECTED;
- }
- return bluetoothCallState;
- }
-
- private int getBtCallState(Call call, boolean isForeground) {
- switch (call.getState()) {
- case CallState.NEW:
- case CallState.ABORTED:
- case CallState.DISCONNECTED:
- case CallState.AUDIO_PROCESSING:
- return CALL_STATE_IDLE;
-
- case CallState.ACTIVE:
- return CALL_STATE_ACTIVE;
-
- case CallState.CONNECTING:
- case CallState.SELECT_PHONE_ACCOUNT:
- case CallState.DIALING:
- case CallState.PULLING:
- // Yes, this is correctly returning ALERTING.
- // "Dialing" for BT means that we have sent information to the service provider
- // to place the call but there is no confirmation that the call is going through.
- // When there finally is confirmation, the ringback is played which is referred to
- // as an "alert" tone, thus, ALERTING.
- // TODO: We should consider using the ALERTING terms in Telecom because that
- // seems to be more industry-standard.
- return CALL_STATE_ALERTING;
-
- case CallState.ON_HOLD:
- return CALL_STATE_HELD;
-
- case CallState.RINGING:
- case CallState.ANSWERED:
- case CallState.SIMULATED_RINGING:
- if (call.isSilentRingingRequested()) {
- return CALL_STATE_IDLE;
- } else if (isForeground) {
- return CALL_STATE_INCOMING;
- } else {
- return CALL_STATE_WAITING;
- }
- }
- return CALL_STATE_IDLE;
- }
-
- /**
- * Returns the best phone account to use for the given state of all calls.
- * First, tries to return the phone account for the foreground call, second the default
- * phone account for PhoneAccount.SCHEME_TEL.
- */
- private PhoneAccount getBestPhoneAccount() {
- if (mPhoneAccountRegistrar == null) {
- return null;
- }
-
- Call call = mCallsManager.getForegroundCall();
-
- PhoneAccount account = null;
- if (call != null) {
- // First try to get the network name of the foreground call.
- account = mPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- call.getTargetPhoneAccount());
- }
-
- if (account == null) {
- // Second, Try to get the label for the default Phone Account.
- account = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
- mPhoneAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
- PhoneAccount.SCHEME_TEL));
- }
- return account;
- }
-}
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
old mode 100755
new mode 100644
index cd236d2..15f9cd1
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -16,6 +16,8 @@
package com.android.server.telecom;
+import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -33,14 +35,18 @@
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
+import android.provider.CallLog;
import android.provider.ContactsContract.Contacts;
+import android.telecom.BluetoothCallQualityReport;
import android.telecom.CallAudioState;
import android.telecom.CallerInfo;
import android.telecom.Conference;
import android.telecom.Connection;
import android.telecom.ConnectionService;
+import android.telecom.DiagnosticCall;
import android.telecom.DisconnectCause;
import android.telecom.GatewayInfo;
+import android.telecom.InCallService;
import android.telecom.Log;
import android.telecom.Logging.EventManager;
import android.telecom.ParcelableConference;
@@ -55,6 +61,7 @@
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
@@ -151,6 +158,8 @@
Bundle extras, boolean isLegacy);
void onHandoverFailed(Call call, int error);
void onHandoverComplete(Call call);
+ void onBluetoothCallQualityReport(Call call, BluetoothCallQualityReport report);
+ void onReceivedDeviceToDeviceMessage(Call call, int messageType, int messageValue);
}
public abstract static class ListenerBase implements Listener {
@@ -239,6 +248,10 @@
public void onHandoverFailed(Call call, int error) {}
@Override
public void onHandoverComplete(Call call) {}
+ @Override
+ public void onBluetoothCallQualityReport(Call call, BluetoothCallQualityReport report) {}
+ @Override
+ public void onReceivedDeviceToDeviceMessage(Call call, int messageType, int messageValue) {}
}
private final CallerInfoLookupHelper.OnQueryCompleteListener mCallerInfoQueryListener =
@@ -507,6 +520,15 @@
private boolean mIsSelfManaged = false;
/**
+ * Indicates whether the {@link PhoneAccount} associated with an self-managed call want to
+ * expose the call to an {@link android.telecom.InCallService} which declares the metadata
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS},
+ * For calls that {@link #mIsSelfManaged} is {@code false}, this value should be {@code false}
+ * as well.
+ */
+ private boolean mVisibleToInCallService = false;
+
+ /**
* Indicates whether the {@link PhoneAccount} associated with this call supports video calling.
* {@code True} if the phone account supports video calling, {@code false} otherwise.
*/
@@ -545,7 +567,7 @@
private ParcelFileDescriptor[] mConnectionServiceToInCallStreams;
/**
- * True if we're supposed to start this call with RTT, either due to the master switch or due
+ * True if we're supposed to start this call with RTT, either due to the settings switch or due
* to an extra.
*/
private boolean mDidRequestToStartWithRtt = false;
@@ -588,7 +610,7 @@
/**
* Indicates whether this call is using one of the
- * {@link com.android.server.telecom.callfiltering.IncomingCallFilter.CallFilter} modules.
+ * {@link com.android.server.telecom.callfiltering.CallFilter} modules.
*/
private boolean mIsUsingCallFiltering = false;
@@ -611,6 +633,35 @@
private String mPostCallPackageName;
/**
+ * Call missed information code.
+ */
+ @CallLog.Calls.MissedReason private long mMissedReason;
+
+ /**
+ * Time that this call start ringing or simulated ringing.
+ */
+ private long mStartRingTime;
+
+ /**
+ * The package name of the call screening service that silence this call. If the call is not
+ * silenced, this field will be null.
+ */
+ private CharSequence mCallScreeningAppName;
+
+ /**
+ * The component name of the call screening service that silence this call. If the call is not
+ * silenced, this field will be null.
+ */
+ private String mCallScreeningComponentName;
+
+ /**
+ * When {@code true} indicates this call originated from a SIM-based {@link PhoneAccount}.
+ * A sim-based {@link PhoneAccount} is one with {@link PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION}
+ * set.
+ */
+ private boolean mIsSimCall;
+
+ /**
* Persists the specified parameters and initializes the new instance.
* @param context The context.
* @param repository The connection service repository.
@@ -692,6 +743,8 @@
mClockProxy = clockProxy;
mToastFactory = toastFactory;
mCreationTimeMillis = mClockProxy.currentTimeMillis();
+ mMissedReason = MISSED_REASON_NOT_MISSED;
+ mStartRingTime = 0;
}
/**
@@ -1039,6 +1092,10 @@
}
}
+ public void handleOverrideDisconnectMessage(@Nullable CharSequence message) {
+
+ }
+
/**
* Sets the call state. Although there exists the notion of appropriate state transitions
* (see {@link CallState}), in practice those expectations break down when cellular systems
@@ -1124,6 +1181,12 @@
case CallState.ANSWERED:
event = LogUtils.Events.SET_ANSWERED;
break;
+ case CallState.AUDIO_PROCESSING:
+ event = LogUtils.Events.SET_AUDIO_PROCESSING;
+ break;
+ case CallState.SIMULATED_RINGING:
+ event = LogUtils.Events.SET_SIMULATED_RINGING;
+ break;
}
if (event != null) {
// The string data should be just the tag.
@@ -1595,6 +1658,14 @@
setConnectionProperties(getConnectionProperties());
}
+ public boolean visibleToInCallService() {
+ return mVisibleToInCallService;
+ }
+
+ public void setVisibleToInCallService(boolean visibleToInCallService) {
+ mVisibleToInCallService = visibleToInCallService;
+ }
+
public void markFinishedHandoverStateAndCleanup(int handoverState) {
if (mHandoverSourceCall != null) {
mHandoverSourceCall.setHandoverState(handoverState);
@@ -1651,6 +1722,7 @@
PhoneAccountRegistrar phoneAccountRegistrar = mCallsManager.getPhoneAccountRegistrar();
boolean isWorkCall = false;
boolean isCallRecordingToneSupported = false;
+ boolean isSimCall = false;
PhoneAccount phoneAccount =
phoneAccountRegistrar.getPhoneAccountUnchecked(mTargetPhoneAccountHandle);
if (phoneAccount != null) {
@@ -1668,9 +1740,11 @@
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) && phoneAccount.getExtras() != null
&& phoneAccount.getExtras().getBoolean(
PhoneAccount.EXTRA_PLAY_CALL_RECORDING_TONE, false));
+ isSimCall = phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
}
mIsWorkCall = isWorkCall;
mUseCallRecordingTone = isCallRecordingToneSupported;
+ mIsSimCall = isSimCall;
}
/**
@@ -1851,6 +1925,13 @@
if (didRttChange) {
if ((mConnectionProperties & Connection.PROPERTY_IS_RTT) ==
Connection.PROPERTY_IS_RTT) {
+ // If we already had RTT streams up, that means that either the call started
+ // with RTT or the user previously requested to start RTT. Either way, don't
+ // play the alert tone.
+ if (!areRttStreamsInitialized()) {
+ mCallsManager.playRttUpgradeToneForCall(this);
+ }
+
createRttStreams();
// Call startRtt to pass the RTT pipes down to the connection service.
// They already turned on the RTT property so no request should be sent.
@@ -2429,7 +2510,7 @@
"reject call failed due to null CS callId=%s", getId());
}
Log.addEvent(this, LogUtils.Events.REQUEST_REJECT, reason);
- } else if (isRinging("reject")) {
+ } else if (isRinging("reject") || isAnswered("reject")) {
// Ensure video state history tracks video state at time of rejection.
mVideoStateHistory |= mVideoState;
@@ -2461,7 +2542,7 @@
"reject call failed due to null CS callId=%s", getId());
}
Log.addEvent(this, LogUtils.Events.REQUEST_REJECT);
- } else if (isRinging("reject")) {
+ } else if (isRinging("reject") || isAnswered("reject")) {
// Ensure video state history tracks video state at time of rejection.
mVideoStateHistory |= mVideoState;
@@ -2900,6 +2981,14 @@
}
requestHandover(phoneAccountHandle, videoState, handoverExtrasBundle, true);
} else {
+ // Relay bluetooth call quality reports to the call diagnostic service.
+ if (BluetoothCallQualityReport.EVENT_BLUETOOTH_CALL_QUALITY_REPORT.equals(event)
+ && extras.containsKey(
+ BluetoothCallQualityReport.EXTRA_BLUETOOTH_CALL_QUALITY_REPORT)) {
+ notifyBluetoothCallQualityReport(extras.getParcelable(
+ BluetoothCallQualityReport.EXTRA_BLUETOOTH_CALL_QUALITY_REPORT
+ ));
+ }
Log.addEvent(this, LogUtils.Events.CALL_EVENT, event);
mConnectionService.sendCallEvent(this, event, extras);
}
@@ -2910,6 +2999,17 @@
}
/**
+ * Notifies listeners when a bluetooth quality report is received.
+ * @param report The bluetooth quality report.
+ */
+ void notifyBluetoothCallQualityReport(@NonNull BluetoothCallQualityReport report) {
+ Log.addEvent(this, LogUtils.Events.BT_QUALITY_REPORT, "choppy=" + report.isChoppyVoice());
+ for (Listener l : mListeners) {
+ l.onBluetoothCallQualityReport(this, report);
+ }
+ }
+
+ /**
* Initiates a handover of this Call to the {@link ConnectionService} identified
* by destAcct.
* @param destAcct ConnectionService to which the call should be handed over.
@@ -3142,6 +3242,18 @@
return false;
}
+ /**
+ * @return True if the call is answered, else logs the action name.
+ */
+ private boolean isAnswered(String actionName) {
+ if (mState == CallState.ANSWERED) {
+ return true;
+ }
+
+ Log.i(this, "Request to %s a non-answered call %s", actionName, this);
+ return false;
+ }
+
@SuppressWarnings("rawtypes")
private void decrementAssociatedCallCount(ServiceBinder binder) {
if (binder != null) {
@@ -3627,6 +3739,17 @@
for (Listener l : mListeners) {
l.onCallSwitchFailed(this);
}
+ } else if (Connection.EVENT_DEVICE_TO_DEVICE_MESSAGE.equals(event)
+ && extras != null && extras.containsKey(
+ Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_TYPE)
+ && extras.containsKey(Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_VALUE)) {
+ // Relay an incoming D2D message to interested listeners; most notably the
+ // CallDiagnosticService.
+ int messageType = extras.getInt(Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_TYPE);
+ int messageValue = extras.getInt(Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_VALUE);
+ for (Listener l : mListeners) {
+ l.onReceivedDeviceToDeviceMessage(this, messageType, messageValue);
+ }
} else {
for (Listener l : mListeners) {
l.onConnectionEvent(this, event, extras);
@@ -3828,6 +3951,44 @@
}
/**
+ * Sends a device to device message to the other part of the call.
+ * @param message the message type to send.
+ * @param value the value for the message.
+ */
+ public void sendDeviceToDeviceMessage(@DiagnosticCall.MessageType int message, int value) {
+ Log.i(this, "sendDeviceToDeviceMessage; callId=%s, msg=%d/%d", getId(), message, value);
+ Bundle extras = new Bundle();
+ extras.putInt(Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_TYPE, message);
+ extras.putInt(Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_VALUE, value);
+ // Send to the connection service.
+ sendCallEvent(Connection.EVENT_DEVICE_TO_DEVICE_MESSAGE, extras);
+ }
+
+ /**
+ * Signals to the Dialer app to start displaying a diagnostic message.
+ * @param messageId a unique ID for the message to display.
+ * @param message the message to display.
+ */
+ public void displayDiagnosticMessage(int messageId, @NonNull CharSequence message) {
+ Bundle extras = new Bundle();
+ extras.putInt(android.telecom.Call.EXTRA_DIAGNOSTIC_MESSAGE_ID, messageId);
+ extras.putCharSequence(android.telecom.Call.EXTRA_DIAGNOSTIC_MESSAGE, message);
+ // Send to the dialer.
+ onConnectionEvent(android.telecom.Call.EVENT_DISPLAY_DIAGNOSTIC_MESSAGE, extras);
+ }
+
+ /**
+ * Signals to the Dialer app to stop displaying a diagnostic message.
+ * @param messageId a unique ID for the message to clear.
+ */
+ public void clearDiagnosticMessage(int messageId) {
+ Bundle extras = new Bundle();
+ extras.putInt(android.telecom.Call.EXTRA_DIAGNOSTIC_MESSAGE_ID, messageId);
+ // Send to the dialer.
+ onConnectionEvent(android.telecom.Call.EVENT_CLEAR_DIAGNOSTIC_MESSAGE, extras);
+ }
+
+ /**
* Remaps the call direction as indicated by an {@link android.telecom.Call.Details} direction
* constant to the constants (e.g. {@link #CALL_DIRECTION_INCOMING}) used in this call class.
* @param direction The android.telecom.Call direction.
@@ -3864,4 +4025,62 @@
public String getPostCallPackageName() {
return mPostCallPackageName;
}
+
+ public long getMissedReason() {
+ return mMissedReason;
+ }
+
+ public void setMissedReason(long missedReason) {
+ mMissedReason = missedReason;
+ }
+
+ public void setUserMissed(long code) {
+ mMissedReason |= code;
+ }
+
+ public long getStartRingTime() {
+ return mStartRingTime;
+ }
+
+ public void setStartRingTime(long startRingTime) {
+ mStartRingTime = startRingTime;
+ }
+
+ public CharSequence getCallScreeningAppName() {
+ return mCallScreeningAppName;
+ }
+
+ public void setCallScreeningAppName(CharSequence callScreeningAppName) {
+ mCallScreeningAppName = callScreeningAppName;
+ }
+
+ public String getCallScreeningComponentName() {
+ return mCallScreeningComponentName;
+ }
+
+ public void setCallScreeningComponentName(String callScreeningComponentName) {
+ mCallScreeningComponentName = callScreeningComponentName;
+ }
+
+ public void maybeOnInCallServiceTrackingChanged(boolean isTracking, boolean hasUi) {
+ if (mConnectionService == null) {
+ Log.w(this, "maybeOnInCallServiceTrackingChanged() request on a call"
+ + " without a connection service.");
+ } else {
+ if (hasUi) {
+ mConnectionService.onUsingAlternativeUi(this, isTracking);
+ } else if (isTracking) {
+ mConnectionService.onTrackedByNonUiService(this, isTracking);
+ }
+ }
+ }
+
+ /**
+ * @return {@code true} when this call originated from a SIM-based {@link PhoneAccount}.
+ * A sim-based {@link PhoneAccount} is one with {@link PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION}
+ * set.
+ */
+ public boolean isSimCall() {
+ return mIsSimCall;
+ }
}
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index a6509b4..6a7261e 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -264,6 +264,14 @@
}
}
+ public void playRttUpgradeTone(Call call) {
+ if (call != mForegroundCall) {
+ // We only play tones for foreground calls.
+ return;
+ }
+ mPlayerFactory.createPlayer(InCallTonePlayer.TONE_RTT_REQUEST).startTone();
+ }
+
/**
* Play or stop a call hold tone for a call. Triggered via
* {@link Connection#sendConnectionEvent(String)} when the
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 28f9df9..bcfdedf 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -413,6 +413,8 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -534,6 +536,7 @@
// This may be sent as a confirmation by the BT stack after switch off BT.
return HANDLED;
case CONNECT_DOCK:
+ setSpeakerphoneOn(true);
sendInternalMessage(SWITCH_SPEAKER);
return HANDLED;
case DISCONNECT_DOCK:
@@ -612,6 +615,8 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -727,6 +732,7 @@
return HANDLED;
case DISCONNECT_WIRED_HEADSET:
if (mWasOnSpeaker) {
+ setSpeakerphoneOn(true);
sendInternalMessage(SWITCH_SPEAKER);
} else {
sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
@@ -798,6 +804,7 @@
transitionTo(mActiveHeadsetRoute);
break;
case SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
transitionTo(mActiveSpeakerRoute);
break;
default:
@@ -854,6 +861,8 @@
mHasUserExplicitlyLeftBluetooth = true;
// fall through
case SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
setBluetoothOff();
transitionTo(mActiveSpeakerRoute);
@@ -949,6 +958,8 @@
mHasUserExplicitlyLeftBluetooth = true;
// fall through
case SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -1108,8 +1119,9 @@
@Override
public void enter() {
super.enter();
+ // Don't set speakerphone on here -- we might end up in this state by following
+ // the speaker state that some other app commanded.
mWasOnSpeaker = true;
- setSpeakerphoneOn(true);
CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER,
mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
setSystemAudioState(newState, true);
@@ -1260,6 +1272,7 @@
return HANDLED;
case SWITCH_FOCUS:
if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
+ setSpeakerphoneOn(true);
transitionTo(mActiveSpeakerRoute);
}
return HANDLED;
@@ -1596,12 +1609,8 @@
}
private void setSpeakerphoneOn(boolean on) {
- if (mAudioManager.isSpeakerphoneOn() != on) {
- Log.i(this, "turning speaker phone %s", on);
- mAudioManager.setSpeakerphoneOn(on);
- } else {
- Log.i(this, "Ignoring speakerphone request -- already %s", on);
- }
+ Log.i(this, "turning speaker phone %s", on);
+ mAudioManager.setSpeakerphoneOn(on);
mStatusBarNotifier.notifySpeakerphone(on);
}
diff --git a/src/com/android/server/telecom/CallDiagnosticServiceAdapter.java b/src/com/android/server/telecom/CallDiagnosticServiceAdapter.java
new file mode 100644
index 0000000..79a94d3
--- /dev/null
+++ b/src/com/android/server/telecom/CallDiagnosticServiceAdapter.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.telecom.CallDiagnosticService;
+import android.telecom.DiagnosticCall;
+import android.telecom.Log;
+
+import com.android.internal.telecom.ICallDiagnosticServiceAdapter;
+import com.android.internal.telecom.IInCallAdapter;
+
+/**
+ * Adapter class used to provide a path for messages FROM a {@link CallDiagnosticService} back to
+ * the telecom stack.
+ */
+public class CallDiagnosticServiceAdapter extends ICallDiagnosticServiceAdapter.Stub {
+ public interface TelecomAdapter {
+ void displayDiagnosticMessage(String callId, int messageId, CharSequence message);
+ void clearDiagnosticMessage(String callId, int messageId);
+ void sendDeviceToDeviceMessage(String callId, @DiagnosticCall.MessageType int message,
+ int value);
+ void overrideDisconnectMessage(String callId, CharSequence message);
+ }
+
+ private final TelecomAdapter mTelecomAdapter;
+ private final String mOwnerPackageName;
+ private final String mOwnerPackageAbbreviation;
+ private final TelecomSystem.SyncRoot mLock;
+
+ CallDiagnosticServiceAdapter(@NonNull TelecomAdapter telecomAdapter,
+ @NonNull String ownerPackageName, @NonNull TelecomSystem.SyncRoot lock) {
+ mTelecomAdapter = telecomAdapter;
+ mOwnerPackageName = ownerPackageName;
+ mOwnerPackageAbbreviation = Log.getPackageAbbreviation(ownerPackageName);
+ mLock = lock;
+ }
+
+ @Override
+ public void displayDiagnosticMessage(String callId, int messageId, CharSequence message)
+ throws RemoteException {
+ try {
+ Log.startSession("CDSA.dDM", mOwnerPackageAbbreviation);
+ long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ Log.i(this, "displayDiagnosticMessage; callId=%s, msg=%d/%s", callId, messageId,
+ message);
+ mTelecomAdapter.displayDiagnosticMessage(callId, messageId, message);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void clearDiagnosticMessage(String callId, int messageId) throws RemoteException {
+ try {
+ Log.startSession("CDSA.cDM", mOwnerPackageAbbreviation);
+ long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ Log.i(this, "clearDiagnosticMessage; callId=%s, msg=%d", callId, messageId);
+ mTelecomAdapter.clearDiagnosticMessage(callId, messageId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void sendDeviceToDeviceMessage(String callId, @DiagnosticCall.MessageType int message,
+ int value)
+ throws RemoteException {
+ try {
+ Log.startSession("CDSA.sDTDM", mOwnerPackageAbbreviation);
+ long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ Log.i(this, "sendDeviceToDeviceMessage; callId=%s, msg=%d/%d", callId, message,
+ value);
+ mTelecomAdapter.sendDeviceToDeviceMessage(callId, message, value);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void overrideDisconnectMessage(String callId, CharSequence message)
+ throws RemoteException {
+ try {
+ Log.startSession("CDSA.oDM", mOwnerPackageAbbreviation);
+ long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ Log.i(this, "overrideDisconnectMessage; callId=%s, msg=%s", callId, message);
+ mTelecomAdapter.overrideDisconnectMessage(callId, message);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+}
diff --git a/src/com/android/server/telecom/CallDiagnosticServiceController.java b/src/com/android/server/telecom/CallDiagnosticServiceController.java
new file mode 100644
index 0000000..943a176
--- /dev/null
+++ b/src/com/android/server/telecom/CallDiagnosticServiceController.java
@@ -0,0 +1,654 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.telecom.BluetoothCallQualityReport;
+import android.telecom.CallAudioState;
+import android.telecom.CallDiagnosticService;
+import android.telecom.ConnectionService;
+import android.telecom.DiagnosticCall;
+import android.telecom.InCallService;
+import android.telecom.Log;
+import android.telecom.ParcelableCall;
+import android.telephony.ims.ImsReasonInfo;
+import android.text.TextUtils;
+
+import com.android.internal.telecom.ICallDiagnosticService;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Responsible for maintaining binding to the {@link CallDiagnosticService} defined by the
+ * {@code call_diagnostic_service_package_name} key in the
+ * {@code packages/services/Telecomm/res/values/config.xml} file.
+ */
+public class CallDiagnosticServiceController extends CallsManagerListenerBase {
+ /**
+ * Context dependencies for the {@link CallDiagnosticServiceController}.
+ */
+ public interface ContextProxy {
+ List<ResolveInfo> queryIntentServicesAsUser(@NonNull Intent intent,
+ @PackageManager.ResolveInfoFlags int flags, @UserIdInt int userId);
+ boolean bindServiceAsUser(@NonNull @RequiresPermission Intent service,
+ @NonNull ServiceConnection conn, int flags, @NonNull UserHandle user);
+ void unbindService(@NonNull ServiceConnection conn);
+ UserHandle getCurrentUserHandle();
+ }
+
+ /**
+ * Listener for {@link Call} events; used to propagate these changes to the
+ * {@link CallDiagnosticService}.
+ */
+ private final Call.Listener mCallListener = new Call.ListenerBase() {
+ @Override
+ public void onConnectionCapabilitiesChanged(Call call) {
+ updateCall(call);
+ }
+
+ @Override
+ public void onConnectionPropertiesChanged(Call call, boolean didRttChange) {
+ updateCall(call);
+ }
+
+ /**
+ * Listens for changes to extras reported by a Telecom {@link Call}.
+ *
+ * Extras changes can originate from a {@link ConnectionService} or an {@link InCallService}
+ * so we will only trigger an update of the call information if the source of the extras
+ * change was a {@link ConnectionService}.
+ *
+ * @param call The call.
+ * @param source The source of the extras change ({@link Call#SOURCE_CONNECTION_SERVICE} or
+ * {@link Call#SOURCE_INCALL_SERVICE}).
+ * @param extras The extras.
+ */
+ @Override
+ public void onExtrasChanged(Call call, int source, Bundle extras) {
+ // Do not inform InCallServices of changes which originated there.
+ if (source == Call.SOURCE_INCALL_SERVICE) {
+ return;
+ }
+ updateCall(call);
+ }
+
+ /**
+ * Listens for changes to extras reported by a Telecom {@link Call}.
+ *
+ * Extras changes can originate from a {@link ConnectionService} or an {@link InCallService}
+ * so we will only trigger an update of the call information if the source of the extras
+ * change was a {@link ConnectionService}.
+ * @param call The call.
+ * @param source The source of the extras change ({@link Call#SOURCE_CONNECTION_SERVICE} or
+ * {@link Call#SOURCE_INCALL_SERVICE}).
+ * @param keys The extra key removed
+ */
+ @Override
+ public void onExtrasRemoved(Call call, int source, List<String> keys) {
+ // Do not inform InCallServices of changes which originated there.
+ if (source == Call.SOURCE_INCALL_SERVICE) {
+ return;
+ }
+ updateCall(call);
+ }
+
+ /**
+ * Handles changes to the video state of a call.
+ * @param call
+ * @param previousVideoState
+ * @param newVideoState
+ */
+ @Override
+ public void onVideoStateChanged(Call call, int previousVideoState, int newVideoState) {
+ updateCall(call);
+ }
+
+ /**
+ * Relays a bluetooth call quality report received from the Bluetooth stack to the
+ * CallDiagnosticService.
+ * @param call The call.
+ * @param report The received report.
+ */
+ @Override
+ public void onBluetoothCallQualityReport(Call call, BluetoothCallQualityReport report) {
+ handleBluetoothCallQualityReport(call, report);
+ }
+
+ /**
+ * Relays a device to device message received from Telephony to the CallDiagnosticService.
+ * @param call
+ * @param messageType
+ * @param messageValue
+ */
+ @Override
+ public void onReceivedDeviceToDeviceMessage(Call call, int messageType, int messageValue) {
+ handleReceivedDeviceToDeviceMessage(call, messageType, messageValue);
+ }
+ };
+
+ /**
+ * {@link ServiceConnection} handling changes to binding of the {@link CallDiagnosticService}.
+ */
+ private class CallDiagnosticServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.startSession("CDSC.oSC", Log.getPackageAbbreviation(name));
+ try {
+ synchronized (mLock) {
+ mCallDiagnosticService = ICallDiagnosticService.Stub.asInterface(service);
+
+ handleConnectionComplete(mCallDiagnosticService);
+ }
+ Log.i(CallDiagnosticServiceController.this, "onServiceConnected: cmp=%s", name);
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.startSession("CDSC.oSD", Log.getPackageAbbreviation(name));
+ try {
+ synchronized (mLock) {
+ mCallDiagnosticService = null;
+ mConnection = null;
+ }
+ Log.i(CallDiagnosticServiceController.this, "onServiceDisconnected: cmp=%s", name);
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ Log.startSession("CDSC.oBD", Log.getPackageAbbreviation(name));
+ try {
+ synchronized (mLock) {
+ mCallDiagnosticService = null;
+ mConnection = null;
+ }
+ Log.w(CallDiagnosticServiceController.this, "onBindingDied: cmp=%s", name);
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Log.startSession("CDSC.oNB", Log.getPackageAbbreviation(name));
+ try {
+ synchronized (mLock) {
+ maybeUnbindCallScreeningService();
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+ }
+
+ private final String mPackageName;
+ private final ContextProxy mContextProxy;
+ private String mTestPackageName;
+ private CallDiagnosticServiceConnection mConnection;
+ private CallDiagnosticServiceAdapter mAdapter;
+ private final TelecomSystem.SyncRoot mLock;
+ private ICallDiagnosticService mCallDiagnosticService;
+ private final CallIdMapper mCallIdMapper = new CallIdMapper(Call::getId);
+
+ public CallDiagnosticServiceController(@NonNull ContextProxy contextProxy,
+ @Nullable String packageName, @NonNull TelecomSystem.SyncRoot lock) {
+ mContextProxy = contextProxy;
+ mPackageName = packageName;
+ mLock = lock;
+ }
+
+ /**
+ * Handles Telecom adding new calls. Will bind to the call diagnostic service if needed and
+ * send the calls, or send to an already bound service.
+ * @param call The call to add.
+ */
+ @Override
+ public void onCallAdded(@NonNull Call call) {
+ if (!call.isSimCall() || call.isExternalCall()) {
+ Log.i(this, "onCallAdded: skipping call %s as non-sim or external.", call.getId());
+ return;
+ }
+ if (mCallIdMapper.getCallId(call) == null) {
+ mCallIdMapper.addCall(call);
+ call.addListener(mCallListener);
+ }
+ if (isConnected()) {
+ sendCallToBoundService(call, mCallDiagnosticService);
+ } else {
+ maybeBindCallDiagnosticService();
+ }
+ }
+
+ /**
+ * Handles Telecom removal of calls; will remove the call from the bound service and if the
+ * number of tracked calls falls to zero, unbind from the service.
+ * @param call The call to remove from the bound CDS.
+ */
+ @Override
+ public void onCallRemoved(@NonNull Call call) {
+ if (!call.isSimCall() || call.isExternalCall()) {
+ Log.i(this, "onCallRemoved: skipping call %s as non-sim or external.", call.getId());
+ return;
+ }
+ mCallIdMapper.removeCall(call);
+ call.removeListener(mCallListener);
+ removeCallFromBoundService(call, mCallDiagnosticService);
+
+ if (mCallIdMapper.getCalls().size() == 0) {
+ maybeUnbindCallScreeningService();
+ }
+ }
+
+ @Override
+ public void onCallStateChanged(Call call, int oldState, int newState) {
+ updateCall(call);
+ }
+
+ @Override
+ public void onCallAudioStateChanged(CallAudioState oldCallAudioState,
+ CallAudioState newCallAudioState) {
+ if (mCallDiagnosticService != null) {
+ try {
+ mCallDiagnosticService.updateCallAudioState(newCallAudioState);
+ } catch (RemoteException e) {
+ Log.w(this, "onCallAudioStateChanged: failed %s", e);
+ }
+ }
+ }
+
+ /**
+ * Sets the test call diagnostic service; used by the telecom command line command to override
+ * the {@link CallDiagnosticService} to bind to for CTS test purposes.
+ * @param packageName The package name to set to.
+ */
+ public void setTestCallDiagnosticService(@Nullable String packageName) {
+ if (TextUtils.isEmpty(packageName)) {
+ mTestPackageName = null;
+ } else {
+ mTestPackageName = packageName;
+ }
+
+ Log.i(this, "setTestCallDiagnosticService: packageName=%s", packageName);
+ }
+
+ /**
+ * Determines the active call diagnostic service, taking into account the test override.
+ * @return The package name of the active call diagnostic service.
+ */
+ private @Nullable String getActiveCallDiagnosticService() {
+ if (mTestPackageName != null) {
+ return mTestPackageName;
+ }
+
+ return mPackageName;
+ }
+
+ /**
+ * If we are not already bound to the {@link CallDiagnosticService}, attempts to initiate a
+ * binding tho that service.
+ * @return {@code true} if we bound, {@code false} otherwise.
+ */
+ private boolean maybeBindCallDiagnosticService() {
+ if (mConnection != null) {
+ return false;
+ }
+
+ mConnection = new CallDiagnosticServiceConnection();
+ boolean bound = bindCallDiagnosticService(mContextProxy.getCurrentUserHandle(),
+ getActiveCallDiagnosticService(), mConnection);
+ if (!bound) {
+ mConnection = null;
+ }
+ return bound;
+ }
+
+ /**
+ * Performs binding to the {@link CallDiagnosticService}.
+ * @param userHandle user name to bind via.
+ * @param packageName package name of the CDS.
+ * @param serviceConnection The service connection to be notified of bind events.
+ * @return
+ */
+ private boolean bindCallDiagnosticService(UserHandle userHandle,
+ String packageName, CallDiagnosticServiceConnection serviceConnection) {
+
+ if (TextUtils.isEmpty(packageName)) {
+ Log.i(this, "bindCallDiagnosticService: no package; skip binding.");
+ return false;
+ }
+
+ Intent intent = new Intent(CallDiagnosticService.SERVICE_INTERFACE)
+ .setPackage(packageName);
+ Log.i(this, "bindCallDiagnosticService: user %d.", userHandle.getIdentifier());
+ List<ResolveInfo> entries = mContextProxy.queryIntentServicesAsUser(intent, 0,
+ userHandle.getIdentifier());
+ if (entries.isEmpty()) {
+ Log.i(this, "bindCallDiagnosticService: %s has no service.", packageName);
+ return false;
+ }
+
+ ResolveInfo entry = entries.get(0);
+ if (entry.serviceInfo == null) {
+ Log.i(this, "bindCallDiagnosticService: %s has no service info.", packageName);
+ return false;
+ }
+
+ if (entry.serviceInfo.permission == null || !entry.serviceInfo.permission.equals(
+ Manifest.permission.BIND_CALL_DIAGNOSTIC_SERVICE)) {
+ Log.i(this, "bindCallDiagnosticService: %s doesn't require "
+ + "BIND_CALL_DIAGNOSTIC_SERVICE.", packageName);
+ return false;
+ }
+
+ ComponentName componentName =
+ new ComponentName(entry.serviceInfo.packageName, entry.serviceInfo.name);
+ intent.setComponent(componentName);
+ if (mContextProxy.bindServiceAsUser(
+ intent,
+ serviceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ UserHandle.CURRENT)) {
+ Log.d(this, "bindCallDiagnosticService, found service, waiting for it to connect");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If we are bound to a {@link CallDiagnosticService}, unbind from it.
+ */
+ public void maybeUnbindCallScreeningService() {
+ if (mConnection != null) {
+ Log.i(this, "maybeUnbindCallScreeningService - unbinding from %s",
+ getActiveCallDiagnosticService());
+ try {
+ mContextProxy.unbindService(mConnection);
+ mCallDiagnosticService = null;
+ mConnection = null;
+ } catch (IllegalArgumentException e) {
+ Log.i(this, "maybeUnbindCallScreeningService: Exception when unbind %s : %s",
+ getActiveCallDiagnosticService(), e.getMessage());
+ }
+ } else {
+ Log.w(this, "maybeUnbindCallScreeningService - already unbound");
+ }
+ }
+
+ /**
+ * Implements the abstracted Telecom functionality the {@link CallDiagnosticServiceAdapter}
+ * depends on.
+ */
+ private CallDiagnosticServiceAdapter.TelecomAdapter mTelecomAdapter =
+ new CallDiagnosticServiceAdapter.TelecomAdapter() {
+
+ @Override
+ public void displayDiagnosticMessage(String callId, int messageId, CharSequence message) {
+ handleDisplayDiagnosticMessage(callId, messageId, message);
+ }
+
+ @Override
+ public void clearDiagnosticMessage(String callId, int messageId) {
+ handleClearDiagnosticMessage(callId, messageId);
+ }
+
+ @Override
+ public void sendDeviceToDeviceMessage(String callId,
+ @DiagnosticCall.MessageType int message, int value) {
+ handleSendD2DMessage(callId, message, value);
+ }
+
+ @Override
+ public void overrideDisconnectMessage(String callId, CharSequence message) {
+ handleOverrideDisconnectMessage(callId, message);
+ }
+ };
+
+ /**
+ * Sends all calls to the specified {@link CallDiagnosticService}.
+ * @param callDiagnosticService the CDS to send calls to.
+ */
+ private void handleConnectionComplete(@NonNull ICallDiagnosticService callDiagnosticService) {
+ mAdapter = new CallDiagnosticServiceAdapter(mTelecomAdapter,
+ getActiveCallDiagnosticService(), mLock);
+ try {
+ // Add adapter for communication back from the call diagnostic service to Telecom.
+ callDiagnosticService.setAdapter(mAdapter);
+
+ // Loop through all the calls we've got ready to send since binding.
+ for (Call call : mCallIdMapper.getCalls()) {
+ sendCallToBoundService(call, callDiagnosticService);
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "handleConnectionComplete: error=%s", e);
+ }
+ }
+
+ /**
+ * Handles a request from a {@link CallDiagnosticService} to display a diagnostic message.
+ * @param callId the ID of the call to display the message for.
+ * @param message the message.
+ */
+ private void handleDisplayDiagnosticMessage(@NonNull String callId, int messageId,
+ @Nullable CharSequence message) {
+ Call call = mCallIdMapper.getCall(callId);
+ if (call == null) {
+ Log.w(this, "handleDisplayDiagnosticMessage: callId=%s; msg=%d/%s; invalid call",
+ callId, messageId, message);
+ return;
+ }
+ Log.i(this, "handleDisplayDiagnosticMessage: callId=%s; msg=%d/%s; invalid call",
+ callId, messageId, message);
+ call.displayDiagnosticMessage(messageId, message);
+ }
+
+ /**
+ * Handles a request from a {@link CallDiagnosticService} to clear a previously displayed
+ * diagnostic message.
+ * @param callId the ID of the call to display the message for.
+ * @param messageId the message ID which was previous posted.
+ */
+ private void handleClearDiagnosticMessage(@NonNull String callId, int messageId) {
+ Call call = mCallIdMapper.getCall(callId);
+ if (call == null) {
+ Log.w(this, "handleClearDiagnosticMessage: callId=%s; msg=%d; invalid call",
+ callId, messageId);
+ return;
+ }
+ Log.i(this, "handleClearDiagnosticMessage: callId=%s; msg=%d; invalid call",
+ callId, messageId);
+ call.clearDiagnosticMessage(messageId);
+ }
+
+ /**
+ * Handles a request from a {@link CallDiagnosticService} to send a device to device message.
+ * @param callId The ID of the call to send the D2D message for.
+ * @param message The message type.
+ * @param value The message value.
+ */
+ private void handleSendD2DMessage(@NonNull String callId,
+ @DiagnosticCall.MessageType int message, int value) {
+ Call call = mCallIdMapper.getCall(callId);
+ if (call == null) {
+ Log.w(this, "handleSendD2DMessage: callId=%s; msg=%d/%d; invalid call", callId,
+ message, value);
+ return;
+ }
+ Log.i(this, "handleSendD2DMessage: callId=%s; msg=%d/%d", callId, message, value);
+ call.sendDeviceToDeviceMessage(message, value);
+ }
+
+ /**
+ * Handles a request from a {@link CallDiagnosticService} to override the disconnect message
+ * for a call. This is the response path from a previous call into the
+ * {@link CallDiagnosticService} via {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)}.
+ * @param callId The telecom call ID the disconnect override is pending for.
+ * @param message The new disconnect message, or {@code null} if no override.
+ */
+ private void handleOverrideDisconnectMessage(@NonNull String callId,
+ @Nullable CharSequence message) {
+ Call call = mCallIdMapper.getCall(callId);
+ if (call == null) {
+ Log.w(this, "handleOverrideDisconnectMessage: callId=%s; msg=%s; invalid call", callId,
+ message);
+ return;
+ }
+ Log.i(this, "handleOverrideDisconnectMessage: callId=%s; msg=%s", callId, message);
+ call.handleOverrideDisconnectMessage(message);
+ }
+
+ /**
+ * Sends a single call to the bound {@link CallDiagnosticService}.
+ * @param call The call to send.
+ * @param callDiagnosticService The CDS to send it to.
+ */
+ private void sendCallToBoundService(@NonNull Call call,
+ @NonNull ICallDiagnosticService callDiagnosticService) {
+ try {
+ if (isConnected()) {
+ Log.w(this, "sendCallToBoundService: initializing %s", call.getId());
+ callDiagnosticService.initializeDiagnosticCall(getParceledCall(call));
+ } else {
+ Log.w(this, "sendCallToBoundService: not bound, skipping %s", call.getId());
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "sendCallToBoundService: callId=%s, exception=%s", call.getId(), e);
+ }
+ }
+
+ /**
+ * Removes a call from a bound {@link CallDiagnosticService}.
+ * @param call The call to remove.
+ * @param callDiagnosticService The CDS to remove it from.
+ */
+ private void removeCallFromBoundService(@NonNull Call call,
+ @NonNull ICallDiagnosticService callDiagnosticService) {
+ try {
+ if (isConnected()) {
+ callDiagnosticService.removeDiagnosticCall(call.getId());
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "removeCallFromBoundService: callId=%s, exception=%s", call.getId(), e);
+ }
+ }
+
+ /**
+ * @return {@code true} if the call diagnostic service is bound/connected.
+ */
+ private boolean isConnected() {
+ return mCallDiagnosticService != null;
+ }
+
+ /**
+ * Updates the Call diagnostic service with changes to a call.
+ * @param call The updated call.
+ */
+ private void updateCall(@NonNull Call call) {
+ try {
+ if (isConnected()) {
+ mCallDiagnosticService.updateCall(getParceledCall(call));
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "updateCall: callId=%s, exception=%s", call.getId(), e);
+ }
+ }
+
+ /**
+ * Updates the call diagnostic service with a received bluetooth quality report.
+ * @param call The call.
+ * @param report The bluetooth call quality report.
+ */
+ private void handleBluetoothCallQualityReport(@NonNull Call call,
+ @NonNull BluetoothCallQualityReport report) {
+ try {
+ if (isConnected()) {
+ mCallDiagnosticService.receiveBluetoothCallQualityReport(report);
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "handleBluetoothCallQualityReport: callId=%s, exception=%s", call.getId(),
+ e);
+ }
+ }
+
+ /**
+ * Informs a CallDiagnosticService of an incoming device to device message which was received
+ * via the carrier network.
+ * @param call the call the message was received via.
+ * @param messageType The message type.
+ * @param messageValue The message value.
+ */
+ private void handleReceivedDeviceToDeviceMessage(@NonNull Call call, int messageType,
+ int messageValue) {
+ try {
+ if (isConnected()) {
+ mCallDiagnosticService.receiveDeviceToDeviceMessage(call.getId(), messageType,
+ messageValue);
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "handleReceivedDeviceToDeviceMessage: callId=%s, exception=%s",
+ call.getId(), e);
+ }
+ }
+
+ /**
+ * Get a parcelled representation of a call for transport to the service.
+ * @param call The call.
+ * @return The parcelled call.
+ */
+ private @NonNull ParcelableCall getParceledCall(@NonNull Call call) {
+ return ParcelableCallUtils.toParcelableCall(
+ call,
+ false /* includeVideoProvider */,
+ null /* phoneAcctRegistrar */,
+ false /* supportsExternalCalls */,
+ false /* includeRttCall */,
+ false /* isForSystemDialer */
+ );
+ }
+
+ /**
+ * Dumps the state of the {@link CallDiagnosticServiceController}.
+ *
+ * @param pw The {@code IndentingPrintWriter} to write the state to.
+ */
+ public void dump(IndentingPrintWriter pw) {
+ pw.print("activeCallDiagnosticService: ");
+ pw.println(getActiveCallDiagnosticService());
+ pw.print("isConnected: ");
+ pw.println(isConnected());
+ }
+}
diff --git a/src/com/android/server/telecom/CallIdMapper.java b/src/com/android/server/telecom/CallIdMapper.java
index 72a51f5..2cd5c79 100644
--- a/src/com/android/server/telecom/CallIdMapper.java
+++ b/src/com/android/server/telecom/CallIdMapper.java
@@ -72,6 +72,10 @@
return mSecondaryMap.get(value);
}
+ public Collection<V> getValues() {
+ return mPrimaryMap.values();
+ }
+
public void clear() {
mPrimaryMap.clear();
mSecondaryMap.clear();
@@ -134,7 +138,7 @@
}
Collection<Call> getCalls() {
- return mCalls.mPrimaryMap.values();
+ return mCalls.getValues();
}
void clear() {
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 7305ab9..7f864b8 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -141,6 +141,23 @@
clientExtras.putString(TelecomManager.EXTRA_CALL_SUBJECT, callsubject);
}
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_PRIORITY)) {
+ clientExtras.putInt(android.telecom.TelecomManager.EXTRA_PRIORITY, intent.getIntExtra(
+ android.telecom.TelecomManager.EXTRA_PRIORITY,
+ android.telecom.TelecomManager.PRIORITY_NORMAL));
+ }
+
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_LOCATION)) {
+ clientExtras.putParcelable(android.telecom.TelecomManager.EXTRA_LOCATION,
+ intent.getParcelableExtra(android.telecom.TelecomManager.EXTRA_LOCATION));
+ }
+
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE)) {
+ clientExtras.putParcelable(android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE,
+ intent.getParcelableExtra(
+ android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE));
+ }
+
final int videoState = intent.getIntExtra( TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
VideoProfile.STATE_AUDIO_ONLY);
clientExtras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 7a5af14..3cec618 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -16,6 +16,7 @@
package com.android.server.telecom;
+import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
import static android.telephony.CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL;
import android.annotation.Nullable;
@@ -84,7 +85,8 @@
int features, PhoneAccountHandle accountHandle, long creationDate,
long durationInMillis, Long dataUsage, UserHandle initiatingUser, boolean isRead,
@Nullable LogCallCompletedListener logCallCompletedListener, int callBlockReason,
- CharSequence callScreeningAppName, String callScreeningComponentName) {
+ CharSequence callScreeningAppName, String callScreeningComponentName,
+ long missedReason) {
this.context = context;
this.callerInfo = callerInfo;
this.number = number;
@@ -103,6 +105,7 @@
this.callBockReason = callBlockReason;
this.callScreeningAppName = callScreeningAppName;
this.callScreeningComponentName = callScreeningComponentName;
+ this.missedReason = missedReason;
}
// Since the members are accessed directly, we don't use the
// mXxxx notation.
@@ -127,6 +130,7 @@
public final int callBockReason;
public final CharSequence callScreeningAppName;
public final String callScreeningComponentName;
+ public final long missedReason;
}
private static final String TAG = CallLogManager.class.getSimpleName();
@@ -353,20 +357,27 @@
call.wasEverRttCall(),
call.wasVolte());
- if (callLogType == Calls.BLOCKED_TYPE) {
+ if (result == null) {
+ result = new CallFilteringResult.Builder()
+ .setCallScreeningAppName(call.getCallScreeningAppName())
+ .setCallScreeningComponentName(call.getCallScreeningComponentName())
+ .build();
+ }
+
+ if (callLogType == Calls.BLOCKED_TYPE || callLogType == Calls.MISSED_TYPE) {
logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
creationTime, age, callDataUsage, call.isEmergencyCall(),
call.getInitiatingUser(), call.isSelfManaged(), logCallCompletedListener,
result.mCallBlockReason, result.mCallScreeningAppName,
- result.mCallScreeningComponentName);
+ result.mCallScreeningComponentName, call.getMissedReason());
} else {
logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
creationTime, age, callDataUsage, call.isEmergencyCall(),
call.getInitiatingUser(), call.isSelfManaged(), logCallCompletedListener,
Calls.BLOCK_REASON_NOT_BLOCKED, null /*callScreeningAppName*/,
- null /*callScreeningComponentName*/);
+ null /*callScreeningComponentName*/, call.getMissedReason());
}
}
@@ -390,6 +401,7 @@
* @param callBlockReason The reason why the call is blocked.
* @param callScreeningAppName The call screening application name which block the call.
* @param callScreeningComponentName The call screening component name which block the call.
+ * @param missedReason The encoded information about reasons for missed call.
*/
private void logCall(
CallerInfo callerInfo,
@@ -409,7 +421,8 @@
@Nullable LogCallCompletedListener logCallCompletedListener,
int callBlockReason,
CharSequence callScreeningAppName,
- String callScreeningComponentName) {
+ String callScreeningComponentName,
+ long missedReason) {
// On some devices, to avoid accidental redialing of emergency numbers, we *never* log
// emergency calls to the Call Log. (This behavior is set on a per-product basis, based
@@ -443,7 +456,7 @@
AddCallArgs args = new AddCallArgs(mContext, callerInfo, number, postDialDigits,
viaNumber, presentation, callType, features, accountHandle, start, duration,
dataUsage, initiatingUser, isRead, logCallCompletedListener, callBlockReason,
- callScreeningAppName, callScreeningComponentName);
+ callScreeningAppName, callScreeningComponentName, missedReason);
logCallAsync(args);
} else {
Log.d(TAG, "Not adding emergency call to call log.");
@@ -596,7 +609,7 @@
c.presentation, c.callType, c.features, c.accountHandle, c.timestamp,
c.durationInSec, c.dataUsage, userToBeInserted == null,
userToBeInserted, c.isRead, c.callBockReason, c.callScreeningAppName,
- c.callScreeningComponentName);
+ c.callScreeningComponentName, c.missedReason);
}
@@ -605,7 +618,8 @@
for (int i = 0; i < result.length; i++) {
Uri uri = result[i];
/*
- Performs a simple sanity check to make sure the call was written in the database.
+ Performs a simple correctness check to make sure the call was written in the
+ database.
Typically there is only one result per call so it is easy to identify which one
failed.
*/
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index d785e47..7742422 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -16,6 +16,7 @@
package com.android.server.telecom;
+import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
import static android.telecom.TelecomManager.ACTION_POST_CALL;
import static android.telecom.TelecomManager.DURATION_LONG;
import static android.telecom.TelecomManager.DURATION_MEDIUM;
@@ -27,6 +28,11 @@
import static android.telecom.TelecomManager.MEDIUM_CALL_TIME_MS;
import static android.telecom.TelecomManager.SHORT_CALL_TIME_MS;
import static android.telecom.TelecomManager.VERY_SHORT_CALL_TIME_MS;
+import static android.provider.CallLog.Calls.AUTO_MISSED_EMERGENCY_CALL;
+import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_DIALING;
+import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_RINGING;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_SCREENING_SERVICE_SILENCED;
import android.Manifest;
import android.annotation.NonNull;
@@ -102,7 +108,6 @@
import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
import com.android.server.telecom.callfiltering.DirectToVoicemailFilter;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.callfiltering.IncomingCallFilterGraph;
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.components.ErrorDialogActivity;
@@ -327,6 +332,7 @@
private final ConnectionServiceRepository mConnectionServiceRepository;
private final DtmfLocalTonePlayer mDtmfLocalTonePlayer;
private final InCallController mInCallController;
+ private final CallDiagnosticServiceController mCallDiagnosticServiceController;
private final CallAudioManager mCallAudioManager;
private final CallRecordingTonePlayer mCallRecordingTonePlayer;
private RespondViaSmsManager mRespondViaSmsManager;
@@ -352,7 +358,6 @@
private final DisconnectedCallNotifier mDisconnectedCallNotifier;
private IncomingCallNotifier mIncomingCallNotifier;
private final CallerInfoLookupHelper mCallerInfoLookupHelper;
- private final IncomingCallFilter.Factory mIncomingCallFilterFactory;
private final DefaultDialerCache mDefaultDialerCache;
private final Timeouts.Adapter mTimeoutsAdapter;
private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
@@ -483,8 +488,8 @@
CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
InCallControllerFactory inCallControllerFactory,
+ CallDiagnosticServiceController callDiagnosticServiceController,
RoleManagerAdapter roleManagerAdapter,
- IncomingCallFilter.Factory incomingCallFilterFactory,
ToastFactory toastFactory) {
mContext = context;
mLock = lock;
@@ -502,7 +507,6 @@
mTimeoutsAdapter = timeoutsAdapter;
mEmergencyCallHelper = emergencyCallHelper;
mCallerInfoLookupHelper = callerInfoLookupHelper;
- mIncomingCallFilterFactory = incomingCallFilterFactory;
mDtmfLocalTonePlayer =
new DtmfLocalTonePlayer(new DtmfLocalTonePlayer.ToneGeneratorProxy());
@@ -541,6 +545,7 @@
mInCallController = inCallControllerFactory.create(context, mLock, this,
systemStateHelper, defaultDialerCache, mTimeoutsAdapter,
emergencyCallHelper);
+ mCallDiagnosticServiceController = callDiagnosticServiceController;
mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer,
ringtoneFactory, systemVibrator,
new Ringer.VibrationEffectProxy(), mInCallController);
@@ -570,6 +575,7 @@
mListeners.add(mCallLogManager);
mListeners.add(mPhoneStateBroadcaster);
mListeners.add(mInCallController);
+ mListeners.add(mCallDiagnosticServiceController);
mListeners.add(mCallAudioManager);
mListeners.add(mCallRecordingTonePlayer);
mListeners.add(missedCallNotifier);
@@ -620,6 +626,10 @@
return mRoleManagerAdapter;
}
+ public CallDiagnosticServiceController getCallDiagnosticServiceController() {
+ return mCallDiagnosticServiceController;
+ }
+
@Override
public void onSuccessfulOutgoingCall(Call call, int callState) {
Log.v(this, "onSuccessfulOutgoingCall, %s", call);
@@ -669,7 +679,7 @@
.setShouldReject(false)
.setShouldAddToCallLog(true)
.setShouldShowNotification(true)
- .build());
+ .build(), false);
incomingCall.setIsUsingCallFiltering(false);
return;
}
@@ -735,12 +745,19 @@
}
@Override
- public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {
+ public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result,
+ boolean timeout) {
// Only set the incoming call as ringing if it isn't already disconnected. It is possible
// that the connection service disconnected the call before it was even added to Telecom, in
// which case it makes no sense to set it back to a ringing state.
+ Log.i(this, "onCallFilteringComplete");
mGraphHandlerThreads.clear();
+ if (timeout) {
+ Log.i(this, "onCallFilteringCompleted: Call filters timeout!");
+ incomingCall.setUserMissed(USER_MISSED_CALL_FILTERS_TIMEOUT);
+ }
+
if (incomingCall.getState() != CallState.DISCONNECTED &&
incomingCall.getState() != CallState.DISCONNECTING) {
setCallState(incomingCall, CallState.RINGING,
@@ -754,22 +771,26 @@
incomingCall.setPostCallPackageName(
getRoleManagerAdapter().getDefaultCallScreeningApp());
+ Log.i(this, "onCallFilteringComplete: allow call.");
if (hasMaximumManagedRingingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
incomingCall.silence();
} else {
Log.i(this, "onCallFilteringCompleted: Call rejected! " +
"Exceeds maximum number of ringing calls.");
- rejectCallAndLog(incomingCall, result);
+ incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_RINGING);
+ autoMissCallAndLog(incomingCall, result);
+ return;
}
} else if (hasMaximumManagedDialingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
incomingCall.silence();
} else {
-
Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
"dialing calls.");
- rejectCallAndLog(incomingCall, result);
+ incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_DIALING);
+ autoMissCallAndLog(incomingCall, result);
+ return;
}
} else if (result.shouldScreenViaAudio) {
Log.i(this, "onCallFilteringCompleted: starting background audio processing");
@@ -778,6 +799,9 @@
} else if (result.shouldSilence) {
Log.i(this, "onCallFilteringCompleted: setting the call to silent ringing state");
incomingCall.setSilentRingingRequested(true);
+ incomingCall.setUserMissed(USER_MISSED_CALL_SCREENING_SERVICE_SILENCED);
+ incomingCall.setCallScreeningAppName(result.mCallScreeningAppName);
+ incomingCall.setCallScreeningComponentName(result.mCallScreeningComponentName);
addCall(incomingCall);
} else {
addCall(incomingCall);
@@ -1221,10 +1245,14 @@
PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
phoneAccountHandle);
if (phoneAccount != null) {
+ Bundle phoneAccountExtras = phoneAccount.getExtras();
call.setIsSelfManaged(phoneAccount.isSelfManaged());
if (call.isSelfManaged()) {
// Self managed calls will always be voip audio mode.
call.setIsVoipAudioMode(true);
+ call.setVisibleToInCallService(phoneAccountExtras != null
+ && phoneAccountExtras.getBoolean(
+ PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true));
} else {
// Incoming call is managed, the active call is self-managed and can't be held.
// We need to set extras on it to indicate whether answering will cause a
@@ -1243,7 +1271,6 @@
}
}
- Bundle phoneAccountExtras = phoneAccount.getExtras();
if (phoneAccountExtras != null
&& phoneAccountExtras.getBoolean(
PhoneAccount.EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE)) {
@@ -1335,12 +1362,19 @@
if (isConference) {
notifyCreateConferenceFailed(phoneAccountHandle, call);
} else {
+ if (hasMaximumManagedRingingCalls(call)) {
+ call.setMissedReason(AUTO_MISSED_MAXIMUM_RINGING);
+ mCallLogManager.logCall(call, Calls.MISSED_TYPE,
+ true /*showNotificationForMissedCall*/, null /*CallFilteringResult*/);
+ }
notifyCreateConnectionFailed(phoneAccountHandle, call);
}
} else if (isInEmergencyCall()) {
// The incoming call is implicitly being rejected so the user does not get any incoming
// call UI during an emergency call. In this case, log the call as missed instead of
// rejected since the user did not explicitly reject.
+ call.setMissedReason(AUTO_MISSED_EMERGENCY_CALL);
+ call.getAnalytics().setMissedReason(call.getMissedReason());
mCallLogManager.logCall(call, Calls.MISSED_TYPE,
true /*showNotificationForMissedCall*/, null /*CallFilteringResult*/);
if (isConference) {
@@ -1451,6 +1485,7 @@
PhoneAccount account =
mPhoneAccountRegistrar.getPhoneAccount(requestedAccountHandle, initiatingUser);
+ Bundle phoneAccountExtra = account != null ? account.getExtras() : null;
boolean isSelfManaged = account != null && account.isSelfManaged();
// Create a call with original handle. The handle may be changed when the call is attached
@@ -1481,6 +1516,9 @@
if (isSelfManaged) {
// Self-managed calls will ALWAYS use voip audio mode.
call.setIsVoipAudioMode(true);
+ call.setVisibleToInCallService(phoneAccountExtra != null
+ && phoneAccountExtra.getBoolean(
+ PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true));
}
call.setInitiatingUser(initiatingUser);
isReusedCall = false;
@@ -1586,6 +1624,17 @@
// call transitioning into the CONNECTING state.
if (isReusedCall) {
return CompletableFuture.completedFuture(finalCall);
+ } else {
+ Call reusableCall = reuseOutgoingCall(handle);
+ if (reusableCall != null) {
+ Log.i(CallsManager.this,
+ "reusable call %s came in later; disconnect it.",
+ reusableCall.getId());
+ mPendingCallsToDisconnect.remove(reusableCall);
+ reusableCall.disconnect();
+ markCallAsDisconnected(reusableCall,
+ new DisconnectCause(DisconnectCause.CANCELED));
+ }
}
// If we can not supportany more active calls, our options are to move a call
@@ -2695,6 +2744,16 @@
updateCanAddCall();
}
+ @Override
+ public void onRemoteRttRequest(Call call, int requestId) {
+ Log.i(this, "onRemoteRttRequest: call %s", call.getId());
+ playRttUpgradeToneForCall(call);
+ }
+
+ public void playRttUpgradeToneForCall(Call call) {
+ mCallAudioManager.playRttUpgradeTone(call);
+ }
+
// Construct the list of possible PhoneAccounts that the outgoing call can use based on the
// active calls in CallsManager. If any of the active calls are on a SIM based PhoneAccount,
// then include only that SIM based PhoneAccount and any non-SIM PhoneAccounts, such as SIP.
@@ -2994,9 +3053,10 @@
*
* @param disconnectCause The disconnect cause, see {@link android.telecom.DisconnectCause}.
*/
- void markCallAsDisconnected(Call call, DisconnectCause disconnectCause) {
- int oldState = call.getState();
- if (call.getState() == CallState.SIMULATED_RINGING
+ @VisibleForTesting
+ public void markCallAsDisconnected(Call call, DisconnectCause disconnectCause) {
+ int oldState = call.getState();
+ if (call.getState() == CallState.SIMULATED_RINGING
&& disconnectCause.getCode() == DisconnectCause.REMOTE) {
// If the remote end hangs up while in SIMULATED_RINGING, the call should
// be marked as missed.
@@ -3042,7 +3102,11 @@
Log.i(this, "Auto-unholding held foreground call (call doesn't support hold)");
foregroundCall.unhold();
}
- }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock));
+ }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock))
+ .exceptionally((throwable) -> {
+ Log.e(TAG, throwable, "Error while executing call removal");
+ return null;
+ });
}
/**
@@ -3437,7 +3501,8 @@
* Reject an incoming call and manually add it to the Call Log.
* @param incomingCall Incoming call that has been rejected
*/
- private void rejectCallAndLog(Call incomingCall, CallFilteringResult result) {
+ private void autoMissCallAndLog(Call incomingCall, CallFilteringResult result) {
+ incomingCall.getAnalytics().setMissedReason(incomingCall.getMissedReason());
if (incomingCall.getConnectionService() != null) {
// Only reject the call if it has not already been destroyed. If a call ends while
// incoming call filtering is taking place, it is possible that the call has already
@@ -3463,7 +3528,7 @@
@VisibleForTesting
public void addCall(Call call) {
Trace.beginSection("addCall");
- Log.v(this, "addCall(%s)", call);
+ Log.i(this, "addCall(%s)", call);
call.addListener(this);
mCalls.add(call);
@@ -3575,27 +3640,21 @@
(newState == CallState.DISCONNECTED)) {
maybeSendPostCallScreenIntent(call);
}
+ int disconnectCode = call.getDisconnectCause().getCode();
+ if ((newState == CallState.ABORTED || newState == CallState.DISCONNECTED)
+ && ((disconnectCode != DisconnectCause.MISSED)
+ && (disconnectCode != DisconnectCause.CANCELED))) {
+ call.setMissedReason(MISSED_REASON_NOT_MISSED);
+ }
+ call.getAnalytics().setMissedReason(call.getMissedReason());
+
maybeShowErrorDialogOnDisconnect(call);
Trace.beginSection("onCallStateChanged");
maybeHandleHandover(call, newState);
+ notifyCallStateChanged(call, oldState, newState);
- // Only broadcast state change for calls that are being tracked.
- if (mCalls.contains(call)) {
- updateCanAddCall();
- updateHasActiveRttCall();
- for (CallsManagerListener listener : mListeners) {
- if (LogUtils.SYSTRACE_DEBUG) {
- Trace.beginSection(listener.getClass().toString() +
- " onCallStateChanged");
- }
- listener.onCallStateChanged(call, oldState, newState);
- if (LogUtils.SYSTRACE_DEBUG) {
- Trace.endSection();
- }
- }
- }
Trace.endSection();
} else {
Log.i(this, "failed in setting the state to new state");
@@ -3603,6 +3662,24 @@
}
}
+ private void notifyCallStateChanged(Call call, int oldState, int newState) {
+ // Only broadcast state change for calls that are being tracked.
+ if (mCalls.contains(call)) {
+ updateCanAddCall();
+ updateHasActiveRttCall();
+ for (CallsManagerListener listener : mListeners) {
+ if (LogUtils.SYSTRACE_DEBUG) {
+ Trace.beginSection(listener.getClass().toString() +
+ " onCallStateChanged");
+ }
+ listener.onCallStateChanged(call, oldState, newState);
+ if (LogUtils.SYSTRACE_DEBUG) {
+ Trace.endSection();
+ }
+ }
+ }
+ }
+
/**
* Identifies call state transitions for a call which trigger handover events.
* - If this call has a handover to it which just started and this call goes active, treat
@@ -3988,7 +4065,7 @@
+ " livecall = " + liveCall);
if (emergencyCall == liveCall) {
- // Not likely, but a good sanity check.
+ // Not likely, but a good correctness check.
return true;
}
@@ -4002,7 +4079,7 @@
return true;
}
if (outgoingCall.getState() == CallState.SELECT_PHONE_ACCOUNT) {
- // Sanity check: if there is an orphaned emergency call in the
+ // Correctness check: if there is an orphaned emergency call in the
// {@link CallState#SELECT_PHONE_ACCOUNT} state, just disconnect it since the user
// has explicitly started a new call.
emergencyCall.getAnalytics().setCallIsAdditional(true);
@@ -4640,6 +4717,13 @@
pw.decreaseIndent();
}
+ if (mCallDiagnosticServiceController != null) {
+ pw.println("mCallDiagnosticServiceController:");
+ pw.increaseIndent();
+ mCallDiagnosticServiceController.dump(pw);
+ pw.decreaseIndent();
+ }
+
if (mDefaultDialerCache != null) {
pw.println("mDefaultDialerCache:");
pw.increaseIndent();
@@ -4696,6 +4780,9 @@
extras.putLong(TelecomManager.EXTRA_CALL_TELECOM_ROUTING_START_TIME_MILLIS,
SystemClock.elapsedRealtime());
+ if (call.visibleToInCallService()) {
+ extras.putBoolean(PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
+ }
call.setIntentExtras(extras);
}
@@ -5340,4 +5427,9 @@
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivityAsUser(intent, mCurrentUserHandle);
}
+
+ @VisibleForTesting
+ public void addToPendingCallsToDisconnect(Call call) {
+ mPendingCallsToDisconnect.add(call);
+ }
}
diff --git a/src/com/android/server/telecom/CarModeTracker.java b/src/com/android/server/telecom/CarModeTracker.java
index 0ec4917..e64ef5d 100644
--- a/src/com/android/server/telecom/CarModeTracker.java
+++ b/src/com/android/server/telecom/CarModeTracker.java
@@ -28,6 +28,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.PriorityQueue;
import java.util.stream.Collectors;
@@ -144,6 +145,28 @@
}
/**
+ * Force-removes a package from the car mode tracking list, no matter at which priority.
+ *
+ * This handles the case where packages are disabled or uninstalled. In those case, remove them
+ * from the tracking list so they don't cause a leak.
+ * @param packageName Package name of the app to force-remove
+ */
+ public void forceExitCarMode(@NonNull String packageName) {
+ Optional<CarModeApp> forcedApp = mCarModeApps.stream()
+ .filter(c -> c.getPackageName().equals(packageName))
+ .findAny();
+ if (forcedApp.isPresent()) {
+ String logString = String.format("forceExitCarMode: packageName=%s, was at priority=%s",
+ packageName, forcedApp.get().getPriority());
+ Log.i(this, logString);
+ mCarModeChangeLog.log(logString);
+ mCarModeApps.removeIf(c -> c.getPackageName().equals(packageName));
+ } else {
+ Log.i(this, "Package %s is not tracked as requesting car mode", packageName);
+ }
+ }
+
+ /**
* Retrieves a list of the apps which are currently in car mode, ordered by priority such that
* the highest priority app is first.
* @return List of apps in car mode.
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 01acdd1..1cb3957 100755
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -91,6 +91,7 @@
mServiceInterface.createConnectionComplete(callId,
Log.getExternalSession());
} catch (RemoteException e) {
+ logOutgoing("createConnectionComplete remote exception=%s", e);
}
}
}
@@ -1206,6 +1207,10 @@
mPendingResponses.put(callId, response);
Bundle extras = call.getIntentExtras();
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
Log.addEvent(call, LogUtils.Events.START_CONFERENCE,
Log.piiHandle(call.getHandle()));
@@ -1568,6 +1573,34 @@
}
}
+ /** @see IConnectionService#onUsingAlternativeUi(String, boolean, Session.Info) */
+ @VisibleForTesting
+ public void onUsingAlternativeUi(Call activeCall, boolean isUsingAlternativeUi) {
+ final String callId = mCallIdMapper.getCallId(activeCall);
+ if (callId != null && isServiceValid("onUsingAlternativeUi")) {
+ try {
+ logOutgoing("onUsingAlternativeUi %s", isUsingAlternativeUi);
+ mServiceInterface.onUsingAlternativeUi(callId, isUsingAlternativeUi,
+ Log.getExternalSession(TELECOM_ABBREVIATION));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see IConnectionService#onTrackedByNonUiService(String, boolean, Session.Info) */
+ @VisibleForTesting
+ public void onTrackedByNonUiService(Call activeCall, boolean isTracked) {
+ final String callId = mCallIdMapper.getCallId(activeCall);
+ if (callId != null && isServiceValid("onTrackedByNonUiService")) {
+ try {
+ logOutgoing("onTrackedByNonUiService %s", isTracked);
+ mServiceInterface.onTrackedByNonUiService(callId, isTracked,
+ Log.getExternalSession(TELECOM_ABBREVIATION));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
/** @see IConnectionService#disconnect(String, Session.Info) */
void disconnect(Call call) {
final String callId = mCallIdMapper.getCallId(call);
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 700dac7..2e67b08 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -403,6 +403,7 @@
// When testing emergency calls, we want the calls to go through to the test connection
// service, not the telephony ConnectionService.
if (mCall.isTestEmergencyCall()) {
+ Log.i(this, "Processing test emergency call -- special rules");
allAccounts = mPhoneAccountRegistrar.filterRestrictedPhoneAccounts(allAccounts);
}
@@ -411,7 +412,7 @@
preferredPAH);
// Next, add all SIM phone accounts which can place emergency calls.
sortSimPhoneAccountsForEmergency(allAccounts, preferredPA);
- // and pick the fist one that can place emergency calls.
+ // and pick the first one that can place emergency calls.
for (PhoneAccount phoneAccount : allAccounts) {
if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
&& phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
@@ -438,7 +439,10 @@
mPhoneAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
mCall.getHandle() == null
? null : mCall.getHandle().getScheme()));
- if (!mAttemptRecords.contains(callAttemptRecord)) {
+ // If the target phone account is null, we'll run into a NPE during the retry
+ // process, so skip it now if it's null.
+ if (callAttemptRecord.targetPhoneAccount != null
+ && !mAttemptRecords.contains(callAttemptRecord)) {
Log.i(this, "Will try Connection Manager account %s for emergency",
callManager);
mAttemptRecords.add(callAttemptRecord);
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 399c28a..14e5bf0 100644
--- a/src/com/android/server/telecom/CreateConnectionTimeout.java
+++ b/src/com/android/server/telecom/CreateConnectionTimeout.java
@@ -69,7 +69,7 @@
}
// Timeout is only supported for SIM call managers that are set by the carrier.
- if (!Objects.equals(connectionManager.getComponentName(),
+ if (connectionManager != null && !Objects.equals(connectionManager.getComponentName(),
mPhoneAccountRegistrar.getSystemSimCallManagerComponent())) {
Log.d(this, "isTimeoutNeededForCall, not a system sim call manager");
return false;
diff --git a/src/com/android/server/telecom/DefaultDialerCache.java b/src/com/android/server/telecom/DefaultDialerCache.java
index c2b78ee..a4a0242 100644
--- a/src/com/android/server/telecom/DefaultDialerCache.java
+++ b/src/com/android/server/telecom/DefaultDialerCache.java
@@ -217,6 +217,12 @@
return mSystemDialerComponentName;
}
+ public ComponentName getDialtactsSystemDialerComponent() {
+ final Resources resources = mContext.getResources();
+ return new ComponentName(getSystemDialerApplication(),
+ resources.getString(R.string.dialer_default_class));
+ }
+
public void observeDefaultDialerApplication(Executor executor, IntConsumer observer) {
mRoleManagerAdapter.observeDefaultDialerApp(executor, observer);
}
@@ -289,4 +295,8 @@
public ContentObserver getContentObserver() {
return mDefaultDialerObserver;
}
+
+ public RoleManagerAdapter getRoleManagerAdapter() {
+ return mRoleManagerAdapter;
+ }
}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 72a4a39..b138eae 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -23,9 +23,12 @@
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.PermissionChecker;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -46,6 +49,7 @@
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
// TODO: Needed for move to system service: import com.android.internal.R;
@@ -61,6 +65,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -108,7 +113,7 @@
public Call mCall;
}
- private class InCallServiceInfo {
+ public static class InCallServiceInfo {
private final ComponentName mComponentName;
private boolean mIsExternalCallsSupported;
private boolean mIsSelfManagedCallsSupported;
@@ -274,7 +279,8 @@
}
if (call != null && call.isSelfManaged() &&
- !mInCallServiceInfo.isSelfManagedCallsSupported()) {
+ (!mInCallServiceInfo.isSelfManagedCallsSupported()
+ || !call.visibleToInCallService())) {
Log.i(this, "Skipping binding to %s - doesn't support self-mgd calls",
mInCallServiceInfo);
mIsConnected = false;
@@ -337,6 +343,7 @@
mInCallServiceInfo.getType(),
mInCallServiceInfo.getDisconnectTime()
- mInCallServiceInfo.getBindingStartTime(), mIsNullBinding);
+ updateCallTracking(mCall, mInCallServiceInfo, false /* isAdd */);
}
InCallController.this.onDisconnected(mInCallServiceInfo);
@@ -452,7 +459,7 @@
@Override
public void disconnect() {
- Log.i(this, "Disconnect forced!");
+ Log.i(this, "Disconnecting from InCallService");
if (mIsProxying) {
mSubConnection.disconnect();
} else {
@@ -729,6 +736,24 @@
}
pw.decreaseIndent();
}
+
+ public void addConnections(List<InCallServiceBindingConnection> newConnections) {
+ // connect() needs to be called with a Call object. Since we're in the middle of any
+ // possible number of calls right now, choose an arbitrary one from the ones that
+ // InCallController is tracking.
+ if (mCallIdMapper.getCalls().isEmpty()) {
+ Log.w(InCallController.this, "No calls tracked while adding new NonUi incall");
+ return;
+ }
+ Call callToConnectWith = mCallIdMapper.getCalls().iterator().next();
+ for (InCallServiceBindingConnection newConnection : newConnections) {
+ newConnection.connect(callToConnectWith);
+ }
+ }
+
+ public List<InCallServiceBindingConnection> getSubConnections() {
+ return mSubConnections;
+ }
}
private final Call.Listener mCallListener = new Call.ListenerBase() {
@@ -855,12 +880,53 @@
}
};
- private final SystemStateListener mSystemStateListener =
- (priority, packageName, isCarMode) -> InCallController.this.handleCarModeChange(
- priority, packageName, isCarMode);
+ private BroadcastReceiver mPackageChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.startSession("ICC.pCR");
+ try {
+ if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) {
+ synchronized (mLock) {
+ String changedPackage = intent.getData().getSchemeSpecificPart();
+ List<InCallServiceBindingConnection> componentsToBind =
+ Arrays.stream(intent.getStringArrayExtra(
+ Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST))
+ .map((className) ->
+ ComponentName.createRelative(changedPackage,
+ className))
+ .filter(mKnownNonUiInCallServices::contains)
+ .flatMap(componentName -> getInCallServiceComponents(
+ componentName,
+ IN_CALL_SERVICE_TYPE_NON_UI).stream())
+ .map(InCallServiceBindingConnection::new)
+ .collect(Collectors.toList());
+
+ if (mNonUIInCallServiceConnections != null) {
+ mNonUIInCallServiceConnections.addConnections(componentsToBind);
+ }
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+ };
+
+ private final SystemStateListener mSystemStateListener = new SystemStateListener() {
+ @Override
+ public void onCarModeChanged(int priority, String packageName, boolean isCarMode) {
+ InCallController.this.handleCarModeChange(priority, packageName, isCarMode);
+ }
+
+ @Override
+ public void onPackageUninstalled(String packageName) {
+ mCarModeTracker.forceExitCarMode(packageName);
+ updateCarModeForConnections();
+ }
+ };
private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
- private static final int IN_CALL_SERVICE_TYPE_DIALER_UI = 1;
+ private static final int IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI = 1;
private static final int IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
private static final int IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
private static final int IN_CALL_SERVICE_TYPE_NON_UI = 4;
@@ -884,6 +950,11 @@
private NonUIInCallServiceConnectionCollection mNonUIInCallServiceConnections;
private final ClockProxy mClockProxy;
+ // A set of known non-UI in call services on the device, including those that are disabled.
+ // We track this so that we can efficiently bind to them when we're notified that a new
+ // component has been enabled.
+ private Set<ComponentName> mKnownNonUiInCallServices = new ArraySet<>();
+
// Future that's in a completed state unless we're in the middle of binding to a service.
// The future will complete with true if binding succeeds, false if it timed out.
private CompletableFuture<Boolean> mBindingFuture = CompletableFuture.completedFuture(true);
@@ -902,10 +973,9 @@
private boolean mIsCallUsingMicrophone = false;
public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager,
- SystemStateHelper systemStateHelper,
- DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
- EmergencyCallHelper emergencyCallHelper, CarModeTracker carModeTracker,
- ClockProxy clockProxy) {
+ SystemStateHelper systemStateHelper, DefaultDialerCache defaultDialerCache,
+ Timeouts.Adapter timeoutsAdapter, EmergencyCallHelper emergencyCallHelper,
+ CarModeTracker carModeTracker, ClockProxy clockProxy) {
mContext = context;
mAppOpsManager = context.getSystemService(AppOpsManager.class);
mLock = lock;
@@ -948,12 +1018,16 @@
continue;
}
- if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && (!call.visibleToInCallService()
+ || !info.isSelfManagedCallsSupported())) {
continue;
}
// Only send the RTT call if it's a UI in-call service
- boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ boolean includeRttCall = false;
+ if (mInCallServiceConnection != null) {
+ includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ }
componentsUpdated.add(info.getComponentName());
IInCallService inCallService = entry.getValue();
@@ -961,9 +1035,11 @@
ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(call,
true /* includeVideoProvider */, mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(), includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1013,7 +1089,8 @@
continue;
}
- if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && !call.visibleToInCallService()
+ && !info.isSelfManagedCallsSupported()) {
continue;
}
@@ -1026,9 +1103,11 @@
ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(call,
true /* includeVideoProvider */, mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(), includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1056,7 +1135,8 @@
false /* supportsExternalCalls */,
android.telecom.Call.STATE_DISCONNECTED /* overrideState */,
false /* includeRttCall */,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI
);
try {
@@ -1268,7 +1348,13 @@
/**
* Unbinds an existing bound connection to the in-call app.
*/
- private void unbindFromServices() {
+ public void unbindFromServices() {
+ try {
+ mContext.unregisterReceiver(mPackageChangedReceiver);
+ } catch (IllegalArgumentException e) {
+ // Ignore this -- we may or may not have registered it, but when we bind, we want to
+ // unregister no matter what.
+ }
if (mInCallServiceConnection != null) {
mInCallServiceConnection.disconnect();
mInCallServiceConnection = null;
@@ -1282,7 +1368,8 @@
/**
* Binds to all the UI-providing InCallService as well as system-implemented non-UI
- * InCallServices. Method-invoker must check {@link #isBoundAndConnectedToServices()} before invoking.
+ * InCallServices. Method-invoker must check {@link #isBoundAndConnectedToServices()}
+ * before invoking.
*
* @param call The newly added call that triggered the binding to the in-call services.
*/
@@ -1319,11 +1406,12 @@
mInCallServiceConnection.chooseInitialInCallService(shouldUseCarModeUI());
- // Actually try binding to the UI InCallService. If the response
+ // Actually try binding to the UI InCallService.
if (mInCallServiceConnection.connect(call) ==
- InCallServiceConnection.CONNECTION_SUCCEEDED) {
+ InCallServiceConnection.CONNECTION_SUCCEEDED || call.isSelfManaged()) {
// Only connect to the non-ui InCallServices if we actually connected to the main UI
- // one.
+ // one, or if the call is self-managed (in which case we'd still want to keep Wear, BT,
+ // etc. informed.
connectToNonUiInCallServices(call);
mBindingFuture = new CompletableFuture<Boolean>().completeOnTimeout(false,
mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
@@ -1334,7 +1422,7 @@
}
}
- private void connectToNonUiInCallServices(Call call) {
+ private void updateNonUiInCallServices() {
List<InCallServiceInfo> nonUIInCallComponents =
getInCallServiceComponents(IN_CALL_SERVICE_TYPE_NON_UI);
List<InCallServiceBindingConnection> nonUIInCalls = new LinkedList<>();
@@ -1344,7 +1432,7 @@
List<String> callCompanionApps = mCallsManager
.getRoleManagerAdapter().getCallCompanionApps();
if (callCompanionApps != null && !callCompanionApps.isEmpty()) {
- for(String pkg : callCompanionApps) {
+ for (String pkg : callCompanionApps) {
InCallServiceInfo info = getInCallServiceComponent(pkg,
IN_CALL_SERVICE_TYPE_COMPANION);
if (info != null) {
@@ -1352,8 +1440,19 @@
}
}
}
- mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
+ mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(
+ nonUIInCalls);
+ }
+
+ private void connectToNonUiInCallServices(Call call) {
+ if (mNonUIInCallServiceConnections == null) {
+ updateNonUiInCallServices();
+ }
mNonUIInCallServiceConnections.connect(call);
+
+ IntentFilter packageChangedFilter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
+ packageChangedFilter.addDataScheme("package");
+ mContext.registerReceiver(mPackageChangedReceiver, packageChangedFilter);
}
private InCallServiceInfo getDefaultDialerComponent() {
@@ -1365,7 +1464,7 @@
InCallServiceInfo defaultDialerComponent =
(systemPackageName != null && systemPackageName.equals(packageName))
? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI)
- : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_DIALER_UI);
+ : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI);
/* TODO: in Android 12 re-enable this an InCallService is required by the dialer role.
if (packageName != null && defaultDialerComponent == null) {
// The in call service of default phone app is disabled, send notification.
@@ -1415,7 +1514,6 @@
private List<InCallServiceInfo> getInCallServiceComponents(String packageName,
ComponentName componentName, int requestedType) {
-
List<InCallServiceInfo> retval = new LinkedList<>();
Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
@@ -1429,7 +1527,7 @@
PackageManager packageManager = mContext.getPackageManager();
for (ResolveInfo entry : packageManager.queryIntentServicesAsUser(
serviceIntent,
- PackageManager.GET_META_DATA,
+ PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS,
mCallsManager.getCurrentUserHandle().getIdentifier())) {
ServiceInfo serviceInfo = entry.serviceInfo;
if (serviceInfo != null) {
@@ -1442,19 +1540,24 @@
int currentType = getInCallServiceType(entry.serviceInfo, packageManager,
packageName);
- if (requestedType == 0 || requestedType == currentType) {
- if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
- // We enforce the rule that self-managed calls are not supported by non-ui
- // InCallServices.
- isSelfManageCallsSupported = false;
- }
- retval.add(new InCallServiceInfo(
- new ComponentName(serviceInfo.packageName, serviceInfo.name),
- isExternalCallsSupported, isSelfManageCallsSupported, requestedType));
+ ComponentName foundComponentName =
+ new ComponentName(serviceInfo.packageName, serviceInfo.name);
+ if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
+ mKnownNonUiInCallServices.add(foundComponentName);
+ }
+
+ boolean isRequestedType;
+ if (requestedType == IN_CALL_SERVICE_TYPE_INVALID) {
+ isRequestedType = true;
+ } else {
+ isRequestedType = requestedType == currentType;
+ }
+ if (serviceInfo.enabled && isRequestedType) {
+ retval.add(new InCallServiceInfo(foundComponentName, isExternalCallsSupported,
+ isSelfManageCallsSupported, requestedType));
}
}
}
-
return retval;
}
@@ -1500,9 +1603,17 @@
p -> packageManager.checkPermission(
Manifest.permission.CONTROL_INCALL_EXPERIENCE,
p) == PackageManager.PERMISSION_GRANTED);
+
+ boolean hasAppOpsPermittedManageOngoingCalls = false;
+ if (isAppOpsPermittedManageOngoingCalls(serviceInfo.applicationInfo.uid,
+ serviceInfo.packageName)) {
+ hasAppOpsPermittedManageOngoingCalls = true;
+ }
+
boolean isCarModeUIService = serviceInfo.metaData != null &&
serviceInfo.metaData.getBoolean(
TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI, false);
+
if (isCarModeUIService && hasControlInCallPermission) {
return IN_CALL_SERVICE_TYPE_CAR_MODE_UI;
}
@@ -1512,12 +1623,13 @@
mDefaultDialerCache.getDefaultDialerApplication(
mCallsManager.getCurrentUserHandle().getIdentifier()));
if (isDefaultDialerPackage && isUIService) {
- return IN_CALL_SERVICE_TYPE_DIALER_UI;
+ return IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
}
// Also allow any in-call service that has the control-experience permission (to ensure
// that it is a system app) and doesn't claim to show any UI.
- if (!isUIService && !isCarModeUIService && hasControlInCallPermission) {
+ if (!isUIService && !isCarModeUIService && (hasControlInCallPermission ||
+ hasAppOpsPermittedManageOngoingCalls)) {
return IN_CALL_SERVICE_TYPE_NON_UI;
}
@@ -1550,7 +1662,7 @@
if (info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
|| info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
- || info.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
+ || info.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
trackCallingUserInterfaceStarted(info);
}
IInCallService inCallService = IInCallService.Stub.asInterface(service);
@@ -1576,13 +1688,17 @@
int numCallsSent = 0;
for (Call call : calls) {
try {
- if ((call.isSelfManaged() && !info.isSelfManagedCallsSupported()) ||
+ if ((call.isSelfManaged() && (!info.isSelfManagedCallsSupported()
+ || !call.visibleToInCallService())) ||
(call.isExternalCall() && !info.isExternalCallsSupported())) {
continue;
}
// Only send the RTT call if it's a UI in-call service
- boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ boolean includeRttCall = false;
+ if (mInCallServiceConnection != null) {
+ includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ }
// Track the call if we don't already know about it.
addCall(call);
@@ -1593,8 +1709,10 @@
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1621,7 +1739,7 @@
Log.i(this, "onDisconnected from %s", disconnectedInfo.getComponentName());
if (disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
|| disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
- || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
+ || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
trackCallingUserInterfaceStopped(disconnectedInfo);
}
mInCallServices.remove(disconnectedInfo);
@@ -1655,7 +1773,8 @@
continue;
}
- if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && (!call.visibleToInCallService()
+ || !info.isSelfManagedCallsSupported())) {
continue;
}
@@ -1665,7 +1784,8 @@
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
rttInfoChanged && info.equals(mInCallServiceConnection.getInfo()),
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
ComponentName componentName = info.getComponentName();
IInCallService inCallService = entry.getValue();
componentsUpdated.add(componentName);
@@ -1735,7 +1855,7 @@
*/
private ComponentName getConnectedUi() {
InCallServiceInfo connectedUi = mInCallServices.keySet().stream().filter(
- i -> i.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI
+ i -> i.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI
|| i.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI)
.findAny()
.orElse(null);
@@ -1757,7 +1877,7 @@
if (TextUtils.isEmpty(ringingPackage)) {
// The current in-call UI returned nothing, so lets use the default dialer.
- ringingPackage = mDefaultDialerCache.getDefaultDialerApplication(
+ ringingPackage = mDefaultDialerCache.getRoleManagerAdapter().getDefaultDialerApp(
mCallsManager.getCurrentUserHandle().getIdentifier());
if (ringingPackage != null) {
Log.d(this, "doesConnectedDialerSupportRinging: notCurentlyConnectedPackage=%s",
@@ -1840,7 +1960,8 @@
public void handleCarModeChange(int priority, String packageName, boolean isCarMode) {
Log.i(this, "handleCarModeChange: packageName=%s, priority=%d, isCarMode=%b",
packageName, priority, isCarMode);
- if (!isCarModeInCallService(packageName)) {
+ // Don't ignore the signal if we are disabling car mode; package may be uninstalled.
+ if (isCarMode && !isCarModeInCallService(packageName)) {
Log.i(this, "handleCarModeChange: not a valid InCallService; packageName=%s",
packageName);
return;
@@ -1852,9 +1973,13 @@
mCarModeTracker.handleExitCarMode(priority, packageName);
}
+ updateCarModeForConnections();
+ }
+
+ public void updateCarModeForConnections() {
+ Log.i(this, "updateCarModeForConnections: car mode apps: %s",
+ mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
if (mInCallServiceConnection != null) {
- Log.i(this, "handleCarModeChange: car mode apps: %s",
- mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
if (shouldUseCarModeUI()) {
mInCallServiceConnection.changeCarModeApp(
mCarModeTracker.getCurrentCarModePackage());
@@ -1927,6 +2052,12 @@
return mCallsManager.getAudioState().isMuted();
}
+ private boolean isAppOpsPermittedManageOngoingCalls(int uid, String callingPackage) {
+ return PermissionChecker.checkPermissionForPreflight(mContext,
+ Manifest.permission.MANAGE_ONGOING_CALLS, PermissionChecker.PID_UNKNOWN, uid,
+ callingPackage) == PermissionChecker.PERMISSION_GRANTED;
+ }
+
private void sendCrashedInCallServiceNotification(String packageName) {
PackageManager packageManager = mContext.getPackageManager();
CharSequence appName;
@@ -1958,4 +2089,11 @@
notificationManager.notify(NOTIFICATION_TAG, IN_CALL_SERVICE_NOTIFICATION_ID,
builder.build());
}
+
+ private void updateCallTracking(Call call, InCallServiceInfo info, boolean isAdd) {
+ int type = info.getType();
+ boolean hasUi = type == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
+ || type == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
+ call.maybeOnInCallServiceTrackingChanged(isAdd, hasUi);
+ }
}
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
index 4f0cf8d..7500436 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -162,6 +162,8 @@
public static final int TONE_UNOBTAINABLE_NUMBER = 12;
public static final int TONE_VOICE_PRIVACY = 13;
public static final int TONE_VIDEO_UPGRADE = 14;
+ public static final int TONE_RTT_REQUEST = 15;
+ public static final int TONE_IN_CALL_QUALITY_NOTIFICATION = 16;
private static final int TONE_RESOURCE_ID_UNDEFINED = -1;
@@ -329,12 +331,22 @@
// TODO: fill in.
throw new IllegalStateException("Voice privacy tone NYI.");
case TONE_VIDEO_UPGRADE:
+ case TONE_RTT_REQUEST:
// Similar to the call waiting tone, but does not repeat.
toneType = ToneGenerator.TONE_SUP_CALL_WAITING;
toneVolume = RELATIVE_VOLUME_HIPRI;
toneLengthMillis = 4000;
mediaResourceId = TONE_RESOURCE_ID_UNDEFINED;
break;
+ case TONE_IN_CALL_QUALITY_NOTIFICATION:
+ // Don't use tone generator
+ toneType = ToneGenerator.TONE_UNKNOWN;
+ toneVolume = RELATIVE_VOLUME_UNDEFINED;
+ toneLengthMillis = 0;
+
+ // Use a tone resource file for a more rich, full-bodied tone experience.
+ mediaResourceId = R.raw.InCallQualityNotification;
+ break;
default:
throw new IllegalStateException("Bad toneId: " + mToneId);
}
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index 5bb14e6..a9bf18c 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -101,6 +101,8 @@
public static final String SET_DISCONNECTED = "SET_DISCONNECTED";
public static final String SET_DISCONNECTING = "SET_DISCONNECTING";
public static final String SET_SELECT_PHONE_ACCOUNT = "SET_SELECT_PHONE_ACCOUNT";
+ public static final String SET_AUDIO_PROCESSING = "SET_AUDIO_PROCESSING";
+ public static final String SET_SIMULATED_RINGING = "SET_SIMULATED_RINGING";
public static final String REQUEST_HOLD = "REQUEST_HOLD";
public static final String REQUEST_UNHOLD = "REQUEST_UNHOLD";
public static final String REQUEST_DISCONNECT = "REQUEST_DISCONNECT";
@@ -194,6 +196,7 @@
public static final String REDIRECTION_USER_CONFIRMATION = "REDIRECTION_USER_CONFIRMATION";
public static final String REDIRECTION_USER_CONFIRMED = "REDIRECTION_USER_CONFIRMED";
public static final String REDIRECTION_USER_CANCELLED = "REDIRECTION_USER_CANCELLED";
+ public static final String BT_QUALITY_REPORT = "BT_QUALITY_REPORT";
public static class Timings {
public static final String ACCEPT_TIMING = "accept";
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index f0efe92..86fedd5 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -21,7 +21,6 @@
import android.app.Activity;
import android.app.BroadcastOptions;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -495,9 +494,7 @@
private void launchSystemDialer(Uri handle) {
Intent systemDialerIntent = new Intent();
- systemDialerIntent.setComponent(
- new ComponentName(mDefaultDialerCache.getSystemDialerApplication(),
- mContext.getResources().getString(R.string.dialer_default_class)));
+ systemDialerIntent.setComponent(mDefaultDialerCache.getDialtactsSystemDialerComponent());
systemDialerIntent.setAction(Intent.ACTION_DIAL);
systemDialerIntent.setData(handle);
systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index 5c821a4..a5291e7 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -42,9 +42,9 @@
/**
* A list of extra keys which should be removed from a {@link ParcelableCall} when it is being
- * generated for the purpose of sending to a dialer other than the system dialer.
+ * generated for the purpose of sending to a incallservice other than the system incallservice.
* By convention we only pass keys namespaced with android.*, however there are some keys which
- * should not be passed to non-system dialer apps either.
+ * should not be passed to non-system incallservice apps either.
*/
private static List<String> EXTRA_KEYS_TO_SANITIZE;
static {
@@ -90,9 +90,9 @@
* {@link InCallService} which supports external calls or not.
* @param includeRttCall {@code true} if the RTT call should be included, {@code false}
* otherwise.
- * @param isForSystemDialer {@code true} if this call is being parcelled for the system dialer,
- * {@code false} otherwise. When parceling for the system dialer, the entire call extras
- * is included. When parceling for anything other than the system dialer, some extra key
+ * @param isForSystemInCallService {@code true} if this call is being parcelled for the system incallservice,
+ * {@code false} otherwise. When parceling for the system incallservice, the entire call extras
+ * is included. When parceling for anything other than the system incallservice, some extra key
* values will be stripped for privacy sake.
*/
public static ParcelableCall toParcelableCall(
@@ -101,10 +101,10 @@
PhoneAccountRegistrar phoneAccountRegistrar,
boolean supportsExternalCalls,
boolean includeRttCall,
- boolean isForSystemDialer) {
+ boolean isForSystemInCallService) {
return toParcelableCall(call, includeVideoProvider, phoneAccountRegistrar,
supportsExternalCalls, CALL_STATE_OVERRIDE_NONE /* overrideState */,
- includeRttCall, isForSystemDialer);
+ includeRttCall, isForSystemInCallService);
}
/**
@@ -120,9 +120,9 @@
* {@link InCallService} which supports external calls or not.
* @param overrideState When not {@link #CALL_STATE_OVERRIDE_NONE}, use the provided state as an
* override to whatever is defined in the call.
- * @param isForSystemDialer {@code true} if this call is being parcelled for the system dialer,
- * {@code false} otherwise. When parceling for the system dialer, the entire call extras
- * is included. When parceling for anything other than the system dialer, some extra key
+ * @param isForSystemInCallService {@code true} if this call is being parcelled for the system incallservice,
+ * {@code false} otherwise. When parceling for the system incallservice, the entire call extras
+ * is included. When parceling for anything other than the system incallservice, some extra key
* values will be stripped for privacy sake.
* @return The {@link ParcelableCall} containing all call information from the {@link Call}.
*/
@@ -133,7 +133,7 @@
boolean supportsExternalCalls,
int overrideState,
boolean includeRttCall,
- boolean isForSystemDialer) {
+ boolean isForSystemInCallService) {
int state;
if (overrideState == CALL_STATE_OVERRIDE_NONE) {
state = getParcelableState(call, supportsExternalCalls);
@@ -216,7 +216,7 @@
}
Bundle extras;
- if (isForSystemDialer) {
+ if (isForSystemInCallService) {
extras = call.getExtras();
} else {
extras = sanitizeExtras(call.getExtras());
@@ -269,9 +269,9 @@
* <li>Caller number verification status (verstat)</li>
* </ul>
* All other fields are nulled or set to 0 values.
- * Where the call screening service is part of the system dialer, the
+ * Where the call screening service is part of the system incallservice, the
* {@link Connection#EXTRA_SIP_INVITE} header information is also sent to the call screening
- * service (since the system dialer has access to this anyways).
+ * service (since the system incallservice has access to this anyways).
* @param call The telecom call to send to a call screening service.
* @param areRestrictedExtrasIncluded {@code true} if the set of restricted extras defined in
* {@link #RESTRICTED_CALL_SCREENING_EXTRA_KEYS} are to
@@ -333,7 +333,7 @@
/**
* Sanitize the extras bundle passed in, removing keys which should not be sent to non-system
- * dialer apps.
+ * incallservice apps.
* @param oldExtras Extras bundle to sanitize.
* @return The sanitized extras bundle.
*/
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index ef2840a..9a4f7df 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -485,6 +486,7 @@
* target phone account.
* @return phone account handle of sim call manager based on the ongoing call.
*/
+ @Nullable
public PhoneAccountHandle getSimCallManagerFromCall(Call call) {
if (call == null) {
return null;
@@ -1264,11 +1266,11 @@
// Comparator which places PhoneAccounts with a specified sort order first, followed by
// those with no sort order.
Comparator<PhoneAccount> bySortOrder = (p1, p2) -> {
- String sort1 = p1.getExtras() == null ? null :
- p1.getExtras().getString(PhoneAccount.EXTRA_SORT_ORDER, null);
- String sort2 = p2.getExtras() == null ? null :
- p2.getExtras().getString(PhoneAccount.EXTRA_SORT_ORDER, null);
- return nullSafeStringComparator.compare(sort1, sort2);
+ int sort1 = p1.getExtras() == null ? Integer.MAX_VALUE:
+ p1.getExtras().getInt(PhoneAccount.EXTRA_SORT_ORDER, Integer.MAX_VALUE);
+ int sort2 = p2.getExtras() == null ? Integer.MAX_VALUE:
+ p2.getExtras().getInt(PhoneAccount.EXTRA_SORT_ORDER, Integer.MAX_VALUE);
+ return Integer.compare(sort1, sort2);
};
// Comparator which sorts PhoneAccounts by label.
@@ -1597,10 +1599,16 @@
return BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
}
+ @Nullable
protected Icon readIcon(XmlPullParser parser) throws IOException {
- byte[] iconByteArray = Base64.decode(parser.getText(), 0);
- ByteArrayInputStream stream = new ByteArrayInputStream(iconByteArray);
- return Icon.createFromStream(stream);
+ try {
+ byte[] iconByteArray = Base64.decode(parser.getText(), 0);
+ ByteArrayInputStream stream = new ByteArrayInputStream(iconByteArray);
+ return Icon.createFromStream(stream);
+ } catch (IllegalArgumentException e) {
+ Log.e(this, e, "Bitmap must not be null.");
+ return null;
+ }
}
}
diff --git a/src/com/android/server/telecom/PhoneStateBroadcaster.java b/src/com/android/server/telecom/PhoneStateBroadcaster.java
index f2531ed..f02f7e8 100644
--- a/src/com/android/server/telecom/PhoneStateBroadcaster.java
+++ b/src/com/android/server/telecom/PhoneStateBroadcaster.java
@@ -17,8 +17,16 @@
package com.android.server.telecom;
import android.telecom.Log;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyRegistryManager;
+import android.telephony.emergency.EmergencyNumber;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
/**
* Send a {@link TelephonyManager#ACTION_PHONE_STATE_CHANGED} broadcast when the call state
@@ -52,6 +60,10 @@
return;
}
updateStates(call);
+
+ if (call.isEmergencyCall() && !call.isIncoming()) {
+ sendOutgoingEmergencyCallEvent(call);
+ }
}
@Override
@@ -113,4 +125,31 @@
Log.i(this, "Broadcasted state change: %s", mCurrentState);
}
}
+
+ private void sendOutgoingEmergencyCallEvent(Call call) {
+ TelephonyManager tm = mCallsManager.getContext().getSystemService(TelephonyManager.class);
+ String strippedNumber =
+ PhoneNumberUtils.stripSeparators(call.getHandle().getSchemeSpecificPart());
+ Optional<EmergencyNumber> emergencyNumber = tm.getEmergencyNumberList().values().stream()
+ .flatMap(List::stream)
+ .filter(numberObj -> Objects.equals(numberObj.getNumber(), strippedNumber))
+ .findFirst();
+
+ int subscriptionId = tm.getSubscriptionId(call.getTargetPhoneAccount());
+ SubscriptionManager subscriptionManager =
+ mCallsManager.getContext().getSystemService(SubscriptionManager.class);
+ int simSlotIndex = SubscriptionManager.DEFAULT_PHONE_INDEX;
+ if (subscriptionManager != null) {
+ SubscriptionInfo subInfo =
+ subscriptionManager.getActiveSubscriptionInfo(subscriptionId);
+ if (subInfo != null) {
+ simSlotIndex = subInfo.getSimSlotIndex();
+ }
+ }
+
+ if (emergencyNumber.isPresent()) {
+ mRegistry.notifyOutgoingEmergencyCall(
+ simSlotIndex, subscriptionId, emergencyNumber.get());
+ }
+ }
}
diff --git a/src/com/android/server/telecom/RoleManagerAdapterImpl.java b/src/com/android/server/telecom/RoleManagerAdapterImpl.java
index eb216d0..4a98d7b 100644
--- a/src/com/android/server/telecom/RoleManagerAdapterImpl.java
+++ b/src/com/android/server/telecom/RoleManagerAdapterImpl.java
@@ -85,8 +85,11 @@
@Override
public void observeDefaultDialerApp(Executor executor, IntConsumer observer) {
- mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) ->
- observer.accept(user.getIdentifier()), UserHandle.ALL);
+ mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) -> {
+ if (ROLE_DIALER.equals(roleName)) {
+ observer.accept(user.getIdentifier());
+ }
+ }, UserHandle.ALL);
}
@Override
diff --git a/src/com/android/server/telecom/SystemStateHelper.java b/src/com/android/server/telecom/SystemStateHelper.java
index 073b081..3be3d5e 100644
--- a/src/com/android/server/telecom/SystemStateHelper.java
+++ b/src/com/android/server/telecom/SystemStateHelper.java
@@ -26,6 +26,7 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.net.Uri;
import android.telecom.Log;
import java.util.Set;
@@ -38,7 +39,7 @@
* Provides various system states to the rest of the telecom codebase.
*/
public class SystemStateHelper {
- public static interface SystemStateListener {
+ public interface SystemStateListener {
/**
* Listener method to inform interested parties when a package name requests to enter or
* exit car mode.
@@ -48,6 +49,12 @@
* otherwise.
*/
void onCarModeChanged(int priority, String packageName, boolean isCarMode);
+
+ /**
+ * Notifies when a package has been uninstalled.
+ * @param packageName the package name of the uninstalled package
+ */
+ void onPackageUninstalled(String packageName);
}
private final Context mContext;
@@ -62,7 +69,7 @@
UiModeManager.DEFAULT_PRIORITY);
String callingPackage = intent.getStringExtra(
UiModeManager.EXTRA_CALLING_PACKAGE);
- Log.i(SystemStateHelper.this, "ENTER_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
+ Log.i(SystemStateHelper.this, "ENTER_CAR_MODE_PRIORITIZED; priority=%d, pkg=%s",
priority, callingPackage);
onEnterCarMode(priority, callingPackage);
} else if (UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED.equals(action)) {
@@ -70,11 +77,21 @@
UiModeManager.DEFAULT_PRIORITY);
String callingPackage = intent.getStringExtra(
UiModeManager.EXTRA_CALLING_PACKAGE);
- Log.i(SystemStateHelper.this, "EXIT_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
+ Log.i(SystemStateHelper.this, "EXIT_CAR_MODE_PRIORITIZED; priority=%d, pkg=%s",
priority, callingPackage);
onExitCarMode(priority, callingPackage);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ Uri data = intent.getData();
+ if (data == null) {
+ Log.w(SystemStateHelper.this,
+ "Got null data for package removed, ignoring");
+ return;
+ }
+ mListeners.forEach(
+ l -> l.onPackageUninstalled(data.getEncodedSchemeSpecificPart()));
} else {
- Log.w(this, "Unexpected intent received: %s", intent.getAction());
+ Log.w(SystemStateHelper.this,
+ "Unexpected intent received: %s", intent.getAction());
}
} finally {
Log.endSession();
@@ -88,11 +105,16 @@
public SystemStateHelper(Context context) {
mContext = context;
- IntentFilter intentFilter = new IntentFilter(
+ IntentFilter intentFilter1 = new IntentFilter(
UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
- intentFilter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter);
- Log.i(this, "Registering car mode receiver: %s", intentFilter);
+ intentFilter1.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+
+ IntentFilter intentFilter2 = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter2.addDataScheme("package");
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter1);
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter2);
+ Log.i(this, "Registering broadcast receiver: %s", intentFilter1);
+ Log.i(this, "Registering broadcast receiver: %s", intentFilter2);
mIsCarMode = getSystemCarMode();
}
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 9ccae9a..69ffd26 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -34,6 +34,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -727,7 +728,7 @@
public ComponentName getDefaultPhoneApp() {
try {
Log.startSession("TSI.gDPA");
- return mDefaultDialerCache.getSystemDialerComponent();
+ return mDefaultDialerCache.getDialtactsSystemDialerComponent();
} finally {
Log.endSession();
}
@@ -831,6 +832,22 @@
}
/**
+ * @see android.telecom.TelecomManager#hasManageOngoingCallsPermission
+ */
+ @Override
+ public boolean hasManageOngoingCallsPermission(String callingPackage) {
+ try {
+ Log.startSession("TSI.hMOCP");
+ return PermissionChecker.checkPermissionForPreflight(mContext,
+ Manifest.permission.MANAGE_ONGOING_CALLS,
+ PermissionChecker.PID_UNKNOWN, Binder.getCallingUid(),
+ callingPackage) == PermissionChecker.PERMISSION_GRANTED;
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ /**
* @see android.telecom.TelecomManager#isInManagedCall
*/
@Override
@@ -1754,6 +1771,33 @@
}
}
+ /**
+ * A method intended for use in testing to clean up any calls that get stuck in the
+ * {@link CallState#DISCONNECTED} or {@link CallState#DISCONNECTING} states. Stuck calls
+ * during CTS cause cascading failures, so if the CTS test detects such a state, it should
+ * call this method via a shell command to clean up before moving on to the next test.
+ */
+ @Override
+ public void cleanupStuckCalls() {
+ Log.startSession("TCI.cSC");
+ try {
+ synchronized (mLock) {
+ enforceShellOnly(Binder.getCallingUid(), "cleanupStuckCalls");
+ Binder.withCleanCallingIdentity(() -> {
+ for (Call call : mCallsManager.getCalls()) {
+ if (call.getState() == CallState.DISCONNECTED
+ || call.getState() == CallState.DISCONNECTING) {
+ mCallsManager.markCallAsRemoved(call);
+ }
+ }
+ mCallsManager.getInCallController().unbindFromServices();
+ });
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
@Override
public void setTestDefaultCallRedirectionApp(String packageName) {
try {
@@ -1856,6 +1900,30 @@
Log.endSession();
}
}
+
+ @Override
+ public void setTestCallDiagnosticService(String packageName) {
+ try {
+ Log.startSession("TSI.sTCDS");
+ enforceModifyPermission();
+ enforceShellOnly(Binder.getCallingUid(), "setTestCallDiagnosticService is for "
+ + "shell use only.");
+ synchronized (mLock) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ CallDiagnosticServiceController controller =
+ mCallsManager.getCallDiagnosticServiceController();
+ if (controller != null) {
+ controller.setTestCallDiagnosticService(packageName);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
};
/**
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 08389b9..5f6b62a 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -20,14 +20,12 @@
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.DisconnectedCallNotifier;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
-import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
import com.android.server.telecom.ui.ToastFactory;
@@ -38,8 +36,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
@@ -47,8 +47,11 @@
import android.telecom.PhoneAccountHandle;
import android.widget.Toast;
+import androidx.annotation.NonNull;
+
import java.io.FileNotFoundException;
import java.io.InputStream;
+import java.util.List;
/**
* Top-level Application class for Telecom.
@@ -116,7 +119,6 @@
private final CallsManager mCallsManager;
private final RespondViaSmsManager mRespondViaSmsManager;
private final Context mContext;
- private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
private final CallIntentProcessor mCallIntentProcessor;
private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
private final TelecomServiceImpl mTelecomServiceImpl;
@@ -193,8 +195,6 @@
ProximitySensorManagerFactory proximitySensorManagerFactory,
InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
AudioServiceFactory audioServiceFactory,
- BluetoothPhoneServiceImplFactory
- bluetoothPhoneServiceImplFactory,
ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
connectionServiceFocusManagerFactory,
Timeouts.Adapter timeoutsAdapter,
@@ -206,7 +206,6 @@
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
ClockProxy clockProxy,
RoleManagerAdapter roleManagerAdapter,
- IncomingCallFilter.Factory incomingCallFilterFactory,
ContactsAsyncHelper.Factory contactsAsyncHelperFactory,
DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
mContext = context.getApplicationContext();
@@ -266,6 +265,39 @@
}
};
+ CallDiagnosticServiceController callDiagnosticServiceController =
+ new CallDiagnosticServiceController(
+ new CallDiagnosticServiceController.ContextProxy() {
+ @Override
+ public List<ResolveInfo> queryIntentServicesAsUser(
+ @NonNull Intent intent, int flags, int userId) {
+ return mContext.getPackageManager().queryIntentServicesAsUser(
+ intent, flags, userId);
+ }
+
+ @Override
+ public boolean bindServiceAsUser(@NonNull Intent service,
+ @NonNull ServiceConnection conn, int flags,
+ @NonNull UserHandle user) {
+ return mContext.bindServiceAsUser(service, conn, flags, user);
+ }
+
+ @Override
+ public void unbindService(@NonNull ServiceConnection conn) {
+ mContext.unbindService(conn);
+ }
+
+ @Override
+ public UserHandle getCurrentUserHandle() {
+ return mCallsManager.getCurrentUserHandle();
+ }
+ },
+ mContext.getResources().getString(
+ com.android.server.telecom.R.string
+ .call_diagnostic_service_package_name),
+ mLock
+ );
+
AudioProcessingNotification audioProcessingNotification =
new AudioProcessingNotification(mContext);
@@ -309,8 +341,8 @@
callAudioRouteStateMachineFactory,
callAudioModeStateMachineFactory,
inCallControllerFactory,
+ callDiagnosticServiceController,
roleManagerAdapter,
- incomingCallFilterFactory,
toastFactory);
mIncomingCallNotifier = incomingCallNotifier;
@@ -353,8 +385,6 @@
mCallsManager.onUserSwitch(currentUserHandle);
}
- mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
- mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
mContext, mCallsManager);
@@ -392,10 +422,6 @@
return mCallsManager;
}
- public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
- return mBluetoothPhoneServiceImpl;
- }
-
public CallIntentProcessor getCallIntentProcessor() {
return mCallIntentProcessor;
}
diff --git a/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java b/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
index 052ce57..1043774 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
@@ -18,5 +18,5 @@
import com.android.server.telecom.Call;
public interface CallFilterResultCallback {
- void onCallFilteringComplete(Call call, CallFilteringResult result);
+ void onCallFilteringComplete(Call call, CallFilteringResult result, boolean timeout);
}
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
deleted file mode 100644
index 860de1f..0000000
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.telecom.callfiltering;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.telecom.Log;
-import android.telecom.Logging.Runnable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.telecom.Call;
-import com.android.server.telecom.LogUtils;
-import com.android.server.telecom.TelecomSystem;
-import com.android.server.telecom.Timeouts;
-import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
-
-import java.util.List;
-
-public class IncomingCallFilter implements CallFilterResultCallback {
-
- public static class Factory {
- public IncomingCallFilter create(Context context, CallFilterResultCallback listener,
- Call call, TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<CallFilter> filters) {
- return new IncomingCallFilter(context, listener, call, lock, timeoutsAdapter, filters,
- new Handler(Looper.getMainLooper()));
- }
- }
-
- public interface CallFilter {
- void startFilterLookup(Call call, CallFilterResultCallback listener);
- }
-
- private final TelecomSystem.SyncRoot mTelecomLock;
- private final Context mContext;
- private final Handler mHandler;
- private final List<CallFilter> mFilters;
- private final Call mCall;
- private final CallFilterResultCallback mListener;
- private final Timeouts.Adapter mTimeoutsAdapter;
-
- private CallFilteringResult mResult = new Builder()
- .setShouldAllowCall(true)
- .setShouldReject(false)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .build();
-
- private boolean mIsPending = true;
- private int mNumPendingFilters;
-
- public IncomingCallFilter(Context context, CallFilterResultCallback listener, Call call,
- TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<CallFilter> filters, Handler handler) {
- mContext = context;
- mListener = listener;
- mCall = call;
- mTelecomLock = lock;
- mFilters = filters;
- mNumPendingFilters = filters.size();
- mTimeoutsAdapter = timeoutsAdapter;
- mHandler = handler;
- }
-
- public void performFiltering() {
- Log.addEvent(mCall, LogUtils.Events.FILTERING_INITIATED);
- for (CallFilter filter : mFilters) {
- filter.startFilterLookup(mCall, this);
- }
- // synchronized to prevent a race on mResult and to enter into Telecom.
- mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { // performFiltering time-out
- @Override
- public void loggedRun() {
- if (mIsPending) {
- Log.i(IncomingCallFilter.this, "Call filtering has timed out.");
- Log.addEvent(mCall, LogUtils.Events.FILTERING_TIMED_OUT);
- mListener.onCallFilteringComplete(mCall, mResult);
- mIsPending = false;
- }
- }
- }.prepare(), mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));
- }
-
- public void onCallFilteringComplete(Call call, CallFilteringResult result) {
- synchronized (mTelecomLock) { // synchronizing to prevent race on mResult
- mNumPendingFilters--;
- mResult = result.combine(mResult);
- if (mNumPendingFilters == 0) {
- // synchronized on mTelecomLock to enter into Telecom.
- mHandler.post(new Runnable("ICF.oCFC", mTelecomLock) {
- @Override
- public void loggedRun() {
- if (mIsPending) {
- Log.addEvent(mCall, LogUtils.Events.FILTERING_COMPLETED, mResult);
- mListener.onCallFilteringComplete(mCall, mResult);
- mIsPending = false;
- }
- }
- }.prepare());
- }
- }
- }
-
- /**
- * Returns the handler, for testing purposes.
- */
- @VisibleForTesting
- public Handler getHandler() {
- return mHandler;
- }
-}
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
index 1543270..e3c68c9 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
@@ -73,7 +73,7 @@
if (mFilter.equals(mDummyComplete)) {
synchronized (mLock) {
mFinished = true;
- mListener.onCallFilteringComplete(mCall, result);
+ mListener.onCallFilteringComplete(mCall, result, false);
Log.addEvent(mCall, LogUtils.Events.FILTERING_COMPLETED, result);
}
mHandlerThread.quit();
@@ -122,7 +122,7 @@
if (!mFinished) {
Log.i(this, "Graph timed out when performing filtering.");
Log.addEvent(mCall, LogUtils.Events.FILTERING_TIMED_OUT);
- mListener.onCallFilteringComplete(mCall, mCurrentResult);
+ mListener.onCallFilteringComplete(mCall, mCurrentResult, true);
mFinished = true;
mHandlerThread.quit();
}
diff --git a/src/com/android/server/telecom/components/BluetoothPhoneService.java b/src/com/android/server/telecom/components/BluetoothPhoneService.java
deleted file mode 100644
index c5e195c..0000000
--- a/src/com/android/server/telecom/components/BluetoothPhoneService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom.components;
-
-import com.android.server.telecom.TelecomSystem;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Bluetooth headset manager for Telecom. This class shares the call state with the bluetooth device
- * and accepts call-related commands to perform on behalf of the BT device.
- */
-public final class BluetoothPhoneService extends Service implements TelecomSystem.Component {
-
- @Override
- public IBinder onBind(Intent intent) {
- synchronized (getTelecomSystem().getLock()) {
- return getTelecomSystem().getBluetoothPhoneServiceImpl().getBinder();
- }
- }
-
- @Override
- public TelecomSystem getTelecomSystem() {
- return TelecomSystem.getInstance();
- }
-}
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index b6705f4..9ad0da4 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -18,7 +18,6 @@
import android.app.Service;
import android.app.role.RoleManager;
-import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.media.IAudioService;
@@ -35,8 +34,6 @@
import com.android.internal.telecom.ITelecomLoader;
import com.android.internal.telecom.ITelecomService;
import com.android.server.telecom.AsyncRingtonePlayer;
-import com.android.server.telecom.BluetoothAdapterProxy;
-import com.android.server.telecom.BluetoothPhoneServiceImpl;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
import com.android.server.telecom.CallerInfoAsyncQueryFactory;
@@ -60,7 +57,6 @@
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.TelecomWakeLock;
import com.android.server.telecom.Timeouts;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl;
import com.android.server.telecom.ui.NotificationChannelManager;
@@ -173,17 +169,6 @@
ServiceManager.getService(Context.AUDIO_SERVICE));
}
},
- new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() {
- @Override
- public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(
- Context context, TelecomSystem.SyncRoot lock,
- CallsManager callsManager,
- PhoneAccountRegistrar phoneAccountRegistrar) {
- return new BluetoothPhoneServiceImpl(context, lock,
- callsManager, new BluetoothAdapterProxy(),
- phoneAccountRegistrar);
- }
- },
ConnectionServiceFocusManager::new,
new Timeouts.Adapter(),
new AsyncRingtonePlayer(),
@@ -205,13 +190,9 @@
},
new RoleManagerAdapterImpl(context,
(RoleManager) context.getSystemService(Context.ROLE_SERVICE)),
- new IncomingCallFilter.Factory(),
new ContactsAsyncHelper.Factory(),
internalServiceRetriever.getDeviceIdleController()));
}
- if (BluetoothAdapter.getDefaultAdapter() != null) {
- context.startService(new Intent(context, BluetoothPhoneService.class));
- }
}
@Override
diff --git a/src/com/android/server/telecom/settings/BlockedNumbersActivity.java b/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
index 3549db5..1fe7c5f 100644
--- a/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
+++ b/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
@@ -38,6 +38,7 @@
import android.provider.ContactsContract;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
@@ -285,7 +286,7 @@
* Add blocked number if it does not exist.
*/
private void addBlockedNumber(String number) {
- if (PhoneNumberUtils.isEmergencyNumber(number)) {
+ if (isEmergencyNumber(this, number)) {
Toast.makeText(
this,
getString(R.string.blocked_numbers_block_emergency_number_message),
@@ -298,6 +299,16 @@
}
}
+ private boolean isEmergencyNumber(Context context, String number) {
+ try {
+ TelephonyManager tm = (TelephonyManager) context.getSystemService(
+ Context.TELEPHONY_SERVICE);
+ return tm.isEmergencyNumber(number);
+ } catch (IllegalStateException ise) {
+ return false;
+ }
+ }
+
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// no-op
diff --git a/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java b/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java
index 3f54689..66f9fe4 100644
--- a/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java
+++ b/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java
@@ -333,7 +333,8 @@
UserHandle userHandle) {
Intent intent = new Intent(action, data, mContext, TelecomBroadcastReceiver.class);
intent.putExtra(TelecomBroadcastIntentProcessor.EXTRA_USERHANDLE, userHandle);
- return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ return PendingIntent.getBroadcast(mContext, 0, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
private boolean canRespondViaSms(@NonNull CallInfo call) {
@@ -354,7 +355,7 @@
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(mContext);
taskStackBuilder.addNextIntent(intent);
- return taskStackBuilder.getPendingIntent(0, 0, null, userHandle);
+ return taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_IMMUTABLE, null, userHandle);
}
/**
diff --git a/src/com/android/server/telecom/ui/IncomingCallNotifier.java b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
index 6e203aa..edea89b 100644
--- a/src/com/android/server/telecom/ui/IncomingCallNotifier.java
+++ b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
@@ -41,6 +41,7 @@
import com.android.server.telecom.TelecomBroadcastIntentProcessor;
import com.android.server.telecom.components.TelecomBroadcastReceiver;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -68,7 +69,7 @@
public static final int NOTIFICATION_INCOMING_CALL = 1;
@VisibleForTesting
public static final String NOTIFICATION_TAG = IncomingCallNotifier.class.getSimpleName();
-
+ private final Object mLock = new Object();
public final Call.ListenerBase mCallListener = new Call.ListenerBase() {
@Override
@@ -104,8 +105,10 @@
@Override
public void onCallAdded(Call call) {
- if (!mCalls.contains(call)) {
- mCalls.add(call);
+ synchronized (mLock) {
+ if (!mCalls.contains(call)) {
+ mCalls.add(call);
+ }
}
updateIncomingCall();
@@ -113,10 +116,11 @@
@Override
public void onCallRemoved(Call call) {
- if (mCalls.contains(call)) {
- mCalls.remove(call);
+ synchronized (mLock) {
+ if (mCalls.contains(call)) {
+ mCalls.remove(call);
+ }
}
-
updateIncomingCall();
}
@@ -130,11 +134,16 @@
* UI.
*/
private void updateIncomingCall() {
- Optional<Call> incomingCallOp = mCalls.stream()
- .filter(call -> call.isSelfManaged() && call.isIncoming() &&
- call.getState() == CallState.RINGING &&
- call.getHandoverState() == HandoverState.HANDOVER_NONE)
- .findFirst();
+ Optional<Call> incomingCallOp;
+ synchronized (mLock) {
+ incomingCallOp = mCalls.stream()
+ .filter(Objects::nonNull)
+ .filter(call -> call.isSelfManaged() && call.isIncoming() &&
+ call.getState() == CallState.RINGING &&
+ call.getHandoverState() == HandoverState.HANDOVER_NONE)
+ .findFirst();
+ }
+
Call incomingCall = incomingCallOp.orElse(null);
if (incomingCall != null && mCallsManagerProxy != null &&
!mCallsManagerProxy.hasUnholdableCallsForOtherConnectionService(
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index e37fe6b..4e32c9f 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -559,7 +559,8 @@
UserHandle userHandle) {
Intent intent = new Intent(action, data, mContext, TelecomBroadcastReceiver.class);
intent.putExtra(TelecomBroadcastIntentProcessor.EXTRA_USERHANDLE, userHandle);
- return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ return PendingIntent.getBroadcast(mContext, 0, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
/**
diff --git a/testapps/Android.bp b/testapps/Android.bp
index 26347fe..11ea474 100644
--- a/testapps/Android.bp
+++ b/testapps/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
android_test {
name: "TelecomTestApps",
static_libs: [
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index 4238191..dd8258a 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -15,40 +15,48 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- coreApp="true"
- package="com.android.server.telecom.testapps">
+ coreApp="true"
+ package="com.android.server.telecom.testapps">
- <uses-sdk
- android:minSdkVersion="28"
- android:targetSdkVersion="30" />
+ <uses-sdk android:minSdkVersion="28"
+ android:targetSdkVersion="30"/>
- <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.CAMERA" />
- <uses-permission android:name="android.permission.CALL_PHONE" />
- <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
- <uses-permission android:name="android.permission.READ_CALL_LOG" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
- <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" />
- <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
- <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
+ <uses-permission android:name="android.permission.ACCEPT_HANDOVER"/>
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.CAMERA"/>
+ <uses-permission android:name="android.permission.CALL_PHONE"/>
+ <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
+ <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER"/>
+ <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"/>
+ <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<application android:label="@string/app_name">
- <uses-library android:name="android.test.runner" />
+ <uses-library android:name="android.test.runner"/>
<!-- Miscellaneous telecom app-related test activities. -->
-
- <service android:name="com.android.server.telecom.testapps.TestConnectionService"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+ <service android:name="com.android.server.telecom.testapps.TestCallDiagnosticService"
+ android:permission="android.permission.BIND_CALL_DIAGNOSTIC_SERVICE"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ConnectionService" />
+ <action android:name="android.telecom.CallDiagnosticService"/>
</intent-filter>
</service>
- <receiver android:name=".TestConnectionServiceReceiver">
+ <service android:name="com.android.server.telecom.testapps.TestConnectionService"
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telecom.ConnectionService"/>
+ </intent-filter>
+ </service>
+
+ <receiver android:name=".TestConnectionServiceReceiver"
+ android:exported="true">
<intent-filter>
<action android:name="android.server.telecom.testapps.ACTION_SWITCH_PHONE_ACCOUNT"/>
<action android:name="android.server.telecom.testapps.ACTION_SWITCH_PHONE_ACCOUNT_WRONG"/>
@@ -56,23 +64,29 @@
</receiver>
<service android:name="com.android.server.telecom.testapps.TestConnectionManager"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ConnectionService" />
+ <action android:name="android.telecom.ConnectionService"/>
</intent-filter>
</service>
<service android:name="com.android.server.telecom.testapps.TestInCallServiceImpl"
- android:process="com.android.server.telecom.testapps.TestInCallService"
- android:permission="android.permission.BIND_INCALL_SERVICE" >
- <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true"/>
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:permission="android.permission.BIND_INCALL_SERVICE"
+ android:exported="true">
+ <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI"
+ android:value="true"/>
+ <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+ android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
<receiver android:name="com.android.server.telecom.testapps.TestInCallServiceBroadcastReceiver"
- android:process="com.android.server.telecom.testapps.TestInCallService" >
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:exported="true">
<intent-filter>
<action android:name="android.server.telecom.testapps.ACTION_SEND_UPDATE_REQUEST_FROM_TEST_INCALL_SERVICE"/>
<action android:name="android.server.telecom.testapps.ACTION_SEND_UPGRADE_RESPONSE"/>
@@ -84,201 +98,212 @@
<activity android:name="com.android.server.telecom.testapps.TestInCallUI"
- android:process="com.android.server.telecom.testapps.TestInCallService"
- android:label="@string/inCallUiAppLabel"
- android:launchMode="singleInstance">
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/inCallUiAppLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestRttActivity"
- android:process="com.android.server.telecom.testapps.TestInCallService"
- android:label="@string/rttUiLabel"
- android:launchMode="singleInstance">
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/rttUiLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestCallActivity"
- android:theme="@android:style/Theme.NoDisplay"
- android:label="@string/testCallActivityLabel">
+ android:theme="@android:style/Theme.NoDisplay"
+ android:label="@string/testCallActivityLabel"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_START_INCOMING_CALL" />
- <action android:name="android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
- <data android:scheme="sip" />
+ <action android:name="android.telecom.testapps.ACTION_START_INCOMING_CALL"/>
+ <action android:name="android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_HANGUP_CALLS" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.testapps.ACTION_HANGUP_CALLS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_SEND_UPGRADE_REQUEST" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="int" />
+ <action android:name="android.telecom.testapps.ACTION_SEND_UPGRADE_REQUEST"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="int"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_RTT_CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.telecom.testapps.ACTION_RTT_CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_REMOTE_RTT_UPGRADE" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.testapps.ACTION_REMOTE_RTT_UPGRADE"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<receiver android:name="com.android.server.telecom.testapps.CallNotificationReceiver"
- android:exported="false">
+ android:exported="false">
<intent-filter>
- <action android:name="com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT" />
+ <action android:name="com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT"/>
</intent-filter>
</receiver>
<activity android:name="com.android.server.telecom.testapps.TestDialerActivity"
- android:label="@string/testDialerActivityLabel"
- android:process="com.android.server.telecom.testapps.TestInCallService">
+ android:label="@string/testDialerActivityLabel"
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.VIEW"/>
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestUssdActivity"
- android:label="@string/UssdUiAppLabel"
- android:launchMode="singleInstance">
+ android:label="@string/UssdUiAppLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestCertActivity"
- android:label="@string/KeyUiAppLabel"
- android:launchMode="singleInstance">
+ android:label="@string/KeyUiAppLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.SelfManagedCallingActivity"
- android:label="@string/selfManagedCallingActivityLabel"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
- android:theme="@android:style/Theme.Material.Light">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:theme="@android:style/Theme.Material.Light"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.IncomingSelfManagedCallActivity"
- android:label="@string/selfManagedCallingActivityLabel"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.HandoverActivity"
- android:label="@string/selfManagedCallingActivityLabel"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<service android:name="com.android.server.telecom.testapps.SelfManagedConnectionService"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ConnectionService" />
+ <action android:name="android.telecom.ConnectionService"/>
</intent-filter>
</service>
<receiver android:exported="false"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
- android:name="com.android.server.telecom.testapps.SelfManagedCallNotificationReceiver" />
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:name="com.android.server.telecom.testapps.SelfManagedCallNotificationReceiver"/>
<receiver android:exported="true"
- android:name="com.android.server.telecom.testapps.NuisanceReportReceiver">
+ android:name="com.android.server.telecom.testapps.NuisanceReportReceiver">
<intent-filter>
- <action android:name="android.telecom.action.NUISANCE_CALL_STATUS_CHANGED" />
+ <action android:name="android.telecom.action.NUISANCE_CALL_STATUS_CHANGED"/>
</intent-filter>
</receiver>
- <service
- android:name=".TestCallScreeningService"
- android:permission="android.permission.BIND_SCREENING_SERVICE">
+ <service android:name=".TestCallScreeningService"
+ android:permission="android.permission.BIND_SCREENING_SERVICE"
+ android:exported="true">
<intent-filter>
<action android:name="android.telecom.CallScreeningService"/>
</intent-filter>
</service>
<activity android:name=".CallScreeningActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance">
</activity>
- <service
- android:name=".TestCallRedirectionService"
- android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
+ <service android:name=".TestCallRedirectionService"
+ android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE"
+ android:exported="true">
<intent-filter>
<action android:name="android.telecom.CallRedirectionService"/>
</intent-filter>
</service>
<activity android:name=".CallRedirectionActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance">
</activity>
<activity android:name=".PostCallActivity"
- android:label="@string/postCallActivityLabel">
+ android:label="@string/postCallActivityLabel"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.action.POST_CALL" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.action.POST_CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
diff --git a/testapps/carmodedialer/Android.bp b/testapps/carmodedialer/Android.bp
index 7179b1f..9f65b8c 100644
--- a/testapps/carmodedialer/Android.bp
+++ b/testapps/carmodedialer/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
android_test {
name: "TelecomCarModeApp",
static_libs: [
diff --git a/testapps/carmodedialer/AndroidManifest.xml b/testapps/carmodedialer/AndroidManifest.xml
index 7f55f7e..239726c 100644
--- a/testapps/carmodedialer/AndroidManifest.xml
+++ b/testapps/carmodedialer/AndroidManifest.xml
@@ -15,75 +15,79 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- coreApp="true"
- package="com.android.server.telecom.carmodedialer">
+ coreApp="true"
+ package="com.android.server.telecom.carmodedialer">
- <uses-sdk
- android:minSdkVersion="28"
- android:targetSdkVersion="29" />
+ <uses-sdk android:minSdkVersion="28"
+ android:targetSdkVersion="29"/>
- <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.CALL_PHONE" />
- <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
- <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.READ_CALL_LOG" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
+ <uses-permission android:name="android.permission.ACCEPT_HANDOVER"/>
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.CALL_PHONE"/>
+ <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+ <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<application android:label="Telecom CarMode">
- <uses-library android:name="android.test.runner" />
+ <uses-library android:name="android.test.runner"/>
<service android:name="com.android.server.telecom.carmodedialer.CarModeInCallServiceImpl"
- android:permission="android.permission.BIND_INCALL_SERVICE" >
- <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
- android:value="true"/>
+ android:permission="android.permission.BIND_INCALL_SERVICE"
+ android:exported="true">
+ <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
+ android:value="true"/>
+ <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+ android:value="true"/>
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
<activity android:name="com.android.server.telecom.carmodedialer.CarModeInCallUI"
- android:label="CarMode Dialer"
- android:launchMode="singleInstance">
+ android:label="CarMode Dialer"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.carmodedialer.CarModeDialerActivity"
- android:label="CarMode Dialer">
+ android:label="CarMode Dialer"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.VIEW"/>
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
diff --git a/testapps/res/layout/self_managed_sample_main.xml b/testapps/res/layout/self_managed_sample_main.xml
index 28f4473..d26d629 100644
--- a/testapps/res/layout/self_managed_sample_main.xml
+++ b/testapps/res/layout/self_managed_sample_main.xml
@@ -90,7 +90,6 @@
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
-
<Button
android:id="@+id/placeOutgoingCallButton"
android:layout_width="wrap_content"
@@ -113,6 +112,35 @@
android:text="Req CallScreen Role"/>
</LinearLayout>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button
+ android:id="@+id/placeSelfManagedOutgoingCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SelfManagedOutgoing"/>
+ <Button
+ android:id="@+id/placeSelfManagedIncomingCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SelfManagedIncoming"/>
+ </LinearLayout>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button
+ android:id="@+id/enableCarMode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Enable car mode"/>
+ <Button
+ android:id="@+id/disableCarMode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Disable car mode"/>
+ </LinearLayout>
<ListView
android:id="@+id/callList"
android:layout_width="match_parent"
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
index 4b5fa57..d4661ff 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
@@ -46,8 +46,10 @@
public static String SELF_MANAGED_ACCOUNT_1 = "1";
public static String SELF_MANAGED_ACCOUNT_2 = "2";
+ public static String SELF_MANAGED_ACCOUNT_3 = "3";
public static String SELF_MANAGED_NAME_1 = "SuperCall";
public static String SELF_MANAGED_NAME_2 = "Mega Call";
+ public static String SELF_MANAGED_NAME_3 = "SM Call";
public static String CUSTOM_URI_SCHEME = "custom";
private static SelfManagedCallList sInstance;
@@ -99,6 +101,8 @@
SELF_MANAGED_NAME_1, true /* areCallsLogged */);
registerPhoneAccount(context, SELF_MANAGED_ACCOUNT_2, SELF_MANAGED_ADDRESS_2,
SELF_MANAGED_NAME_2, false /* areCallsLogged */);
+ registerPhoneAccount(context, SELF_MANAGED_ACCOUNT_3, SELF_MANAGED_ADDRESS_1,
+ SELF_MANAGED_NAME_3, true /* areCallsLogged */);
}
public void registerPhoneAccount(Context context, String id, Uri address, String name,
@@ -110,6 +114,9 @@
if (areCallsLogged) {
extras.putBoolean(PhoneAccount.EXTRA_LOG_SELF_MANAGED_CALLS, true);
}
+ if (id.equals(SELF_MANAGED_ACCOUNT_3)) {
+ extras.putBoolean(PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
+ }
PhoneAccount.Builder builder = PhoneAccount.builder(handle, name)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
index fd12a2e..44410d2 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
@@ -16,9 +16,12 @@
package com.android.server.telecom.testapps;
+import static android.app.UiModeManager.DEFAULT_PRIORITY;
+
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
+import android.app.UiModeManager;
import android.app.role.RoleManager;
import android.content.Intent;
import android.media.AudioAttributes;
@@ -54,9 +57,13 @@
private SelfManagedCallList mCallList = SelfManagedCallList.getInstance();
private CheckBox mCheckIfPermittedBeforeCalling;
private Button mPlaceOutgoingCallButton;
+ private Button mPlaceSelfManagedOutgoingCallButton;
+ private Button mPlaceSelfManagedIncomingCallButton;
private Button mPlaceIncomingCallButton;
private Button mHandoverFrom;
private Button mRequestCallScreeningRole;
+ private Button mEnableCarMode;
+ private Button mDisableCarMode;
private RadioButton mUseAcct1Button;
private RadioButton mUseAcct2Button;
private CheckBox mHoldableCheckbox;
@@ -119,6 +126,20 @@
placeOutgoingCall();
}
});
+ mPlaceSelfManagedOutgoingCallButton = (Button) findViewById(
+ R.id.placeSelfManagedOutgoingCallButton);
+ mPlaceSelfManagedOutgoingCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ placeSelfManagedOutgoingCall();
+ }
+ });
+ mPlaceSelfManagedIncomingCallButton = (Button) findViewById(
+ R.id.placeSelfManagedIncomingCallButton);
+ mPlaceSelfManagedIncomingCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) { placeSelfManagedIncomingCall(); }
+ });
mPlaceIncomingCallButton = (Button) findViewById(R.id.placeIncomingCallButton);
mPlaceIncomingCallButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -134,7 +155,14 @@
mRequestCallScreeningRole.setOnClickListener((v -> {
requestCallScreeningRole();
}));
-
+ mEnableCarMode = (Button) findViewById(R.id.enableCarMode);
+ mEnableCarMode.setOnClickListener((v -> {
+ enableCarMode();
+ }));
+ mDisableCarMode = (Button) findViewById(R.id.disableCarMode);
+ mDisableCarMode.setOnClickListener((v -> {
+ disableCarMode();
+ }));
mUseAcct1Button = findViewById(R.id.useAcct1Button);
mUseAcct2Button = findViewById(R.id.useAcct2Button);
mHasFocus = findViewById(R.id.hasFocus);
@@ -184,6 +212,25 @@
tm.placeCall(Uri.parse(mNumber.getText().toString()), extras);
}
+ private void placeSelfManagedOutgoingCall() {
+ TelecomManager tm = TelecomManager.from(this);
+ PhoneAccountHandle phoneAccountHandle = mCallList.getPhoneAccountHandle(
+ SelfManagedCallList.SELF_MANAGED_ACCOUNT_3);
+
+ if (mCheckIfPermittedBeforeCalling.isChecked()) {
+ Toast.makeText(this, R.string.outgoingCallNotPermitted, Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+ if (mVideoCallCheckbox.isChecked()) {
+ extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
+ VideoProfile.STATE_BIDIRECTIONAL);
+ }
+ tm.placeCall(Uri.parse(mNumber.getText().toString()), extras);
+ }
+
private void initiateHandover() {
TelecomManager tm = TelecomManager.from(this);
PhoneAccountHandle phoneAccountHandle = getSelectedPhoneAccountHandle();
@@ -214,6 +261,37 @@
tm.addNewIncomingCall(getSelectedPhoneAccountHandle(), extras);
}
+ private void placeSelfManagedIncomingCall() {
+ TelecomManager tm = TelecomManager.from(this);
+ PhoneAccountHandle phoneAccountHandle = mCallList.getPhoneAccountHandle(
+ SelfManagedCallList.SELF_MANAGED_ACCOUNT_3);
+
+ if (mCheckIfPermittedBeforeCalling.isChecked()) {
+ if (!tm.isIncomingCallPermitted(phoneAccountHandle)) {
+ Toast.makeText(this, R.string.incomingCallNotPermitted , Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
+ Uri.parse(mNumber.getText().toString()));
+ tm.addNewIncomingCall(phoneAccountHandle, extras);
+ }
+
+ private void enableCarMode() {
+ UiModeManager uiModeManager = getSystemService(UiModeManager.class);
+ uiModeManager.enableCarMode(0);
+ Toast.makeText(this, "Enabling car mode with priority " + DEFAULT_PRIORITY,
+ Toast.LENGTH_LONG).show();
+ }
+
+ private void disableCarMode() {
+ UiModeManager uiModeManager = getSystemService(UiModeManager.class);
+ uiModeManager.disableCarMode(0);
+ Toast.makeText(this, "Disabling car mode", Toast.LENGTH_LONG).show();
+ }
+
private void configureNotificationChannel() {
NotificationChannel channel = new NotificationChannel(
SelfManagedConnection.INCOMING_CALL_CHANNEL_ID, "Incoming Calls",
diff --git a/testapps/src/com/android/server/telecom/testapps/TestCallDiagnosticService.java b/testapps/src/com/android/server/telecom/testapps/TestCallDiagnosticService.java
new file mode 100644
index 0000000..73bf438
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestCallDiagnosticService.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom.testapps;
+
+import android.telecom.BluetoothCallQualityReport;
+import android.telecom.Call;
+import android.telecom.CallAudioState;
+import android.telecom.CallDiagnosticService;
+import android.telecom.DiagnosticCall;
+import android.telecom.Log;
+import android.telephony.CallQuality;
+import android.telephony.ims.ImsReasonInfo;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+public class TestCallDiagnosticService extends CallDiagnosticService {
+
+ public static final class TestDiagnosticCall extends DiagnosticCall {
+ public Call.Details details;
+
+ TestDiagnosticCall(Call.Details details) {
+ this.details = details;
+ }
+
+ @Override
+ public void onCallDetailsChanged(@NonNull Call.Details details) {
+ Log.i(this, "onCallDetailsChanged; %s", details);
+ }
+
+ @Override
+ public void onReceiveDeviceToDeviceMessage(int message, int value) {
+ Log.i(this, "onReceiveDeviceToDeviceMessage; %d/%d", message, value);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence onCallDisconnected(int disconnectCause, int preciseDisconnectCause) {
+ Log.i(this, "onCallDisconnected");
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public CharSequence onCallDisconnected(@NonNull ImsReasonInfo disconnectReason) {
+ Log.i(this, "onCallDisconnected");
+ return null;
+ }
+
+ @Override
+ public void onCallQualityReceived(@NonNull CallQuality callQuality) {
+ Log.i(this, "onCallQualityReceived %s", callQuality);
+ }
+ }
+
+ @NonNull
+ @Override
+ public DiagnosticCall onInitializeDiagnosticCall(@NonNull Call.Details call) {
+ Log.i(this, "onInitiatlizeDiagnosticCall %s", call);
+ return new TestDiagnosticCall(call);
+ }
+
+ @Override
+ public void onRemoveDiagnosticCall(@NonNull DiagnosticCall call) {
+ Log.i(this, "onRemoveDiagnosticCall %s", call);
+ }
+
+ @Override
+ public void onCallAudioStateChanged(@NonNull CallAudioState audioState) {
+ Log.i(this, "onCallAudioStateChanged %s", audioState);
+ }
+
+ @Override
+ public void onBluetoothCallQualityReportReceived(
+ @NonNull BluetoothCallQualityReport qualityReport) {
+ Log.i(this, "onBluetoothCallQualityReportReceived %s", qualityReport);
+ }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
index abb9108..5c78d52 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
@@ -37,7 +37,6 @@
/**
* Service which acts as a fake ConnectionManager if so configured.
- * TODO(santoscordon): Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
*/
public class TestConnectionManager extends ConnectionService {
public final class TestManagedConnection extends Connection {
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
index f6fa116..3d1bc70 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -53,7 +53,6 @@
/**
* Service which provides fake calls to test the ConnectionService interface.
- * TODO: Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
*/
public class TestConnectionService extends ConnectionService {
/**
@@ -430,9 +429,9 @@
int videoState = extras.getInt(EXTRA_START_VIDEO_STATE, VideoProfile.STATE_AUDIO_ONLY);
Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
- // Use dummy number for testing incoming calls.
+ // Use test number for testing incoming calls.
Uri address = providedHandle == null ?
- Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getRandomNumber(
VideoProfile.isVideo(videoState)), null)
: providedHandle;
connection.setVideoState(videoState);
@@ -480,7 +479,7 @@
final Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
Uri handle = providedHandle == null ?
- Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(false), null)
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getRandomNumber(false), null)
: providedHandle;
connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
@@ -613,7 +612,7 @@
* @param isVideo {@code True} if the call is a video call.
* @return The phone number.
*/
- private String getDummyNumber(boolean isVideo) {
+ private String getRandomNumber(boolean isVideo) {
int videoDigit = isVideo ? 1 : 0;
int number = mRandom.nextInt(999);
return String.format("555%s%03d", videoDigit, number);
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 3fb2a84..02b35a4 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -27,4 +27,10 @@
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
+ <object type="module_controller"
+ class="com.android.tradefed.testtype.suite.module.TestFailureModuleController">
+ <option name="screenshot-on-failure" value="false" />
+ <option name="bugreportz-on-failure" value="false" />
+ <option name="logcat-on-failure" value="true" />
+ </object>
</configuration>
diff --git a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
index ec5f7ba..a64f39d 100644
--- a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
+++ b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
@@ -16,6 +16,8 @@
package com.android.server.telecom.tests;
+import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -127,7 +129,8 @@
Analytics.dump(ip);
String dumpResult = sr.toString();
String[] expectedFields = {"startTime", "endTime", "direction", "isAdditionalCall",
- "isInterrupted", "callTechnologies", "callTerminationReason", "connectionService"};
+ "isInterrupted", "callTechnologies", "callTerminationReason", "connectionService",
+ "missedReason"};
for (String field : expectedFields) {
assertTrue(dumpResult.contains(field));
}
@@ -200,6 +203,8 @@
assertTrue(callAnalytics2.startTime > 0);
assertEquals(0, callAnalytics1.endTime);
assertEquals(0, callAnalytics2.endTime);
+ assertEquals(MISSED_REASON_NOT_MISSED, callAnalytics1.missedReason);
+ assertEquals(MISSED_REASON_NOT_MISSED, callAnalytics2.missedReason);
assertEquals(Analytics.INCOMING_DIRECTION, callAnalytics1.callDirection);
assertEquals(Analytics.OUTGOING_DIRECTION, callAnalytics2.callDirection);
diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
index 6fd53eb..a8e1c00 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -163,6 +163,9 @@
.getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
telecomManager.acceptRingingCall();
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
.answer(eq(ids.mConnectionId), any());
mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
@@ -219,6 +222,9 @@
.getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY);
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
// The generic answer method on the ConnectionService is used to answer audio-only calls.
verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
.answer(eq(ids.mConnectionId), any());
@@ -248,6 +254,9 @@
.getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
telecomManager.acceptRingingCall(999 /* invalid videostate */);
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
// Answer video API should be called
verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
.answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any());
@@ -626,6 +635,10 @@
mConnectionServiceFixtureA.
sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE);
+ waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
+ .getCallAudioModeStateMachine().getHandler(), TEST_TIMEOUT);
+ waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
+ .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT);
verify(audioManager, timeout(TEST_TIMEOUT))
.abandonAudioFocusForCall();
verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce())
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
deleted file mode 100644
index 532cc7e..0000000
--- a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
+++ /dev/null
@@ -1,1136 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.telecom.tests;
-
-import android.bluetooth.BluetoothAdapter;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
-import android.net.Uri;
-import android.os.Binder;
-import android.telecom.Connection;
-import android.telecom.GatewayInfo;
-import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.server.telecom.BluetoothAdapterProxy;
-import com.android.server.telecom.BluetoothHeadsetProxy;
-import com.android.server.telecom.BluetoothPhoneServiceImpl;
-import com.android.server.telecom.Call;
-import com.android.server.telecom.CallState;
-import com.android.server.telecom.CallsManager;
-import com.android.server.telecom.PhoneAccountRegistrar;
-import com.android.server.telecom.TelecomSystem;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyChar;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
-
-@RunWith(JUnit4.class)
-public class BluetoothPhoneServiceTest extends TelecomTestCase {
-
- private static final int TEST_DTMF_TONE = 0;
- private static final String TEST_ACCOUNT_ADDRESS = "//foo.com/";
- private static final int TEST_ACCOUNT_INDEX = 0;
-
- // match up with BluetoothPhoneServiceImpl
- private static final int CALL_STATE_ACTIVE = 0;
- private static final int CALL_STATE_HELD = 1;
- private static final int CALL_STATE_DIALING = 2;
- private static final int CALL_STATE_ALERTING = 3;
- private static final int CALL_STATE_INCOMING = 4;
- private static final int CALL_STATE_WAITING = 5;
- private static final int CALL_STATE_IDLE = 6;
- private static final int CALL_STATE_DISCONNECTED = 7;
- // Terminate all held or set UDUB("busy") to a waiting call
- private static final int CHLD_TYPE_RELEASEHELD = 0;
- // Terminate all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
- // Hold all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
- // Add all held calls to a conference
- private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
-
- private BluetoothPhoneServiceImpl mBluetoothPhoneService;
- private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {
- };
-
- @Mock CallsManager mMockCallsManager;
- @Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
- @Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- MockitoAnnotations.initMocks(this);
- mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
-
- // Ensure initialization does not actually try to access any of the CallsManager fields.
- // This also works to return null if it is not overwritten later in the test.
- doNothing().when(mMockCallsManager).addListener(any(
- CallsManager.CallsManagerListener.class));
- doReturn(null).when(mMockCallsManager).getActiveCall();
- doReturn(null).when(mMockCallsManager).getRingingOrSimulatedRingingCall();
- doReturn(null).when(mMockCallsManager).getHeldCall();
- doReturn(null).when(mMockCallsManager).getOutgoingCall();
- doReturn(0).when(mMockCallsManager).getNumHeldCalls();
- doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls();
- mBluetoothPhoneService = new BluetoothPhoneServiceImpl(mContext, mLock, mMockCallsManager,
- mock(BluetoothAdapterProxy.class), mMockPhoneAccountRegistrar);
-
- // Bring in test Bluetooth Headset
- mBluetoothPhoneService.setBluetoothHeadset(mMockBluetoothHeadset);
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
-
- mBluetoothPhoneService = null;
- super.tearDown();
- }
-
- @SmallTest
- @Test
- public void testHeadsetAnswerCall() throws Exception {
- Call mockCall = createRingingCall();
-
- boolean callAnswered = mBluetoothPhoneService.mBinder.answerCall();
-
- verify(mMockCallsManager).answerCall(eq(mockCall), any(int.class));
- assertEquals(callAnswered, true);
- }
-
- @SmallTest
- @Test
- public void testHeadsetAnswerCallNull() throws Exception {
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(null);
-
- boolean callAnswered = mBluetoothPhoneService.mBinder.answerCall();
-
- verify(mMockCallsManager,never()).answerCall(any(Call.class), any(int.class));
- assertEquals(callAnswered, false);
- }
-
- @SmallTest
- @Test
- public void testHeadsetHangupCall() throws Exception {
- Call mockCall = createForegroundCall();
-
- boolean callHungup = mBluetoothPhoneService.mBinder.hangupCall();
-
- verify(mMockCallsManager).disconnectCall(eq(mockCall));
- assertEquals(callHungup, true);
- }
-
- @SmallTest
- @Test
- public void testHeadsetHangupCallNull() throws Exception {
- when(mMockCallsManager.getForegroundCall()).thenReturn(null);
-
- boolean callHungup = mBluetoothPhoneService.mBinder.hangupCall();
-
- verify(mMockCallsManager,never()).disconnectCall(any(Call.class));
- assertEquals(callHungup, false);
- }
-
- @SmallTest
- @Test
- public void testHeadsetSendDTMF() throws Exception {
- Call mockCall = createForegroundCall();
-
- boolean sentDtmf = mBluetoothPhoneService.mBinder.sendDtmf(TEST_DTMF_TONE);
-
- verify(mMockCallsManager).playDtmfTone(eq(mockCall), eq((char) TEST_DTMF_TONE));
- verify(mMockCallsManager).stopDtmfTone(eq(mockCall));
- assertEquals(sentDtmf, true);
- }
-
- @SmallTest
- @Test
- public void testHeadsetSendDTMFNull() throws Exception {
- when(mMockCallsManager.getForegroundCall()).thenReturn(null);
-
- boolean sentDtmf = mBluetoothPhoneService.mBinder.sendDtmf(TEST_DTMF_TONE);
-
- verify(mMockCallsManager,never()).playDtmfTone(any(Call.class), anyChar());
- verify(mMockCallsManager,never()).stopDtmfTone(any(Call.class));
- assertEquals(sentDtmf, false);
- }
-
- @SmallTest
- @Test
- public void testGetNetworkOperator() throws Exception {
- Call mockCall = createForegroundCall();
- PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
- when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
-
- String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
-
- assertEquals(networkOperator, "label0");
- }
-
- @SmallTest
- @Test
- public void testGetNetworkOperatorNoPhoneAccount() throws Exception {
- when(mMockCallsManager.getForegroundCall()).thenReturn(null);
-
- String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
-
- assertEquals(networkOperator, "label1");
- }
-
- @SmallTest
- @Test
- public void testGetSubscriberNumber() throws Exception {
- Call mockCall = createForegroundCall();
- PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
- when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
-
- String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
-
- assertEquals(subscriberNumber, TEST_ACCOUNT_ADDRESS + TEST_ACCOUNT_INDEX);
- }
-
- @SmallTest
- @Test
- public void testGetSubscriberNumberFallbackToTelephony() throws Exception {
- Call mockCall = createForegroundCall();
- String fakeNumber = "8675309";
- when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- nullable(PhoneAccountHandle.class))).thenReturn(null);
- when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(
- nullable(PhoneAccountHandle.class))).thenReturn(null);
- when(mComponentContextFixture.getTelephonyManager().getLine1Number())
- .thenReturn(fakeNumber);
-
- String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
-
- assertEquals(subscriberNumber, fakeNumber);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsOneCall() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call activeCall = createActiveCall();
- when(activeCall.getState()).thenReturn(CallState.ACTIVE);
- calls.add(activeCall);
- when(activeCall.isConference()).thenReturn(false);
- when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsSilentRinging() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call silentRingingCall = createActiveCall();
- when(silentRingingCall.getState()).thenReturn(CallState.RINGING);
- when(silentRingingCall.isSilentRingingRequested()).thenReturn(true);
- calls.add(silentRingingCall);
- when(silentRingingCall.isConference()).thenReturn(false);
- when(silentRingingCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(silentRingingCall);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset, never()).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testConferenceInProgressCDMA() throws Exception {
- // If two calls are being conferenced and updateHeadsetWithCallState runs while this is
- // still occuring, it will look like there is an active and held call still while we are
- // transitioning into a conference.
- // Call has been put into a CDMA "conference" with one call on hold.
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- final Call confCall1 = mock(Call.class);
- final Call confCall2 = createHeldCall();
- calls.add(parentCall);
- calls.add(confCall1);
- calls.add(confCall2);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(confCall1.getState()).thenReturn(CallState.ACTIVE);
- when(confCall2.getState()).thenReturn(CallState.ACTIVE);
- when(confCall1.isIncoming()).thenReturn(false);
- when(confCall2.isIncoming()).thenReturn(true);
- when(confCall1.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(confCall2.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
- addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(confCall1);
- add(confCall2);
- }});
- //Add links from child calls to parent
- when(confCall1.getParentCall()).thenReturn(parentCall);
- when(confCall2.getParentCall()).thenReturn(parentCall);
-
- mBluetoothPhoneService.mBinder.queryPhoneState();
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- when(mMockCallsManager.getHeldCall()).thenReturn(null);
- // Spurious call to onIsConferencedChanged.
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- // Make sure the call has only occurred collectively 2 times (not on the third)
- verify(mMockBluetoothHeadset, times(2)).phoneStateChanged(any(int.class),
- any(int.class), any(int.class), nullable(String.class), any(int.class),
- nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsCdmaHold() throws Exception {
- // Call has been put into a CDMA "conference" with one call on hold.
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- final Call foregroundCall = mock(Call.class);
- final Call heldCall = createHeldCall();
- calls.add(parentCall);
- calls.add(foregroundCall);
- calls.add(heldCall);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(foregroundCall.getState()).thenReturn(CallState.ACTIVE);
- when(heldCall.getState()).thenReturn(CallState.ACTIVE);
- when(foregroundCall.isIncoming()).thenReturn(false);
- when(heldCall.isIncoming()).thenReturn(true);
- when(foregroundCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(heldCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
- addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.getConferenceLevelActiveCall()).thenReturn(foregroundCall);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(foregroundCall);
- add(heldCall);
- }});
- //Add links from child calls to parent
- when(foregroundCall.getParentCall()).thenReturn(parentCall);
- when(heldCall.getParentCall()).thenReturn(parentCall);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
- eq(false), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
- eq(false), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsCdmaConference() throws Exception {
- // Call is in a true CDMA conference
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- final Call confCall1 = mock(Call.class);
- final Call confCall2 = createHeldCall();
- calls.add(parentCall);
- calls.add(confCall1);
- calls.add(confCall2);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(confCall1.getState()).thenReturn(CallState.ACTIVE);
- when(confCall2.getState()).thenReturn(CallState.ACTIVE);
- when(confCall1.isIncoming()).thenReturn(false);
- when(confCall2.isIncoming()).thenReturn(true);
- when(confCall1.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(confCall2.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
- removeCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
- when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(confCall1);
- add(confCall2);
- }});
- //Add links from child calls to parent
- when(confCall1.getParentCall()).thenReturn(parentCall);
- when(confCall2.getParentCall()).thenReturn(parentCall);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
- eq(true), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
- eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testWaitingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- // This test does not define a value for getForegroundCall(), so this ringing call will
- // be treated as if it is a waiting call when listCurrentCalls() is invoked.
- Call waitingCall = createRingingCall();
- calls.add(waitingCall);
- when(waitingCall.isIncoming()).thenReturn(true);
- when(waitingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(waitingCall.getState()).thenReturn(CallState.RINGING);
- when(waitingCall.isConference()).thenReturn(false);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_WAITING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testNewCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call newCall = createForegroundCall();
- calls.add(newCall);
- when(newCall.getState()).thenReturn(CallState.NEW);
- when(newCall.isConference()).thenReturn(false);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(1)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testRingingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call ringingCall = createForegroundCall();
- calls.add(ringingCall);
- when(ringingCall.getState()).thenReturn(CallState.RINGING);
- when(ringingCall.isIncoming()).thenReturn(true);
- when(ringingCall.isConference()).thenReturn(false);
- when(ringingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testCallClccCache() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call ringingCall = createForegroundCall();
- calls.add(ringingCall);
- when(ringingCall.getState()).thenReturn(CallState.RINGING);
- when(ringingCall.isIncoming()).thenReturn(true);
- when(ringingCall.isConference()).thenReturn(false);
- when(ringingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:5550000")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
-
- // Test Caching of old call indicies in clcc
- when(ringingCall.getState()).thenReturn(CallState.ACTIVE);
- Call newHoldingCall = createHeldCall();
- calls.add(0, newHoldingCall);
- when(newHoldingCall.getState()).thenReturn(CallState.ON_HOLD);
- when(newHoldingCall.isIncoming()).thenReturn(true);
- when(newHoldingCall.isConference()).thenReturn(false);
- when(newHoldingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_ACTIVE, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
- "5550001", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testAlertingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call dialingCall = createForegroundCall();
- calls.add(dialingCall);
- when(dialingCall.getState()).thenReturn(CallState.DIALING);
- when(dialingCall.isIncoming()).thenReturn(false);
- when(dialingCall.isConference()).thenReturn(false);
- when(dialingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testHoldingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call dialingCall = createForegroundCall();
- calls.add(dialingCall);
- when(dialingCall.getState()).thenReturn(CallState.DIALING);
- when(dialingCall.isIncoming()).thenReturn(false);
- when(dialingCall.isConference()).thenReturn(false);
- when(dialingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- Call holdingCall = createHeldCall();
- calls.add(holdingCall);
- when(holdingCall.getState()).thenReturn(CallState.ON_HOLD);
- when(holdingCall.isIncoming()).thenReturn(true);
- when(holdingCall.isConference()).thenReturn(false);
- when(holdingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
- "5550001", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(3)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsImsConference() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- calls.add(parentCall);
- addCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getState()).thenReturn(CallState.ACTIVE);
- when(parentCall.isIncoming()).thenReturn(true);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
- eq(true), (String) isNull(), eq(-1));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsHeldImsCepConference() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createHeldCall();
- Call childCall1 = createActiveCall();
- Call childCall2 = createActiveCall();
- calls.add(parentCall);
- calls.add(childCall1);
- calls.add(childCall2);
- addCallCapability(parentCall, Connection.CAPABILITY_MANAGE_CONFERENCE);
- when(childCall1.getParentCall()).thenReturn(parentCall);
- when(childCall2.getParentCall()).thenReturn(parentCall);
-
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getState()).thenReturn(CallState.ON_HOLD);
- when(childCall1.getState()).thenReturn(CallState.ACTIVE);
- when(childCall2.getState()).thenReturn(CallState.ACTIVE);
-
- when(parentCall.isIncoming()).thenReturn(true);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_HELD), eq(0),
- eq(true), (String) isNull(), eq(-1));
- verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(0), eq(CALL_STATE_HELD), eq(0),
- eq(true), (String) isNull(), eq(-1));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testQueryPhoneState() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
-
- mBluetoothPhoneService.mBinder.queryPhoneState();
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testCDMAConferenceQueryState() throws Exception {
- Call parentConfCall = createActiveCall();
- final Call confCall1 = mock(Call.class);
- final Call confCall2 = mock(Call.class);
- when(parentConfCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
- addCallCapability(parentConfCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentConfCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentConfCall.wasConferencePreviouslyMerged()).thenReturn(true);
- when(parentConfCall.isConference()).thenReturn(true);
- when(parentConfCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(confCall1);
- add(confCall2);
- }});
-
- mBluetoothPhoneService.mBinder.queryPhoneState();
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testProcessChldTypeReleaseHeldRinging() throws Exception {
- Call ringingCall = createRingingCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
-
- verify(mMockCallsManager).rejectCall(eq(ringingCall), eq(false), nullable(String.class));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldTypeReleaseHeldHold() throws Exception {
- Call onHoldCall = createHeldCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
-
- verify(mMockCallsManager).disconnectCall(eq(onHoldCall));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldReleaseActiveRinging() throws Exception {
- Call activeCall = createActiveCall();
- Call ringingCall = createRingingCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).disconnectCall(eq(activeCall));
- verify(mMockCallsManager).answerCall(eq(ringingCall), any(int.class));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldReleaseActiveHold() throws Exception {
- Call activeCall = createActiveCall();
- Call heldCall = createHeldCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).disconnectCall(eq(activeCall));
- // Call unhold will occur as part of CallsManager auto-unholding the background call on its
- // own.
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveRinging() throws Exception {
- Call ringingCall = createRingingCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).answerCall(eq(ringingCall), any(int.class));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveUnhold() throws Exception {
- Call heldCall = createHeldCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).unholdCall(eq(heldCall));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveHold() throws Exception {
- Call activeCall = createActiveCall();
- addCallCapability(activeCall, Connection.CAPABILITY_HOLD);
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).holdCall(eq(activeCall));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldAddHeldToConfHolding() throws Exception {
- Call activeCall = createActiveCall();
- addCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_ADDHELDTOCONF);
-
- verify(activeCall).mergeConference();
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldAddHeldToConf() throws Exception {
- Call activeCall = createActiveCall();
- removeCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- Call conferenceableCall = mock(Call.class);
- ArrayList<Call> conferenceableCalls = new ArrayList<>();
- conferenceableCalls.add(conferenceableCall);
- when(activeCall.getConferenceableCalls()).thenReturn(conferenceableCalls);
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_ADDHELDTOCONF);
-
- verify(mMockCallsManager).conference(activeCall, conferenceableCall);
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveSwapConference() throws Exception {
- // Create an active CDMA Call with a call on hold and simulate a swapConference().
- Call parentCall = createActiveCall();
- final Call foregroundCall = mock(Call.class);
- final Call heldCall = createHeldCall();
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(foregroundCall);
- add(heldCall);
- }});
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(parentCall).swapConference();
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""),
- eq(128), nullable(String.class));
- assertEquals(didProcess, true);
- }
-
- // Testing the CallsManager Listener Functionality on Bluetooth
- @MediumTest
- @Test
- public void testOnCallAddedRinging() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testSilentRingingCallState() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.isSilentRingingRequested()).thenReturn(true);
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallAddedCdmaActiveHold() throws Exception {
- // Call has been put into a CDMA "conference" with one call on hold.
- Call parentCall = createActiveCall();
- final Call foregroundCall = mock(Call.class);
- final Call heldCall = createHeldCall();
- addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(foregroundCall);
- add(heldCall);
- }});
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(parentCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallRemoved() throws Exception {
- Call activeCall = createActiveCall();
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(activeCall);
- doReturn(null).when(mMockCallsManager).getActiveCall();
- mBluetoothPhoneService.mCallsManagerListener.onCallRemoved(activeCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedConnectingCall() throws Exception {
- Call activeCall = mock(Call.class);
- Call connectingCall = mock(Call.class);
- when(connectingCall.getState()).thenReturn(CallState.CONNECTING);
- ArrayList<Call> calls = new ArrayList<>();
- calls.add(connectingCall);
- calls.add(activeCall);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
- CallState.ACTIVE, CallState.ON_HOLD);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallAddedAudioProcessing() throws Exception {
- Call call = mock(Call.class);
- when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(call);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedRingingToAudioProcessing() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
-
- when(ringingCall.getState()).thenReturn(CallState.AUDIO_PROCESSING);
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(null);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
- CallState.RINGING, CallState.AUDIO_PROCESSING);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedAudioProcessingToSimulatedRinging() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
- CallState.AUDIO_PROCESSING, CallState.SIMULATED_RINGING);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedAudioProcessingToActive() throws Exception {
- Call activeCall = createActiveCall();
- when(activeCall.getState()).thenReturn(CallState.ACTIVE);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
- CallState.AUDIO_PROCESSING, CallState.ACTIVE);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedDialing() throws Exception {
- Call activeCall = createActiveCall();
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
- CallState.CONNECTING, CallState.DIALING);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedAlerting() throws Exception {
- Call outgoingCall = createOutgoingCall();
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(outgoingCall,
- CallState.NEW, CallState.DIALING);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DIALING),
- eq(""), eq(128), nullable(String.class));
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_ALERTING),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedDisconnected() throws Exception {
- Call disconnectedCall = createDisconnectedCall();
- doReturn(true).when(mMockCallsManager).hasOnlyDisconnectedCalls();
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(disconnectedCall,
- CallState.DISCONNECTING, CallState.DISCONNECTED);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
- eq(""), eq(128), nullable(String.class));
-
- doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls();
- mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(true);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
- eq(""), eq(128), nullable(String.class));
-
- mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(false);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChanged() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
-
- //Switch to active
- doReturn(null).when(mMockCallsManager).getRingingOrSimulatedRingingCall();
- when(mMockCallsManager.getActiveCall()).thenReturn(ringingCall);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
- CallState.RINGING, CallState.ACTIVE);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedGSMSwap() throws Exception {
- Call heldCall = createHeldCall();
- when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
- doReturn(2).when(mMockCallsManager).getNumHeldCalls();
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(heldCall,
- CallState.ACTIVE, CallState.ON_HOLD);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(eq(0), eq(2), eq(CALL_STATE_HELD),
- eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnIsConferencedChanged() throws Exception {
- // Start with two calls that are being merged into a CDMA conference call. The
- // onIsConferencedChanged method will be called multiple times during the call. Make sure
- // that the bluetooth phone state is updated properly.
- Call parentCall = createActiveCall();
- Call activeCall = mock(Call.class);
- Call heldCall = createHeldCall();
- when(activeCall.getParentCall()).thenReturn(parentCall);
- when(heldCall.getParentCall()).thenReturn(parentCall);
- ArrayList<Call> calls = new ArrayList<>();
- calls.add(activeCall);
- when(parentCall.getChildCalls()).thenReturn(calls);
- when(parentCall.isConference()).thenReturn(true);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
-
- // Be sure that onIsConferencedChanged rejects spurious changes during set up of
- // CDMA "conference"
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(activeCall);
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(heldCall);
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
-
- calls.add(heldCall);
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testBluetoothAdapterReceiver() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
-
- Intent intent = new Intent();
- intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
- mBluetoothPhoneService.mBluetoothAdapterReceiver.onReceive(mContext, intent);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- private void addCallCapability(Call call, int capability) {
- when(call.can(capability)).thenReturn(true);
- }
-
- private void removeCallCapability(Call call, int capability) {
- when(call.can(capability)).thenReturn(false);
- }
-
- private Call createActiveCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getActiveCall()).thenReturn(call);
- return call;
- }
-
- private Call createRingingCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(call);
- return call;
- }
-
- private Call createHeldCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getHeldCall()).thenReturn(call);
- return call;
- }
-
- private Call createOutgoingCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getOutgoingCall()).thenReturn(call);
- return call;
- }
-
- private Call createDisconnectedCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getFirstCallWithState(CallState.DISCONNECTED)).thenReturn(call);
- return call;
- }
-
- private Call createForegroundCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getForegroundCall()).thenReturn(call);
- return call;
- }
-
- private static ComponentName makeQuickConnectionServiceComponentName() {
- return new ComponentName("com.android.server.telecom.tests",
- "com.android.server.telecom.tests.MockConnectionService");
- }
-
- private static PhoneAccountHandle makeQuickAccountHandle(String id) {
- return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id,
- Binder.getCallingUserHandle());
- }
-
- private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
- return new PhoneAccount.Builder(makeQuickAccountHandle(id), "label" + idx);
- }
-
- private PhoneAccount makeQuickAccount(String id, int idx) {
- return makeQuickAccountBuilder(id, idx)
- .setAddress(Uri.parse(TEST_ACCOUNT_ADDRESS + idx))
- .setSubscriptionAddress(Uri.parse("tel:555-000" + idx))
- .setCapabilities(idx)
- .setIcon(Icon.createWithResource(
- "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
- .setShortDescription("desc" + idx)
- .setIsEnabled(true)
- .build();
- }
-}
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 24476f0..5592cf4 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -455,6 +455,37 @@
@SmallTest
@Test
+ public void testFocusChangeFromQuiescentSpeaker() {
+ CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
+ mContext,
+ mockCallsManager,
+ mockBluetoothRouteManager,
+ mockWiredHeadsetManager,
+ mockStatusBarNotifier,
+ mAudioServiceFactory,
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
+ stateMachine.setCallAudioManager(mockCallAudioManager);
+
+ when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
+
+ CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER,
+ CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER);
+ stateMachine.initialize(initState);
+
+ // Switch to active, pretending that a call came in.
+ stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
+ CallAudioRouteStateMachine.ACTIVE_FOCUS);
+ waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
+
+ // Make sure that we've successfully switched to the active speaker route and that we've
+ // called setSpeakerOn
+ assertTrue(stateMachine.isInActiveState());
+ verify(mockAudioManager).setSpeakerphoneOn(true);
+ }
+
+ @SmallTest
+ @Test
public void testFocusChangeWithAlreadyActiveBtDevice() {
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
index bf105e5..879ed0f 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
@@ -815,7 +815,7 @@
"Speakerphone turned off externally during speaker", // name
CallAudioState.ROUTE_SPEAKER, // initialRoute
CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
- NONE, // speakerInteraction
+ OFF, // speakerInteraction
ON, // bluetoothInteraction
CallAudioRouteStateMachine.SPEAKER_OFF, // action
CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
diff --git a/tests/src/com/android/server/telecom/tests/CallDiagnosticServiceControllerTest.java b/tests/src/com/android/server/telecom/tests/CallDiagnosticServiceControllerTest.java
new file mode 100644
index 0000000..d420f1d
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/CallDiagnosticServiceControllerTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom.tests;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.telecom.ParcelableCall;
+
+import com.android.internal.telecom.ICallDiagnosticService;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallDiagnosticServiceController;
+import com.android.server.telecom.TelecomSystem;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class CallDiagnosticServiceControllerTest {
+ private static final String TEST_CDS_PACKAGE = "com.test.stuff";
+ private static final String TEST_PACKAGE = "com.android.telecom.calldiagnosticservice";
+ private static final String TEST_CLASS =
+ "com.android.telecom.calldiagnosticservice.TestService";
+ private static final ComponentName TEST_COMPONENT = new ComponentName(TEST_PACKAGE, TEST_CLASS);
+ private static final List<ResolveInfo> RESOLVE_INFOS = new ArrayList<>();
+ private static final ResolveInfo TEST_RESOLVE_INFO = new ResolveInfo();
+ static {
+ TEST_RESOLVE_INFO.serviceInfo = new ServiceInfo();
+ TEST_RESOLVE_INFO.serviceInfo.packageName = TEST_PACKAGE;
+ TEST_RESOLVE_INFO.serviceInfo.name = TEST_CLASS;
+ TEST_RESOLVE_INFO.serviceInfo.permission = Manifest.permission.BIND_CALL_DIAGNOSTIC_SERVICE;
+ RESOLVE_INFOS.add(TEST_RESOLVE_INFO);
+ }
+ private static final String ID_1 = "1";
+ private static final String ID_2 = "2";
+
+ @Mock
+ private CallDiagnosticServiceController.ContextProxy mContextProxy;
+ @Mock
+ private Call mCall;
+ @Mock
+ private Call mCallTwo;
+ @Mock
+ private ICallDiagnosticService mICallDiagnosticService;
+ private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
+
+ private CallDiagnosticServiceController mCallDiagnosticService;
+ private ServiceConnection mServiceConnection;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mCall.getId()).thenReturn(ID_1);
+ when(mCall.isSimCall()).thenReturn(true);
+ when(mCall.isExternalCall()).thenReturn(false);
+
+ when(mCallTwo.getId()).thenReturn(ID_2);
+ when(mCallTwo.isSimCall()).thenReturn(true);
+ when(mCallTwo.isExternalCall()).thenReturn(false);
+ mServiceConnection = null;
+
+ // Mock out the context and other junk that we depend on.
+ when(mContextProxy.queryIntentServicesAsUser(any(Intent.class), anyInt(), anyInt()))
+ .thenReturn(RESOLVE_INFOS);
+ when(mContextProxy.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
+ anyInt(), any(UserHandle.class))).thenReturn(true);
+ when(mContextProxy.getCurrentUserHandle()).thenReturn(UserHandle.CURRENT);
+
+ mCallDiagnosticService = new CallDiagnosticServiceController(mContextProxy,
+ TEST_PACKAGE, mLock);
+ }
+
+ /**
+ * Verify no binding takes place for a non-sim call.
+ */
+ @Test
+ public void testNoBindOnNonSimCall() {
+ Call mockCall = Mockito.mock(Call.class);
+ when(mockCall.isSimCall()).thenReturn(false);
+
+ mCallDiagnosticService.onCallAdded(mockCall);
+
+ verify(mContextProxy, never()).bindServiceAsUser(any(Intent.class),
+ any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+ }
+
+ /**
+ * Verify no binding takes place for a SIM external call.
+ */
+ @Test
+ public void testNoBindOnExternalCall() {
+ Call mockCall = Mockito.mock(Call.class);
+ when(mockCall.isSimCall()).thenReturn(true);
+ when(mockCall.isExternalCall()).thenReturn(true);
+
+ mCallDiagnosticService.onCallAdded(mockCall);
+
+ verify(mContextProxy, never()).bindServiceAsUser(any(Intent.class),
+ any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+ }
+
+ /**
+ * Verify a valid SIM call causes binding to initiate.
+ */
+ @Test
+ public void testAddSimCallCausesBind() throws RemoteException {
+ mCallDiagnosticService.onCallAdded(mCall);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ ArgumentCaptor<ServiceConnection> serviceConnectionCaptor = ArgumentCaptor.forClass(
+ ServiceConnection.class);
+ verify(mContextProxy).bindServiceAsUser(intentCaptor.capture(),
+ serviceConnectionCaptor.capture(), anyInt(), any(UserHandle.class));
+ assertEquals(TEST_PACKAGE, intentCaptor.getValue().getPackage());
+
+ // Now we'll pretend bind completed and we sent back the binder.
+ IBinder mockBinder = mock(IBinder.class);
+ when(mockBinder.queryLocalInterface(anyString())).thenReturn(mICallDiagnosticService);
+ serviceConnectionCaptor.getValue().onServiceConnected(TEST_COMPONENT, mockBinder);
+ mServiceConnection = serviceConnectionCaptor.getValue();
+
+ // Make sure it's sent
+ verify(mICallDiagnosticService).initializeDiagnosticCall(any(ParcelableCall.class));
+ }
+
+ /**
+ * Verify removing the active call causes it to be removed from the CallDiagnosticService and
+ * that an unbind takes place.
+ */
+ @Test
+ public void testRemoveSimCallCausesRemoveAndUnbind() throws RemoteException {
+ testAddSimCallCausesBind();
+ mCallDiagnosticService.onCallRemoved(mCall);
+
+ verify(mICallDiagnosticService).removeDiagnosticCall(eq(ID_1));
+ verify(mContextProxy).unbindService(eq(mServiceConnection));
+ }
+
+ /**
+ * Try to add and remove two and verify bind/unbind.
+ */
+ @Test
+ public void testAddTwo() throws RemoteException {
+ testAddSimCallCausesBind();
+ mCallDiagnosticService.onCallAdded(mCallTwo);
+ verify(mICallDiagnosticService, times(2)).initializeDiagnosticCall(
+ any(ParcelableCall.class));
+
+ mCallDiagnosticService.onCallRemoved(mCall);
+ // Not yet!
+ verify(mContextProxy, never()).unbindService(eq(mServiceConnection));
+
+ mCallDiagnosticService.onCallRemoved(mCallTwo);
+
+ verify(mICallDiagnosticService).removeDiagnosticCall(eq(ID_1));
+ verify(mICallDiagnosticService).removeDiagnosticCall(eq(ID_2));
+ verify(mContextProxy).unbindService(eq(mServiceConnection));
+ }
+
+ /**
+ * Verifies we can override the call diagnostic service package to a test package (used by CTS
+ * tests).
+ */
+ @Test
+ public void testTestOverride() {
+ mCallDiagnosticService.setTestCallDiagnosticService(TEST_CDS_PACKAGE);
+ mCallDiagnosticService.onCallAdded(mCall);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContextProxy).bindServiceAsUser(intentCaptor.capture(),
+ any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+ assertEquals(TEST_CDS_PACKAGE, intentCaptor.getValue().getPackage());
+ }
+}
diff --git a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
index 953c711..dfc3258 100644
--- a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
@@ -60,6 +60,7 @@
import androidx.test.filters.FlakyTest;
+import com.android.server.telecom.Analytics;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallLogManager;
import com.android.server.telecom.CallState;
@@ -89,6 +90,7 @@
private PhoneAccountHandle mOtherUserAccountHandle;
private PhoneAccountHandle mManagedProfileAccountHandle;
private PhoneAccountHandle mSelfManagedAccountHandle;
+ private Analytics.CallInfo mCallInfo;
private static final Uri TEL_PHONEHANDLE = Uri.parse("tel:5555551234");
@@ -148,6 +150,7 @@
TEST_SELF_MGD_PHONE_ACCOUNT_ID,
UserHandle.of(CURRENT_USER_ID)
);
+ mCallInfo = new Analytics.CallInfo();
// Since we can't mock ContentResolver directly, use a ContentProvider
when(mContext.getContentResolver()).thenReturn(ContentResolver.wrap(mContentProvider));
@@ -1006,6 +1009,7 @@
when(fakeCall.getParentCall()).thenReturn(null);
when(fakeCall.hadChildren()).thenReturn(true);
when(fakeCall.hasProperty(eq(Connection.PROPERTY_REMOTELY_HOSTED))).thenReturn(false);
+ when(fakeCall.getAnalytics()).thenReturn(mCallInfo);
return fakeCall;
}
diff --git a/tests/src/com/android/server/telecom/tests/CallTest.java b/tests/src/com/android/server/telecom/tests/CallTest.java
index 541d278..d326a29 100644
--- a/tests/src/com/android/server/telecom/tests/CallTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallTest.java
@@ -19,13 +19,17 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
import android.content.ComponentName;
import android.net.Uri;
@@ -34,6 +38,7 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
import android.widget.Toast;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -44,6 +49,8 @@
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceWrapper;
+import com.android.server.telecom.InCallController;
+import com.android.server.telecom.InCallController.InCallServiceInfo;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneNumberUtilsAdapter;
import com.android.server.telecom.TelecomSystem;
@@ -54,17 +61,23 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
@RunWith(AndroidJUnit4.class)
public class CallTest extends TelecomTestCase {
private static final Uri TEST_ADDRESS = Uri.parse("tel:555-1212");
+ private static final ComponentName COMPONENT_NAME_1 = ComponentName
+ .unflattenFromString("com.foo/.Blah");
+ private static final ComponentName COMPONENT_NAME_2 = ComponentName
+ .unflattenFromString("com.bar/.Blah");
private static final PhoneAccountHandle SIM_1_HANDLE = new PhoneAccountHandle(
- ComponentName.unflattenFromString("com.foo/.Blah"), "Sim1");
+ COMPONENT_NAME_1, "Sim1");
private static final PhoneAccount SIM_1_ACCOUNT = new PhoneAccount.Builder(SIM_1_HANDLE, "Sim1")
.setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
| PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
+ private static final long TIMEOUT_MILLIS = 1000;
@Mock private CallsManager mMockCallsManager;
@Mock private CallerInfoLookupHelper mMockCallerInfoLookupHelper;
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index 4dffe59..08f3536 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -42,8 +42,11 @@
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -56,6 +59,7 @@
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
import android.widget.Toast;
import com.android.server.telecom.AsyncRingtonePlayer;
@@ -63,6 +67,7 @@
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
+import com.android.server.telecom.CallDiagnosticServiceController;
import com.android.server.telecom.CallState;
import com.android.server.telecom.CallerInfoLookupHelper;
import com.android.server.telecom.CallsManager;
@@ -92,7 +97,6 @@
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
import com.android.server.telecom.callfiltering.CallFilteringResult;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.DisconnectedCallNotifier;
import com.android.server.telecom.ui.ToastFactory;
@@ -107,8 +111,6 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -116,6 +118,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -193,10 +197,9 @@
@Mock private CallAudioRouteStateMachine.Factory mCallAudioRouteStateMachineFactory;
@Mock private CallAudioModeStateMachine mCallAudioModeStateMachine;
@Mock private CallAudioModeStateMachine.Factory mCallAudioModeStateMachineFactory;
+ @Mock private CallDiagnosticServiceController mCallDiagnosticServiceController;
@Mock private BluetoothStateReceiver mBluetoothStateReceiver;
@Mock private RoleManagerAdapter mRoleManagerAdapter;
- @Mock private IncomingCallFilter.Factory mIncomingCallFilterFactory;
- @Mock private IncomingCallFilter mIncomingCallFilter;
@Mock private ToastFactory mToastFactory;
@Mock private Toast mToast;
@@ -219,8 +222,6 @@
anyInt())).thenReturn(mCallAudioRouteStateMachine);
when(mCallAudioModeStateMachineFactory.create(any(), any()))
.thenReturn(mCallAudioModeStateMachine);
- when(mIncomingCallFilterFactory.create(any(), any(), any(), any(), any(), any()))
- .thenReturn(mIncomingCallFilter);
when(mClockProxy.currentTimeMillis()).thenReturn(System.currentTimeMillis());
when(mClockProxy.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
when(mConnSvrFocusManagerFactory.create(any())).thenReturn(mConnectionSvrFocusMgr);
@@ -254,8 +255,8 @@
mCallAudioRouteStateMachineFactory,
mCallAudioModeStateMachineFactory,
mInCallControllerFactory,
+ mCallDiagnosticServiceController,
mRoleManagerAdapter,
- mIncomingCallFilterFactory,
mToastFactory);
when(mPhoneAccountRegistrar.getPhoneAccount(
@@ -1019,7 +1020,7 @@
@SmallTest
@Test
public void testHangupActiveCallWhenHeadsetMediaButtonLongPressDuringTwoCalls() {
- // GIVEN an ongoing call
+ // GIVEN an ongoing call
Call ongoingCall = addSpyCall();
doReturn(CallState.ACTIVE).when(ongoingCall).getState();
@@ -1332,6 +1333,8 @@
@Test
public void testHandleSilenceVsBackgroundScreeningOrdering() throws Exception {
Call screenedCall = mock(Call.class);
+ Bundle extra = new Bundle();
+ when(screenedCall.getIntentExtras()).thenReturn(extra);
String appName = "blah";
CallFilteringResult result = new CallFilteringResult.Builder()
.setShouldAllowCall(true)
@@ -1342,7 +1345,7 @@
.setShouldShowNotification(true)
.setCallScreeningAppName(appName)
.build();
- mCallsManager.onCallFilteringComplete(screenedCall, result);
+ mCallsManager.onCallFilteringComplete(screenedCall, result, false);
verify(mConnectionSvrFocusMgr).requestFocus(eq(screenedCall),
nullable(ConnectionServiceFocusManager.RequestFocusCallback.class));
@@ -1381,6 +1384,80 @@
}
/**
+ * This test verifies a race condition seen with the new outgoing call broadcast.
+ * The scenario occurs when an incoming call is handled by an app which receives the
+ * NewOutgoingCallBroadcast. That app cancels the call by modifying the new outgoing call
+ * broadcast. Meanwhile, it places that same call again, expecting that Telecom will reuse the
+ * same same. HOWEVER, if the system delays passing of the new outgoing call broadcast back to
+ * Telecom, the app will have placed a new outgoing call BEFORE telecom is aware that the call
+ * was cancelled.
+ * The consequence of this is that in CallsManager#startOutgoingCall, when we first get the
+ * call to reuse, it will come back empty. Meanwhile, by the time we get into the various
+ * completable futures, the call WILL be in the list of calls which can be reused. Since the
+ * reusable call was not found earlier on, we end up aborting the new outgoing call.
+ * @throws Exception
+ */
+ @SmallTest
+ @Test
+ public void testReuseCallConcurrency() throws Exception {
+ // Ensure contact info lookup succeeds
+ doAnswer(invocation -> {
+ Uri handle = invocation.getArgument(0);
+ CallerInfo info = new CallerInfo();
+ CompletableFuture<Pair<Uri, CallerInfo>> callerInfoFuture = new CompletableFuture<>();
+ callerInfoFuture.complete(new Pair<>(handle, info));
+ return callerInfoFuture;
+ }).when(mCallerInfoLookupHelper).startLookup(any(Uri.class));
+
+ // Ensure we have candidate phone account handle info.
+ when(mPhoneAccountRegistrar.getOutgoingPhoneAccountForScheme(any(), any())).thenReturn(
+ SIM_1_HANDLE);
+ when(mPhoneAccountRegistrar.getCallCapablePhoneAccounts(any(), anyBoolean(),
+ any(), anyInt(), anyInt())).thenReturn(
+ new ArrayList<>(Arrays.asList(SIM_1_HANDLE, SIM_2_HANDLE)));
+
+ // Let's add an existing call which is in connecting state; this emulates the case where
+ // we have an outgoing call which we have not yet disconnected as a result of the new
+ // outgoing call broadcast cancelling the call.
+ Call outgoingCall = addSpyCall(CallState.CONNECTING);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ // Get the handler for the main looper, which is the same one the CallsManager will use.
+ // We'll post a little something to block up the handler for now. This prevents
+ // startOutgoingCall from process it's completablefutures.
+ Handler handler = new Handler(Looper.getMainLooper());
+ handler.post(() -> {
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+
+ // Now while the main handler is blocked up we'll start another outgoing call.
+ CompletableFuture<Call> callFuture = mCallsManager.startOutgoingCall(
+ outgoingCall.getHandle(), outgoingCall.getTargetPhoneAccount(), new Bundle(),
+ UserHandle.CURRENT, new Intent(), "com.test.stuff");
+
+ // And we'll add the initial outgoing call to the list of pending disconnects; this
+ // emulates a scenario where the pending disconnect call came in AFTER this call began.
+ mCallsManager.addToPendingCallsToDisconnect(outgoingCall);
+
+ // And we'll unblock the handler; this will let all the startOutgoingCall futures to happen.
+ latch.countDown();
+
+ // Wait for the future to become the present.
+ callFuture.join();
+
+ // We should have gotten a call out of this; if we did not then it means the call was
+ // aborted.
+ assertNotNull(callFuture.get());
+
+ // And the original call should be disconnected now.
+ assertEquals(CallState.DISCONNECTED, outgoingCall.getState());
+ }
+
+ /**
* Ensures that if we have two calls hosted by the same connection manager, but with
* different target phone accounts, we can swap between them.
* @throws Exception
@@ -1460,7 +1537,6 @@
// Mocks some methods to not call the real method.
doNothing().when(callSpy).unhold();
doNothing().when(callSpy).hold();
- doNothing().when(callSpy).disconnect();
doNothing().when(callSpy).answer(Matchers.anyInt());
doNothing().when(callSpy).setStartWithSpeakerphoneOn(Matchers.anyBoolean());
diff --git a/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java b/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
index 4ef4596..dbfcdb1 100644
--- a/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.tests;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertNull;
@@ -104,6 +105,17 @@
}
/**
+ * Ensure that we don't keep a package around after it's been removed from the device
+ */
+ @Test
+ public void testForceExitCarMode() {
+ testEnterCarModeBasic();
+ mCarModeTracker.forceExitCarMode(CAR_MODE_APP1_PACKAGE_NAME);
+ assertFalse(mCarModeTracker.isInCarMode());
+ assertNull(mCarModeTracker.getCurrentCarModePackage());
+ }
+
+ /**
* Verifies only the first app at the default priority gets tracked.
*/
@Test
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index af062d7..a4302b6 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -42,6 +42,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
@@ -485,6 +486,7 @@
private final RoleManager mRoleManager = mock(RoleManager.class);
private final TelephonyRegistryManager mTelephonyRegistryManager =
mock(TelephonyRegistryManager.class);
+ private final PermissionInfo mPermissionInfo = mock(PermissionInfo.class);
private TelecomManager mTelecomManager = mock(TelecomManager.class);
@@ -539,6 +541,14 @@
matches(Manifest.permission.CALL_COMPANION_APP), anyString()))
.thenReturn(PackageManager.PERMISSION_DENIED);
+ try {
+ when(mPackageManager.getPermissionInfo(anyString(), anyInt())).thenReturn(
+ mPermissionInfo);
+ } catch (PackageManager.NameNotFoundException ex) {
+ }
+
+ when(mPermissionInfo.isAppOp()).thenReturn(true);
+
// Used in CreateConnectionProcessor to rank emergency numbers by viability.
// For the test, make them all equal to INVALID so that the preferred PhoneAccount will be
// chosen.
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 46b1522..5b4e800 100755
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -249,6 +249,7 @@
@Override
public void createConnectionComplete(String id, Session.Info info) throws RemoteException {
+ Log.i(ConnectionServiceFixture.this, "createConnectionComplete: %s", id);
mConnectionServiceDelegateAdapter.createConnectionComplete(id, null /*Session.Info*/);
}
@@ -341,6 +342,14 @@
throws RemoteException { }
@Override
+ public void onUsingAlternativeUi(String activeCallId, boolean usingAlternativeUi,
+ Session.Info info) throws RemoteException { }
+
+ @Override
+ public void onTrackedByNonUiService(String activeCallId, boolean isTracked,
+ Session.Info info) throws RemoteException { }
+
+ @Override
public void playDtmfTone(String callId, char digit,
Session.Info info) throws RemoteException { }
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index 78b3332..0b926fe 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -35,6 +35,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -51,6 +52,7 @@
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
@@ -67,6 +69,7 @@
import android.telecom.TelecomManager;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
import com.android.internal.telecom.IInCallAdapter;
@@ -120,6 +123,7 @@
@Mock ClockProxy mClockProxy;
@Mock Analytics.CallInfoImpl mCallInfo;
@Mock NotificationManager mNotificationManager;
+ @Mock PermissionInfo mMockPermissionInfo;
private static final int CURRENT_USER_ID = 900973;
private static final String DEF_PKG = "defpkg";
@@ -140,6 +144,9 @@
private static final String NONUI_PKG = "nonui_pkg";
private static final String NONUI_CLASS = "nonui_cls";
private static final int NONUI_UID = 6;
+ private static final String APPOP_NONUI_PKG = "appop_nonui_pkg";
+ private static final String APPOP_NONUI_CLASS = "appop_nonui_cls";
+ private static final int APPOP_NONUI_UID = 7;
private static final PhoneAccountHandle PA_HANDLE =
new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
@@ -148,6 +155,8 @@
private InCallController mInCallController;
private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
private EmergencyCallHelper mEmergencyCallHelper;
+ private SystemStateHelper.SystemStateListener mSystemStateListener;
+ private CarModeTracker mCarModeTracker = spy(new CarModeTracker());
@Override
@Before
@@ -169,9 +178,17 @@
when(mMockCallsManager.getRoleManagerAdapter()).thenReturn(mMockRoleManagerAdapter);
when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
.thenReturn(mNotificationManager);
+ when(mMockPackageManager.getPermissionInfo(anyString(), anyInt())).thenReturn(
+ mMockPermissionInfo);
mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter,
- mEmergencyCallHelper, new CarModeTracker(), mClockProxy);
+ mEmergencyCallHelper, mCarModeTracker, mClockProxy);
+
+ ArgumentCaptor<SystemStateHelper.SystemStateListener> systemStateListenerArgumentCaptor
+ = ArgumentCaptor.forClass(SystemStateHelper.SystemStateListener.class);
+ verify(mMockSystemStateHelper).addListener(systemStateListenerArgumentCaptor.capture());
+ mSystemStateListener = systemStateListenerArgumentCaptor.getValue();
+
// Companion Apps don't have CONTROL_INCALL_EXPERIENCE permission.
doAnswer(invocation -> {
int uid = invocation.getArgument(0);
@@ -188,6 +205,8 @@
return new String[] { CAR2_PKG };
case NONUI_UID:
return new String[] { NONUI_PKG };
+ case APPOP_NONUI_UID:
+ return new String[] { APPOP_NONUI_PKG };
}
return null;
}).when(mMockPackageManager).getPackagesForUid(anyInt());
@@ -203,6 +222,9 @@
when(mMockPackageManager.checkPermission(
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
matches(NONUI_PKG))).thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mMockPackageManager.checkPermission(
+ matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
+ matches(APPOP_NONUI_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
when(mMockCallsManager.getAudioState()).thenReturn(new CallAudioState(false, 0, 0));
}
@@ -214,6 +236,24 @@
super.tearDown();
}
+ @SmallTest
+ @Test
+ public void testCarModeAppRemoval() {
+ setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
+ when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
+
+ mSystemStateListener.onCarModeChanged(666, CAR_PKG, true);
+ verify(mCarModeTracker).handleEnterCarMode(666, CAR_PKG);
+ assertTrue(mCarModeTracker.isInCarMode());
+
+ mSystemStateListener.onPackageUninstalled(CAR_PKG);
+ verify(mCarModeTracker).forceExitCarMode(CAR_PKG);
+ assertFalse(mCarModeTracker.isInCarMode());
+ }
+
@MediumTest
@Test
public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
@@ -306,7 +346,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -365,7 +406,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -443,7 +485,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -525,7 +568,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -651,7 +695,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -789,6 +834,79 @@
verifyBinding(bindIntentCaptor, 0, DEF_PKG, DEF_CLASS);
}
+ /**
+ * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
+ * supports third party app
+ */
+ @MediumTest
+ @Test
+ public void testBindToService_ThirdPartyApp() throws Exception {
+ setupMocks(false /* isExternalCall */);
+ setupMockPackageManager(false /* default */, false /* nonui */, true /* appop_nonui */,
+ true /* system */, false /* external calls */, false /* self mgd in default */,
+ false /* self mgd in car*/);
+
+ // Enable Third Party Companion App
+ when(mMockPackageManager.getPermissionInfo(anyString(), anyInt())).thenReturn(
+ mMockPermissionInfo);
+ when(mMockPermissionInfo.isAppOp()).thenReturn(true);
+ when(mMockAppOpsManager.unsafeCheckOpRawNoThrow(matches(
+ AppOpsManager.OPSTR_MANAGE_ONGOING_CALLS), eq(APPOP_NONUI_UID),
+ matches(APPOP_NONUI_PKG))).thenReturn(AppOpsManager.MODE_ALLOWED);
+
+ // Now bind; we should bind to the system dialer and app op non ui app.
+ mInCallController.bindToServices(mMockCall);
+
+ // Bind InCallServices
+ ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mMockContext, times(2)).bindServiceAsUser(
+ bindIntentCaptor.capture(),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
+ eq(UserHandle.CURRENT));
+
+ // Verify bind
+ assertEquals(2, bindIntentCaptor.getAllValues().size());
+
+ // Should have first bound to the system dialer.
+ verifyBinding(bindIntentCaptor, 0, SYS_PKG, SYS_CLASS);
+
+ // Should have next bound to the third party app op non ui app.
+ verifyBinding(bindIntentCaptor, 1, APPOP_NONUI_PKG, APPOP_NONUI_CLASS);
+ }
+
+ /**
+ * Ensures that the {@link InCallController} will bind to a non-ui service even if no ui service
+ * is bound if the call is self managed.
+ */
+ @MediumTest
+ @Test
+ public void testBindToService_NonUiSelfManaged() throws Exception {
+ setupMocks(false /* isExternalCall */, true);
+ setupMockPackageManager(false /* default */, true/* nonui */, true /* appop_nonui */,
+ true /* system */, false /* external calls */, false /* self mgd in default */,
+ false /* self mgd in car*/, true /* self managed in nonui */);
+
+ // we should bind to only the non ui app.
+ mInCallController.bindToServices(mMockCall);
+
+ // Bind InCallServices
+ ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mMockContext, times(1)).bindServiceAsUser(
+ bindIntentCaptor.capture(),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
+ eq(UserHandle.CURRENT));
+
+ // Verify bind
+ assertEquals(1, bindIntentCaptor.getAllValues().size());
+
+ // Should have bound to the third party non ui app.
+ verifyBinding(bindIntentCaptor, 0, NONUI_PKG, NONUI_CLASS);
+ }
+
@MediumTest
@Test
public void testSanitizeContactName() throws Exception {
@@ -901,8 +1019,8 @@
nullable(ContentResolver.class))).thenReturn(500L);
when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
- setupMockPackageManager(true /* default */, true /* nonui */, true /* system */,
- false /* external calls */,
+ setupMockPackageManager(true /* default */, true /* nonui */, false /* appop_nonui */ ,
+ true /* system */, false /* external calls */,
false /* self mgd in default*/, false /* self mgd in car*/);
mInCallController.bindToServices(mMockCall);
@@ -1072,6 +1190,7 @@
anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
when(mMockCall.isExternalCall()).thenReturn(isExternalCall);
when(mMockCall.isSelfManaged()).thenReturn(isSelfManagedCall);
+ when(mMockCall.visibleToInCallService()).thenReturn(isSelfManagedCall);
}
private ResolveInfo getDefResolveInfo(final boolean includeExternalCalls,
@@ -1083,6 +1202,7 @@
serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.applicationInfo.uid = DEF_UID;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
+ serviceInfo.enabled = true;
serviceInfo.metaData = new Bundle();
serviceInfo.metaData.putBoolean(
TelecomManager.METADATA_IN_CALL_SERVICE_UI, true);
@@ -1110,6 +1230,7 @@
serviceInfo.applicationInfo.uid = CAR2_UID;
}
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
+ serviceInfo.enabled = true;
serviceInfo.metaData = new Bundle();
serviceInfo.metaData.putBoolean(
TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI, true);
@@ -1131,6 +1252,7 @@
serviceInfo.name = SYS_CLASS;
serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.applicationInfo.uid = SYS_UID;
+ serviceInfo.enabled = true;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
}};
}
@@ -1142,11 +1264,12 @@
serviceInfo.name = COMPANION_CLASS;
serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.applicationInfo.uid = COMPANION_UID;
+ serviceInfo.enabled = true;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
}};
}
- private ResolveInfo getNonUiResolveinfo() {
+ private ResolveInfo getNonUiResolveinfo(boolean supportsSelfManaged) {
return new ResolveInfo() {{
serviceInfo = new ServiceInfo();
serviceInfo.packageName = NONUI_PKG;
@@ -1155,12 +1278,29 @@
serviceInfo.applicationInfo.uid = NONUI_UID;
serviceInfo.enabled = true;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
+ serviceInfo.metaData = new Bundle();
+ if (supportsSelfManaged) {
+ serviceInfo.metaData.putBoolean(
+ TelecomManager.METADATA_INCLUDE_SELF_MANAGED_CALLS, true);
+ }
+ }};
+ }
+
+ private ResolveInfo getAppOpNonUiResolveinfo() {
+ return new ResolveInfo() {{
+ serviceInfo = new ServiceInfo();
+ serviceInfo.packageName = APPOP_NONUI_PKG;
+ serviceInfo.name = APPOP_NONUI_CLASS;
+ serviceInfo.applicationInfo = new ApplicationInfo();
+ serviceInfo.applicationInfo.uid = APPOP_NONUI_UID;
+ serviceInfo.enabled = true;
+ serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
}};
}
private void setupMockPackageManager(final boolean useDefaultDialer,
final boolean useSystemDialer, final boolean includeExternalCalls) {
- setupMockPackageManager(useDefaultDialer, false, useSystemDialer, includeExternalCalls,
+ setupMockPackageManager(useDefaultDialer, false, false, useSystemDialer, includeExternalCalls,
false /* self mgd */, false /* self mgd */);
}
@@ -1168,16 +1308,28 @@
final boolean useSystemDialer, final boolean includeExternalCalls,
final boolean includeSelfManagedCallsInDefaultDialer,
final boolean includeSelfManagedCallsInCarModeDialer) {
- setupMockPackageManager(useDefaultDialer, false /* nonui */, useSystemDialer,
- includeExternalCalls, includeSelfManagedCallsInDefaultDialer,
+ setupMockPackageManager(useDefaultDialer, false /* nonui */, false /* appop_nonui */,
+ useSystemDialer, includeExternalCalls, includeSelfManagedCallsInDefaultDialer,
includeSelfManagedCallsInCarModeDialer);
}
private void setupMockPackageManager(final boolean useDefaultDialer,
- final boolean useNonUiInCalls,
+ final boolean useNonUiInCalls, final boolean useAppOpNonUiInCalls,
final boolean useSystemDialer, final boolean includeExternalCalls,
final boolean includeSelfManagedCallsInDefaultDialer,
final boolean includeSelfManagedCallsInCarModeDialer) {
+ setupMockPackageManager(useDefaultDialer, useNonUiInCalls/* nonui */,
+ useAppOpNonUiInCalls/* appop_nonui */,
+ useSystemDialer, includeExternalCalls, includeSelfManagedCallsInDefaultDialer,
+ includeSelfManagedCallsInCarModeDialer, false);
+ }
+
+ private void setupMockPackageManager(final boolean useDefaultDialer,
+ final boolean useNonUiInCalls, final boolean useAppOpNonUiInCalls,
+ final boolean useSystemDialer, final boolean includeExternalCalls,
+ final boolean includeSelfManagedCallsInDefaultDialer,
+ final boolean includeSelfManagedCallsInCarModeDialer,
+ final boolean includeSelfManagedCallsInNonUi) {
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
@@ -1215,14 +1367,18 @@
} else {
// InCallController uses a blank package name when querying for non-ui incalls
if (useNonUiInCalls) {
- resolveInfo.add(getNonUiResolveinfo());
+ resolveInfo.add(getNonUiResolveinfo(includeSelfManagedCallsInNonUi));
+ }
+ // InCallController uses a blank package name when querying for App Op non-ui incalls
+ if (useAppOpNonUiInCalls) {
+ resolveInfo.add(getAppOpNonUiResolveinfo());
}
}
return resolveInfo;
}
}).when(mMockPackageManager).queryIntentServicesAsUser(
- any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ any(Intent.class), anyInt(), eq(CURRENT_USER_ID));
}
private void setupMockPackageManagerLocationPermission(final String pkg,
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
index 8c0adfb..9269836 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
@@ -112,7 +112,7 @@
@Test
public void testEmptyGraph() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
@@ -125,7 +125,7 @@
@Test
public void testFiltersPerformOrder() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
@@ -143,7 +143,7 @@
@Test
public void testFiltersPerformInParallel() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
@@ -162,7 +162,7 @@
@Test
public void testFiltersTimeout() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
deleted file mode 100644
index 8e2d11e..0000000
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.telecom.tests;
-
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.CallLog.Calls;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.server.telecom.Call;
-import com.android.server.telecom.Timeouts;
-import com.android.server.telecom.callfiltering.CallFilterResultCallback;
-import com.android.server.telecom.callfiltering.CallFilteringResult;
-import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
-import com.android.server.telecom.TelecomSystem;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atMost;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(JUnit4.class)
-public class IncomingCallFilterTest extends TelecomTestCase {
- @Mock private CallFilterResultCallback mResultCallback;
- @Mock private Call mCall;
- private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
-
- @Mock private IncomingCallFilter.CallFilter mFilter1;
- @Mock private IncomingCallFilter.CallFilter mFilter2;
- @Mock private IncomingCallFilter.CallFilter mFilter3;
- @Mock private IncomingCallFilter.CallFilter mFilter4;
-
- @Mock private Timeouts.Adapter mTimeoutsAdapter;
-
- private static final Uri TEST_HANDLE = Uri.parse("tel:1235551234");
- private static final long LONG_TIMEOUT = 1000000;
- private static final long SHORT_TIMEOUT = 100;
-
- private static final CallFilteringResult PASS_CALL_RESULT =
- new Builder()
- .setShouldAllowCall(true)
- .setShouldReject(false)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .build();
-
- private static final CallFilteringResult ASYNC_BLOCK_CHECK_BLOCK_RESULT =
- new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(false)
- .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build();
-
- private static final CallFilteringResult DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT =
- new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build();
-
- private static final CallFilteringResult CALL_SCREENING_SERVICE_BLOCK_RESULT =
- new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
- .setCallScreeningAppName("com.android.thirdparty")
- .setCallScreeningComponentName(
- "com.android.thirdparty/"
- + "com.android.thirdparty.callscreeningserviceimpl")
- .build();
-
- private static final CallFilteringResult DEFAULT_RESULT = PASS_CALL_RESULT;
- private Handler mHandler = new Handler(Looper.getMainLooper());
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
- when(mCall.getHandle()).thenReturn(TEST_HANDLE);
- setTimeoutLength(LONG_TIMEOUT);
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- mHandler.removeCallbacksAndMessages(null);
- waitForHandlerAction(mHandler, 1000);
- super.tearDown();
- }
-
- @SmallTest
- @Test
- public void testAsyncBlockCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
- (ASYNC_BLOCK_CHECK_BLOCK_RESULT));
- }
-
- @SmallTest
- @Test
- public void testDirectToVoiceMailCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
- (DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT));
- }
-
- @SmallTest
- @Test
- public void testCallScreeningServiceBlockCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
- (CALL_SCREENING_SERVICE_BLOCK_RESULT));
- }
-
- @SmallTest
- @Test
- public void testPassCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(PASS_CALL_RESULT));
- }
-
- @SmallTest
- @Test
- public void testMultipleFiltersForAsyncBlockCheckFilter() {
- List<IncomingCallFilter.CallFilter> filters =
- new ArrayList<IncomingCallFilter.CallFilter>() {{
- add(mFilter1);
- add(mFilter2);
- add(mFilter3);
- add(mFilter4);
- }};
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters, mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
- verify(mFilter2).startFilterLookup(mCall, testFilter);
- verify(mFilter3).startFilterLookup(mCall, testFilter);
- verify(mFilter4).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
- testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(false)
- .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build()));
- }
-
- @SmallTest
- @Test
- public void testMultipleFiltersForDirectToVoicemailCallFilter() {
- List<IncomingCallFilter.CallFilter> filters =
- new ArrayList<IncomingCallFilter.CallFilter>() {{
- add(mFilter1);
- add(mFilter2);
- add(mFilter3);
- }};
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters, mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
- verify(mFilter2).startFilterLookup(mCall, testFilter);
- verify(mFilter3).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build()));
- }
-
- @SmallTest
- @Test
- public void testMultipleFiltersForCallScreeningServiceFilter() {
- List<IncomingCallFilter.CallFilter> filters =
- new ArrayList<IncomingCallFilter.CallFilter>() {{
- add(mFilter1);
- add(mFilter2);
- }};
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters, mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
- verify(mFilter2).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
- .setCallScreeningAppName("com.android.thirdparty")
- .setCallScreeningComponentName(
- "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl")
- .build()));
- }
-
- @SmallTest
- @Test
- public void testFilterTimeout() throws Exception {
- setTimeoutLength(SHORT_TIMEOUT);
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mResultCallback, timeout((int) SHORT_TIMEOUT * 2)).onCallFilteringComplete(eq(mCall),
- eq(DEFAULT_RESULT));
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- // verify that we don't report back again with the result
- verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
- any(CallFilteringResult.class));
- }
-
- @SmallTest
- @Test
- public void testFilterTimeoutDoesntTrip() throws Exception {
- setTimeoutLength(SHORT_TIMEOUT);
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- Thread.sleep(SHORT_TIMEOUT);
- verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
- any(CallFilteringResult.class));
- }
-
- @SmallTest
- @Test
- public void testToString() {
- assertEquals("[Allow, logged, notified]", PASS_CALL_RESULT.toString());
- assertEquals("[Reject, notified, mCallBlockReason = 1, mCallScreeningAppName = com" +
- ".android.thirdparty, mCallScreeningComponentName = com.android.thirdparty/com" +
- ".android.thirdparty.callscreeningserviceimpl]",
- CALL_SCREENING_SERVICE_BLOCK_RESULT.toString());
- assertEquals("[Reject, logged, mCallBlockReason = 3]",
- ASYNC_BLOCK_CHECK_BLOCK_RESULT.toString());
- }
-
- private void setTimeoutLength(long length) throws Exception {
- when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
- .thenReturn(length);
- }
-}
diff --git a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
index 9dd90f5..db44dcd 100644
--- a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
@@ -400,9 +400,9 @@
TelecomBroadcastReceiver.class);
assertNotNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- callBackIntent, PendingIntent.FLAG_NO_CREATE));
+ callBackIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
assertNotNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- smsIntent, PendingIntent.FLAG_NO_CREATE));
+ smsIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
}
@SmallTest
@@ -437,9 +437,9 @@
TelecomBroadcastReceiver.class);
assertNotNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- callBackIntent, PendingIntent.FLAG_NO_CREATE));
+ callBackIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
assertNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- smsIntent, PendingIntent.FLAG_NO_CREATE));
+ smsIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
}
@SmallTest
diff --git a/tests/src/com/android/server/telecom/tests/MissedInformationTest.java b/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
new file mode 100644
index 0000000..a8e1c5f
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom.tests;
+
+import static android.provider.CallLog.Calls.AUTO_MISSED_EMERGENCY_CALL;
+import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_DIALING;
+import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_RINGING;
+import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_SCREENING_SERVICE_SILENCED;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.IContentProvider;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.CallLog;
+import android.telecom.DisconnectCause;
+import android.telecom.TelecomManager;
+
+import com.android.server.telecom.Analytics;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallIntentProcessor;
+import com.android.server.telecom.CallState;
+import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.callfiltering.CallFilteringResult;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.util.Map;
+
+public class MissedInformationTest extends TelecomSystemTest {
+ private static final int TEST_TIMEOUT_MILLIS = 1000;
+ private static final String TEST_NUMBER = "650-555-1212";
+ private static final String TEST_NUMBER_1 = "7";
+ private static final String PACKAGE_NAME = "com.android.server.telecom.tests";
+ private static final String CALL_SCREENING_SERVICE_PACKAGE_NAME = "testapp";
+ private static final String CALL_SCREENING_COMPONENT_NAME = "testapp";
+
+ @Mock ContentResolver mContentResolver;
+ @Mock IContentProvider mContentProvider;
+ @Mock Call mEmergencyCall;
+ @Mock Analytics.CallInfo mCallInfo;
+ @Mock Call mIncomingCall;
+ private CallsManager mCallsManager;
+ private CallIntentProcessor.AdapterImpl mAdapter;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ mCallsManager = mTelecomSystem.getCallsManager();
+ mAdapter = new CallIntentProcessor.AdapterImpl(mCallsManager.getDefaultDialerCache());
+ when(mContentResolver.getPackageName()).thenReturn(PACKAGE_NAME);
+ when(mContentResolver.acquireProvider(any(String.class))).thenReturn(mContentProvider);
+ when(mContentProvider.call(any(String.class), any(String.class),
+ any(String.class), any(Bundle.class))).thenReturn(new Bundle());
+ doReturn(mContentResolver).when(mSpyContext).getContentResolver();
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testNotMissedCall() throws Exception {
+ IdPair testCall = startAndMakeActiveIncomingCall(
+ TEST_NUMBER,
+ mPhoneAccountA0.getAccountHandle(),
+ mConnectionServiceFixtureA);
+
+ mConnectionServiceFixtureA.
+ sendSetDisconnected(testCall.mConnectionId, DisconnectCause.LOCAL);
+ ContentValues values = verifyInsertionWithCapture();
+
+ Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
+ Analytics.CallInfoImpl callAnalytics = analyticsMap.get(testCall.mCallId);
+ assertEquals(MISSED_REASON_NOT_MISSED, callAnalytics.missedReason);
+ assertEquals(MISSED_REASON_NOT_MISSED,
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
+ }
+
+ @Test
+ public void testEmergencyCallPlacing() throws Exception {
+ Analytics.dumpToParcelableAnalytics();
+ setUpEmergencyCall();
+ mCallsManager.addCall(mEmergencyCall);
+ assertTrue(mCallsManager.isInEmergencyCall());
+
+ Intent intent = new Intent();
+ intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+ mPhoneAccountA0.getAccountHandle());
+ mAdapter.processIncomingCallIntent(mCallsManager, intent);
+
+ ContentValues values = verifyInsertionWithCapture();
+
+ Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
+ assertEquals(AUTO_MISSED_EMERGENCY_CALL,
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
+ for (Analytics.CallInfoImpl ci : analyticsMap.values()) {
+ assertEquals(AUTO_MISSED_EMERGENCY_CALL, ci.missedReason);
+ }
+ }
+
+ @Test
+ public void testMaximumDialingCalls() throws Exception {
+ Analytics.dumpToParcelableAnalytics();
+ IdPair testDialingCall = startAndMakeDialingOutgoingCall(
+ TEST_NUMBER,
+ mPhoneAccountA0.getAccountHandle(),
+ mConnectionServiceFixtureA);
+
+ Intent intent = new Intent();
+ intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+ mPhoneAccountA0.getAccountHandle());
+ mAdapter.processIncomingCallIntent(mCallsManager, intent);
+
+ ContentValues values = verifyInsertionWithCapture();
+
+ Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
+ for (String callId : analyticsMap.keySet()) {
+ if (callId.equals(testDialingCall.mCallId)) {
+ continue;
+ }
+ assertEquals(AUTO_MISSED_MAXIMUM_DIALING, analyticsMap.get(callId).missedReason);
+ }
+ assertEquals(AUTO_MISSED_MAXIMUM_DIALING,
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
+ }
+
+ @Test
+ public void testMaximumRingingCalls() throws Exception {
+ Analytics.dumpToParcelableAnalytics();
+ IdPair testRingingCall = startAndMakeRingingIncomingCall(
+ TEST_NUMBER,
+ mPhoneAccountA0.getAccountHandle(),
+ mConnectionServiceFixtureA);
+
+ Intent intent = new Intent();
+ intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+ mPhoneAccountA0.getAccountHandle());
+ mAdapter.processIncomingCallIntent(mCallsManager, intent);
+
+ ContentValues values = verifyInsertionWithCapture();
+
+ Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
+ for (String callId : analyticsMap.keySet()) {
+ if (callId.equals(testRingingCall.mCallId)) {
+ continue;
+ }
+ assertEquals(AUTO_MISSED_MAXIMUM_RINGING, analyticsMap.get(callId).missedReason);
+ }
+ assertEquals(AUTO_MISSED_MAXIMUM_RINGING,
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
+ }
+
+ @Test
+ public void testCallFiltersTimeout() throws Exception {
+ setUpIncomingCall();
+ CallFilteringResult result = new CallFilteringResult.Builder()
+ .setShouldAllowCall(true)
+ .build();
+ mCallsManager.onCallFilteringComplete(mIncomingCall, result, true);
+ mCallsManager.markCallAsDisconnected(mIncomingCall,
+ new DisconnectCause(DisconnectCause.MISSED));
+ ContentValues values = verifyInsertionWithCapture();
+
+ long missedReason = values.getAsLong(CallLog.Calls.MISSED_REASON);
+ assertTrue((missedReason & USER_MISSED_CALL_FILTERS_TIMEOUT) > 0);
+ missedReason = ((Analytics.CallInfoImpl) mIncomingCall.getAnalytics()).missedReason;
+ assertTrue((missedReason & USER_MISSED_CALL_FILTERS_TIMEOUT) > 0);
+ }
+
+ @Test
+ public void testCallScreeningServiceSilence() throws Exception {
+ setUpIncomingCall();
+ CallFilteringResult result = new CallFilteringResult.Builder()
+ .setShouldAllowCall(true)
+ .setShouldSilence(true)
+ .setCallScreeningAppName(CALL_SCREENING_SERVICE_PACKAGE_NAME)
+ .setCallScreeningComponentName(CALL_SCREENING_COMPONENT_NAME)
+ .build();
+ mCallsManager.onCallFilteringComplete(mIncomingCall, result, false);
+ assertTrue(mIncomingCall.isIncoming());
+ mCallsManager.markCallAsDisconnected(mIncomingCall,
+ new DisconnectCause(DisconnectCause.MISSED));
+ ContentValues values = verifyInsertionWithCapture();
+
+ long missedReason = values.getAsLong(CallLog.Calls.MISSED_REASON);
+ assertTrue((missedReason & USER_MISSED_CALL_SCREENING_SERVICE_SILENCED) > 0);
+ assertEquals(CALL_SCREENING_COMPONENT_NAME,
+ values.getAsString(CallLog.Calls.CALL_SCREENING_COMPONENT_NAME));
+ assertEquals(CALL_SCREENING_SERVICE_PACKAGE_NAME,
+ values.getAsString(CallLog.Calls.CALL_SCREENING_APP_NAME));
+ missedReason = ((Analytics.CallInfoImpl) mIncomingCall.getAnalytics()).missedReason;
+ assertTrue((missedReason & USER_MISSED_CALL_SCREENING_SERVICE_SILENCED) > 0);
+ }
+
+ private ContentValues verifyInsertionWithCapture() {
+ ArgumentCaptor<ContentValues> captor = ArgumentCaptor.forClass(ContentValues.class);
+ verify(mContentResolver, timeout(TEST_TIMEOUT_MILLIS))
+ .insert(any(Uri.class), captor.capture());
+ return captor.getValue();
+ }
+
+ private void setUpEmergencyCall() {
+ when(mEmergencyCall.isEmergencyCall()).thenReturn(true);
+ when(mEmergencyCall.getIntentExtras()).thenReturn(new Bundle());
+ when(mEmergencyCall.getAnalytics()).thenReturn(mCallInfo);
+ when(mEmergencyCall.getState()).thenReturn(CallState.ACTIVE);
+ when(mEmergencyCall.getContext()).thenReturn(mSpyContext);
+ when(mEmergencyCall.getHandle()).thenReturn(Uri.parse("tel:" + TEST_NUMBER));
+ }
+
+ private void setUpIncomingCall() throws Exception {
+ mIncomingCall = spy(new Call("0", mSpyContext, mCallsManager,
+ (TelecomSystem.SyncRoot) mTelecomSystem.getLock(),
+ null, mCallsManager.getPhoneNumberUtilsAdapter(), null,
+ null, null, mPhoneAccountA0.getAccountHandle(),
+ Call.CALL_DIRECTION_INCOMING, false, false,
+ mClockProxy, null));
+ mIncomingCall.initAnalytics();
+ when(mIncomingCall.getIntentExtras()).thenReturn(new Bundle());
+ when(mIncomingCall.getViaNumber()).thenReturn(TEST_NUMBER);
+ }
+}
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index 9470008..a5b78b7 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -229,7 +229,7 @@
mComponentContextFixture.putResource(R.string.dialer_default_class,
dialer_default_class_string);
when(mDefaultDialerCache.getSystemDialerApplication()).thenReturn(ui_package_string);
- when(mDefaultDialerCache.getSystemDialerComponent()).thenReturn(
+ when(mDefaultDialerCache.getDialtactsSystemDialerComponent()).thenReturn(
new ComponentName(ui_package_string, dialer_default_class_string));
int result = processIntent(intent, false).disconnectCause;
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index 00ef87c..a56036a 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -725,16 +725,20 @@
mComponentContextFixture.addConnectionService(componentC,
Mockito.mock(IConnectionService.class));
+ Bundle account1Extras = new Bundle();
+ account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1);
PhoneAccount account1 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentA, "c"), "c")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
- .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "A"))
+ .setExtras(account1Extras)
.build();
+ Bundle account2Extras = new Bundle();
+ account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2);
PhoneAccount account2 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentB, "b"), "b")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
- .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "B"))
+ .setExtras(account2Extras)
.build();
PhoneAccount account3 = new PhoneAccount.Builder(
@@ -814,18 +818,23 @@
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentZ,
Mockito.mock(IConnectionService.class));
+
+ Bundle account1Extras = new Bundle();
+ account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2);
PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "y"), "y")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
- .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "2"))
+ .setExtras(account1Extras)
.build();
+ Bundle account2Extras = new Bundle();
+ account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1);
PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "z"), "z")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
- .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "1"))
+ .setExtras(account2Extras)
.build();
PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(
diff --git a/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java b/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
index 2de3c83..893ae3d 100644
--- a/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
+++ b/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
@@ -16,6 +16,8 @@
package com.android.server.telecom.tests;
+import static junit.framework.Assert.fail;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -23,9 +25,11 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,6 +43,7 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.net.Uri;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.SystemStateHelper;
@@ -53,11 +58,10 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.util.reflection.FieldSetter;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
/**
* Unit tests for SystemStateHelper
@@ -128,16 +132,53 @@
@SmallTest
@Test
- public void testReceiverAndIntentFilter() {
- ArgumentCaptor<IntentFilter> intentFilter = ArgumentCaptor.forClass(IntentFilter.class);
- new SystemStateHelper(mContext);
- verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
+ public void testPackageRemoved() {
+ ArgumentCaptor<BroadcastReceiver> receiver =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ new SystemStateHelper(mContext).addListener(mSystemStateListener);
+ verify(mContext, atLeastOnce())
+ .registerReceiver(receiver.capture(), any(IntentFilter.class));
+ Intent packageRemovedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+ packageRemovedIntent.setData(Uri.fromParts("package", "com.android.test", null));
+ receiver.getValue().onReceive(mContext, packageRemovedIntent);
+ verify(mSystemStateListener).onPackageUninstalled("com.android.test");
+ }
- assertEquals(2, intentFilter.getValue().countActions());
- assertEquals(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED,
- intentFilter.getValue().getAction(0));
- assertEquals(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED,
- intentFilter.getValue().getAction(1));
+ @SmallTest
+ @Test
+ public void testReceiverAndIntentFilter() {
+ ArgumentCaptor<IntentFilter> intentFilterCaptor =
+ ArgumentCaptor.forClass(IntentFilter.class);
+ new SystemStateHelper(mContext);
+ verify(mContext, times(2)).registerReceiver(
+ any(BroadcastReceiver.class), intentFilterCaptor.capture());
+
+ Predicate<IntentFilter> carModeFilterTest = (intentFilter) ->
+ 2 == intentFilter.countActions()
+ && intentFilter.hasAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED)
+ && intentFilter.hasAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+
+ Predicate<IntentFilter> packageRemovedFilterTest = (intentFilter) ->
+ 1 == intentFilter.countActions()
+ && intentFilter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
+ && intentFilter.hasDataScheme("package");
+
+ List<IntentFilter> capturedFilters = intentFilterCaptor.getAllValues();
+ assertEquals(2, capturedFilters.size());
+ for (IntentFilter filter : capturedFilters) {
+ if (carModeFilterTest.test(filter)) {
+ carModeFilterTest = (i) -> false;
+ continue;
+ }
+ if (packageRemovedFilterTest.test(filter)) {
+ packageRemovedFilterTest = (i) -> false;
+ continue;
+ }
+ String failString = String.format("Registered intent filters not correct. Got %s",
+ capturedFilters.stream().map(IntentFilter::toString)
+ .collect(Collectors.joining("\n")));
+ fail(failString);
+ }
}
@SmallTest
@@ -147,7 +188,8 @@
ArgumentCaptor.forClass(BroadcastReceiver.class);
new SystemStateHelper(mContext).addListener(mSystemStateListener);
- verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
+ verify(mContext, atLeastOnce())
+ .registerReceiver(receiver.capture(), any(IntentFilter.class));
when(mIntentEnter.getAction()).thenReturn(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
receiver.getValue().onReceive(mContext, mIntentEnter);
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 68b10c6..5c1cdc4 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -69,7 +69,6 @@
import com.android.internal.telecom.IInCallAdapter;
import com.android.server.telecom.AsyncRingtonePlayer;
-import com.android.server.telecom.BluetoothPhoneServiceImpl;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
@@ -96,8 +95,6 @@
import com.android.server.telecom.Timeouts;
import com.android.server.telecom.WiredHeadsetManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
-import com.android.server.telecom.callfiltering.CallFilterResultCallback;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.ui.IncomingCallNotifier;
@@ -203,7 +200,6 @@
@Mock HeadsetMediaButton mHeadsetMediaButton;
@Mock ProximitySensorManager mProximitySensorManager;
@Mock InCallWakeLockController mInCallWakeLockController;
- @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
@Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
@Mock IncomingCallNotifier mIncomingCallNotifier;
@Mock ClockProxy mClockProxy;
@@ -487,7 +483,6 @@
proximitySensorManagerFactory,
inCallWakeLockControllerFactory,
() -> mAudioService,
- (context, lock, callsManager, phoneAccountRegistrar) -> mBluetoothPhoneServiceImpl,
mConnServFMFactory,
mTimeoutsAdapter,
mAsyncRingtonePlayer,
@@ -525,16 +520,6 @@
},
mClockProxy,
mRoleManagerAdapter,
- new IncomingCallFilter.Factory() {
- @Override
- public IncomingCallFilter create(Context context,
- CallFilterResultCallback listener, com.android.server.telecom.Call call,
- TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<IncomingCallFilter.CallFilter> filters) {
- return new IncomingCallFilter(context, listener, call, lock,
- timeoutsAdapter, filters, mHandlerThread.getThreadHandler());
- }
- },
new ContactsAsyncHelper.Factory() {
@Override
public ContactsAsyncHelper create(
@@ -931,7 +916,12 @@
// Wait for the handler to start the CallerInfo lookup
waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ // Wait a few more times to address flakiness due to timing issues.
+ waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+
// Ensure callback to CS on successful creation happened.
+
verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
.createConnectionComplete(anyString(), any());
@@ -1117,6 +1107,54 @@
return ids;
}
+ protected IdPair startAndMakeDialingOutgoingCall(
+ String number,
+ PhoneAccountHandle phoneAccountHandle,
+ ConnectionServiceFixture connectionServiceFixture) throws Exception {
+ IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
+ Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
+
+ connectionServiceFixture.sendSetDialing(ids.mConnectionId);
+ if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
+ assertEquals(Call.STATE_DIALING,
+ mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+ assertEquals(Call.STATE_DIALING,
+ mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+ }
+
+ return ids;
+ }
+
+ protected IdPair startAndMakeRingingIncomingCall(
+ String number,
+ PhoneAccountHandle phoneAccountHandle,
+ ConnectionServiceFixture connectionServiceFixture) throws Exception {
+ IdPair ids = startIncomingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
+
+ if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
+ assertEquals(Call.STATE_RINGING,
+ mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+ assertEquals(Call.STATE_RINGING,
+ mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+ mInCallServiceFixtureX.mInCallAdapter
+ .answerCall(ids.mCallId, VideoProfile.STATE_AUDIO_ONLY);
+
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
+ if (!VideoProfile.isVideo(VideoProfile.STATE_AUDIO_ONLY)) {
+ verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
+ .answer(eq(ids.mConnectionId), any());
+ } else {
+ verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
+ .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_AUDIO_ONLY),
+ any());
+ }
+ }
+ return ids;
+ }
+
protected static void assertTrueWithTimeout(Predicate<Void> predicate) {
int elapsed = 0;
while (elapsed < TEST_TIMEOUT) {