Snap for 8426163 from 2d2dc88e8a5f21f4f5efe4df1d954b8bed05d2d2 to mainline-tzdata2-release
Change-Id: I7bcd7ba3742d6b11b5198e74b1040ea90d677306
diff --git a/Android.bp b/Android.bp
index b7eb450..0d89b00 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,7 +1,3 @@
-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 45e3151..7c57599 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,76 +15,80 @@
-->
<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.READ_PROJECTION_STATE"/>
- <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
@@ -100,61 +104,60 @@
<!-- 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:exported="true">
+ android:label="@string/userCallActivityLabel"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:permission="android.permission.CALL_PHONE"
+ android:excludeFromRecents="true"
+ android:process=":ui">
<!-- 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>
@@ -164,31 +167,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:exported="true"
- 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>
@@ -198,130 +200,123 @@
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:exported="true"
- 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:exported="true">
+ android:process="system">
<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:exported="true">
+ android:label="@string/respond_via_sms_setting_title"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.DialerSettings"
+ android:process=":ui">
<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:exported="true">
+ android:label="@string/enable_account_preference_title"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.DialerSettings"
+ android:process=":ui">
<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:exported="true">
+ android:singleUser="true"
+ android:process="system">
<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:exported="true">
+ android:singleUser="true"
+ android:process="system">
<intent-filter>
- <action android:name="android.telecom.ITelecomService"/>
+ <action android:name="android.telecom.ITelecomService" />
</intent-filter>
</service>
diff --git a/OWNERS b/OWNERS
index 39be2c1..94409ef 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,6 +1,4 @@
breadley@google.com
hallliu@google.com
tgunn@google.com
-xiaotonj@google.com
-shuoq@google.com
-rgreenwalt@google.com
+paulye@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 2e14650..75feeb6 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -16,15 +16,5 @@
}
]
}
- ],
- "presubmit-large": [
- {
- "name": "CtsTelecomTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- }
]
}
diff --git a/res/raw/InCallQualityNotification.ogg b/res/raw/InCallQualityNotification.ogg
deleted file mode 100644
index 84c029a..0000000
--- a/res/raw/InCallQualityNotification.ogg
+++ /dev/null
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 408021f..2857be3 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/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="1825598513414129827">"Foonoproepe"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Oproepbestuur"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Bel"</string>
<string name="unknown" msgid="6993977514360123431">"Onbekend"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Gemiste oproep"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index a5fe872..df8215c 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/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="1825598513414129827">"የስልክ ጥሪዎች"</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>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 8dc37e7..7e204d0 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/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="1825598513414129827">"مكالمات هاتفية"</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>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 0808bbf..2f5de68 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/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="1825598513414129827">"ফ’ন কল"</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>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index e38e653..53817b3 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/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="1825598513414129827">"Telefon Zəngləri"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Zənglərin idarəolunması"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Naməlum"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Buraxılmış zəng"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 5646cb4..eba8c5c 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/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="1825598513414129827">"Telefonski pozivi"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Upravljanje pozivima"</string>
<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>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index b92f69a..b6dd707 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/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="1825598513414129827">"Тэлефонныя выклікі"</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>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 84e1a3d..7afddc2 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/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="1825598513414129827">"Телефонни обаждания"</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>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 3da181c..cf04d40 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/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="1825598513414129827">"ফোন কল"</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>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index d56feeb..1968357 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/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="1825598513414129827">"Telefonski pozivi"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Upravljanje pozivima"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Nepoznato"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Propušteni poziv"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 7e2c81e..69a7b6e 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/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="1825598513414129827">"Trucades telefòniques"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestió de trucades"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telèfon"</string>
<string name="unknown" msgid="6993977514360123431">"Desconegut"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Trucada perduda"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index ec6125b..1730a30 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/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="1825598513414129827">"Telefonní hovory"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Správa hovorů"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Neznámý volající"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Zmeškaný hovor"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index d4bc20e..6a208c4 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/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="1825598513414129827">"Telefonopkald"</string>
+ <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>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index bcf62ed..f60d207 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/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="1825598513414129827">"Telefonanrufe"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Anrufverwaltung"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Unbekannt"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Entgangener Anruf"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index a4498ce..ab523c1 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/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="1825598513414129827">"Τηλεφωνικές κλήσεις"</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>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index d422e58..7ce0e53 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/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="1825598513414129827">"Phone calls"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Call Management"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Phone"</string>
<string name="unknown" msgid="6993977514360123431">"Unknown"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Missed call"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index d422e58..7ce0e53 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/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="1825598513414129827">"Phone calls"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Call Management"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Phone"</string>
<string name="unknown" msgid="6993977514360123431">"Unknown"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Missed call"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index d422e58..7ce0e53 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/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="1825598513414129827">"Phone calls"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Call Management"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Phone"</string>
<string name="unknown" msgid="6993977514360123431">"Unknown"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Missed call"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index d422e58..7ce0e53 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/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="1825598513414129827">"Phone calls"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Call Management"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Phone"</string>
<string name="unknown" msgid="6993977514360123431">"Unknown"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Missed call"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index f533e0a..3b3a983 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/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="1825598513414129827">"Phone Calls"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Call Management"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Phone"</string>
<string name="unknown" msgid="6993977514360123431">"Unknown"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Missed call"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 9da169d..826b877 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/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="1825598513414129827">"Llamadas telefónicas"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Administración de llamadas"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Teléfono"</string>
<string name="unknown" msgid="6993977514360123431">"Desconocida"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Llamada perdida"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 68499c2..b7b9cff 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/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="1825598513414129827">"Llamadas"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestión de llamadas"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Teléfono"</string>
<string name="unknown" msgid="6993977514360123431">"Desconocido"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Llamada perdida"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 34bd333..bb291ad 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/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="1825598513414129827">"Telefonikõned"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Kõnehaldus"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Tundmatu"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Vastamata kõne"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 79b9524..1191f52 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/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="1825598513414129827">"Telefono-deiak"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Deien kudeaketa"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefonoa"</string>
<string name="unknown" msgid="6993977514360123431">"Ezezaguna"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Dei galdua"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 991ee5b..c873159 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/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="1825598513414129827">"تماسهای تلفنی"</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>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 3ad0c23..74cdf7e 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/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="1825598513414129827">"Puhelut"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Puhelujen hallinta"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Puhelin"</string>
<string name="unknown" msgid="6993977514360123431">"Tuntematon"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Vastaamatta jäänyt puhelu"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 46bc45a..5061eda 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/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="1825598513414129827">"Appels téléphoniques"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestion des appels"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Téléphone"</string>
<string name="unknown" msgid="6993977514360123431">"Inconnu"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Appel manqué"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index bee3695..c2a95a2 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/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="1825598513414129827">"Appels téléphoniques"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestion des appels"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Téléphone"</string>
<string name="unknown" msgid="6993977514360123431">"Inconnu"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Appel manqué"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index cc5efc2..c62fffc 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/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="1825598513414129827">"Chamadas telefónicas"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Xestión de chamadas"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Teléfono"</string>
<string name="unknown" msgid="6993977514360123431">"Descoñecido"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Chamada perdida"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index e04f38c..731618a 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/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="1825598513414129827">"Phone Calls"</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>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 94fcdb1..4562a5f 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/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="1825598513414129827">"फ़ोन कॉल"</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>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 7928978..d341565 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/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="1825598513414129827">"Telefonski pozivi"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Upravljanje pozivima"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Nepoznato"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Propušteni poziv"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 7bbff68..55e5535 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/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="1825598513414129827">"Telefonhívások"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Híváskezelés"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Ismeretlen"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Nem fogadott hívás"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 851e4e9..98a3bc1 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/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="1825598513414129827">"Հեռախոսազանգեր"</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>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index d71cd15..f479340 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/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="1825598513414129827">"Panggilan Telepon"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Pengelolaan Panggilan Telepon"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telepon"</string>
<string name="unknown" msgid="6993977514360123431">"Tidak diketahui"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Panggilan tak terjawab"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 2c5ef10..442b9d5 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/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="1825598513414129827">"Símtöl"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Símtalastjórnun"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Sími"</string>
<string name="unknown" msgid="6993977514360123431">"Óþekkt"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Ósvarað símtal"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 97a23d0..60f32d7 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/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="1825598513414129827">"Telefonate"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestione chiamate"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefono"</string>
<string name="unknown" msgid="6993977514360123431">"Sconosciuto"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Chiamata persa"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 8811efb..17e4a1b 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/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="1825598513414129827">"שיחות טלפון"</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>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index d78bce9..a11d8d2 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/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="1825598513414129827">"電話"</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>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index f3ac3d6..be27e8b 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/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="1825598513414129827">"სატელეფონო ზარები"</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>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 22f7d28..0bab244 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/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="1825598513414129827">"Телефон қоңыраулары"</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>
@@ -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>
@@ -90,7 +90,7 @@
<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>
+ <string name="cant_call_due_to_no_supported_service" msgid="1635626384149947077">"Қоңырау шалу мүмкін емес, себебі бұндай қоңырауларға қолдау көрсететін есептік жазба жоқ."</string>
<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>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 7186180..58b2abf 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/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="1825598513414129827">"Phone Calls"</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>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index acee7a9..dff4d0a 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/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="1825598513414129827">"ಫೋನ್ ಕರೆಗಳು"</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>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0134017..1a29b2e 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/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="1825598513414129827">"전화 통화"</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>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index ad7a017..83e498e 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/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="1825598513414129827">"Телефон чалуулар"</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>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 8118fa8..64142ca 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/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="1825598513414129827">"ການໂທລະສັບ"</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>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 34c2997..29090d1 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/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="1825598513414129827">"Telefono skambučiai"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Skambučių tvarkymas"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefonas"</string>
<string name="unknown" msgid="6993977514360123431">"Nežinomas"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Praleistas skambutis"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 65fe942..782777d 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/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="1825598513414129827">"Tālruņa zvani"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Zvanu pārvaldība"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Tālrunis"</string>
<string name="unknown" msgid="6993977514360123431">"Nezināms"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Neatbildēts zvans"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 87de64f..a9b3cc3 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="1825598513414129827">"Телефонски повици"</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>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 36bb494..5c64034 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="1825598513414129827">"ഫോൺ കോളുകൾ"</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>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index d1f5273..cdef26b 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/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="1825598513414129827">"Утасны дуудлага"</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>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 6fbdc03..c235aab 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/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="1825598513414129827">"फोन कॉल"</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>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 7571b9d..b43b554 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/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="1825598513414129827">"Panggilan Telefon"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Pengurusan Panggilan"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Tidak diketahui"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Panggilan tidak dijawab"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index ac6965f..4d94c1a 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/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="1825598513414129827">"ဖုန်းခေါ်ဆိုမှုများ"</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>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index df39be6..3f65c62 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/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="1825598513414129827">"Telefonanrop"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Administrering av samtaler"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Ukjent"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Tapt anrop"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index e38ed9d..5ef8bc0 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/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="1825598513414129827">"फोन कलहरू"</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>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 4051118..166e95d 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/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="1825598513414129827">"Telefoongesprekken"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Oproepbeheer"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefoon"</string>
<string name="unknown" msgid="6993977514360123431">"Onbekend"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Gemist gesprek"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 758beda..e3ca712 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/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="1825598513414129827">"ଫୋନ୍ କଲଗୁଡ଼ିକ"</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>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index e08b5e9..2b94316 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/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="1825598513414129827">"ਫ਼ੋਨ ਕਾਲਾਂ"</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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index f341da7..9cb1980 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/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="1825598513414129827">"Połączenia telefoniczne"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Zarządzanie połączeniami"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Nieznany"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Nieodebrane połączenie"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 42b435e..bb5213e 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/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="1825598513414129827">"Chamadas telefónicas"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestão de chamadas"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefone"</string>
<string name="unknown" msgid="6993977514360123431">"Desconhecido"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Chamada não atendida"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 68bd2c5..5d88619 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/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="1825598513414129827">"Chamadas telefônicas"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gerenciamento de chamadas"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefone"</string>
<string name="unknown" msgid="6993977514360123431">"Desconhecido"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Chamada perdida"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index adb1ff8..a95d4a4 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/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="1825598513414129827">"Apeluri telefonice"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Gestionarea apelurilor"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Necunoscut"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Apel nepreluat"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 49ab1db..a50907a 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/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="1825598513414129827">"Телефонные звонки"</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>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 315a0dc..b73272b 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/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="1825598513414129827">"දුරකථන ඇමතුම්"</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>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 5209880..0d79f1a 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/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="1825598513414129827">"Telefonické hovory"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Správa hovorov"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefón"</string>
<string name="unknown" msgid="6993977514360123431">"Neznáme"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Zmeškaný hovor"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 845e88b..e16de63 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/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="1825598513414129827">"Telefonski klici"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Upravljanje klicev"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Neznano"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Neodgovorjeni klic"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 6ae9e26..53f4efc 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/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="1825598513414129827">"Telefonatat"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Menaxhimi i thirrjes"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefoni"</string>
<string name="unknown" msgid="6993977514360123431">"I panjohur"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Telefonatë e humbur"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 6d83483..adfece0 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/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="1825598513414129827">"Телефонски позиви"</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>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 22e526b..b646cbb 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/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="1825598513414129827">"Telefonsamtal"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Samtalshantering"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Okänd"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Missat samtal"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index cc17765..d1142f7 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/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="1825598513414129827">"Simu"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Kudhibiti Simu"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Simu"</string>
<string name="unknown" msgid="6993977514360123431">"Haijulikani"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Simu uliyokosa"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 0608652..ee48214 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/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="1825598513414129827">"ஃபோன் அழைப்புகள்"</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>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 22c6d2a..cdf805d 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/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="1825598513414129827">"ఫోన్ కాల్స్"</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>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 0def6f6..615abb9 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/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="1825598513414129827">"โทรศัพท์"</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>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 2889d15..998abef 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/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="1825598513414129827">"Mga Tawag sa Telepono"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Pamamahala sa Tawag"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telepono"</string>
<string name="unknown" msgid="6993977514360123431">"Di-kilala"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Hindi nasagot na tawag"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 2b3cfc5..2e02f8c 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/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="1825598513414129827">"Telefon Aramaları"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Çağrı Yönetimi"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Telefon"</string>
<string name="unknown" msgid="6993977514360123431">"Bilinmiyor"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Cevapsız çağrı"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 762341c..d86b3eb 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/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="1825598513414129827">"Телефонні виклики"</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>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index bc81512..20cca1b 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/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="1825598513414129827">"فون کالز"</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>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index cda0a1b..3271245 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="1825598513414129827">"Telefon chaqiruvlari"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Chaqiruvlar 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>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index d4195b6..c6fe44a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/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="1825598513414129827">"Cuộc gọi điện thoại"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Quản lý cuộc gọi"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Điện thoại"</string>
<string name="unknown" msgid="6993977514360123431">"Không xác định"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Cuộc gọi nhỡ"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 1c9ed1b..6080b06 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/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="1825598513414129827">"电话"</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>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 98f1fa1..0f26c9d 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/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="1825598513414129827">"電話通話"</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>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 3c87562..7c98928 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/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="1825598513414129827">"電話"</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>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 9f5ef44..30c147d 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/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="1825598513414129827">"Amakholi Wefoni"</string>
+ <string name="telecommAppLabel" product="default" msgid="3077225713817780583">"Ukuphathwa kwekholi"</string>
<string name="userCallActivityLabel" product="default" msgid="3605391260292846248">"Ifoni"</string>
<string name="unknown" msgid="6993977514360123431">"Akwaziwa"</string>
<string name="notification_missedCallTitle" msgid="5060387047205532974">"Ikholi ekulahlekele"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index b0e50b0..9cbbf46 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -69,8 +69,4 @@
<!-- 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/values/strings.xml b/res/values/strings.xml
index 01bb88c..df08d7c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -17,10 +17,8 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Official label of the Telecomm/Phone app, as seen in "Manage Applications"
and other settings UIs. This is the "app name" used in notification, recents,
- and app info screens. The term "phone calls" is used since an end user would more commonly
- think of the stuff the Telecom framework deals with as having to do with "phone calls",
- not "call management" (even though that is technically more accurate). -->
- <string name="telecommAppLabel" product="default">Phone Calls</string>
+ and app info screens. -->
+ <string name="telecommAppLabel" product="default">Call Management</string>
<!-- Title used for the activity for placing a call. This name appears
in activity disambig dialogs -->
diff --git a/res/xml/activity_blocked_numbers.xml b/res/xml/activity_blocked_numbers.xml
index df1a759..f884ec9 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="48dp"
+ android:layout_height="wrap_content"
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 73ed2af..32c4c5d 100644
--- a/res/xml/enhanced_call_blocking_settings.xml
+++ b/res/xml/enhanced_call_blocking_settings.xml
@@ -41,4 +41,8 @@
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 9dbfc2f..3cdd771 100644
--- a/res/xml/layout_blocked_number.xml
+++ b/res/xml/layout_blocked_number.xml
@@ -28,8 +28,9 @@
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/scripts/aosp_tag_preupload.py b/scripts/aosp_tag_preupload.py
index bfcdbd6..77a9714 100755
--- a/scripts/aosp_tag_preupload.py
+++ b/scripts/aosp_tag_preupload.py
@@ -41,18 +41,15 @@
commit_msg = subprocess.check_output(["git", "show",
sys.argv[1], "--no-notes"])
for commit_line in commit_msg.splitlines():
- # Some lines in the commit message will be given to us as bytes
- commit_line_str = str(commit_line)
- if re.search(AOSP_COMMIT_TAG_REGEX, str(commit_line_str), re.IGNORECASE):
- _check_aosp_message(commit_line_str)
+ if re.search(AOSP_COMMIT_TAG_REGEX, commit_line, re.IGNORECASE):
+ _check_aosp_message(commit_line)
print(ERROR_MESSAGE)
- # Print the warning, but do not fail the presubmit check.
- sys.exit(77)
+ sys.exit(0)
def _is_in_aosp():
branch_info = subprocess.check_output(["git", "branch", "-vv"])
- return re.search(AOSP_BRANCH_REGEX, str(branch_info)) is not None
+ return re.search(AOSP_BRANCH_REGEX, branch_info) is not None
def _check_aosp_message(aosp_line):
if re.search(AOSP_COMMIT_LINK_REGEX, aosp_line):
@@ -62,8 +59,7 @@
sys.exit(0)
print(ERROR_MESSAGE)
- # Print the warning, but do not fail the presubmit check.
- sys.exit(77)
+ sys.exit(0)
if __name__ == '__main__':
main()
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index d6780ed..9c227a6 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -208,9 +208,6 @@
public void setCallSource(int callSource) {
}
-
- public void setMissedReason(long missedReason) {
- }
}
/**
@@ -245,7 +242,6 @@
public List<TelecomLogClass.InCallServiceInfo> inCallServiceInfos;
public int callProperties = 0;
public int callSource = CALL_SOURCE_UNSPECIFIED;
- public long missedReason;
private long mTimeOfLastVideoEvent = -1;
@@ -258,7 +254,6 @@
connectionService = "";
videoEvents = new LinkedList<>();
inCallServiceInfos = new LinkedList<>();
- missedReason = 0;
}
CallInfoImpl(CallInfoImpl other) {
@@ -277,7 +272,6 @@
this.videoEvents = other.videoEvents;
this.callProperties = other.callProperties;
this.callSource = other.callSource;
- this.missedReason = other.missedReason;
if (other.callTerminationReason != null) {
this.callTerminationReason = new DisconnectCause(
@@ -348,13 +342,6 @@
}
@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;
}
@@ -412,7 +399,6 @@
+ " isEmergency: " + isEmergency + '\n'
+ " callTechnologies: " + getCallTechnologiesAsString() + '\n'
+ " callTerminationReason: " + getCallDisconnectReasonString() + '\n'
- + " missedReason: " + getMissedReasonString() + '\n'
+ " connectionService: " + connectionService + '\n'
+ " isVideoCall: " + isVideo + '\n'
+ " inCallServices: " + getInCallServicesString() + '\n'
@@ -540,27 +526,20 @@
}
}
- private String getMissedReasonString() {
- //TODO: Implement this
- return null;
- }
-
private String getInCallServicesString() {
StringBuilder s = new StringBuilder();
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");
- }
+ 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();
@@ -633,7 +612,7 @@
}
public static CallInfo initiateCallAnalytics(String callId, int direction) {
- Log.i(TAG, "Starting analytics for call " + callId);
+ Log.d(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 e4eed87..a43b3cd 100644
--- a/src/com/android/server/telecom/BluetoothHeadsetProxy.java
+++ b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
@@ -36,6 +36,19 @@
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
new file mode 100644
index 0000000..f2ea950
--- /dev/null
+++ b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
@@ -0,0 +1,932 @@
+/*
+ * 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 100644
new mode 100755
index 0218124..df6322c
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -16,8 +16,6 @@
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;
@@ -35,12 +33,8 @@
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.CallDiagnosticService;
-import android.telecom.CallDiagnostics;
import android.telecom.CallerInfo;
import android.telecom.Conference;
import android.telecom.Connection;
@@ -57,11 +51,9 @@
import android.telecom.StatusHints;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
-import android.telephony.CallQuality;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
-import android.telephony.ims.ImsReasonInfo;
import android.text.TextUtils;
import android.widget.Toast;
@@ -82,10 +74,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
/**
* Encapsulates all aspects of a given phone call throughout its lifecycle, starting
@@ -162,10 +151,6 @@
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);
- void onReceivedCallQualityReport(Call call, CallQuality callQuality);
- void onCallerNumberVerificationStatusChanged(Call call, int callerNumberVerificationStatus);
}
public abstract static class ListenerBase implements Listener {
@@ -254,15 +239,6 @@
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) {}
- @Override
- public void onReceivedCallQualityReport(Call call, CallQuality callQuality) {}
- @Override
- public void onCallerNumberVerificationStatusChanged(Call call,
- int callerNumberVerificationStatus) {}
}
private final CallerInfoLookupHelper.OnQueryCompleteListener mCallerInfoQueryListener =
@@ -531,15 +507,6 @@
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.
*/
@@ -578,7 +545,7 @@
private ParcelFileDescriptor[] mConnectionServiceToInCallStreams;
/**
- * True if we're supposed to start this call with RTT, either due to the settings switch or due
+ * True if we're supposed to start this call with RTT, either due to the master switch or due
* to an extra.
*/
private boolean mDidRequestToStartWithRtt = false;
@@ -621,7 +588,7 @@
/**
* Indicates whether this call is using one of the
- * {@link com.android.server.telecom.callfiltering.CallFilter} modules.
+ * {@link com.android.server.telecom.callfiltering.IncomingCallFilter.CallFilter} modules.
*/
private boolean mIsUsingCallFiltering = false;
@@ -644,51 +611,6 @@
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;
-
- /**
- * Set to {@code true} if we received a valid response ({@code null} or otherwise) from
- * the {@link CallDiagnostics#onCallDisconnected(ImsReasonInfo)} or
- * {@link CallDiagnostics#onCallDisconnected(int, int)} calls. This is used to detect a timeout
- * when awaiting a response from the call diagnostic service.
- */
- private boolean mReceivedCallDiagnosticPostCallResponse = false;
-
- /**
- * {@link CompletableFuture} used to delay posting disconnection and removal to a call until
- * after a {@link CallDiagnosticService} is able to handle the disconnection and provide a
- * disconnect message via {@link CallDiagnostics#onCallDisconnected(ImsReasonInfo)} or
- * {@link CallDiagnostics#onCallDisconnected(int, int)}.
- */
- private CompletableFuture<Boolean> mDisconnectFuture;
-
- /**
* Persists the specified parameters and initializes the new instance.
* @param context The context.
* @param repository The connection service repository.
@@ -770,8 +692,6 @@
mClockProxy = clockProxy;
mToastFactory = toastFactory;
mCreationTimeMillis = mClockProxy.currentTimeMillis();
- mMissedReason = MISSED_REASON_NOT_MISSED;
- mStartRingTime = 0;
}
/**
@@ -935,7 +855,7 @@
PhoneAccountHandle delegatePhoneAccountHandle = getDelegatePhoneAccountHandle();
boolean isTargetSameAsRemote = targetPhoneAccountHandle != null
&& targetPhoneAccountHandle.equals(remotePhoneAccountHandle);
- if (Objects.equals(delegatePhoneAccountHandle, targetPhoneAccountHandle)) {
+ if (delegatePhoneAccountHandle.equals(targetPhoneAccountHandle)) {
s.append(">>>");
}
s.append("Target");
@@ -1120,31 +1040,6 @@
}
/**
- * Handles an incoming overridden disconnect message for this call.
- *
- * We only care if the disconnect is handled via a future.
- * @param message the overridden disconnect message.
- */
- public void handleOverrideDisconnectMessage(@Nullable CharSequence message) {
- Log.i(this, "handleOverrideDisconnectMessage; callid=%s, msg=%s", getId(), message);
-
- if (isDisconnectHandledViaFuture()) {
- mReceivedCallDiagnosticPostCallResponse = true;
- if (message != null) {
- Log.addEvent(this, LogUtils.Events.OVERRIDE_DISCONNECT_MESSAGE, message);
- // Replace the existing disconnect cause in this call
- setOverrideDisconnectCauseCode(new DisconnectCause(DisconnectCause.ERROR, message,
- message, null));
- }
-
- mDisconnectFuture.complete(true);
- } else {
- Log.w(this, "handleOverrideDisconnectMessage; callid=%s - got override when unbound",
- getId());
- }
- }
-
- /**
* 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
* misbehave and they do this very often. The result is that we do not enforce state transitions
@@ -1229,12 +1124,6 @@
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.
@@ -1328,8 +1217,6 @@
public void setCallerNumberVerificationStatus(
@Connection.VerificationStatus int callerNumberVerificationStatus) {
mCallerNumberVerificationStatus = callerNumberVerificationStatus;
- mListeners.forEach(l -> l.onCallerNumberVerificationStatusChanged(this,
- callerNumberVerificationStatus));
}
public @Connection.VerificationStatus int getCallerNumberVerificationStatus() {
@@ -1366,9 +1253,6 @@
} catch (IllegalStateException ise) {
Log.e(this, ise, "setHandle: can't determine if number is emergency");
mIsEmergencyCall = false;
- } catch (RuntimeException r) {
- Log.e(this, r, "setHandle: can't determine if number is emergency");
- mIsEmergencyCall = false;
}
mAnalytics.setCallIsEmergency(mIsEmergencyCall);
}
@@ -1393,8 +1277,6 @@
number.equals(eNumber.getNumber()));
} catch (IllegalStateException ise) {
return false;
- } catch (RuntimeException r) {
- return false;
}
}
@@ -1713,14 +1595,6 @@
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);
@@ -1777,7 +1651,6 @@
PhoneAccountRegistrar phoneAccountRegistrar = mCallsManager.getPhoneAccountRegistrar();
boolean isWorkCall = false;
boolean isCallRecordingToneSupported = false;
- boolean isSimCall = false;
PhoneAccount phoneAccount =
phoneAccountRegistrar.getPhoneAccountUnchecked(mTargetPhoneAccountHandle);
if (phoneAccount != null) {
@@ -1795,11 +1668,9 @@
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;
}
/**
@@ -1980,13 +1851,6 @@
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.
@@ -2028,16 +1892,6 @@
}
}
- boolean wasDowngradedConference =
- (previousProperties & Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE) != 0;
- boolean isDowngradedConference =
- (connectionProperties & Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE) != 0;
- if (wasDowngradedConference && !isDowngradedConference) {
- Log.i(this, "DOWNGRADED_CONFERENCE property removed; setting"
- + " conference state to false");
- setConferenceState(false);
- }
-
mAnalytics.addCallProperties(mConnectionProperties);
int xorProps = previousProperties ^ mConnectionProperties;
@@ -2575,7 +2429,7 @@
"reject call failed due to null CS callId=%s", getId());
}
Log.addEvent(this, LogUtils.Events.REQUEST_REJECT, reason);
- } else if (isRinging("reject") || isAnswered("reject")) {
+ } else if (isRinging("reject")) {
// Ensure video state history tracks video state at time of rejection.
mVideoStateHistory |= mVideoState;
@@ -2607,7 +2461,7 @@
"reject call failed due to null CS callId=%s", getId());
}
Log.addEvent(this, LogUtils.Events.REQUEST_REJECT);
- } else if (isRinging("reject") || isAnswered("reject")) {
+ } else if (isRinging("reject")) {
// Ensure video state history tracks video state at time of rejection.
mVideoStateHistory |= mVideoState;
@@ -2720,8 +2574,7 @@
return mState == CallState.ACTIVE;
}
- @VisibleForTesting
- public Bundle getExtras() {
+ Bundle getExtras() {
return mExtras;
}
@@ -2761,16 +2614,6 @@
setOriginalConnectionId(extras.getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID));
}
- if (extras.containsKey(Connection.EXTRA_CALLER_NUMBER_VERIFICATION_STATUS)
- && source == SOURCE_CONNECTION_SERVICE) {
- int callerNumberVerificationStatus =
- extras.getInt(Connection.EXTRA_CALLER_NUMBER_VERIFICATION_STATUS);
- if (mCallerNumberVerificationStatus != callerNumberVerificationStatus) {
- Log.addEvent(this, LogUtils.Events.VERSTAT_CHANGED, callerNumberVerificationStatus);
- setCallerNumberVerificationStatus(callerNumberVerificationStatus);
- }
- }
-
// The remote connection service API can track the phone account which was originally
// requested to create a connection via the remote connection service API; we store that so
// we have some visibility into how a call was actually placed.
@@ -3057,14 +2900,6 @@
}
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);
}
@@ -3075,17 +2910,6 @@
}
/**
- * 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.
@@ -3161,13 +2985,6 @@
void setConferenceableCalls(List<Call> conferenceableCalls) {
mConferenceableCalls.clear();
mConferenceableCalls.addAll(conferenceableCalls);
- String confCallIds = "";
- if (!conferenceableCalls.isEmpty()) {
- confCallIds = conferenceableCalls.stream()
- .map(c -> c.getId())
- .collect(Collectors.joining(","));
- }
- Log.addEvent(this, LogUtils.Events.CONF_CALLS_CHANGED, confCallIds);
for (Listener l : mListeners) {
l.onConferenceableCallsChanged(this);
@@ -3325,18 +3142,6 @@
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) {
@@ -3799,10 +3604,7 @@
* @param extras The extras.
*/
public void onConnectionEvent(String event, Bundle extras) {
- // Don't log call quality reports; they're quite frequent and will clog the log.
- if (!Connection.EVENT_CALL_QUALITY_REPORT.equals(event)) {
- Log.addEvent(this, LogUtils.Events.CONNECTION_EVENT, event);
- }
+ Log.addEvent(this, LogUtils.Events.CONNECTION_EVENT, event);
if (Connection.EVENT_ON_HOLD_TONE_START.equals(event)) {
mIsRemotelyHeld = true;
Log.addEvent(this, LogUtils.Events.REMOTELY_HELD);
@@ -3825,23 +3627,6 @@
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 if (Connection.EVENT_CALL_QUALITY_REPORT.equals(event)
- && extras != null && extras.containsKey(Connection.EXTRA_CALL_QUALITY_REPORT)) {
- CallQuality callQuality = extras.getParcelable(Connection.EXTRA_CALL_QUALITY_REPORT);
- for (Listener l : mListeners) {
- l.onReceivedCallQualityReport(this, callQuality);
- }
} else {
for (Listener l : mListeners) {
l.onConnectionEvent(this, event, extras);
@@ -4007,10 +3792,6 @@
mIsUsingCallFiltering = isUsingCallFiltering;
}
- public boolean isUsingCallFiltering() {
- return mIsUsingCallFiltering;
- }
-
/**
* Returns whether or not Volte call was used.
*
@@ -4047,44 +3828,6 @@
}
/**
- * 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(@CallDiagnostics.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.
@@ -4121,127 +3864,4 @@
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;
- }
-
- /**
- * Sets whether this is a sim call or not.
- * @param isSimCall {@code true} if this is a SIM call, {@code false} otherwise.
- */
- public void setIsSimCall(boolean isSimCall) {
- mIsSimCall = isSimCall;
- }
-
- /**
- * Initializes a disconnect future which is used to chain up pending operations which take
- * place when the {@link CallDiagnosticService} returns the result of the
- * {@link CallDiagnostics#onCallDisconnected(int, int)} or
- * {@link CallDiagnostics#onCallDisconnected(ImsReasonInfo)} invocation via
- * {@link CallDiagnosticServiceAdapter}. If no {@link CallDiagnosticService} is in use, we
- * would not try to make a disconnect future.
- * @param timeoutMillis Timeout we use for waiting for the response.
- * @return the {@link CompletableFuture}.
- */
- public CompletableFuture<Boolean> initializeDisconnectFuture(long timeoutMillis) {
- if (mDisconnectFuture == null) {
- mDisconnectFuture = new CompletableFuture<Boolean>()
- .completeOnTimeout(false, timeoutMillis, TimeUnit.MILLISECONDS);
- // After all the chained stuff we will report where the CDS timed out.
- mDisconnectFuture.thenRunAsync(() -> {
- if (!mReceivedCallDiagnosticPostCallResponse) {
- Log.addEvent(this, LogUtils.Events.CALL_DIAGNOSTIC_SERVICE_TIMEOUT);
- }
- // Clear the future as a final step.
- mDisconnectFuture = null;
- },
- new LoggedHandlerExecutor(mHandler, "C.iDF", mLock))
- .exceptionally((throwable) -> {
- Log.e(this, throwable, "Error while executing disconnect future");
- return null;
- });
- }
- return mDisconnectFuture;
- }
-
- /**
- * @return the disconnect future, if initialized. Used for chaining operations after creation.
- */
- public CompletableFuture<Boolean> getDisconnectFuture() {
- return mDisconnectFuture;
- }
-
- /**
- * @return {@code true} if disconnection and removal is handled via a future, or {@code false}
- * if this is handled immediately.
- */
- public boolean isDisconnectHandledViaFuture() {
- return mDisconnectFuture != null;
- }
-
- /**
- * Perform any cleanup on this call as a result of a {@link TelecomServiceImpl}
- * {@code cleanupStuckCalls} request.
- */
- public void cleanup() {
- if (mDisconnectFuture != null) {
- mDisconnectFuture.complete(false);
- mDisconnectFuture = null;
- }
- }
}
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 6a7261e..a6509b4 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -264,14 +264,6 @@
}
}
- 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 e5a6ecc..a562021 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -413,8 +413,6 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
- setSpeakerphoneOn(true);
- // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -461,8 +459,6 @@
switch (msg.what) {
case SWITCH_EARPIECE:
case USER_SWITCH_EARPIECE:
- case SPEAKER_ON:
- // Ignore speakerphone state changes outside of calls.
case SPEAKER_OFF:
// Nothing to do here
return HANDLED;
@@ -488,13 +484,12 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ case SPEAKER_ON:
transitionTo(mQuiescentSpeakerRoute);
return HANDLED;
case SWITCH_FOCUS:
if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
transitionTo(mActiveEarpieceRoute);
- } else {
- mCallAudioManager.notifyAudioOperationsComplete();
}
return HANDLED;
default:
@@ -538,7 +533,6 @@
// 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:
@@ -617,8 +611,6 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
- setSpeakerphoneOn(true);
- // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -685,20 +677,17 @@
return HANDLED;
case SWITCH_HEADSET:
case USER_SWITCH_HEADSET:
- case SPEAKER_ON:
- // Ignore speakerphone state changes outside of calls.
case SPEAKER_OFF:
// Nothing to do
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ case SPEAKER_ON:
transitionTo(mQuiescentSpeakerRoute);
return HANDLED;
case SWITCH_FOCUS:
if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
transitionTo(mActiveHeadsetRoute);
- } else {
- mCallAudioManager.notifyAudioOperationsComplete();
}
return HANDLED;
default:
@@ -736,7 +725,6 @@
return HANDLED;
case DISCONNECT_WIRED_HEADSET:
if (mWasOnSpeaker) {
- setSpeakerphoneOn(true);
sendInternalMessage(SWITCH_SPEAKER);
} else {
sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
@@ -808,7 +796,6 @@
transitionTo(mActiveHeadsetRoute);
break;
case SWITCH_SPEAKER:
- setSpeakerphoneOn(true);
transitionTo(mActiveSpeakerRoute);
break;
default:
@@ -865,8 +852,6 @@
mHasUserExplicitlyLeftBluetooth = true;
// fall through
case SWITCH_SPEAKER:
- setSpeakerphoneOn(true);
- // fall through
case SPEAKER_ON:
setBluetoothOff();
transitionTo(mActiveSpeakerRoute);
@@ -962,8 +947,6 @@
mHasUserExplicitlyLeftBluetooth = true;
// fall through
case SWITCH_SPEAKER:
- setSpeakerphoneOn(true);
- // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -1029,8 +1012,6 @@
return HANDLED;
case SWITCH_BLUETOOTH:
case USER_SWITCH_BLUETOOTH:
- case SPEAKER_ON:
- // Ignore speakerphone state changes outside of calls.
case SPEAKER_OFF:
// Nothing to do
return HANDLED;
@@ -1044,6 +1025,7 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ case SPEAKER_ON:
transitionTo(mQuiescentSpeakerRoute);
return HANDLED;
case SWITCH_FOCUS:
@@ -1055,8 +1037,6 @@
} else {
transitionTo(mRingingBluetoothRoute);
}
- } else {
- mCallAudioManager.notifyAudioOperationsComplete();
}
return HANDLED;
case BT_AUDIO_DISCONNECTED:
@@ -1125,9 +1105,8 @@
@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);
@@ -1278,10 +1257,7 @@
return HANDLED;
case SWITCH_FOCUS:
if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
- setSpeakerphoneOn(true);
transitionTo(mActiveSpeakerRoute);
- } else {
- mCallAudioManager.notifyAudioOperationsComplete();
}
return HANDLED;
default:
@@ -1347,15 +1323,6 @@
} else {
sendInternalMessage(MUTE_EXTERNALLY_CHANGED);
}
- } else if (AudioManager.STREAM_MUTE_CHANGED_ACTION.equals(intent.getAction())) {
- int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- boolean isStreamMuted = intent.getBooleanExtra(
- AudioManager.EXTRA_STREAM_VOLUME_MUTED, false);
-
- if (streamType == AudioManager.STREAM_RING && !isStreamMuted) {
- Log.i(this, "Ring stream was un-muted.");
- mCallAudioManager.onRingerModeChange();
- }
} else {
Log.w(this, "Received non-mute-change intent");
}
@@ -1539,8 +1506,6 @@
mWasOnSpeaker = false;
mContext.registerReceiver(mMuteChangeReceiver,
new IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED));
- mContext.registerReceiver(mMuteChangeReceiver,
- new IntentFilter(AudioManager.STREAM_MUTE_CHANGED_ACTION));
mContext.registerReceiver(mSpeakerPhoneChangeReceiver,
new IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED));
@@ -1628,8 +1593,12 @@
}
private void setSpeakerphoneOn(boolean on) {
- Log.i(this, "turning speaker phone %s", on);
- mAudioManager.setSpeakerphoneOn(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);
+ }
mStatusBarNotifier.notifySpeakerphone(on);
}
diff --git a/src/com/android/server/telecom/CallDiagnosticServiceAdapter.java b/src/com/android/server/telecom/CallDiagnosticServiceAdapter.java
deleted file mode 100644
index 8623866..0000000
--- a/src/com/android/server/telecom/CallDiagnosticServiceAdapter.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom;
-
-import android.annotation.NonNull;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.telecom.CallDiagnosticService;
-import android.telecom.CallDiagnostics;
-import android.telecom.Log;
-
-import com.android.internal.telecom.ICallDiagnosticServiceAdapter;
-
-/**
- * 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, @CallDiagnostics.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, @CallDiagnostics.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
deleted file mode 100644
index d8ee475..0000000
--- a/src/com/android/server/telecom/CallDiagnosticServiceController.java
+++ /dev/null
@@ -1,722 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-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.CallDiagnostics;
-import android.telecom.DisconnectCause;
-import android.telecom.InCallService;
-import android.telecom.Log;
-import android.telecom.ParcelableCall;
-import android.telephony.CallQuality;
-import android.telephony.ims.ImsReasonInfo;
-import android.text.TextUtils;
-
-import com.android.internal.telecom.ICallDiagnosticService;
-import com.android.internal.util.IndentingPrintWriter;
-
-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);
- }
-
- /**
- * Handles an incoming {@link CallQuality} report from a {@link android.telecom.Connection}.
- * @param call The call.
- * @param callQualityReport The call quality report.
- */
- @Override
- public void onReceivedCallQualityReport(Call call, CallQuality callQualityReport) {
- handleCallQualityReport(call, callQualityReport);
- }
- };
-
- /**
- * {@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 InCallTonePlayer.Factory mPlayerFactory;
- 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;
- }
-
- /**
- * Sets the current {@link InCallTonePlayer.Factory} for this instance.
- * @param factory the factory.
- */
- public void setInCallTonePlayerFactory(InCallTonePlayer.Factory factory) {
- mPlayerFactory = factory;
- }
-
- /**
- * 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 a newly disconnected call signalled from {@link CallsManager}.
- * @param call The call
- * @param disconnectCause The disconnect cause
- * @return {@code true} if the {@link CallDiagnosticService} was sent the call, {@code false}
- * if the call was not applicable to the CDS or if there was an issue sending it.
- */
- public boolean onCallDisconnected(@NonNull Call call,
- @NonNull DisconnectCause disconnectCause) {
- if (!call.isSimCall() || call.isExternalCall()) {
- Log.i(this, "onCallDisconnected: skipping call %s as non-sim or external.",
- call.getId());
- return false;
- }
- String callId = mCallIdMapper.getCallId(call);
- try {
- if (isConnected()) {
- mCallDiagnosticService.notifyCallDisconnected(callId, disconnectCause);
- return true;
- }
- } catch (RemoteException e) {
- Log.w(this, "onCallDisconnected: callId=%s, exception=%s", call.getId(), e);
- }
- return false;
- }
-
- /**
- * 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,
- @CallDiagnostics.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",
- callId, messageId, message);
- if (mPlayerFactory != null) {
- // Play that tone!
- mPlayerFactory.createPlayer(InCallTonePlayer.TONE_IN_CALL_QUALITY_NOTIFICATION)
- .startTone();
- }
- 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,
- @CallDiagnostics.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 CallDiagnostics#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.
- */
- public 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);
- }
- }
-
- /**
- * Handles a reported {@link CallQuality} report from a {@link android.telecom.Connection}.
- * @param call The call the report originated from.
- * @param callQualityReport The {@link CallQuality} report.
- */
- private void handleCallQualityReport(@NonNull Call call,
- @NonNull CallQuality callQualityReport) {
- try {
- if (isConnected()) {
- mCallDiagnosticService.callQualityChanged(call.getId(), callQualityReport);
- }
- } catch (RemoteException e) {
- Log.w(this, "handleCallQualityReport: 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 2cd5c79..da2c199 100644
--- a/src/com/android/server/telecom/CallIdMapper.java
+++ b/src/com/android/server/telecom/CallIdMapper.java
@@ -20,7 +20,6 @@
import com.android.internal.annotations.VisibleForTesting;
-import java.util.Collection;
import java.util.Map;
/** Utility to map {@link Call} objects to unique IDs. IDs are generated when a call is added. */
@@ -72,10 +71,6 @@
return mSecondaryMap.get(value);
}
- public Collection<V> getValues() {
- return mPrimaryMap.values();
- }
-
public void clear() {
mPrimaryMap.clear();
mSecondaryMap.clear();
@@ -137,10 +132,6 @@
return mCalls.getValue(callId);
}
- Collection<Call> getCalls() {
- return mCalls.getValues();
- }
-
void clear() {
mCalls.clear();
}
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 7f864b8..7305ab9 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -141,23 +141,6 @@
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 0ec2362..7a5af14 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -16,7 +16,6 @@
package com.android.server.telecom;
-import static android.provider.CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
import static android.telephony.CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL;
import android.annotation.Nullable;
@@ -24,26 +23,25 @@
import android.content.Intent;
import android.location.Country;
import android.location.CountryDetector;
-import android.location.Location;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Looper;
import android.os.UserHandle;
import android.os.PersistableBundle;
-import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
+// TODO: Needed for move to system service: import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import android.telecom.CallerInfo;
import com.android.server.telecom.callfiltering.CallFilteringResult;
import java.util.Arrays;
@@ -67,19 +65,68 @@
* Parameter object to hold the arguments to add a call in the call log DB.
*/
private static class AddCallArgs {
- public AddCallArgs(Context context, CallLog.AddCallParams params,
- @Nullable LogCallCompletedListener logCallCompletedListener) {
+ /**
+ * @param callerInfo Caller details.
+ * @param number The phone number to be logged.
+ * @param presentation Number presentation of the phone number to be logged.
+ * @param callType The type of call (e.g INCOMING_TYPE). @see
+ * {@link android.provider.CallLog} for the list of values.
+ * @param features The features of the call (e.g. FEATURES_VIDEO). @see
+ * {@link android.provider.CallLog} for the list of values.
+ * @param creationDate Time when the call was created (milliseconds since epoch).
+ * @param durationInMillis Duration of the call (milliseconds).
+ * @param dataUsage Data usage in bytes, or null if not applicable.
+ * @param isRead Indicates if the entry has been read or not.
+ * @param logCallCompletedListener optional callback called after the call is logged.
+ */
+ public AddCallArgs(Context context, CallerInfo callerInfo, String number,
+ String postDialDigits, String viaNumber, int presentation, int callType,
+ int features, PhoneAccountHandle accountHandle, long creationDate,
+ long durationInMillis, Long dataUsage, UserHandle initiatingUser, boolean isRead,
+ @Nullable LogCallCompletedListener logCallCompletedListener, int callBlockReason,
+ CharSequence callScreeningAppName, String callScreeningComponentName) {
this.context = context;
- this.params = params;
+ this.callerInfo = callerInfo;
+ this.number = number;
+ this.postDialDigits = postDialDigits;
+ this.viaNumber = viaNumber;
+ this.presentation = presentation;
+ this.callType = callType;
+ this.features = features;
+ this.accountHandle = accountHandle;
+ this.timestamp = creationDate;
+ this.durationInSec = (int)(durationInMillis / 1000);
+ this.dataUsage = dataUsage;
+ this.initiatingUser = initiatingUser;
+ this.isRead = isRead;
this.logCallCompletedListener = logCallCompletedListener;
-
+ this.callBockReason = callBlockReason;
+ this.callScreeningAppName = callScreeningAppName;
+ this.callScreeningComponentName = callScreeningComponentName;
}
// Since the members are accessed directly, we don't use the
// mXxxx notation.
public final Context context;
- public final CallLog.AddCallParams params;
+ public final CallerInfo callerInfo;
+ public final String number;
+ public final String postDialDigits;
+ public final String viaNumber;
+ public final int presentation;
+ public final int callType;
+ public final int features;
+ public final PhoneAccountHandle accountHandle;
+ public final long timestamp;
+ public final int durationInSec;
+ public final Long dataUsage;
+ public final UserHandle initiatingUser;
+ public final boolean isRead;
+
@Nullable
public final LogCallCompletedListener logCallCompletedListener;
+
+ public final int callBockReason;
+ public final CharSequence callScreeningAppName;
+ public final String callScreeningComponentName;
}
private static final String TAG = CallLogManager.class.getSimpleName();
@@ -264,133 +311,106 @@
*/
void logCall(Call call, int callLogType,
@Nullable LogCallCompletedListener logCallCompletedListener, CallFilteringResult result) {
+ long creationTime;
- CallLog.AddCallParams.AddCallParametersBuilder paramBuilder =
- new CallLog.AddCallParams.AddCallParametersBuilder();
if (call.getConnectTimeMillis() != 0
&& call.getConnectTimeMillis() < call.getCreationTimeMillis()) {
// If connected time is available, use connected time. The connected time might be
// earlier than created time since it might come from carrier sent special SMS to
// notifier user earlier missed call.
- paramBuilder.setStart(call.getConnectTimeMillis());
+ creationTime = call.getConnectTimeMillis();
} else {
- paramBuilder.setStart(call.getCreationTimeMillis());
+ creationTime = call.getCreationTimeMillis();
}
- paramBuilder.setDuration((int) (call.getAgeMillis() / 1000));
+ final long age = call.getAgeMillis();
- String logNumber = getLogNumber(call);
- paramBuilder.setNumber(logNumber);
+ final String logNumber = getLogNumber(call);
Log.d(TAG, "logNumber set to: %s", Log.pii(logNumber));
+ final PhoneAccountHandle emergencyAccountHandle =
+ TelephonyUtil.getDefaultEmergencyPhoneAccount().getAccountHandle();
+
String formattedViaNumber = PhoneNumberUtils.formatNumber(call.getViaNumber(),
getCountryIso());
formattedViaNumber = (formattedViaNumber != null) ?
formattedViaNumber : call.getViaNumber();
- paramBuilder.setViaNumber(formattedViaNumber);
- final PhoneAccountHandle emergencyAccountHandle =
- TelephonyUtil.getDefaultEmergencyPhoneAccount().getAccountHandle();
PhoneAccountHandle accountHandle = call.getTargetPhoneAccount();
if (emergencyAccountHandle.equals(accountHandle)) {
accountHandle = null;
}
- paramBuilder.setAccountHandle(accountHandle);
- paramBuilder.setDataUsage(call.getCallDataUsage() == Call.DATA_USAGE_NOT_SET
- ? Long.MIN_VALUE : call.getCallDataUsage());
+ Long callDataUsage = call.getCallDataUsage() == Call.DATA_USAGE_NOT_SET ? null :
+ call.getCallDataUsage();
- paramBuilder.setFeatures(getCallFeatures(call.getVideoStateHistory(),
+ int callFeatures = getCallFeatures(call.getVideoStateHistory(),
call.getDisconnectCause().getCode() == DisconnectCause.CALL_PULLED,
call.wasHighDefAudio(), call.wasWifi(),
(call.getConnectionProperties() & Connection.PROPERTY_ASSISTED_DIALING) ==
Connection.PROPERTY_ASSISTED_DIALING,
call.wasEverRttCall(),
- call.wasVolte()));
+ call.wasVolte());
- if (result == null) {
- result = new CallFilteringResult.Builder()
- .setCallScreeningAppName(call.getCallScreeningAppName())
- .setCallScreeningComponentName(call.getCallScreeningComponentName())
- .build();
- }
- if (callLogType == Calls.BLOCKED_TYPE || callLogType == Calls.MISSED_TYPE) {
- paramBuilder.setCallBlockReason(result.mCallBlockReason);
- paramBuilder.setCallScreeningComponentName(result.mCallScreeningComponentName);
- paramBuilder.setCallScreeningAppName(result.mCallScreeningAppName);
+ if (callLogType == Calls.BLOCKED_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);
} else {
- paramBuilder.setCallBlockReason(BLOCK_REASON_NOT_BLOCKED);
- }
-
- PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(accountHandle);
- UserHandle initiatingUser = call.getInitiatingUser();
- if (phoneAccount != null &&
- phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
- if (initiatingUser != null &&
- UserUtil.isManagedProfile(mContext, initiatingUser)) {
- paramBuilder.setUserToBeInsertedTo(initiatingUser);
- paramBuilder.setAddForAllUsers(false);
- } else {
- paramBuilder.setAddForAllUsers(true);
- }
- } else {
- if (accountHandle == null) {
- paramBuilder.setAddForAllUsers(true);
- } else {
- paramBuilder.setUserToBeInsertedTo(accountHandle.getUserHandle());
- paramBuilder.setAddForAllUsers(accountHandle.getUserHandle() == null);
- }
- }
- if (call.getIntentExtras() != null) {
- if (call.getIntentExtras().containsKey(TelecomManager.EXTRA_PRIORITY)) {
- paramBuilder.setPriority(call.getIntentExtras()
- .getInt(TelecomManager.EXTRA_PRIORITY));
- }
- if (call.getIntentExtras().containsKey(TelecomManager.EXTRA_CALL_SUBJECT)) {
- paramBuilder.setSubject(call.getIntentExtras()
- .getString(TelecomManager.EXTRA_CALL_SUBJECT));
- }
- if (call.getIntentExtras().containsKey(TelecomManager.EXTRA_PICTURE_URI)) {
- paramBuilder.setPictureUri(call.getIntentExtras()
- .getParcelable(TelecomManager.EXTRA_PICTURE_URI));
- }
- // The picture uri can end up either in extras or in intent extras due to how these
- // two bundles are set. For incoming calls they're in extras, but for outgoing calls
- // they're in intentExtras.
- if (call.getExtras() != null
- && call.getExtras().containsKey(TelecomManager.EXTRA_PICTURE_URI)) {
- paramBuilder.setPictureUri(call.getExtras()
- .getParcelable(TelecomManager.EXTRA_PICTURE_URI));
- }
- if (call.getIntentExtras().containsKey(TelecomManager.EXTRA_LOCATION)) {
- Location l = call.getIntentExtras().getParcelable(TelecomManager.EXTRA_LOCATION);
- if (l != null) {
- paramBuilder.setLatitude(l.getLatitude());
- paramBuilder.setLongitude(l.getLongitude());
- }
- }
- }
-
- paramBuilder.setCallerInfo(call.getCallerInfo());
- paramBuilder.setPostDialDigits(call.getPostDialDigits());
- paramBuilder.setPresentation(call.getHandlePresentation());
- paramBuilder.setCallType(callLogType);
- paramBuilder.setIsRead(call.isSelfManaged());
- paramBuilder.setMissedReason(call.getMissedReason());
-
- sendAddCallBroadcast(callLogType, call.getAgeMillis());
-
- boolean okayToLog =
- okayToLogCall(accountHandle, logNumber, call.isEmergencyCall());
- if (okayToLog) {
- AddCallArgs args = new AddCallArgs(mContext, paramBuilder.build(),
- logCallCompletedListener);
- logCallAsync(args);
+ 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*/);
}
}
- boolean okayToLogCall(PhoneAccountHandle accountHandle, String number, boolean isEmergency) {
+ /**
+ * Inserts a call into the call log, based on the parameters passed in.
+ *
+ * @param callerInfo Caller details.
+ * @param number The number the call was made to or from.
+ * @param postDialDigits The post-dial digits that were dialed after the number,
+ * if it was an outgoing call. Otherwise ''.
+ * @param presentation
+ * @param callType The type of call.
+ * @param features The features of the call.
+ * @param start The start time of the call, in milliseconds.
+ * @param duration The duration of the call, in milliseconds.
+ * @param dataUsage The data usage for the call, null if not applicable.
+ * @param isEmergency {@code true} if this is an emergency call, {@code false} otherwise.
+ * @param logCallCompletedListener optional callback called after the call is logged.
+ * @param initiatingUser The user the call was initiated under.
+ * @param isSelfManaged {@code true} if this is a self-managed call, {@code false} otherwise.
+ * @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.
+ */
+ private void logCall(
+ CallerInfo callerInfo,
+ String number,
+ String postDialDigits,
+ String viaNumber,
+ int presentation,
+ int callType,
+ int features,
+ PhoneAccountHandle accountHandle,
+ long start,
+ long duration,
+ Long dataUsage,
+ boolean isEmergency,
+ UserHandle initiatingUser,
+ boolean isSelfManaged,
+ @Nullable LogCallCompletedListener logCallCompletedListener,
+ int callBlockReason,
+ CharSequence callScreeningAppName,
+ String callScreeningComponentName) {
+
// 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
// on carrier requirements.)
@@ -405,8 +425,29 @@
}
// Don't log emergency numbers if the device doesn't allow it.
- return (!isEmergency || okToLogEmergencyNumber)
+ final boolean isOkToLogThisCall = (!isEmergency || okToLogEmergencyNumber)
&& !isUnloggableNumber(number, configBundle);
+
+ sendAddCallBroadcast(callType, duration);
+
+ if (isOkToLogThisCall) {
+ Log.d(TAG, "Logging Call log entry: " + callerInfo + ", "
+ + Log.pii(number) + "," + presentation + ", " + callType
+ + ", " + start + ", " + duration);
+ boolean isRead = false;
+ if (isSelfManaged) {
+ // Mark self-managed calls are read since they're being handled by their own app.
+ // Their inclusion in the call log is informational only.
+ isRead = true;
+ }
+ AddCallArgs args = new AddCallArgs(mContext, callerInfo, number, postDialDigits,
+ viaNumber, presentation, callType, features, accountHandle, start, duration,
+ dataUsage, initiatingUser, isRead, logCallCompletedListener, callBlockReason,
+ callScreeningAppName, callScreeningComponentName);
+ logCallAsync(args);
+ } else {
+ Log.d(TAG, "Not adding emergency call to call log.");
+ }
}
private boolean isUnloggableNumber(String callNumber, PersistableBundle carrierConfig) {
@@ -512,7 +553,7 @@
mListeners[i] = c.logCallCompletedListener;
try {
// May block.
- result[i] = Calls.addCall(c.context, c.params);
+ result[i] = addCall(c);
} catch (Exception e) {
// This is very rare but may happen in legitimate cases.
// E.g. If the phone is encrypted and thus write request fails, it may cause
@@ -528,13 +569,43 @@
return result;
}
+ private Uri addCall(AddCallArgs c) {
+ PhoneAccount phoneAccount = mPhoneAccountRegistrar
+ .getPhoneAccountUnchecked(c.accountHandle);
+ if (phoneAccount != null &&
+ phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
+ if (c.initiatingUser != null &&
+ UserUtil.isManagedProfile(mContext, c.initiatingUser)) {
+ return addCall(c, c.initiatingUser);
+ } else {
+ return addCall(c, null);
+ }
+ } else {
+ return addCall(c, c.accountHandle == null ? null : c.accountHandle.getUserHandle());
+ }
+ }
+
+ /**
+ * Insert the call to a specific user or all users except managed profile.
+ * @param c context
+ * @param userToBeInserted user handle of user that the call going be inserted to. null
+ * if insert to all users except managed profile.
+ */
+ private Uri addCall(AddCallArgs c, UserHandle userToBeInserted) {
+ return Calls.addCall(c.callerInfo, c.context, c.number, c.postDialDigits, c.viaNumber,
+ 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);
+ }
+
+
@Override
protected void onPostExecute(Uri[] result) {
for (int i = 0; i < result.length; i++) {
Uri uri = result[i];
/*
- Performs a simple correctness check to make sure the call was written in the
- database.
+ Performs a simple sanity 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/CallScreeningServiceHelper.java b/src/com/android/server/telecom/CallScreeningServiceHelper.java
index 9435250..f02b924 100644
--- a/src/com/android/server/telecom/CallScreeningServiceHelper.java
+++ b/src/com/android/server/telecom/CallScreeningServiceHelper.java
@@ -55,8 +55,23 @@
}
@Override
- public void onScreeningResponse(String callId, ComponentName componentName,
- CallScreeningService.ParcelableCallResponse callResponse) {
+ public void allowCall(String s) throws RemoteException {
+ unbindCallScreeningService();
+ }
+
+ @Override
+ public void silenceCall(String s) throws RemoteException {
+ unbindCallScreeningService();
+ }
+
+ @Override
+ public void screenCallFurther(String callId) throws RemoteException {
+ unbindCallScreeningService();
+ }
+
+ @Override
+ public void disallowCall(String s, boolean b, boolean b1, boolean b2,
+ ComponentName componentName) throws RemoteException {
unbindCallScreeningService();
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index ea45abb..1c46209 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -16,7 +16,6 @@
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;
@@ -28,11 +27,6 @@
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;
@@ -72,7 +66,6 @@
import android.provider.Settings;
import android.sysprop.TelephonyProperties;
import android.telecom.CallAudioState;
-import android.telecom.CallScreeningService;
import android.telecom.CallerInfo;
import android.telecom.Conference;
import android.telecom.Connection;
@@ -109,6 +102,7 @@
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;
@@ -179,7 +173,6 @@
void onConnectionTimeChanged(Call call);
void onConferenceStateChanged(Call call, boolean isConference);
void onCdmaConferenceSwap(Call call);
- void onSetCamera(Call call, String cameraId);
}
/** Interface used to define the action which is executed delay under some condition. */
@@ -333,7 +326,6 @@
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;
@@ -359,6 +351,7 @@
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;
@@ -489,8 +482,8 @@
CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
InCallControllerFactory inCallControllerFactory,
- CallDiagnosticServiceController callDiagnosticServiceController,
RoleManagerAdapter roleManagerAdapter,
+ IncomingCallFilter.Factory incomingCallFilterFactory,
ToastFactory toastFactory) {
mContext = context;
mLock = lock;
@@ -508,6 +501,7 @@
mTimeoutsAdapter = timeoutsAdapter;
mEmergencyCallHelper = emergencyCallHelper;
mCallerInfoLookupHelper = callerInfoLookupHelper;
+ mIncomingCallFilterFactory = incomingCallFilterFactory;
mDtmfLocalTonePlayer =
new DtmfLocalTonePlayer(new DtmfLocalTonePlayer.ToneGeneratorProxy());
@@ -546,8 +540,6 @@
mInCallController = inCallControllerFactory.create(context, mLock, this,
systemStateHelper, defaultDialerCache, mTimeoutsAdapter,
emergencyCallHelper);
- mCallDiagnosticServiceController = callDiagnosticServiceController;
- mCallDiagnosticServiceController.setInCallTonePlayerFactory(playerFactory);
mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer,
ringtoneFactory, systemVibrator,
new Ringer.VibrationEffectProxy(), mInCallController);
@@ -577,7 +569,6 @@
mListeners.add(mCallLogManager);
mListeners.add(mPhoneStateBroadcaster);
mListeners.add(mInCallController);
- mListeners.add(mCallDiagnosticServiceController);
mListeners.add(mCallAudioManager);
mListeners.add(mCallRecordingTonePlayer);
mListeners.add(missedCallNotifier);
@@ -628,10 +619,6 @@
return mRoleManagerAdapter;
}
- public CallDiagnosticServiceController getCallDiagnosticServiceController() {
- return mCallDiagnosticServiceController;
- }
-
@Override
public void onSuccessfulOutgoingCall(Call call, int callState) {
Log.v(this, "onSuccessfulOutgoingCall, %s", call);
@@ -681,7 +668,7 @@
.setShouldReject(false)
.setShouldAddToCallLog(true)
.setShouldShowNotification(true)
- .build(), false);
+ .build());
incomingCall.setIsUsingCallFiltering(false);
return;
}
@@ -747,19 +734,12 @@
}
@Override
- public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result,
- boolean timeout) {
+ public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {
// 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,
@@ -769,66 +749,26 @@
return;
}
- // Inform our connection service that call filtering is done (if it was performed at all).
- if (incomingCall.isUsingCallFiltering()) {
- boolean isInContacts = incomingCall.getCallerInfo() != null
- && incomingCall.getCallerInfo().contactExists;
- Connection.CallFilteringCompletionInfo completionInfo =
- new Connection.CallFilteringCompletionInfo(!result.shouldAllowCall,
- isInContacts,
- result.mCallScreeningResponse == null
- ? null : result.mCallScreeningResponse.toCallResponse(),
- result.mCallScreeningComponentName == null ? null
- : ComponentName.unflattenFromString(
- result.mCallScreeningComponentName));
- incomingCall.getConnectionService().onCallFilteringCompleted(incomingCall,
- completionInfo);
- }
-
- // Get rid of the call composer attachments that aren't wanted
- if (result.mIsResponseFromSystemDialer && result.mCallScreeningResponse != null
- && result.mCallScreeningResponse.getCallComposerAttachmentsToShow() >= 0) {
- int attachmentMask = result.mCallScreeningResponse.getCallComposerAttachmentsToShow();
- if ((attachmentMask
- & CallScreeningService.CallResponse.CALL_COMPOSER_ATTACHMENT_LOCATION) == 0) {
- incomingCall.getIntentExtras().remove(TelecomManager.EXTRA_LOCATION);
- }
-
- if ((attachmentMask
- & CallScreeningService.CallResponse.CALL_COMPOSER_ATTACHMENT_SUBJECT) == 0) {
- incomingCall.getIntentExtras().remove(TelecomManager.EXTRA_CALL_SUBJECT);
- }
-
- if ((attachmentMask
- & CallScreeningService.CallResponse.CALL_COMPOSER_ATTACHMENT_PRIORITY) == 0) {
- incomingCall.getIntentExtras().remove(TelecomManager.EXTRA_PRIORITY);
- }
- }
-
if (result.shouldAllowCall) {
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.");
- incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_RINGING);
- autoMissCallAndLog(incomingCall, result);
- return;
+ rejectCallAndLog(incomingCall, result);
}
} else if (hasMaximumManagedDialingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
incomingCall.silence();
} else {
+
Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
"dialing calls.");
- incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_DIALING);
- autoMissCallAndLog(incomingCall, result);
- return;
+ rejectCallAndLog(incomingCall, result);
}
} else if (result.shouldScreenViaAudio) {
Log.i(this, "onCallFilteringCompleted: starting background audio processing");
@@ -837,9 +777,6 @@
} 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);
@@ -1074,18 +1011,6 @@
}
}
- /**
- * Handles a change to the currently active camera for a call by notifying listeners.
- * @param call The call.
- * @param cameraId The ID of the camera in use, or {@code null} if no camera is in use.
- */
- @Override
- public void onSetCamera(Call call, String cameraId) {
- for (CallsManagerListener listener : mListeners) {
- listener.onSetCamera(call, cameraId);
- }
- }
-
public Collection<Call> getCalls() {
return Collections.unmodifiableCollection(mCalls);
}
@@ -1283,14 +1208,10 @@
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
@@ -1309,6 +1230,7 @@
}
}
+ Bundle phoneAccountExtras = phoneAccount.getExtras();
if (phoneAccountExtras != null
&& phoneAccountExtras.getBoolean(
PhoneAccount.EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE)) {
@@ -1400,19 +1322,12 @@
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) {
@@ -1523,7 +1438,6 @@
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
@@ -1554,9 +1468,6 @@
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;
@@ -1662,32 +1573,6 @@
// 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 (!finalCall.isEmergencyCall() && isInEmergencyCall()) {
- Log.i(CallsManager.this, "Aborting call since there's an"
- + " ongoing emergency call");
- // If the ongoing call is a managed call, we will prevent the outgoing
- // call from dialing.
- if (isConference) {
- notifyCreateConferenceFailed(finalCall.getTargetPhoneAccount(),
- finalCall);
- } else {
- notifyCreateConnectionFailed(
- finalCall.getTargetPhoneAccount(), finalCall);
- }
- return CompletableFuture.completedFuture(null);
}
// If we can not supportany more active calls, our options are to move a call
@@ -2079,8 +1964,6 @@
handle.getSchemeSpecificPart());
} catch (IllegalStateException ise) {
isPotentialEmergencyNumber = false;
- } catch (RuntimeException r) {
- isPotentialEmergencyNumber = false;
}
if (shouldCancelCall) {
@@ -2258,16 +2141,8 @@
public void processRedirectedOutgoingCallAfterUserInteraction(String callId, String action) {
Log.i(this, "processRedirectedOutgoingCallAfterUserInteraction for Call ID %s, action=%s",
callId, action);
- if (mPendingRedirectedOutgoingCall != null) {
- String pendingCallId = mPendingRedirectedOutgoingCall.getId();
- if (!pendingCallId.equals(callId)) {
- Log.i(this, "processRedirectedOutgoingCallAfterUserInteraction for new Call ID %s, "
- + "cancel the previous pending Call with ID %s", callId, pendingCallId);
- mPendingRedirectedOutgoingCall.disconnect("Another call redirection requested");
- mPendingRedirectedOutgoingCallInfo.remove(pendingCallId);
- mPendingUnredirectedOutgoingCallInfo.remove(pendingCallId);
- }
-
+ if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId()
+ .equals(callId)) {
if (action.equals(TelecomBroadcastIntentProcessor.ACTION_PLACE_REDIRECTED_CALL)) {
mHandler.post(mPendingRedirectedOutgoingCallInfo.get(callId).prepare());
} else if (action.equals(
@@ -2807,16 +2682,6 @@
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.
@@ -2940,8 +2805,8 @@
}
private boolean isRttSettingOn(PhoneAccountHandle handle) {
- boolean isRttModeSettingOn = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.RTT_CALLING_MODE, 0, mContext.getUserId()) != 0;
+ boolean isRttModeSettingOn = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.RTT_CALLING_MODE, 0) != 0;
// If the carrier config says that we should ignore the RTT mode setting from the user,
// assume that it's off (i.e. only make an RTT call if it's requested through the extra).
boolean shouldIgnoreRttModeSetting = getCarrierConfigForPhoneAccount(handle)
@@ -3019,7 +2884,6 @@
*/
boolean holdActiveCallForNewCall(Call call) {
Call activeCall = (Call) mConnectionSvrFocusMgr.getCurrentFocusCall();
- Log.i(this, "holdActiveCallForNewCall, newCall: %s, activeCall: %s", call, activeCall);
if (activeCall != null && activeCall != call) {
if (canHold(activeCall)) {
activeCall.hold();
@@ -3075,7 +2939,6 @@
@VisibleForTesting
public void markCallAsActive(Call call) {
- Log.i(this, "markCallAsActive, isSelfManaged: " + call.isSelfManaged());
if (call.isSelfManaged()) {
// backward compatibility, the self-managed connection service will set the call state
// to active directly. We should hold or disconnect the current active call based on the
@@ -3118,92 +2981,35 @@
*
* @param disconnectCause The disconnect cause, see {@link android.telecom.DisconnectCause}.
*/
- @VisibleForTesting
- public void markCallAsDisconnected(Call call, DisconnectCause disconnectCause) {
- int oldState = call.getState();
- if (call.getState() == CallState.SIMULATED_RINGING
+ 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.
call.setOverrideDisconnectCauseCode(new DisconnectCause(DisconnectCause.MISSED));
}
+ call.setDisconnectCause(disconnectCause);
+ setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly");
- // If a call diagnostic service is in use, we will log the original telephony-provided
- // disconnect cause, inform the CDS of the disconnection, and then chain the update of the
- // call state until AFTER the CDS reports it's result back.
- if ((oldState == CallState.ACTIVE || oldState == CallState.DIALING)
- && disconnectCause.getCode() != DisconnectCause.MISSED
- && mCallDiagnosticServiceController.isConnected()
- && mCallDiagnosticServiceController.onCallDisconnected(call, disconnectCause)) {
- Log.i(this, "markCallAsDisconnected; callid=%s, postingToFuture.", call.getId());
-
- // Log the original disconnect reason prior to calling into the
- // CallDiagnosticService.
- Log.addEvent(call, LogUtils.Events.SET_DISCONNECTED_ORIG, disconnectCause);
-
- // Setup the future with a timeout so that the CDS is time boxed.
- CompletableFuture<Boolean> future = call.initializeDisconnectFuture(
- mTimeoutsAdapter.getCallDiagnosticServiceTimeoutMillis(
- mContext.getContentResolver()));
-
- // Post the disconnection updates to the future for completion once the CDS returns
- // with it's overridden disconnect message.
- future.thenRunAsync(() -> {
- call.setDisconnectCause(disconnectCause);
- setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly");
- }, new LoggedHandlerExecutor(mHandler, "CM.mCAD", mLock))
- .exceptionally((throwable) -> {
- Log.e(TAG, throwable, "Error while executing disconnect future.");
- return null;
- });
- } else {
- // No CallDiagnosticService, or it doesn't handle this call, so just do this
- // synchronously as always.
- call.setDisconnectCause(disconnectCause);
- setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly");
- }
-
- if (oldState == CallState.NEW && disconnectCause.getCode() == DisconnectCause.MISSED) {
+ if(oldState == CallState.NEW && disconnectCause.getCode() == DisconnectCause.MISSED) {
Log.i(this, "markCallAsDisconnected: logging missed call ");
mCallLogManager.logCall(call, Calls.MISSED_TYPE, true, null);
}
+
}
/**
* Removes an existing disconnected call, and notifies the in-call app.
*/
void markCallAsRemoved(Call call) {
- if (call.isDisconnectHandledViaFuture()) {
- Log.i(this, "markCallAsRemoved; callid=%s, postingToFuture.", call.getId());
- // A future is being used due to a CallDiagnosticService handling the call. We will
- // chain the removal operation to the end of any outstanding disconnect work.
- call.getDisconnectFuture().thenRunAsync(() -> {
- performRemoval(call);
- }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock))
- .exceptionally((throwable) -> {
- Log.e(TAG, throwable, "Error while executing disconnect future");
- return null;
- });
-
- } else {
- Log.i(this, "markCallAsRemoved; callid=%s, immediate.", call.getId());
- performRemoval(call);
- }
- }
-
- /**
- * Work which is completed when a call is to be removed. Can either be be run synchronously or
- * posted to a {@link Call#getDisconnectFuture()}.
- * @param call The call.
- */
- private void performRemoval(Call call) {
mInCallController.getBindingFuture().thenRunAsync(() -> {
call.maybeCleanupHandover();
removeCall(call);
Call foregroundCall = mCallAudioManager.getPossiblyHeldForegroundCall();
if (mLocallyDisconnectingCalls.contains(call)) {
boolean isDisconnectingChildCall = call.isDisconnectingChildCall();
- Log.v(this, "performRemoval: isDisconnectingChildCall = "
+ Log.v(this, "markCallAsRemoved: isDisconnectingChildCall = "
+ isDisconnectingChildCall + "call -> %s", call);
mLocallyDisconnectingCalls.remove(call);
// Auto-unhold the foreground call due to a locally disconnected call, except if the
@@ -3220,15 +3026,10 @@
// The new foreground call is on hold, however the carrier does not display the hold
// button in the UI. Therefore, we need to auto unhold the held call since the user
// has no means of unholding it themselves.
- Log.i(this, "performRemoval: Auto-unholding held foreground call (call doesn't "
- + "support hold)");
+ Log.i(this, "Auto-unholding held foreground call (call doesn't support hold)");
foregroundCall.unhold();
}
- }, new LoggedHandlerExecutor(mHandler, "CM.pR", mLock))
- .exceptionally((throwable) -> {
- Log.e(TAG, throwable, "Error while executing call removal");
- return null;
- });
+ }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock));
}
/**
@@ -3623,8 +3424,7 @@
* Reject an incoming call and manually add it to the Call Log.
* @param incomingCall Incoming call that has been rejected
*/
- private void autoMissCallAndLog(Call incomingCall, CallFilteringResult result) {
- incomingCall.getAnalytics().setMissedReason(incomingCall.getMissedReason());
+ private void rejectCallAndLog(Call incomingCall, CallFilteringResult result) {
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
@@ -3650,7 +3450,7 @@
@VisibleForTesting
public void addCall(Call call) {
Trace.beginSection("addCall");
- Log.i(this, "addCall(%s)", call);
+ Log.v(this, "addCall(%s)", call);
call.addListener(this);
mCalls.add(call);
@@ -3762,21 +3562,27 @@
(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");
@@ -3784,24 +3590,6 @@
}
}
- 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
@@ -4187,7 +3975,7 @@
+ " livecall = " + liveCall);
if (emergencyCall == liveCall) {
- // Not likely, but a good correctness check.
+ // Not likely, but a good sanity check.
return true;
}
@@ -4201,7 +3989,7 @@
return true;
}
if (outgoingCall.getState() == CallState.SELECT_PHONE_ACCOUNT) {
- // Correctness check: if there is an orphaned emergency call in the
+ // Sanity 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);
@@ -4302,8 +4090,7 @@
return false;
}
- @VisibleForTesting
- public boolean makeRoomForOutgoingCall(Call call) {
+ private boolean makeRoomForOutgoingCall(Call call) {
// Already room!
if (!hasMaximumLiveCalls(call)) return true;
@@ -4320,13 +4107,6 @@
return true;
}
- // If the live call is stuck in a connecting state, then we should disconnect it in favor
- // of the new outgoing call.
- if (liveCall.getState() == CallState.CONNECTING) {
- liveCall.disconnect("Force disconnect CONNECTING call.");
- return true;
- }
-
if (hasMaximumOutgoingCalls(call)) {
Call outgoingCall = getFirstCallWithState(OUTGOING_CALL_STATES);
if (outgoingCall.getState() == CallState.SELECT_PHONE_ACCOUNT) {
@@ -4847,13 +4627,6 @@
pw.decreaseIndent();
}
- if (mCallDiagnosticServiceController != null) {
- pw.println("mCallDiagnosticServiceController:");
- pw.increaseIndent();
- mCallDiagnosticServiceController.dump(pw);
- pw.decreaseIndent();
- }
-
if (mDefaultDialerCache != null) {
pw.println("mDefaultDialerCache:");
pw.increaseIndent();
@@ -4910,9 +4683,6 @@
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);
}
@@ -5557,15 +5327,4 @@
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivityAsUser(intent, mCurrentUserHandle);
}
-
- @VisibleForTesting
- public void addToPendingCallsToDisconnect(Call call) {
- mPendingCallsToDisconnect.add(call);
- }
-
- @VisibleForTesting
- public void addConnectionServiceRepositoryCache(ComponentName componentName,
- UserHandle userHandle, ConnectionServiceWrapper service) {
- mConnectionServiceRepository.setService(componentName, userHandle, service);
- }
}
diff --git a/src/com/android/server/telecom/CallsManagerListenerBase.java b/src/com/android/server/telecom/CallsManagerListenerBase.java
index 55c7b53..e0d2831 100644
--- a/src/com/android/server/telecom/CallsManagerListenerBase.java
+++ b/src/com/android/server/telecom/CallsManagerListenerBase.java
@@ -104,8 +104,4 @@
@Override
public void onCdmaConferenceSwap(Call call) {
}
-
- @Override
- public void onSetCamera(Call call, String cameraId) {
- }
}
diff --git a/src/com/android/server/telecom/CarModeTracker.java b/src/com/android/server/telecom/CarModeTracker.java
index 737ce5a..0ec4917 100644
--- a/src/com/android/server/telecom/CarModeTracker.java
+++ b/src/com/android/server/telecom/CarModeTracker.java
@@ -28,9 +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.function.Function;
import java.util.stream.Collectors;
/**
@@ -41,40 +39,30 @@
* Data class holding information about apps which have requested to enter car mode.
*/
private class CarModeApp {
- private final boolean mAutomotiveProjection;
- private final @IntRange(from = 0) int mPriority;
+ private @IntRange(from = 0) int mPriority;
private @NonNull String mPackageName;
- public CarModeApp(@NonNull String packageName) {
- this(true, 0, packageName);
- }
-
public CarModeApp(int priority, @NonNull String packageName) {
- this(false, priority, packageName);
- }
-
- private CarModeApp(boolean automotiveProjection, int priority, @NonNull String packageName) {
- mAutomotiveProjection = automotiveProjection;
mPriority = priority;
mPackageName = Objects.requireNonNull(packageName);
}
- public boolean hasSetAutomotiveProjection() {
- return mAutomotiveProjection;
- }
-
/**
* The priority at which the app requested to enter car mode.
* Will be the same as the one specified when {@link UiModeManager#enableCarMode(int, int)}
- * was called, or {@link UiModeManager#DEFAULT_PRIORITY} if no priority was specified.
+ * was called, or {@link UiModeManager#DEFAULT_PRIORITY} if no priority was specifeid.
* @return The priority.
*/
public int getPriority() {
return mPriority;
}
+ public void setPriority(int priority) {
+ mPriority = priority;
+ }
+
/**
- * @return The package name of the app which requested to enter car mode/set projection.
+ * @return The package name of the app which requested to enter car mode.
*/
public String getPackageName() {
return mPackageName;
@@ -83,24 +71,26 @@
public void setPackageName(String packageName) {
mPackageName = packageName;
}
+ }
- public String toString() {
- return String.format("[%s, %s]",
- mAutomotiveProjection ? "PROJECTION SET" : mPriority,
- mPackageName);
+ /**
+ * Comparator used to maintain the car mode priority queue ordering.
+ */
+ private class CarModeAppComparator implements Comparator<CarModeApp> {
+ @Override
+ public int compare(CarModeApp o1, CarModeApp o2) {
+ // highest priority takes precedence.
+ return Integer.compare(o2.getPriority(), o1.getPriority());
}
}
/**
- * Priority list of apps which have entered or exited car mode, ordered first by whether the app
- * has set automotive projection, and then by highest priority. Where items have the same
- * priority, order is arbitrary, but we only allow one item in the queue per priority.
+ * Priority list of apps which have entered or exited car mode, ordered with the highest
+ * priority app at the top of the queue. Where items have the same priority, they are ordered
+ * by insertion time.
*/
private PriorityQueue<CarModeApp> mCarModeApps = new PriorityQueue<>(2,
- // Natural ordering of booleans is False, True. Natural ordering of ints is increasing.
- Comparator.comparing(CarModeApp::hasSetAutomotiveProjection)
- .thenComparing(CarModeApp::getPriority)
- .reversed());
+ new CarModeAppComparator());
private final LocalLog mCarModeChangeLog = new LocalLog(20);
@@ -153,71 +143,6 @@
mCarModeApps.removeIf(c -> c.getPriority() == priority);
}
- public void handleSetAutomotiveProjection(@NonNull String packageName) {
- Optional<CarModeApp> projectingApp = mCarModeApps.stream()
- .filter(CarModeApp::hasSetAutomotiveProjection)
- .findAny();
- // No app with automotive projection? Easy peasy, just add it.
- if (!projectingApp.isPresent()) {
- Log.i(this, "handleSetAutomotiveProjection: %s", packageName);
- mCarModeChangeLog.log("setAutomotiveProjection: packageName=" + packageName);
- mCarModeApps.add(new CarModeApp(packageName));
- return;
- }
- // Otherwise an app already has automotive projection set. Is it the same app?
- if (packageName.equals(projectingApp.get().getPackageName())) {
- Log.w(this, "handleSetAutomotiveProjection: %s already the automotive projection app",
- packageName);
- return;
- }
- // We have a new app for automotive projection. As a shortcut just reuse the same object by
- // overwriting the package name.
- Log.i(this, "handleSetAutomotiveProjection: %s replacing %s as automotive projection app",
- packageName, projectingApp.get().getPackageName());
- mCarModeChangeLog.log("setAutomotiveProjection: " + packageName + " replaces "
- + projectingApp.get().getPackageName());
- projectingApp.get().setPackageName(packageName);
- }
-
- public void handleReleaseAutomotiveProjection() {
- Optional<String> projectingPackage = mCarModeApps.stream()
- .filter(CarModeApp::hasSetAutomotiveProjection)
- .map(CarModeApp::getPackageName)
- .findAny();
- if (!projectingPackage.isPresent()) {
- Log.w(this, "handleReleaseAutomotiveProjection: no current automotive projection app");
- return;
- }
- Log.i(this, "handleReleaseAutomotiveProjection: %s", projectingPackage.get());
- mCarModeChangeLog.log("releaseAutomotiveProjection: packageName="
- + projectingPackage.get());
- mCarModeApps.removeIf(CarModeApp::hasSetAutomotiveProjection);
- }
-
- /**
- * 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 forceRemove(@NonNull String packageName) {
- // We must account for the possibility that the app has set both car mode AND projection.
- List<CarModeApp> forcedApp = mCarModeApps.stream()
- .filter(c -> c.getPackageName().equals(packageName))
- .collect(Collectors.toList());
- if (forcedApp.isEmpty()) {
- Log.i(this, "Package %s is not tracked.", packageName);
- return;
- }
- for (CarModeApp app : forcedApp) {
- String logString = "forceRemove: " + app;
- Log.i(this, logString);
- mCarModeChangeLog.log(logString);
- }
- mCarModeApps.removeIf(c -> c.getPackageName().equals(packageName));
- }
-
/**
* Retrieves a list of the apps which are currently in car mode, ordered by priority such that
* the highest priority app is first.
@@ -227,7 +152,7 @@
return mCarModeApps
.stream()
.sorted(mCarModeApps.comparator())
- .map(CarModeApp::getPackageName)
+ .map(cma -> cma.getPackageName())
.collect(Collectors.toList());
}
@@ -235,7 +160,7 @@
return mCarModeApps
.stream()
.sorted(mCarModeApps.comparator())
- .map(CarModeApp::toString)
+ .map(cma -> "[" + cma.getPriority() + ", " + cma.getPackageName() + "]")
.collect(Collectors.joining(", "));
}
@@ -268,7 +193,7 @@
pw.increaseIndent();
for (CarModeApp app : mCarModeApps) {
pw.print("[");
- pw.print(app.hasSetAutomotiveProjection() ? "PROJECTION SET" : app.getPriority());
+ pw.print(app.getPriority());
pw.print("] ");
pw.println(app.getPackageName());
}
diff --git a/src/com/android/server/telecom/ConnectionServiceFocusManager.java b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
index aa0a64f..fbb23f4 100644
--- a/src/com/android/server/telecom/ConnectionServiceFocusManager.java
+++ b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
@@ -391,7 +391,7 @@
}
private void handleRequestFocus(FocusRequest focusRequest) {
- Log.i(this, "handleRequestFocus req = %s", focusRequest);
+ Log.d(this, "handleRequestFocus req = %s", focusRequest);
if (mCurrentFocus == null
|| mCurrentFocus.equals(focusRequest.call.getConnectionServiceWrapper())) {
updateConnectionServiceFocus(focusRequest.call.getConnectionServiceWrapper());
diff --git a/src/com/android/server/telecom/ConnectionServiceRepository.java b/src/com/android/server/telecom/ConnectionServiceRepository.java
index 3991ed5..d34ea3c 100644
--- a/src/com/android/server/telecom/ConnectionServiceRepository.java
+++ b/src/com/android/server/telecom/ConnectionServiceRepository.java
@@ -79,13 +79,6 @@
return service;
}
- @VisibleForTesting
- public void setService(ComponentName componentName, UserHandle userHandle,
- ConnectionServiceWrapper service) {
- Pair<ComponentName, UserHandle> cacheKey = Pair.create(componentName, userHandle);
- mServiceCache.put(cacheKey, service);
- }
-
/**
* Dumps the state of the {@link ConnectionServiceRepository}.
*
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index da2669c..01acdd1 100755
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -18,7 +18,6 @@
import static android.Manifest.permission.MODIFY_PHONE_STATE;
-import android.Manifest;
import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
@@ -31,7 +30,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.telecom.CallAudioState;
-import android.telecom.CallScreeningService;
import android.telecom.Connection;
import android.telecom.ConnectionRequest;
import android.telecom.ConnectionService;
@@ -93,7 +91,6 @@
mServiceInterface.createConnectionComplete(callId,
Log.getExternalSession());
} catch (RemoteException e) {
- logOutgoing("createConnectionComplete remote exception=%s", e);
}
}
}
@@ -352,7 +349,7 @@
logIncoming("removeCall %s", callId);
Call call = mCallIdMapper.getCall(callId);
if (call != null) {
- if (call.isAlive() && !call.isDisconnectHandledViaFuture()) {
+ if (call.isAlive()) {
mCallsManager.markCallAsDisconnected(
call, new DisconnectCause(DisconnectCause.REMOTE));
} else {
@@ -920,45 +917,6 @@
} else {
connectIdToCheck = callId;
}
-
- // Handle the case where an existing connection was added by Telephony via
- // a connection manager. The remote connection service API does not include
- // the ability to specify a parent connection when adding an existing
- // connection, so we stash the desired parent in the connection extras.
- if (connectionExtras != null
- && connectionExtras.containsKey(
- Connection.EXTRA_ADD_TO_CONFERENCE_ID)
- && connection.getParentCallId() == null) {
- String parentId = connectionExtras.getString(
- Connection.EXTRA_ADD_TO_CONFERENCE_ID);
- Log.i(ConnectionServiceWrapper.this, "addExistingConnection: remote "
- + "connection will auto-add to parent %s", parentId);
- // Replace parcelable connection instance, swapping the new desired
- // parent in.
- connection = new ParcelableConnection(
- connection.getPhoneAccount(),
- connection.getState(),
- connection.getConnectionCapabilities(),
- connection.getConnectionProperties(),
- connection.getSupportedAudioRoutes(),
- connection.getHandle(),
- connection.getHandlePresentation(),
- connection.getCallerDisplayName(),
- connection.getCallerDisplayNamePresentation(),
- connection.getVideoProvider(),
- connection.getVideoState(),
- connection.isRingbackRequested(),
- connection.getIsVoipAudioMode(),
- connection.getConnectTimeMillis(),
- connection.getConnectElapsedTimeMillis(),
- connection.getStatusHints(),
- connection.getDisconnectCause(),
- connection.getConferenceableConnectionIds(),
- connection.getExtras(),
- parentId,
- connection.getCallDirection(),
- connection.getCallerNumberVerificationStatus());
- }
// Check to see if this Connection has already been added.
Call alreadyAddedConnection = mCallsManager
.getAlreadyAddedConnection(connectIdToCheck);
@@ -1248,10 +1206,6 @@
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()));
@@ -1310,14 +1264,6 @@
@Override
public void onSuccess() {
String callId = mCallIdMapper.getCallId(call);
- if (callId == null) {
- Log.w(ConnectionServiceWrapper.this, "Call not present"
- + " in call id mapper, maybe it was aborted before the bind"
- + " completed successfully?");
- response.handleCreateConnectionFailure(
- new DisconnectCause(DisconnectCause.CANCELED));
- return;
- }
mPendingResponses.put(callId, response);
GatewayInfo gatewayInfo = call.getGatewayInfo();
@@ -1401,8 +1347,7 @@
* create a connection has been denied or failed.
* @param call The call.
*/
- @VisibleForTesting
- public void createConnectionFailed(final Call call) {
+ void createConnectionFailed(final Call call) {
Log.d(this, "createConnectionFailed(%s) via %s.", call, getComponentName());
BindCallback callback = new BindCallback() {
@Override
@@ -1623,34 +1568,6 @@
}
}
- /** @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);
@@ -1913,28 +1830,6 @@
}
}
- void onCallFilteringCompleted(Call call,
- Connection.CallFilteringCompletionInfo completionInfo) {
- final String callId = mCallIdMapper.getCallId(call);
- if (callId != null && isServiceValid("onCallFilteringCompleted")) {
- try {
- logOutgoing("onCallFilteringCompleted %s", completionInfo);
- int contactsPermission = mContext.getPackageManager()
- .checkPermission(Manifest.permission.READ_CONTACTS,
- getComponentName().getPackageName());
- if (contactsPermission == PackageManager.PERMISSION_GRANTED) {
- mServiceInterface.onCallFilteringCompleted(callId, completionInfo,
- Log.getExternalSession(TELECOM_ABBREVIATION));
- } else {
- logOutgoing("Skipping call filtering complete message for %s due"
- + " to lack of READ_CONTACTS", getComponentName().getPackageName());
- }
- } catch (RemoteException e) {
- Log.e(this, e, "Remote exception calling onCallFilteringCompleted");
- }
- }
- }
-
void onExtrasChanged(Call call, Bundle extras) {
final String callId = mCallIdMapper.getCallId(call);
if (callId != null && isServiceValid("onExtrasChanged")) {
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 2e67b08..0a8a6c4 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -403,7 +403,6 @@
// 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);
}
@@ -412,7 +411,7 @@
preferredPAH);
// Next, add all SIM phone accounts which can place emergency calls.
sortSimPhoneAccountsForEmergency(allAccounts, preferredPA);
- // and pick the first one that can place emergency calls.
+ // and pick the fist one that can place emergency calls.
for (PhoneAccount phoneAccount : allAccounts) {
if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
&& phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
@@ -439,10 +438,7 @@
mPhoneAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
mCall.getHandle() == null
? null : mCall.getHandle().getScheme()));
- // 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)) {
+ if (!mAttemptRecords.contains(callAttemptRecord)) {
Log.i(this, "Will try Connection Manager account %s for emergency",
callManager);
mAttemptRecords.add(callAttemptRecord);
@@ -661,7 +657,7 @@
}
// then by hashcode
- return account1.hashCode() - account2.hashCode();
+ return Integer.compare(account1.hashCode(), account2.hashCode());
});
}
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 14e5bf0..399c28a 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 (connectionManager != null && !Objects.equals(connectionManager.getComponentName(),
+ if (!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 a4a0242..c2b78ee 100644
--- a/src/com/android/server/telecom/DefaultDialerCache.java
+++ b/src/com/android/server/telecom/DefaultDialerCache.java
@@ -217,12 +217,6 @@
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);
}
@@ -295,8 +289,4 @@
public ContentObserver getContentObserver() {
return mDefaultDialerObserver;
}
-
- public RoleManagerAdapter getRoleManagerAdapter() {
- return mRoleManagerAdapter;
- }
}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/DeviceIdleControllerAdapter.java b/src/com/android/server/telecom/DeviceIdleControllerAdapter.java
deleted file mode 100644
index d3a798a..0000000
--- a/src/com/android/server/telecom/DeviceIdleControllerAdapter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.PowerWhitelistManager;
-import android.os.RemoteException;
-import android.telecom.Log;
-
-import com.android.internal.telecom.IDeviceIdleControllerAdapter;
-
-/**
- * Telecom is in the same process as the {@link PowerWhitelistManager}, so we can not make direct
- * calls to the manager interface, since they will fail in the DeviceIdleController
- * (see {@link Context#enforceCallingPermission(String, String)}). Instead, we must access it
- * through SystemService#getLocalService, which is only accessible to the Telecom
- * core loader service (TelecomLoaderService). Unfortunately, due to the architecture, this means
- * we must use a Binder to allow services such as this to be accessible.
- */
-public class DeviceIdleControllerAdapter {
-
- private static final String TAG = "DeviceIdleControllerAdapter";
-
- private final IDeviceIdleControllerAdapter mAdapter;
-
- public DeviceIdleControllerAdapter(IDeviceIdleControllerAdapter adapter) {
- mAdapter = adapter;
- }
-
- /**
- * Exempts an application from power restrictions for the duration specified. See
- * DeviceIdleController for more information on how this works.
- */
- public void exemptAppTemporarilyForEvent(@NonNull String packageName, long duration,
- int userHandle, @NonNull String reason) {
- try {
- mAdapter.exemptAppTemporarilyForEvent(packageName, duration, userHandle, reason);
- } catch (RemoteException e) {
- Log.w(TAG, "exemptAppTemporarilyForEvent e=" + e.getMessage());
- }
- }
-}
diff --git a/src/com/android/server/telecom/DtmfLocalTonePlayer.java b/src/com/android/server/telecom/DtmfLocalTonePlayer.java
index 5869008..304a698 100644
--- a/src/com/android/server/telecom/DtmfLocalTonePlayer.java
+++ b/src/com/android/server/telecom/DtmfLocalTonePlayer.java
@@ -193,9 +193,8 @@
final Context context = call.getContext();
final boolean areLocalTonesEnabled;
if (context.getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
- areLocalTonesEnabled = Settings.System.getIntForUser(
- context.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1,
- context.getUserId()) == 1;
+ areLocalTonesEnabled = Settings.System.getInt(
+ context.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
} else {
areLocalTonesEnabled = false;
}
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index ca76456..228cb3d 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -16,36 +16,24 @@
package com.android.server.telecom;
-import static android.app.AppOpsManager.OPSTR_RECORD_AUDIO;
-import static android.os.Process.myUid;
-
import android.Manifest;
import android.annotation.NonNull;
-import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
-import android.content.AttributionSource;
-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;
import android.content.pm.ServiceInfo;
-import android.hardware.SensorPrivacyManager;
-import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
-import android.os.PackageTagsList;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
-import android.os.UserManager;
import android.telecom.CallAudioState;
import android.telecom.ConnectionService;
import android.telecom.InCallService;
@@ -55,12 +43,10 @@
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;
import com.android.internal.telecom.IInCallService;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.telecom.SystemStateHelper.SystemStateListener;
import com.android.server.telecom.ui.NotificationChannelManager;
@@ -72,7 +58,6 @@
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;
@@ -82,10 +67,9 @@
* can send updates to the in-call app. This class is created and owned by CallsManager and retains
* a binding to the {@link IInCallService} (implemented by the in-call app).
*/
-public class InCallController extends CallsManagerListenerBase implements
- AppOpsManager.OnOpActiveChangedListener {
- public static final String NOTIFICATION_TAG = InCallController.class.getSimpleName();
+public class InCallController extends CallsManagerListenerBase {
public static final int IN_CALL_SERVICE_NOTIFICATION_ID = 3;
+ public static final String NOTIFICATION_TAG = InCallController.class.getSimpleName();
public class InCallServiceConnection {
/**
@@ -121,7 +105,7 @@
public Call mCall;
}
- public static class InCallServiceInfo {
+ private class InCallServiceInfo {
private final ComponentName mComponentName;
private boolean mIsExternalCallsSupported;
private boolean mIsSelfManagedCallsSupported;
@@ -230,7 +214,7 @@
Log.startSession("ICSBC.oSD", Log.getPackageAbbreviation(name));
synchronized (mLock) {
try {
- Log.d(this, "onServiceDisconnected: %s", name);
+ Log.d(this, "onDisconnected: %s", name);
mIsBound = false;
onDisconnected();
} finally {
@@ -282,22 +266,12 @@
@Override
public int connect(Call call) {
if (mIsConnected) {
- Log.addEvent(call, LogUtils.Events.INFO, "Already connected, ignoring request: "
- + mInCallServiceInfo);
- if (call != null) {
- // Track the call if we don't already know about it.
- addCall(call);
-
- // Notify this new added call
- sendCallToService(call, mInCallServiceInfo,
- mInCallServices.get(mInCallServiceInfo));
- }
+ Log.addEvent(call, LogUtils.Events.INFO, "Already connected, ignoring request.");
return CONNECTION_SUCCEEDED;
}
if (call != null && call.isSelfManaged() &&
- (!mInCallServiceInfo.isSelfManagedCallsSupported()
- || !call.visibleToInCallService())) {
+ !mInCallServiceInfo.isSelfManagedCallsSupported()) {
Log.i(this, "Skipping binding to %s - doesn't support self-mgd calls",
mInCallServiceInfo);
mIsConnected = false;
@@ -306,7 +280,7 @@
Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
intent.setComponent(mInCallServiceInfo.getComponentName());
- if (call != null && !call.isIncoming() && !call.isExternalCall()) {
+ if (call != null && !call.isIncoming() && !call.isExternalCall()){
intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS,
call.getIntentExtras());
intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
@@ -317,9 +291,9 @@
mIsConnected = true;
mInCallServiceInfo.setBindingStartTime(mClockProxy.elapsedRealtime());
if (!mContext.bindServiceAsUser(intent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
- | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
- UserHandle.CURRENT)) {
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
+ UserHandle.CURRENT)) {
Log.w(this, "Failed to connect.");
mIsConnected = false;
}
@@ -348,10 +322,7 @@
String packageName = mInCallServiceInfo.getComponentName().getPackageName();
mContext.unbindService(mServiceConnection);
mIsConnected = false;
- if (mIsNullBinding && mInCallServiceInfo.getType() != IN_CALL_SERVICE_TYPE_NON_UI) {
- // Non-UI InCallServices are allowed to return null from onBind if they don't
- // want to handle calls at the moment, so don't report them to the user as
- // crashed.
+ if (mIsNullBinding) {
sendCrashedInCallServiceNotification(packageName);
}
if (mCall != null) {
@@ -360,10 +331,7 @@
mInCallServiceInfo.getType(),
mInCallServiceInfo.getDisconnectTime()
- mInCallServiceInfo.getBindingStartTime(), mIsNullBinding);
- updateCallTracking(mCall, mInCallServiceInfo, false /* isAdd */);
}
-
- InCallController.this.onDisconnected(mInCallServiceInfo);
} else {
Log.i(InCallController.this, "ICSBC#disconnect: already disconnected; %s",
mInCallServiceInfo);
@@ -459,15 +427,15 @@
}
mEmergencyCallHelper.maybeGrantTemporaryLocationPermission(call,
- mCallsManager.getCurrentUserHandle());
+ mCallsManager.getCurrentUserHandle());
if (call != null && call.isIncoming()
- && mEmergencyCallHelper.getLastEmergencyCallTimeMillis() > 0) {
- // Add the last emergency call time to the call
- Bundle extras = new Bundle();
- extras.putLong(android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS,
- mEmergencyCallHelper.getLastEmergencyCallTimeMillis());
- call.putExtras(Call.SOURCE_CONNECTION_SERVICE, extras);
+ && mEmergencyCallHelper.getLastEmergencyCallTimeMillis() > 0) {
+ // Add the last emergency call time to the call
+ Bundle extras = new Bundle();
+ extras.putLong(android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS,
+ mEmergencyCallHelper.getLastEmergencyCallTimeMillis());
+ call.putExtras(Call.SOURCE_CONNECTION_SERVICE, extras);
}
// If we are here, we didn't or could not connect to child. So lets connect ourselves.
@@ -476,7 +444,7 @@
@Override
public void disconnect() {
- Log.i(this, "Disconnecting from InCallService");
+ Log.i(this, "Disconnect forced!");
if (mIsProxying) {
mSubConnection.disconnect();
} else {
@@ -501,7 +469,6 @@
return super.getInfo();
}
}
-
@Override
protected void onDisconnected() {
// Save this here because super.onDisconnected() could force us to explicitly
@@ -565,7 +532,6 @@
/**
* Called when we move to a state where calls are present on the device. Chooses the
* {@link InCallService} to which we should connect.
- *
* @param isCarMode {@code true} if device is in car mode, {@code false} otherwise.
*/
public synchronized void chooseInitialInCallService(boolean isCarMode) {
@@ -604,7 +570,6 @@
/**
* Changes the active {@link InCallService} to a car mode app. Called whenever the device
* changes to car mode or the currently active car mode app changes.
- *
* @param packageName The package name of the car mode app.
*/
public synchronized void changeCarModeApp(String packageName) {
@@ -613,8 +578,7 @@
InCallServiceInfo currentConnectionInfo = mCurrentConnection == null ? null
: mCurrentConnection.getInfo();
InCallServiceInfo carModeConnectionInfo =
- getInCallServiceComponent(packageName,
- IN_CALL_SERVICE_TYPE_CAR_MODE_UI, true /* ignoreDisabed */);
+ getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_CAR_MODE_UI);
if (!Objects.equals(currentConnectionInfo, carModeConnectionInfo)) {
Log.i(this, "changeCarModeApp: " + currentConnectionInfo + " => "
@@ -629,7 +593,7 @@
new InCallServiceBindingConnection(carModeConnectionInfo);
mIsCarMode = true;
} else {
- // The app is not enabled. Using the default dialer connection instead
+ // Invalid car mode app; don't expect this but should handle it gracefully.
mCarModeConnection = null;
mIsCarMode = false;
mCurrentConnection = mDialerConnection;
@@ -643,10 +607,6 @@
}
}
- public boolean isCarMode() {
- return mIsCarMode;
- }
-
@Override
public int connect(Call call) {
if (mIsConnected) {
@@ -761,24 +721,6 @@
}
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() {
@@ -903,91 +845,25 @@
public void onRemoteRttRequest(Call call, int requestId) {
notifyRemoteRttRequest(call, requestId);
}
-
- @Override
- public void onCallerNumberVerificationStatusChanged(Call call,
- int callerNumberVerificationStatus) {
- updateCall(call);
- }
};
- 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);
- }
-
- // If the current car mode app become enabled from disabled, update
- // the connection to binding
- updateCarModeForConnections();
- }
- }
- } 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 onAutomotiveProjectionStateSet(String automotiveProjectionPackage) {
- InCallController.this.handleSetAutomotiveProjection(automotiveProjectionPackage);
- }
-
- @Override
- public void onAutomotiveProjectionStateReleased() {
- InCallController.this.handleReleaseAutomotiveProjection();
- }
-
- @Override
- public void onPackageUninstalled(String packageName) {
- mCarModeTracker.forceRemove(packageName);
- updateCarModeForConnections();
- }
- };
+ private final SystemStateListener mSystemStateListener =
+ (priority, packageName, isCarMode) -> InCallController.this.handleCarModeChange(
+ priority, packageName, isCarMode);
private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
- private static final int IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI = 1;
+ private static final int IN_CALL_SERVICE_TYPE_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;
private static final int IN_CALL_SERVICE_TYPE_COMPANION = 5;
- private static final int[] LIVE_CALL_STATES = { CallState.ACTIVE, CallState.PULLING,
- CallState.DISCONNECTING };
-
/** The in-call app implementations, see {@link IInCallService}. */
private final Map<InCallServiceInfo, IInCallService> mInCallServices = new ArrayMap<>();
private final CallIdMapper mCallIdMapper = new CallIdMapper(Call::getId);
private final Context mContext;
- private final AppOpsManager mAppOpsManager;
- private final SensorPrivacyManager mSensorPrivacyManager;
private final TelecomSystem.SyncRoot mLock;
private final CallsManager mCallsManager;
private final SystemStateHelper mSystemStateHelper;
@@ -998,12 +874,6 @@
private CarSwappingInCallServiceConnection mInCallServiceConnection;
private NonUIInCallServiceConnectionCollection mNonUIInCallServiceConnections;
private final ClockProxy mClockProxy;
- private final IBinder mToken = new Binder();
-
- // 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.
@@ -1011,40 +881,12 @@
private final CarModeTracker mCarModeTracker;
- /**
- * The package name of the app which is showing the calling UX.
- */
- private String mCurrentUserInterfacePackageName = null;
-
- /**
- * {@code true} if InCallController is tracking a managed, not external call which is using the
- * microphone, and is not muted {@code false} otherwise.
- */
- private boolean mIsCallUsingMicrophone = false;
-
- /**
- * {@code true} if InCallController is tracking a managed, not external call which is using the
- * microphone, {@code false} otherwise.
- */
- private boolean mIsTrackingManagedAliveCall = false;
-
- private boolean mIsStartCallDelayScheduled = false;
-
- /**
- * A list of call IDs which are currently using the camera.
- */
- private ArrayList<String> mCallsUsingCamera = new ArrayList<>();
-
- private ArraySet<String> mAllCarrierPrivilegedApps = new ArraySet<>();
- private ArraySet<String> mActiveCarrierPrivilegedApps = new ArraySet<>();
-
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);
- mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
mLock = lock;
mCallsManager = callsManager;
mSystemStateHelper = systemStateHelper;
@@ -1054,76 +896,6 @@
mCarModeTracker = carModeTracker;
mSystemStateHelper.addListener(mSystemStateListener);
mClockProxy = clockProxy;
- restrictPhoneCallOps();
- }
-
- private void restrictPhoneCallOps() {
- PackageTagsList packageRestriction = new PackageTagsList.Builder()
- .add(mContext.getPackageName())
- .build();
- mAppOpsManager.setUserRestrictionForUser(AppOpsManager.OP_PHONE_CALL_MICROPHONE, true,
- mToken, packageRestriction, UserHandle.USER_ALL);
- mAppOpsManager.setUserRestrictionForUser(AppOpsManager.OP_PHONE_CALL_CAMERA, true,
- mToken, packageRestriction, UserHandle.USER_ALL);
- }
-
- @Override
- public void onOpActiveChanged(@androidx.annotation.NonNull String op, int uid,
- @androidx.annotation.NonNull String packageName, boolean active) {
- synchronized (mLock) {
- if (!mAllCarrierPrivilegedApps.contains(packageName)) {
- return;
- }
-
- if (active) {
- mActiveCarrierPrivilegedApps.add(packageName);
- } else {
- mActiveCarrierPrivilegedApps.remove(packageName);
- }
- maybeTrackMicrophoneUse(isMuted());
- }
- }
-
- private void updateAllCarrierPrivilegedUsingMic() {
- mActiveCarrierPrivilegedApps.clear();
- UserManager userManager = mContext.getSystemService(UserManager.class);
- PackageManager pkgManager = mContext.getPackageManager();
- for (String pkg : mAllCarrierPrivilegedApps) {
- boolean isActive = mActiveCarrierPrivilegedApps.contains(pkg);
- List<UserHandle> users = userManager.getUserHandles(true);
- for (UserHandle user : users) {
- if (isActive) {
- break;
- }
-
- int uid;
- try {
- uid = pkgManager.getPackageUidAsUser(pkg, user.getIdentifier());
- } catch (PackageManager.NameNotFoundException e) {
- continue;
- }
- List<AppOpsManager.PackageOps> pkgOps = mAppOpsManager.getOpsForPackage(
- uid, pkg, OPSTR_RECORD_AUDIO);
- for (int j = 0; j < pkgOps.size(); j++) {
- List<AppOpsManager.OpEntry> opEntries = pkgOps.get(j).getOps();
- for (int k = 0; k < opEntries.size(); k++) {
- AppOpsManager.OpEntry entry = opEntries.get(k);
- if (entry.isRunning()) {
- mActiveCarrierPrivilegedApps.add(pkg);
- break;
- }
- }
- }
- }
- }
- }
-
- private void updateAllCarrierPrivileged() {
- mAllCarrierPrivilegedApps.clear();
- for (Call call : mCallIdMapper.getCalls()) {
- mAllCarrierPrivilegedApps.add(call.getConnectionManagerPhoneAccount()
- .getComponentName().getPackageName());
- }
}
@Override
@@ -1155,16 +927,12 @@
continue;
}
- if (call.isSelfManaged() && (!call.visibleToInCallService()
- || !info.isSelfManagedCallsSupported())) {
+ if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
continue;
}
// Only send the RTT call if it's a UI in-call service
- boolean includeRttCall = false;
- if (mInCallServiceConnection != null) {
- includeRttCall = info.equals(mInCallServiceConnection.getInfo());
- }
+ boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
componentsUpdated.add(info.getComponentName());
IInCallService inCallService = entry.getValue();
@@ -1172,11 +940,9 @@
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_NON_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
- updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1202,16 +968,10 @@
}
}
}.prepare(), mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
- mContext.getContentResolver()));
+ mContext.getContentResolver()));
}
call.removeListener(mCallListener);
mCallIdMapper.removeCall(call);
- if (mCallIdMapper.getCalls().isEmpty()) {
- mActiveCarrierPrivilegedApps.clear();
- mAppOpsManager.stopWatchingActive(this);
- }
- maybeTrackMicrophoneUse(isMuted());
- onSetCamera(call, null);
}
@Override
@@ -1231,8 +991,7 @@
continue;
}
- if (call.isSelfManaged() && !call.visibleToInCallService()
- && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
continue;
}
@@ -1245,11 +1004,9 @@
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_NON_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
- updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1278,8 +1035,7 @@
android.telecom.Call.STATE_DISCONNECTED /* overrideState */,
false /* includeRttCall */,
info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
- || info.getType() == IN_CALL_SERVICE_TYPE_NON_UI
- );
+ );
try {
inCallService.updateCall(
@@ -1289,12 +1045,10 @@
}
Log.i(this, "External call removed from components: %s", componentsUpdated);
}
- maybeTrackMicrophoneUse(isMuted());
}
@Override
public void onCallStateChanged(Call call, int oldState, int newState) {
- maybeTrackMicrophoneUse(isMuted());
updateCall(call);
}
@@ -1312,7 +1066,6 @@
if (!mInCallServices.isEmpty()) {
Log.i(this, "Calling onAudioStateChanged, audioState: %s -> %s", oldCallAudioState,
newCallAudioState);
- maybeTrackMicrophoneUse(newCallAudioState.isMuted());
for (IInCallService inCallService : mInCallServices.values()) {
try {
inCallService.onCallAudioStateChanged(newCallAudioState);
@@ -1363,7 +1116,6 @@
public void onIsVoipAudioModeChanged(Call call) {
Log.d(this, "onIsVoipAudioModeChanged %s", call);
updateCall(call);
- maybeTrackMicrophoneUse(isMuted());
}
@Override
@@ -1378,40 +1130,6 @@
updateCall(call);
}
- /**
- * Track changes to camera usage for a call.
- *
- * @param call The call.
- * @param cameraId The id of the camera to use, or {@code null} if camera is off.
- */
- @Override
- public void onSetCamera(Call call, String cameraId) {
- if (call == null) {
- return;
- }
-
- Log.i(this, "onSetCamera callId=%s, cameraId=%s", call.getId(), cameraId);
- if (cameraId != null) {
- boolean shouldStart = mCallsUsingCamera.isEmpty();
- if (!mCallsUsingCamera.contains(call.getId())) {
- mCallsUsingCamera.add(call.getId());
- }
-
- if (shouldStart) {
- mAppOpsManager.startOp(AppOpsManager.OP_PHONE_CALL_CAMERA, myUid(),
- mContext.getOpPackageName(), false, null, null);
- mSensorPrivacyManager.showSensorUseDialog(SensorPrivacyManager.Sensors.CAMERA);
- }
- } else {
- boolean hadCall = !mCallsUsingCamera.isEmpty();
- mCallsUsingCamera.remove(call.getId());
- if (hadCall && mCallsUsingCamera.isEmpty()) {
- mAppOpsManager.finishOp(AppOpsManager.OP_PHONE_CALL_CAMERA, myUid(),
- mContext.getOpPackageName(), null);
- }
- }
- }
-
void bringToForeground(boolean showDialpad) {
if (!mInCallServices.isEmpty()) {
for (IInCallService inCallService : mInCallServices.values()) {
@@ -1441,8 +1159,8 @@
for (IInCallService inCallService : mInCallServices.values()) {
try {
Log.i(this, "notifyConnectionEvent {Call: %s, Event: %s, Extras:[%s]}",
- (call != null ? call.toString() : "null"),
- (event != null ? event : "null"),
+ (call != null ? call.toString() :"null"),
+ (event != null ? event : "null") ,
(extras != null ? extras.toString() : "null"));
inCallService.onConnectionEvent(mCallIdMapper.getCallId(call), event, extras);
} catch (RemoteException ignored) {
@@ -1453,7 +1171,7 @@
private void notifyRttInitiationFailure(Call call, int reason) {
if (!mInCallServices.isEmpty()) {
- mInCallServices.entrySet().stream()
+ mInCallServices.entrySet().stream()
.filter((entry) -> entry.getKey().equals(mInCallServiceConnection.getInfo()))
.forEach((entry) -> {
try {
@@ -1508,13 +1226,7 @@
/**
* Unbinds an existing bound connection to the in-call app.
*/
- 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.
- }
+ private void unbindFromServices() {
if (mInCallServiceConnection != null) {
mInCallServiceConnection.disconnect();
mInCallServiceConnection = null;
@@ -1528,8 +1240,7 @@
/**
* 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.
*/
@@ -1566,12 +1277,11 @@
mInCallServiceConnection.chooseInitialInCallService(shouldUseCarModeUI());
- // Actually try binding to the UI InCallService.
+ // Actually try binding to the UI InCallService. If the response
if (mInCallServiceConnection.connect(call) ==
- InCallServiceConnection.CONNECTION_SUCCEEDED || call.isSelfManaged()) {
+ InCallServiceConnection.CONNECTION_SUCCEEDED) {
// Only connect to the non-ui InCallServices if we actually connected to the main UI
- // one, or if the call is self-managed (in which case we'd still want to keep Wear, BT,
- // etc. informed.
+ // one.
connectToNonUiInCallServices(call);
mBindingFuture = new CompletableFuture<Boolean>().completeOnTimeout(false,
mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
@@ -1580,13 +1290,9 @@
} else {
Log.i(this, "bindToServices: current UI doesn't support call; not binding.");
}
-
- IntentFilter packageChangedFilter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
- packageChangedFilter.addDataScheme("package");
- mContext.registerReceiver(mPackageChangedReceiver, packageChangedFilter);
}
- private void updateNonUiInCallServices() {
+ private void connectToNonUiInCallServices(Call call) {
List<InCallServiceInfo> nonUIInCallComponents =
getInCallServiceComponents(IN_CALL_SERVICE_TYPE_NON_UI);
List<InCallServiceBindingConnection> nonUIInCalls = new LinkedList<>();
@@ -1596,22 +1302,15 @@
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, true /* ignoreDisabled */);
+ IN_CALL_SERVICE_TYPE_COMPANION);
if (info != null) {
nonUIInCalls.add(new InCallServiceBindingConnection(info));
}
}
}
- mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(
- nonUIInCalls);
- }
-
- private void connectToNonUiInCallServices(Call call) {
- if (mNonUIInCallServiceConnections == null) {
- updateNonUiInCallServices();
- }
+ mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
mNonUIInCallServiceConnections.connect(call);
}
@@ -1623,10 +1322,8 @@
InCallServiceInfo defaultDialerComponent =
(systemPackageName != null && systemPackageName.equals(packageName))
- ? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI,
- true /* ignoreDisabled */)
- : getInCallServiceComponent(packageName,
- IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI, true /* ignoreDisabled */);
+ ? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI)
+ : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_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.
@@ -1638,7 +1335,7 @@
private InCallServiceInfo getCurrentCarModeComponent() {
return getInCallServiceComponent(mCarModeTracker.getCurrentCarModePackage(),
- IN_CALL_SERVICE_TYPE_CAR_MODE_UI, true /* ignoreDisabled */);
+ IN_CALL_SERVICE_TYPE_CAR_MODE_UI);
}
private InCallServiceInfo getInCallServiceComponent(ComponentName componentName, int type) {
@@ -1648,15 +1345,13 @@
} else {
// Last Resort: Try to bind to the ComponentName given directly.
Log.e(this, new Exception(), "Package Manager could not find ComponentName: "
- + componentName + ". Trying to bind anyway.");
+ + componentName +". Trying to bind anyway.");
return new InCallServiceInfo(componentName, false, false, type);
}
}
- private InCallServiceInfo getInCallServiceComponent(String packageName, int type,
- boolean ignoreDisabled) {
- List<InCallServiceInfo> list = getInCallServiceComponents(packageName, type,
- ignoreDisabled);
+ private InCallServiceInfo getInCallServiceComponent(String packageName, int type) {
+ List<InCallServiceInfo> list = getInCallServiceComponents(packageName, type);
if (list != null && !list.isEmpty()) {
return list.get(0);
}
@@ -1667,9 +1362,8 @@
return getInCallServiceComponents(null, null, type);
}
- private List<InCallServiceInfo> getInCallServiceComponents(String packageName, int type,
- boolean ignoreDisabled) {
- return getInCallServiceComponents(packageName, null, type, ignoreDisabled);
+ private List<InCallServiceInfo> getInCallServiceComponents(String packageName, int type) {
+ return getInCallServiceComponents(packageName, null, type);
}
private List<InCallServiceInfo> getInCallServiceComponents(ComponentName componentName,
@@ -1679,12 +1373,7 @@
private List<InCallServiceInfo> getInCallServiceComponents(String packageName,
ComponentName componentName, int requestedType) {
- return getInCallServiceComponents(packageName, componentName, requestedType,
- true /* ignoreDisabled */);
- }
- private List<InCallServiceInfo> getInCallServiceComponents(String packageName,
- ComponentName componentName, int requestedType, boolean ignoreDisabled) {
List<InCallServiceInfo> retval = new LinkedList<>();
Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
@@ -1698,7 +1387,7 @@
PackageManager packageManager = mContext.getPackageManager();
for (ResolveInfo entry : packageManager.queryIntentServicesAsUser(
serviceIntent,
- PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS,
+ PackageManager.GET_META_DATA,
mCallsManager.getCurrentUserHandle().getIdentifier())) {
ServiceInfo serviceInfo = entry.serviceInfo;
if (serviceInfo != null) {
@@ -1711,45 +1400,22 @@
int currentType = getInCallServiceType(entry.serviceInfo, packageManager,
packageName);
- ComponentName foundComponentName =
- new ComponentName(serviceInfo.packageName, serviceInfo.name);
- if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
- mKnownNonUiInCallServices.add(foundComponentName);
- }
-
- boolean isEnabled = isServiceEnabled(foundComponentName,
- serviceInfo, packageManager);
- boolean isRequestedType;
- if (requestedType == IN_CALL_SERVICE_TYPE_INVALID) {
- isRequestedType = true;
- } else {
- isRequestedType = requestedType == currentType;
- }
-
- if ((!ignoreDisabled || isEnabled) && isRequestedType) {
- retval.add(new InCallServiceInfo(foundComponentName, isExternalCallsSupported,
- isSelfManageCallsSupported, requestedType));
+ 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));
}
}
}
+
return retval;
}
- private boolean isServiceEnabled(ComponentName componentName,
- ServiceInfo serviceInfo, PackageManager packageManager) {
- int componentEnabledState = packageManager.getComponentEnabledSetting(componentName);
-
- if (componentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
- return true;
- }
-
- if (componentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
- return serviceInfo.isEnabled();
- }
-
- return false;
- }
-
private boolean shouldUseCarModeUI() {
return mCarModeTracker.isInCarMode();
}
@@ -1792,17 +1458,9 @@
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;
}
@@ -1812,13 +1470,12 @@
mDefaultDialerCache.getDefaultDialerApplication(
mCallsManager.getCurrentUserHandle().getIdentifier()));
if (isDefaultDialerPackage && isUIService) {
- return IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
+ return IN_CALL_SERVICE_TYPE_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 ||
- hasAppOpsPermittedManageOngoingCalls)) {
+ if (!isUIService && !isCarModeUIService && hasControlInCallPermission) {
return IN_CALL_SERVICE_TYPE_NON_UI;
}
@@ -1849,11 +1506,6 @@
private boolean onConnected(InCallServiceInfo info, IBinder service) {
Log.i(this, "onConnected to %s", info.getComponentName());
- if (info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
- || info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
- || info.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
- trackCallingUserInterfaceStarted(info);
- }
IInCallService inCallService = IInCallService.Stub.asInterface(service);
mInCallServices.put(info, inCallService);
@@ -1876,55 +1528,39 @@
"calls", calls.size(), info.getComponentName());
int numCallsSent = 0;
for (Call call : calls) {
- numCallsSent += sendCallToService(call, info, inCallService);
+ try {
+ if ((call.isSelfManaged() && !info.isSelfManagedCallsSupported()) ||
+ (call.isExternalCall() && !info.isExternalCallsSupported())) {
+ continue;
+ }
+
+ // Only send the RTT call if it's a UI in-call service
+ boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+
+ // Track the call if we don't already know about it.
+ addCall(call);
+ numCallsSent += 1;
+ ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(
+ call,
+ true /* includeVideoProvider */,
+ mCallsManager.getPhoneAccountRegistrar(),
+ info.isExternalCallsSupported(),
+ includeRttCall,
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ } catch (RemoteException ignored) {
+ }
}
try {
inCallService.onCallAudioStateChanged(mCallsManager.getAudioState());
inCallService.onCanAddCallChanged(mCallsManager.canAddCall());
} catch (RemoteException ignored) {
}
- // Don't complete the binding future for non-ui incalls
- if (info.getType() != IN_CALL_SERVICE_TYPE_NON_UI && !mBindingFuture.isDone()) {
- mBindingFuture.complete(true);
- }
-
+ mBindingFuture.complete(true);
Log.i(this, "%s calls sent to InCallService.", numCallsSent);
return true;
}
- private int sendCallToService(Call call, InCallServiceInfo info,
- IInCallService inCallService) {
- try {
- if ((call.isSelfManaged() && (!info.isSelfManagedCallsSupported()
- || !call.visibleToInCallService())) ||
- (call.isExternalCall() && !info.isExternalCallsSupported())) {
- return 0;
- }
-
- // Only send the RTT call if it's a UI in-call service
- boolean includeRttCall = false;
- if (mInCallServiceConnection != null) {
- includeRttCall = info.equals(mInCallServiceConnection.getInfo());
- }
-
- // Track the call if we don't already know about it.
- addCall(call);
- 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_NON_UI);
- inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
- updateCallTracking(call, info, true /* isAdd */);
- return 1;
- } catch (RemoteException ignored) {
- }
- return 0;
- }
-
/**
* Cleans up an instance of in-call app after the service has been unbound.
*
@@ -1932,11 +1568,7 @@
*/
private void onDisconnected(InCallServiceInfo disconnectedInfo) {
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_DEFAULT_DIALER_UI) {
- trackCallingUserInterfaceStopped(disconnectedInfo);
- }
+
mInCallServices.remove(disconnectedInfo);
}
@@ -1968,8 +1600,7 @@
continue;
}
- if (call.isSelfManaged() && (!call.visibleToInCallService()
- || !info.isSelfManagedCallsSupported())) {
+ if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
continue;
}
@@ -1979,8 +1610,7 @@
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
rttInfoChanged && info.equals(mInCallServiceConnection.getInfo()),
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
- info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
ComponentName componentName = info.getComponentName();
IInCallService inCallService = entry.getValue();
componentsUpdated.add(componentName);
@@ -2000,19 +1630,10 @@
* @param call The call to add.
*/
private void addCall(Call call) {
- if (mCallIdMapper.getCalls().size() == 0) {
- mAppOpsManager.startWatchingActive(new String[] { OPSTR_RECORD_AUDIO },
- java.lang.Runnable::run, this);
- updateAllCarrierPrivileged();
- updateAllCarrierPrivilegedUsingMic();
- }
-
if (mCallIdMapper.getCallId(call) == null) {
mCallIdMapper.addCall(call);
call.addListener(mCallListener);
}
-
- maybeTrackMicrophoneUse(isMuted());
}
/**
@@ -2058,7 +1679,7 @@
*/
private ComponentName getConnectedUi() {
InCallServiceInfo connectedUi = mInCallServices.keySet().stream().filter(
- i -> i.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI
+ i -> i.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI
|| i.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI)
.findAny()
.orElse(null);
@@ -2080,7 +1701,7 @@
if (TextUtils.isEmpty(ringingPackage)) {
// The current in-call UI returned nothing, so lets use the default dialer.
- ringingPackage = mDefaultDialerCache.getRoleManagerAdapter().getDefaultDialerApp(
+ ringingPackage = mDefaultDialerCache.getDefaultDialerApplication(
mCallsManager.getCurrentUserHandle().getIdentifier());
if (ringingPackage != null) {
Log.d(this, "doesConnectedDialerSupportRinging: notCurentlyConnectedPackage=%s",
@@ -2155,19 +1776,15 @@
* {@code false} otherwise.
*/
private boolean isCarModeInCallService(@NonNull String packageName) {
- // Disabled InCallService should also be considered as a valid InCallService here so that
- // it can be added to the CarModeTracker, in case it will be enabled in future.
InCallServiceInfo info =
- getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_CAR_MODE_UI,
- false /* ignoreDisabled */);
+ getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_CAR_MODE_UI);
return info != null && info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI;
}
public void handleCarModeChange(int priority, String packageName, boolean isCarMode) {
Log.i(this, "handleCarModeChange: packageName=%s, priority=%d, isCarMode=%b",
packageName, priority, isCarMode);
- // Don't ignore the signal if we are disabling car mode; package may be uninstalled.
- if (isCarMode && !isCarModeInCallService(packageName)) {
+ if (!isCarModeInCallService(packageName)) {
Log.i(this, "handleCarModeChange: not a valid InCallService; packageName=%s",
packageName);
return;
@@ -2179,155 +1796,21 @@
mCarModeTracker.handleExitCarMode(priority, packageName);
}
- updateCarModeForConnections();
- }
-
- public void handleSetAutomotiveProjection(@NonNull String packageName) {
- Log.i(this, "handleSetAutomotiveProjection: packageName=%s", packageName);
- if (!isCarModeInCallService(packageName)) {
- Log.i(this, "handleSetAutomotiveProjection: not a valid InCallService: packageName=%s",
- packageName);
- return;
- }
- mCarModeTracker.handleSetAutomotiveProjection(packageName);
-
- updateCarModeForConnections();
- }
-
- public void handleReleaseAutomotiveProjection() {
- Log.i(this, "handleReleaseAutomotiveProjection");
- mCarModeTracker.handleReleaseAutomotiveProjection();
-
- 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()) {
- Log.i(this, "updateCarModeForConnections: potentially update car mode app.");
mInCallServiceConnection.changeCarModeApp(
mCarModeTracker.getCurrentCarModePackage());
} else {
- if (mInCallServiceConnection.isCarMode()) {
- Log.i(this, "updateCarModeForConnections: car mode no longer "
- + "applicable; disabling");
- mInCallServiceConnection.disableCarMode();
- }
+ mInCallServiceConnection.disableCarMode();
}
}
}
- /**
- * Tracks start of microphone use on binding to the current calling UX.
- * @param info
- */
- private void trackCallingUserInterfaceStarted(InCallServiceInfo info) {
- String packageName = info.getComponentName().getPackageName();
- if (!Objects.equals(mCurrentUserInterfacePackageName, packageName)) {
- Log.i(this, "trackCallingUserInterfaceStarted: %s is now calling UX.", packageName);
- mCurrentUserInterfacePackageName = packageName;
- }
- maybeTrackMicrophoneUse(isMuted());
- }
-
- /**
- * Tracks stop of microphone use on unbind from the current calling UX.
- * @param info
- */
- private void trackCallingUserInterfaceStopped(InCallServiceInfo info) {
- maybeTrackMicrophoneUse(isMuted());
- mCurrentUserInterfacePackageName = null;
- String packageName = info.getComponentName().getPackageName();
- Log.i(this, "trackCallingUserInterfaceStopped: %s is no longer calling UX", packageName);
- }
-
- private void maybeTrackMicrophoneUse(boolean isMuted) {
- maybeTrackMicrophoneUse(isMuted, false);
- }
-
- /**
- * As calls are added, removed and change between external and non-external status, track
- * whether the current active calling UX is using the microphone. We assume if there is a
- * managed call present and the mic is not muted that the microphone is in use.
- */
- private void maybeTrackMicrophoneUse(boolean isMuted, boolean isScheduledDelay) {
- if (mIsStartCallDelayScheduled && !isScheduledDelay) {
- return;
- }
-
- mIsStartCallDelayScheduled = false;
- boolean wasUsingMicrophone = mIsCallUsingMicrophone;
- boolean wasTrackingCall = mIsTrackingManagedAliveCall;
- mIsTrackingManagedAliveCall = isTrackingManagedAliveCall();
- if (!wasTrackingCall && mIsTrackingManagedAliveCall) {
- mIsStartCallDelayScheduled = true;
- mHandler.postDelayed(new Runnable("ICC.mTMU", mLock) {
- @Override
- public void loggedRun() {
- maybeTrackMicrophoneUse(isMuted(), true);
- }
- }.prepare(), mTimeoutsAdapter.getCallStartAppOpDebounceIntervalMillis());
- return;
- }
-
- mIsCallUsingMicrophone = mIsTrackingManagedAliveCall && !isMuted
- && !isCarrierPrivilegedUsingMicDuringVoipCall();
- if (wasUsingMicrophone != mIsCallUsingMicrophone) {
- if (mIsCallUsingMicrophone) {
- mAppOpsManager.startOp(AppOpsManager.OP_PHONE_CALL_MICROPHONE, myUid(),
- mContext.getOpPackageName(), false, null, null);
- mSensorPrivacyManager.showSensorUseDialog(SensorPrivacyManager.Sensors.MICROPHONE);
- } else {
- mAppOpsManager.finishOp(AppOpsManager.OP_PHONE_CALL_MICROPHONE, myUid(),
- mContext.getOpPackageName(), null);
- }
- }
- }
-
- /**
- * @return {@code true} if InCallController is tracking a managed call (i.e. not self managed
- * and not external) that is active.
- */
- private boolean isTrackingManagedAliveCall() {
- return mCallIdMapper.getCalls().stream().anyMatch(c -> !c.isExternalCall()
- && !c.isSelfManaged() && c.isAlive() && ArrayUtils.contains(LIVE_CALL_STATES,
- c.getState()));
- }
-
- private boolean isCarrierPrivilegedUsingMicDuringVoipCall() {
- return !mActiveCarrierPrivilegedApps.isEmpty() &&
- mCallIdMapper.getCalls().stream().anyMatch(Call::getIsVoipAudioMode);
- }
-
- /**
- * @return {@code true} if the audio is currently muted, {@code false} otherwise.
- */
- private boolean isMuted() {
- if (mCallsManager.getAudioState() == null) {
- return false;
- }
- return mCallsManager.getAudioState().isMuted();
- }
-
- private boolean isAppOpsPermittedManageOngoingCalls(int uid, String callingPackage) {
- return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(mContext,
- Manifest.permission.MANAGE_ONGOING_CALLS, PermissionChecker.PID_UNKNOWN,
- new AttributionSource(mContext.getAttributionSource(),
- new AttributionSource(uid, callingPackage,
- /*attributionTag*/ null)), "Checking whether the app has"
- + " MANAGE_ONGOING_CALLS permission")
- == PermissionChecker.PERMISSION_GRANTED;
- }
-
private void sendCrashedInCallServiceNotification(String packageName) {
PackageManager packageManager = mContext.getPackageManager();
CharSequence appName;
- String systemDialer = mDefaultDialerCache.getSystemDialerApplication();
- if ((systemDialer != null) && systemDialer.equals(packageName)) {
- return;
- }
try {
appName = packageManager.getApplicationLabel(
packageManager.getApplicationInfo(packageName, 0));
@@ -2352,11 +1835,4 @@
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 524d119..4f0cf8d 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -162,8 +162,6 @@
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;
@@ -331,22 +329,12 @@
// 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);
}
@@ -439,7 +427,7 @@
@Override
public void onCompletion(MediaPlayer mp) {
Log.i(this, "playMediaTone: toneResourceId=%d completed.", toneResourceId);
- synchronized (InCallTonePlayer.this) {
+ synchronized (this) {
mState = STATE_OFF;
}
mToneMediaPlayer.release();
diff --git a/src/com/android/server/telecom/InternalServiceRetrieverAdapter.java b/src/com/android/server/telecom/InternalServiceRetrieverAdapter.java
deleted file mode 100644
index 4a2c3d1..0000000
--- a/src/com/android/server/telecom/InternalServiceRetrieverAdapter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom;
-
-import android.os.RemoteException;
-
-import com.android.internal.telecom.IInternalServiceRetriever;
-
-/**
- * Contains all services that Telecom must access that are only accessible as a local service as
- * part of the SYSTEM process.
- */
-public class InternalServiceRetrieverAdapter {
-
- private final IInternalServiceRetriever mRetriever;
-
- public InternalServiceRetrieverAdapter(IInternalServiceRetriever retriever) {
- mRetriever = retriever;
- }
-
- public DeviceIdleControllerAdapter getDeviceIdleController() {
- try {
- return new DeviceIdleControllerAdapter(mRetriever.getDeviceIdleController());
- } catch (RemoteException e) {
- // This should not happen - if it does, there is a bad configuration as this should
- // all be local.
- throw new IllegalStateException(e);
- }
- }
-}
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index f53f239..5bb14e6 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -101,8 +101,6 @@
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";
@@ -138,7 +136,6 @@
public static final String REMOVE_CHILD = "REMOVE_CHILD";
public static final String SET_PARENT = "SET_PARENT";
public static final String CONF_STATE_CHANGED = "CONF_STATE_CHANGED";
- public static final String CONF_CALLS_CHANGED = "CONF_CALLS_CHANGED";
public static final String CALL_DIRECTION_CHANGED = "CALL_DIRECTION_CHANGED";
public static final String MUTE = "MUTE";
public static final String UNMUTE = "UNMUTE";
@@ -197,12 +194,6 @@
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 final String SET_DISCONNECTED_ORIG = "SET_DISCONNECTED_ORIG";
- public static final String OVERRIDE_DISCONNECT_MESSAGE = "OVERRIDE_DISCONNECT_MSG";
- public static final String CALL_DIAGNOSTIC_SERVICE_TIMEOUT =
- "CALL_DIAGNOSTIC_SERVICE_TIMEOUT";
- public static final String VERSTAT_CHANGED = "VERSTAT_CHANGED";
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 86fedd5..f0efe92 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -21,6 +21,7 @@
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;
@@ -494,7 +495,9 @@
private void launchSystemDialer(Uri handle) {
Intent systemDialerIntent = new Intent();
- systemDialerIntent.setComponent(mDefaultDialerCache.getDialtactsSystemDialerComponent());
+ systemDialerIntent.setComponent(
+ new ComponentName(mDefaultDialerCache.getSystemDialerApplication(),
+ mContext.getResources().getString(R.string.dialer_default_class)));
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 f500828..5c821a4 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -27,7 +27,6 @@
import android.telecom.ParcelableCall;
import android.telecom.ParcelableRttCall;
import android.telecom.TelecomManager;
-import android.telephony.ims.ImsCallProfile;
import android.text.TextUtils;
import java.util.ArrayList;
@@ -43,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 incallservice other than the system incallservice.
+ * generated for the purpose of sending to a dialer other than the system dialer.
* By convention we only pass keys namespaced with android.*, however there are some keys which
- * should not be passed to non-system incallservice apps either.
+ * should not be passed to non-system dialer apps either.
*/
private static List<String> EXTRA_KEYS_TO_SANITIZE;
static {
@@ -62,7 +61,6 @@
static {
RESTRICTED_CALL_SCREENING_EXTRA_KEYS = new ArrayList<>();
RESTRICTED_CALL_SCREENING_EXTRA_KEYS.add(android.telecom.Connection.EXTRA_SIP_INVITE);
- RESTRICTED_CALL_SCREENING_EXTRA_KEYS.add(ImsCallProfile.EXTRA_IS_BUSINESS_CALL);
}
public static class Converter {
@@ -92,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 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
+ * @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
* values will be stripped for privacy sake.
*/
public static ParcelableCall toParcelableCall(
@@ -103,10 +101,10 @@
PhoneAccountRegistrar phoneAccountRegistrar,
boolean supportsExternalCalls,
boolean includeRttCall,
- boolean isForSystemInCallService) {
+ boolean isForSystemDialer) {
return toParcelableCall(call, includeVideoProvider, phoneAccountRegistrar,
supportsExternalCalls, CALL_STATE_OVERRIDE_NONE /* overrideState */,
- includeRttCall, isForSystemInCallService);
+ includeRttCall, isForSystemDialer);
}
/**
@@ -122,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 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
+ * @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
* values will be stripped for privacy sake.
* @return The {@link ParcelableCall} containing all call information from the {@link Call}.
*/
@@ -135,7 +133,7 @@
boolean supportsExternalCalls,
int overrideState,
boolean includeRttCall,
- boolean isForSystemInCallService) {
+ boolean isForSystemDialer) {
int state;
if (overrideState == CALL_STATE_OVERRIDE_NONE) {
state = getParcelableState(call, supportsExternalCalls);
@@ -218,7 +216,7 @@
}
Bundle extras;
- if (isForSystemInCallService) {
+ if (isForSystemDialer) {
extras = call.getExtras();
} else {
extras = sanitizeExtras(call.getExtras());
@@ -271,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 incallservice, the
+ * Where the call screening service is part of the system dialer, the
* {@link Connection#EXTRA_SIP_INVITE} header information is also sent to the call screening
- * service (since the system incallservice has access to this anyways).
+ * service (since the system dialer 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
@@ -335,7 +333,7 @@
/**
* Sanitize the extras bundle passed in, removing keys which should not be sent to non-system
- * incallservice apps.
+ * dialer apps.
* @param oldExtras Extras bundle to sanitize.
* @return The sanitized extras bundle.
*/
@@ -556,10 +554,7 @@
android.telecom.Call.Details.PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL,
Connection.PROPERTY_IS_ADHOC_CONFERENCE,
- android.telecom.Call.Details.PROPERTY_IS_ADHOC_CONFERENCE,
-
- Connection.PROPERTY_CROSS_SIM,
- android.telecom.Call.Details.PROPERTY_CROSS_SIM
+ android.telecom.Call.Details.PROPERTY_IS_ADHOC_CONFERENCE
};
private static int convertConnectionToCallProperties(int connectionProperties) {
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 5ef3dd5..ef2840a 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -18,7 +18,6 @@
import android.Manifest;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -486,7 +485,6 @@
* 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;
@@ -1266,11 +1264,11 @@
// Comparator which places PhoneAccounts with a specified sort order first, followed by
// those with no sort order.
Comparator<PhoneAccount> bySortOrder = (p1, p2) -> {
- 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);
+ 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);
};
// Comparator which sorts PhoneAccounts by label.
@@ -1599,16 +1597,10 @@
return BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
}
- @Nullable
protected Icon readIcon(XmlPullParser parser) throws IOException {
- 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;
- }
+ byte[] iconByteArray = Base64.decode(parser.getText(), 0);
+ ByteArrayInputStream stream = new ByteArrayInputStream(iconByteArray);
+ return Icon.createFromStream(stream);
}
}
@@ -1993,8 +1985,8 @@
* @return {@code True} if SIP should be used for all calls.
*/
private boolean useSipForPstnCalls(Context context) {
- String option = Settings.System.getStringForUser(context.getContentResolver(),
- Settings.System.SIP_CALL_OPTIONS, context.getUserId());
+ String option = Settings.System.getString(context.getContentResolver(),
+ Settings.System.SIP_CALL_OPTIONS);
option = (option != null) ? option : Settings.System.SIP_ADDRESS_ONLY;
return option.equals(Settings.System.SIP_ALWAYS);
}
diff --git a/src/com/android/server/telecom/PhoneStateBroadcaster.java b/src/com/android/server/telecom/PhoneStateBroadcaster.java
index 490db85..f2531ed 100644
--- a/src/com/android/server/telecom/PhoneStateBroadcaster.java
+++ b/src/com/android/server/telecom/PhoneStateBroadcaster.java
@@ -17,16 +17,8 @@
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
@@ -60,10 +52,6 @@
return;
}
updateStates(call);
-
- if (call.isEmergencyCall() && !call.isIncoming()) {
- sendOutgoingEmergencyCallEvent(call);
- }
}
@Override
@@ -125,38 +113,4 @@
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;
- try {
- emergencyNumber = tm.getEmergencyNumberList().values().stream()
- .flatMap(List::stream)
- .filter(numberObj -> Objects.equals(numberObj.getNumber(), strippedNumber))
- .findFirst();
- } catch (IllegalStateException ie) {
- emergencyNumber = Optional.empty();
- } catch (RuntimeException r) {
- emergencyNumber = Optional.empty();
- }
-
- 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/RespondViaSmsManager.java b/src/com/android/server/telecom/RespondViaSmsManager.java
index 23ccc1c..00d94f0 100644
--- a/src/com/android/server/telecom/RespondViaSmsManager.java
+++ b/src/com/android/server/telecom/RespondViaSmsManager.java
@@ -204,7 +204,7 @@
for (int i = 0; i < messageParts.size(); i++) {
Intent intent = new Intent(ACTION_MESSAGE_SENT);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, i, intent,
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
+ PendingIntent.FLAG_ONE_SHOT);
sentIntents.add(pendingIntent);
}
MessageSentReceiver receiver = new MessageSentReceiver(
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index 91276de..a769a94 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -20,27 +20,26 @@
import android.app.NotificationManager;
import android.app.Person;
import android.content.Context;
+import android.os.VibrationEffect;
+import android.telecom.Log;
+import android.telecom.TelecomManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.VolumeShaper;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.VibrationEffect;
import android.os.Vibrator;
-import android.telecom.Log;
-import android.telecom.TelecomManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.telecom.LogUtils.EventTimer;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
/**
* Controls the ringtone player.
@@ -115,8 +114,6 @@
private static final int REPEAT_SIMPLE_VIBRATION_AT = 1;
- private static final long RINGER_ATTRIBUTES_TIMEOUT = 5000; // 5 seconds
-
private static final float EPSILON = 1e-6f;
private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
@@ -150,7 +147,6 @@
private InCallTonePlayer mCallWaitingPlayer;
private RingtoneFactory mRingtoneFactory;
- private AudioManager mAudioManager;
/**
* Call objects that are ringing, vibrating or call-waiting. These are used only for logging
@@ -165,8 +161,6 @@
*/
private boolean mIsVibrating = false;
- private Handler mHandler = null;
-
/** Initializes the Ringer. */
@VisibleForTesting
public Ringer(
@@ -189,7 +183,6 @@
mRingtoneFactory = ringtoneFactory;
mInCallController = inCallController;
mVibrationEffectProxy = vibrationEffectProxy;
- mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
if (mContext.getResources().getBoolean(R.bool.use_simple_vibration_pattern)) {
mDefaultVibrationEffect = mVibrationEffectProxy.createWaveform(SIMPLE_VIBRATION_PATTERN,
@@ -223,39 +216,58 @@
return false;
}
- // Use completable future to establish a timeout, not intent to make these work outside the
- // main thread asynchronously
- // TODO: moving these RingerAttributes calculation out of Telecom lock to avoid blocking.
- CompletableFuture<RingerAttributes> ringerAttributesFuture = CompletableFuture
- .supplyAsync(() -> getRingerAttributes(foregroundCall, isHfpDeviceAttached),
- new LoggedHandlerExecutor(getHandler(), "R.sR", null));
+ AudioManager audioManager =
+ (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ LogUtils.EventTimer timer = new EventTimer();
+ boolean isVolumeOverZero = audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0;
+ timer.record("isVolumeOverZero");
+ boolean shouldRingForContact = shouldRingForContact(foregroundCall.getContactUri());
+ timer.record("shouldRingForContact");
+ boolean isRingtonePresent = !(mRingtoneFactory.getRingtone(foregroundCall) == null);
+ timer.record("getRingtone");
+ boolean isSelfManaged = foregroundCall.isSelfManaged();
+ timer.record("isSelfManaged");
+ boolean isSilentRingingRequested = foregroundCall.isSilentRingingRequested();
+ timer.record("isSilentRingRequested");
- RingerAttributes attributes = null;
- try {
- attributes = ringerAttributesFuture.get(
- RINGER_ATTRIBUTES_TIMEOUT, TimeUnit.MILLISECONDS);
- } catch (ExecutionException | InterruptedException | TimeoutException e) {
- // Keep attributs as null
- Log.i(this, "getAttributes error: " + e);
- }
+ boolean isRingerAudible = isVolumeOverZero && shouldRingForContact && isRingtonePresent;
+ timer.record("isRingerAudible");
+ boolean hasExternalRinger = hasExternalRinger(foregroundCall);
+ timer.record("hasExternalRinger");
+ // Don't do call waiting operations or vibration unless these are false.
+ boolean isTheaterModeOn = mSystemSettingsUtil.isTheaterModeOn(mContext);
+ timer.record("isTheaterModeOn");
+ boolean letDialerHandleRinging = mInCallController.doesConnectedDialerSupportRinging();
+ timer.record("letDialerHandleRinging");
- if (attributes == null) {
- Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING, "RingerAttributes error");
- return false;
- }
+ Log.i(this, "startRinging timings: " + timer);
+ boolean endEarly = isTheaterModeOn || letDialerHandleRinging || isSelfManaged ||
+ hasExternalRinger || isSilentRingingRequested;
- if (attributes.isEndEarly()) {
- if (attributes.letDialerHandleRinging()) {
+ // Acquire audio focus under any of the following conditions:
+ // 1. Should ring for contact and there's an HFP device attached
+ // 2. Volume is over zero, we should ring for the contact, and there's a audible ringtone
+ // present.
+ // 3. The call is self-managed.
+ boolean shouldAcquireAudioFocus =
+ isRingerAudible || (isHfpDeviceAttached && shouldRingForContact) || isSelfManaged;
+
+ if (endEarly) {
+ if (letDialerHandleRinging) {
Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING, "Dialer handles");
}
- if (attributes.isSilentRingingRequested()) {
+ if (isSilentRingingRequested) {
Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING, "Silent ringing "
+ "requested");
}
+ Log.i(this, "Ending early -- isTheaterModeOn=%s, letDialerHandleRinging=%s, " +
+ "isSelfManaged=%s, hasExternalRinger=%s, silentRingingRequested=%s",
+ isTheaterModeOn, letDialerHandleRinging, isSelfManaged, hasExternalRinger,
+ isSilentRingingRequested);
if (mBlockOnRingingFuture != null) {
mBlockOnRingingFuture.complete(null);
}
- return attributes.shouldAcquireAudioFocus();
+ return shouldAcquireAudioFocus;
}
stopCallWaiting();
@@ -264,7 +276,7 @@
CompletableFuture<Boolean> hapticsFuture = null;
// Determine if the settings and DND mode indicate that the vibrator can be used right now.
boolean isVibratorEnabled = isVibratorEnabled(mContext, foregroundCall);
- if (attributes.isRingerAudible()) {
+ if (isRingerAudible) {
mRingingCall = foregroundCall;
Log.addEvent(foregroundCall, LogUtils.Events.START_RINGER);
// Because we wait until a contact info query to complete before processing a
@@ -297,14 +309,15 @@
effect = getVibrationEffectForCall(mRingtoneFactory, foregroundCall);
}
} else {
- Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING, "Inaudible: "
- + attributes.getInaudibleReason());
+ String reason = String.format(
+ "isVolumeOverZero=%s, shouldRingForContact=%s, isRingtonePresent=%s",
+ isVolumeOverZero, shouldRingForContact, isRingtonePresent);
+ Log.i(this, "startRinging: skipping because ringer would not be audible. " + reason);
+ Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING, "Inaudible: " + reason);
effect = mDefaultVibrationEffect;
}
if (hapticsFuture != null) {
- final boolean shouldRingForContact = attributes.shouldRingForContact();
- final boolean isRingerAudible = attributes.isRingerAudible();
mVibrateFuture = hapticsFuture.thenAccept(isUsingAudioCoupledHaptics -> {
if (!isUsingAudioCoupledHaptics || !mIsHapticPlaybackSupportedByDevice) {
Log.i(this, "startRinging: fileHasHaptics=%b, hapticsSupported=%b",
@@ -329,11 +342,11 @@
mBlockOnRingingFuture.complete(null);
}
Log.w(this, "startRinging: No haptics future; fallback to default behavior");
- maybeStartVibration(foregroundCall, attributes.shouldRingForContact(), effect,
- isVibratorEnabled, attributes.isRingerAudible());
+ maybeStartVibration(foregroundCall, shouldRingForContact, effect, isVibratorEnabled,
+ isRingerAudible);
}
- return attributes.shouldAcquireAudioFocus();
+ return shouldAcquireAudioFocus;
}
private void maybeStartVibration(Call foregroundCall, boolean shouldRingForContact,
@@ -504,75 +517,4 @@
return mSystemSettingsUtil.canVibrateWhenRinging(context)
|| mSystemSettingsUtil.applyRampingRinger(context);
}
-
- private RingerAttributes getRingerAttributes(Call call, boolean isHfpDeviceAttached) {
- RingerAttributes.Builder builder = new RingerAttributes.Builder();
-
- LogUtils.EventTimer timer = new EventTimer();
-
- boolean isVolumeOverZero = mAudioManager.getStreamVolume(AudioManager.STREAM_RING) > 0;
- timer.record("isVolumeOverZero");
- boolean shouldRingForContact = shouldRingForContact(call.getHandle());
- timer.record("shouldRingForContact");
- boolean isRingtonePresent = !(mRingtoneFactory.getRingtone(call) == null);
- timer.record("getRingtone");
- boolean isSelfManaged = call.isSelfManaged();
- timer.record("isSelfManaged");
- boolean isSilentRingingRequested = call.isSilentRingingRequested();
- timer.record("isSilentRingRequested");
-
- boolean isRingerAudible = isVolumeOverZero && shouldRingForContact && isRingtonePresent;
- timer.record("isRingerAudible");
- String inaudibleReason = "";
- if (!isRingerAudible) {
- inaudibleReason = String.format(
- "isVolumeOverZero=%s, shouldRingForContact=%s, isRingtonePresent=%s",
- isVolumeOverZero, shouldRingForContact, isRingtonePresent);
- }
-
- boolean hasExternalRinger = hasExternalRinger(call);
- timer.record("hasExternalRinger");
- // Don't do call waiting operations or vibration unless these are false.
- boolean isTheaterModeOn = mSystemSettingsUtil.isTheaterModeOn(mContext);
- timer.record("isTheaterModeOn");
- boolean letDialerHandleRinging = mInCallController.doesConnectedDialerSupportRinging();
- timer.record("letDialerHandleRinging");
-
- Log.i(this, "startRinging timings: " + timer);
- boolean endEarly = isTheaterModeOn || letDialerHandleRinging || isSelfManaged ||
- hasExternalRinger || isSilentRingingRequested;
-
- if (endEarly) {
- Log.i(this, "Ending early -- isTheaterModeOn=%s, letDialerHandleRinging=%s, " +
- "isSelfManaged=%s, hasExternalRinger=%s, silentRingingRequested=%s",
- isTheaterModeOn, letDialerHandleRinging, isSelfManaged, hasExternalRinger,
- isSilentRingingRequested);
- }
-
- // Acquire audio focus under any of the following conditions:
- // 1. Should ring for contact and there's an HFP device attached
- // 2. Volume is over zero, we should ring for the contact, and there's a audible ringtone
- // present.
- // 3. The call is self-managed.
- boolean shouldAcquireAudioFocus =
- isRingerAudible || (isHfpDeviceAttached && shouldRingForContact) || isSelfManaged;
-
- return builder.setEndEarly(endEarly)
- .setLetDialerHandleRinging(letDialerHandleRinging)
- .setAcquireAudioFocus(shouldAcquireAudioFocus)
- .setRingerAudible(isRingerAudible)
- .setInaudibleReason(inaudibleReason)
- .setShouldRingForContact(shouldRingForContact)
- .setSilentRingingRequested(isSilentRingingRequested)
- .build();
- }
-
- private Handler getHandler() {
- if (mHandler == null) {
- HandlerThread handlerThread = new HandlerThread("Ringer");
- handlerThread.start();
- mHandler = handlerThread.getThreadHandler();
- }
- return mHandler;
- }
}
diff --git a/src/com/android/server/telecom/RingerAttributes.java b/src/com/android/server/telecom/RingerAttributes.java
deleted file mode 100644
index 840d815..0000000
--- a/src/com/android/server/telecom/RingerAttributes.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom;
-
-public class RingerAttributes {
- public static class Builder {
- private boolean mEndEarly;
- private boolean mLetDialerHandleRinging;
- private boolean mAcquireAudioFocus;
- private boolean mRingerAudible;
- private String mInaudibleReason;
- private boolean mShouldRingForContact;
- private boolean mSilentRingingRequested;
-
- public RingerAttributes.Builder setEndEarly(boolean endEarly) {
- mEndEarly = endEarly;
- return this;
- }
-
- public RingerAttributes.Builder setLetDialerHandleRinging(boolean letDialerHandleRinging) {
- mLetDialerHandleRinging = letDialerHandleRinging;
- return this;
- }
-
- public RingerAttributes.Builder setAcquireAudioFocus(boolean acquireAudioFocus) {
- mAcquireAudioFocus = acquireAudioFocus;
- return this;
- }
-
- public RingerAttributes.Builder setRingerAudible(boolean ringerAudible) {
- mRingerAudible = ringerAudible;
- return this;
- }
-
- public RingerAttributes.Builder setInaudibleReason(String inaudibleReason) {
- mInaudibleReason = inaudibleReason;
- return this;
- }
-
- public RingerAttributes.Builder setShouldRingForContact(boolean shouldRingForContact) {
- mShouldRingForContact = shouldRingForContact;
- return this;
- }
-
- public RingerAttributes.Builder setSilentRingingRequested(boolean silentRingingRequested) {
- mSilentRingingRequested = silentRingingRequested;
- return this;
- }
-
- public RingerAttributes build() {
- return new RingerAttributes(mEndEarly, mLetDialerHandleRinging, mAcquireAudioFocus,
- mRingerAudible, mInaudibleReason, mShouldRingForContact,
- mSilentRingingRequested);
- }
- }
-
- private boolean mEndEarly;
- private boolean mLetDialerHandleRinging;
- private boolean mAcquireAudioFocus;
- private boolean mRingerAudible;
- private String mInaudibleReason;
- private boolean mShouldRingForContact;
- private boolean mSilentRingingRequested;
-
- private RingerAttributes(boolean endEarly, boolean letDialerHandleRinging,
- boolean acquireAudioFocus, boolean ringerAudible, String inaudibleReason,
- boolean shouldRingForContact, boolean silentRingingRequested) {
- mEndEarly = endEarly;
- mLetDialerHandleRinging = letDialerHandleRinging;
- mAcquireAudioFocus = acquireAudioFocus;
- mRingerAudible = ringerAudible;
- mInaudibleReason = inaudibleReason;
- mShouldRingForContact = shouldRingForContact;
- mSilentRingingRequested = silentRingingRequested;
- }
-
- public boolean isEndEarly() {
- return mEndEarly;
- }
-
- public boolean letDialerHandleRinging() {
- return mLetDialerHandleRinging;
- }
-
- public boolean shouldAcquireAudioFocus() {
- return mAcquireAudioFocus;
- }
-
- public boolean isRingerAudible() {
- return mRingerAudible;
- }
-
- public String getInaudibleReason() {
- return mInaudibleReason;
- }
-
- public boolean shouldRingForContact() {
- return mShouldRingForContact;
- }
-
- public boolean isSilentRingingRequested() {
- return mSilentRingingRequested;
- }
-}
diff --git a/src/com/android/server/telecom/RingtoneFactory.java b/src/com/android/server/telecom/RingtoneFactory.java
index df89ee7..d3d2d0e 100644
--- a/src/com/android/server/telecom/RingtoneFactory.java
+++ b/src/com/android/server/telecom/RingtoneFactory.java
@@ -75,12 +75,7 @@
if(ringtoneUri != null && userContext != null) {
// Ringtone URI is explicitly specified. First, try to create a Ringtone with that.
- try {
- ringtone = RingtoneManager.getRingtone(userContext, ringtoneUri,
- volumeShaperConfig);
- } catch (NullPointerException npe) {
- Log.e(this, npe, "getRingtone: NPE while getting ringtone.");
- }
+ ringtone = RingtoneManager.getRingtone(userContext, ringtoneUri, volumeShaperConfig);
}
if(ringtone == null) {
// Contact didn't specify ringtone or custom Ringtone creation failed. Get default
@@ -96,12 +91,8 @@
if (defaultRingtoneUri == null) {
return null;
}
- try {
- ringtone = RingtoneManager.getRingtone(
- contextToUse, defaultRingtoneUri, volumeShaperConfig);
- } catch (NullPointerException npe) {
- Log.e(this, npe, "getRingtone: NPE while getting ringtone.");
- }
+ ringtone = RingtoneManager.getRingtone(
+ contextToUse, defaultRingtoneUri, volumeShaperConfig);
}
if (ringtone != null) {
ringtone.setAudioAttributes(new AudioAttributes.Builder()
diff --git a/src/com/android/server/telecom/RoleManagerAdapterImpl.java b/src/com/android/server/telecom/RoleManagerAdapterImpl.java
index 4a98d7b..eb216d0 100644
--- a/src/com/android/server/telecom/RoleManagerAdapterImpl.java
+++ b/src/com/android/server/telecom/RoleManagerAdapterImpl.java
@@ -85,11 +85,8 @@
@Override
public void observeDefaultDialerApp(Executor executor, IntConsumer observer) {
- mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) -> {
- if (ROLE_DIALER.equals(roleName)) {
- observer.accept(user.getIdentifier());
- }
- }, UserHandle.ALL);
+ mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) ->
+ observer.accept(user.getIdentifier()), UserHandle.ALL);
}
@Override
diff --git a/src/com/android/server/telecom/ServiceBinder.java b/src/com/android/server/telecom/ServiceBinder.java
index aa2e2a2..2fcd2f5 100644
--- a/src/com/android/server/telecom/ServiceBinder.java
+++ b/src/com/android/server/telecom/ServiceBinder.java
@@ -87,8 +87,7 @@
ServiceConnection connection = new ServiceBinderConnection(call);
Log.addEvent(call, LogUtils.Events.BIND_CS, mComponentName);
- final int bindingFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
- | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS;
+ final int bindingFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
final boolean isBound;
if (mUserHandle != null) {
isBound = mContext.bindServiceAsUser(serviceIntent, connection, bindingFlags,
diff --git a/src/com/android/server/telecom/SystemSettingsUtil.java b/src/com/android/server/telecom/SystemSettingsUtil.java
index 7baae05..f104f27 100644
--- a/src/com/android/server/telecom/SystemSettingsUtil.java
+++ b/src/com/android/server/telecom/SystemSettingsUtil.java
@@ -40,19 +40,18 @@
}
public boolean canVibrateWhenRinging(Context context) {
- return Settings.System.getIntForUser(context.getContentResolver(),
- Settings.System.VIBRATE_WHEN_RINGING, 0, context.getUserId()) != 0;
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
}
public boolean isEnhancedCallBlockingEnabled(Context context) {
- return Settings.System.getIntForUser(context.getContentResolver(),
- Settings.System.DEBUG_ENABLE_ENHANCED_CALL_BLOCKING, 0, context.getUserId()) != 0;
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.DEBUG_ENABLE_ENHANCED_CALL_BLOCKING, 0) != 0;
}
public boolean setEnhancedCallBlockingEnabled(Context context, boolean enabled) {
- return Settings.System.putIntForUser(context.getContentResolver(),
- Settings.System.DEBUG_ENABLE_ENHANCED_CALL_BLOCKING, enabled ? 1 : 0,
- context.getUserId());
+ return Settings.System.putInt(context.getContentResolver(),
+ Settings.System.DEBUG_ENABLE_ENHANCED_CALL_BLOCKING, enabled ? 1 : 0);
}
public boolean applyRampingRinger(Context context) {
diff --git a/src/com/android/server/telecom/SystemStateHelper.java b/src/com/android/server/telecom/SystemStateHelper.java
index dd978c2..073b081 100644
--- a/src/com/android/server/telecom/SystemStateHelper.java
+++ b/src/com/android/server/telecom/SystemStateHelper.java
@@ -16,7 +16,6 @@
package com.android.server.telecom;
-import android.annotation.NonNull;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -27,7 +26,6 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-import android.net.Uri;
import android.telecom.Log;
import java.util.Set;
@@ -39,8 +37,8 @@
/**
* Provides various system states to the rest of the telecom codebase.
*/
-public class SystemStateHelper implements UiModeManager.OnProjectionStateChangedListener {
- public interface SystemStateListener {
+public class SystemStateHelper {
+ public static interface SystemStateListener {
/**
* Listener method to inform interested parties when a package name requests to enter or
* exit car mode.
@@ -50,66 +48,33 @@
* otherwise.
*/
void onCarModeChanged(int priority, String packageName, boolean isCarMode);
-
- /**
- * Listener method to inform interested parties when a package has set automotive projection
- * state.
- * @param automotiveProjectionPackage the package that set automotive projection.
- */
- void onAutomotiveProjectionStateSet(String automotiveProjectionPackage);
-
- /**
- * Listener method to inform interested parties when automotive projection state has been
- * cleared.
- */
- void onAutomotiveProjectionStateReleased();
-
- /**
- * Notifies when a package has been uninstalled.
- * @param packageName the package name of the uninstalled package
- */
- void onPackageUninstalled(String packageName);
}
private final Context mContext;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.startSession("SSH.oR");
+ Log.startSession("SSP.oR");
try {
- synchronized (mLock) {
- String action = intent.getAction();
- if (UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED.equals(action)) {
- int priority = intent.getIntExtra(UiModeManager.EXTRA_PRIORITY,
- UiModeManager.DEFAULT_PRIORITY);
- String callingPackage = intent.getStringExtra(
- UiModeManager.EXTRA_CALLING_PACKAGE);
- 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)) {
- int priority = intent.getIntExtra(UiModeManager.EXTRA_PRIORITY,
- UiModeManager.DEFAULT_PRIORITY);
- String callingPackage = intent.getStringExtra(
- UiModeManager.EXTRA_CALLING_PACKAGE);
- 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(SystemStateHelper.this,
- "Unexpected intent received: %s", intent.getAction());
- }
+ String action = intent.getAction();
+ if (UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED.equals(action)) {
+ int priority = intent.getIntExtra(UiModeManager.EXTRA_PRIORITY,
+ UiModeManager.DEFAULT_PRIORITY);
+ String callingPackage = intent.getStringExtra(
+ UiModeManager.EXTRA_CALLING_PACKAGE);
+ Log.i(SystemStateHelper.this, "ENTER_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
+ priority, callingPackage);
+ onEnterCarMode(priority, callingPackage);
+ } else if (UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED.equals(action)) {
+ int priority = intent.getIntExtra(UiModeManager.EXTRA_PRIORITY,
+ UiModeManager.DEFAULT_PRIORITY);
+ String callingPackage = intent.getStringExtra(
+ UiModeManager.EXTRA_CALLING_PACKAGE);
+ Log.i(SystemStateHelper.this, "EXIT_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
+ priority, callingPackage);
+ onExitCarMode(priority, callingPackage);
+ } else {
+ Log.w(this, "Unexpected intent received: %s", intent.getAction());
}
} finally {
Log.endSession();
@@ -117,46 +82,19 @@
}
};
- @Override
- public void onProjectionStateChanged(int activeProjectionTypes,
- @NonNull Set<String> projectingPackages) {
- Log.startSession("SSH.oPSC");
- try {
- synchronized (mLock) {
- if (projectingPackages.isEmpty()) {
- onReleaseAutomotiveProjection();
- } else {
- onSetAutomotiveProjection(projectingPackages.iterator().next());
- }
- }
- } finally {
- Log.endSession();
- }
-
- }
-
private Set<SystemStateListener> mListeners = new CopyOnWriteArraySet<>();
- private boolean mIsCarModeOrProjectionActive;
- private final TelecomSystem.SyncRoot mLock;
+ private boolean mIsCarMode;
- public SystemStateHelper(Context context, TelecomSystem.SyncRoot lock) {
+ public SystemStateHelper(Context context) {
mContext = context;
- mLock = lock;
- IntentFilter intentFilter1 = new IntentFilter(
+ IntentFilter intentFilter = new IntentFilter(
UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
- intentFilter1.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+ intentFilter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+ Log.i(this, "Registering car mode receiver: %s", intentFilter);
- 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);
-
- mContext.getSystemService(UiModeManager.class).addOnProjectionStateChangedListener(
- UiModeManager.PROJECTION_TYPE_AUTOMOTIVE, mContext.getMainExecutor(), this);
- mIsCarModeOrProjectionActive = getSystemCarModeOrProjectionState();
+ mIsCarMode = getSystemCarMode();
}
public void addListener(SystemStateListener listener) {
@@ -169,8 +107,8 @@
return mListeners.remove(listener);
}
- public boolean isCarModeOrProjectionActive() {
- return mIsCarModeOrProjectionActive;
+ public boolean isCarMode() {
+ return mIsCarMode;
}
public boolean isDeviceAtEar() {
@@ -255,7 +193,7 @@
private void onEnterCarMode(int priority, String packageName) {
Log.i(this, "Entering carmode");
- mIsCarModeOrProjectionActive = getSystemCarModeOrProjectionState();
+ mIsCarMode = getSystemCarMode();
for (SystemStateListener listener : mListeners) {
listener.onCarModeChanged(priority, packageName, true /* isCarMode */);
}
@@ -263,44 +201,25 @@
private void onExitCarMode(int priority, String packageName) {
Log.i(this, "Exiting carmode");
- mIsCarModeOrProjectionActive = getSystemCarModeOrProjectionState();
+ mIsCarMode = getSystemCarMode();
for (SystemStateListener listener : mListeners) {
listener.onCarModeChanged(priority, packageName, false /* isCarMode */);
}
}
- private void onSetAutomotiveProjection(String packageName) {
- Log.i(this, "Automotive projection set.");
- mIsCarModeOrProjectionActive = getSystemCarModeOrProjectionState();
- for (SystemStateListener listener : mListeners) {
- listener.onAutomotiveProjectionStateSet(packageName);
- }
-
- }
-
- private void onReleaseAutomotiveProjection() {
- Log.i(this, "Automotive projection released.");
- mIsCarModeOrProjectionActive = getSystemCarModeOrProjectionState();
- for (SystemStateListener listener : mListeners) {
- listener.onAutomotiveProjectionStateReleased();
- }
- }
-
/**
- * Checks the system for the current car projection state.
+ * Checks the system for the current car mode.
*
- * @return True if projection is active, false otherwise.
+ * @return True if in car mode, false otherwise.
*/
- private boolean getSystemCarModeOrProjectionState() {
- UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
+ private boolean getSystemCarMode() {
+ UiModeManager uiModeManager =
+ (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
if (uiModeManager != null) {
- return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
- || (uiModeManager.getActiveProjectionTypes()
- & UiModeManager.PROJECTION_TYPE_AUTOMOTIVE) != 0;
+ return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;
}
- Log.w(this, "Got null UiModeManager, returning false.");
return false;
}
}
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 86d5ebc..9ccae9a 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -30,14 +30,10 @@
import android.Manifest;
import android.app.ActivityManager;
import android.app.AppOpsManager;
-import android.app.UiModeManager;
-import android.app.compat.CompatChanges;
-import android.content.AttributionSource;
import android.content.ComponentName;
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;
@@ -61,6 +57,7 @@
import android.util.EventLog;
import com.android.internal.telecom.ITelecomService;
+import com.android.internal.telephony.TelephonyPermissions;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.settings.BlockedNumbersActivity;
@@ -317,21 +314,9 @@
}
@Override
- public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle,
- String callingPackage) {
+ public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
synchronized (mLock) {
final UserHandle callingUserHandle = Binder.getCallingUserHandle();
- if (CompatChanges.isChangeEnabled(
- TelecomManager.ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION,
- callingPackage, Binder.getCallingUserHandle())) {
- if (Binder.getCallingUid() != Process.SHELL_UID &&
- !canGetPhoneAccount(callingPackage, accountHandle)) {
- SecurityException e = new SecurityException("getPhoneAccount API requires" +
- "READ_PHONE_NUMBERS");
- Log.e(this, e, "getPhoneAccount %s", accountHandle);
- throw e;
- }
- }
long token = Binder.clearCallingIdentity();
try {
Log.startSession("TSI.gPA");
@@ -341,7 +326,7 @@
// profile's phone account handle.
return mPhoneAccountRegistrar
.getPhoneAccount(accountHandle, callingUserHandle,
- /* acrossProfiles */ true);
+ /* acrossProfiles */ true);
} catch (Exception e) {
Log.e(this, e, "getPhoneAccount %s", accountHandle);
throw e;
@@ -471,11 +456,11 @@
try {
Log.startSession("TSI.gSCMFU");
final int callingUid = Binder.getCallingUid();
- if (user != ActivityManager.getCurrentUser()) {
- enforceCrossUserPermission(callingUid);
- }
long token = Binder.clearCallingIdentity();
try {
+ if (user != ActivityManager.getCurrentUser()) {
+ enforceCrossUserPermission(callingUid);
+ }
return mPhoneAccountRegistrar.getSimCallManager(UserHandle.of(user));
} finally {
Binder.restoreCallingIdentity(token);
@@ -742,7 +727,7 @@
public ComponentName getDefaultPhoneApp() {
try {
Log.startSession("TSI.gDPA");
- return mDefaultDialerCache.getDialtactsSystemDialerComponent();
+ return mDefaultDialerCache.getSystemDialerComponent();
} finally {
Log.endSession();
}
@@ -846,27 +831,6 @@
}
/**
- * @see android.telecom.TelecomManager#hasManageOngoingCallsPermission
- */
- @Override
- public boolean hasManageOngoingCallsPermission(String callingPackage) {
- try {
- Log.startSession("TSI.hMOCP");
- enforceCallingPackage(callingPackage);
- return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(
- mContext, Manifest.permission.MANAGE_ONGOING_CALLS,
- Binder.getCallingPid(),
- new AttributionSource(mContext.getAttributionSource(),
- new AttributionSource(Binder.getCallingUid(),
- callingPackage, /*attributionTag*/ null)),
- "Checking whether the caller has MANAGE_ONGOING_CALLS permission")
- == PermissionChecker.PERMISSION_GRANTED;
- } finally {
- Log.endSession();
- }
- }
-
- /**
* @see android.telecom.TelecomManager#isInManagedCall
*/
@Override
@@ -917,48 +881,12 @@
}
/**
- * @see TelecomManager#getCallState()
- * @deprecated this is only being kept due to an @UnsupportedAppUsage tag. Apps targeting
- * API 31+ must use {@link #getCallStateUsingPackage(String, String)} below.
+ * @see TelecomManager#getCallState
*/
- @Deprecated
@Override
public int getCallState() {
try {
- Log.startSession("TSI.getCallState(DEPRECATED)");
- if (CompatChanges.isChangeEnabled(
- TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
- Binder.getCallingUid())) {
- // Do not allow this API to be called on API version 31+, it should only be
- // called on old apps using this Binder call directly.
- throw new SecurityException("This method can only be used for applications "
- + "targeting API version 30 or less.");
- }
- synchronized (mLock) {
- return mCallsManager.getCallState();
- }
- } finally {
- Log.endSession();
- }
- }
-
- /**
- * @see TelecomManager#getCallState()
- */
- @Override
- public int getCallStateUsingPackage(String callingPackage, String callingFeatureId) {
- try {
- Log.startSession("TSI.getCallStateUsingPackage");
- if (CompatChanges.isChangeEnabled(
- TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION, callingPackage,
- Binder.getCallingUserHandle())) {
- // Bypass canReadPhoneState check if this is being called from SHELL UID
- if (Binder.getCallingUid() != Process.SHELL_UID && !canReadPhoneState(
- callingPackage, callingFeatureId, "getCallState")) {
- throw new SecurityException("getCallState API requires READ_PHONE_STATE"
- + " for API version 31+");
- }
- }
+ Log.startSession("TSI.getCallState");
synchronized (mLock) {
return mCallsManager.getCallState();
}
@@ -1003,7 +931,7 @@
long token = Binder.clearCallingIdentity();
try {
- acceptRingingCallInternal(DEFAULT_VIDEO_STATE, packageName);
+ acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1026,7 +954,7 @@
long token = Binder.clearCallingIdentity();
try {
- acceptRingingCallInternal(videoState, packageName);
+ acceptRingingCallInternal(videoState);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1826,58 +1754,6 @@
}
}
- /**
- * 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.
- * Also cleans up any pending futures related to
- * {@link android.telecom.CallDiagnosticService}s.
- */
- @Override
- public void cleanupStuckCalls() {
- Log.startSession("TCI.cSC");
- try {
- synchronized (mLock) {
- enforceShellOnly(Binder.getCallingUid(), "cleanupStuckCalls");
- Binder.withCleanCallingIdentity(() -> {
- for (Call call : mCallsManager.getCalls()) {
- call.cleanup();
- if (call.getState() == CallState.DISCONNECTED
- || call.getState() == CallState.DISCONNECTING) {
- mCallsManager.markCallAsRemoved(call);
- }
- }
- mCallsManager.getInCallController().unbindFromServices();
- });
- }
- } finally {
- Log.endSession();
- }
- }
-
- /**
- * A method intended for use in testing to reset car mode at all priorities.
- *
- * Runs during setup to avoid cascading failures from failing car mode CTS.
- */
- @Override
- public void resetCarMode() {
- Log.startSession("TCI.rCM");
- try {
- synchronized (mLock) {
- enforceShellOnly(Binder.getCallingUid(), "resetCarMode");
- Binder.withCleanCallingIdentity(() -> {
- UiModeManager uiModeManager =
- mContext.getSystemService(UiModeManager.class);
- uiModeManager.disableCarMode(UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES);
- });
- }
- } finally {
- Log.endSession();
- }
- }
-
@Override
public void setTestDefaultCallRedirectionApp(String packageName) {
try {
@@ -1980,30 +1856,6 @@
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();
- }
- }
};
/**
@@ -2133,16 +1985,9 @@
return false;
}
- private void acceptRingingCallInternal(int videoState, String packageName) {
- Call call = mCallsManager.getFirstCallWithState(CallState.RINGING,
- CallState.SIMULATED_RINGING);
+ private void acceptRingingCallInternal(int videoState) {
+ Call call = mCallsManager.getFirstCallWithState(CallState.RINGING, CallState.SIMULATED_RINGING);
if (call != null) {
- if (call.isSelfManaged()) {
- Log.addEvent(call, LogUtils.Events.REQUEST_ACCEPT,
- "self-mgd accept ignored from " + packageName);
- return;
- }
-
if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
videoState = call.getVideoState();
}
@@ -2170,12 +2015,6 @@
return false;
}
- if (call.isSelfManaged()) {
- Log.addEvent(call, LogUtils.Events.REQUEST_DISCONNECT,
- "self-mgd disconnect ignored from " + callingPackage);
- return false;
- }
-
if (call.getState() == CallState.RINGING
|| call.getState() == CallState.SIMULATED_RINGING) {
mCallsManager.rejectCall(call, false /* rejectWithMessage */, null);
@@ -2435,28 +2274,6 @@
== AppOpsManager.MODE_ALLOWED;
}
- private boolean canGetPhoneAccount(String callingPackage, PhoneAccountHandle accountHandle) {
- // Allow default dialer, system dialer and sim call manager to be able to do this without
- // extra permission
- try {
- if (isPrivilegedDialerCalling(callingPackage) || isCallerSimCallManager(
- accountHandle)) {
- return true;
- }
- } catch (SecurityException e) {
- // ignore
- }
-
- try {
- mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, null);
- return true;
- } catch (SecurityException e) {
- // Accessing phone state is gated by a special permission.
- mContext.enforceCallingOrSelfPermission(READ_PHONE_NUMBERS, null);
- return true;
- }
- }
-
private boolean isCallerSimCallManager(PhoneAccountHandle targetPhoneAccount) {
long token = Binder.clearCallingIdentity();
PhoneAccountHandle accountHandle = null;
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index c824a65..807cc2d 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -20,12 +20,14 @@
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;
@@ -36,10 +38,8 @@
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,11 +47,8 @@
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.
@@ -119,6 +116,7 @@
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;
@@ -195,6 +193,8 @@
ProximitySensorManagerFactory proximitySensorManagerFactory,
InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
AudioServiceFactory audioServiceFactory,
+ BluetoothPhoneServiceImplFactory
+ bluetoothPhoneServiceImplFactory,
ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
connectionServiceFocusManagerFactory,
Timeouts.Adapter timeoutsAdapter,
@@ -206,8 +206,8 @@
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
ClockProxy clockProxy,
RoleManagerAdapter roleManagerAdapter,
- ContactsAsyncHelper.Factory contactsAsyncHelperFactory,
- DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
+ IncomingCallFilter.Factory incomingCallFilterFactory,
+ ContactsAsyncHelper.Factory contactsAsyncHelperFactory) {
mContext = context.getApplicationContext();
LogUtils.initLogging(mContext);
DefaultDialerManagerAdapter defaultDialerAdapter =
@@ -217,208 +217,167 @@
defaultDialerAdapter, roleManagerAdapter, mLock);
Log.startSession("TS.init");
- // Wrap this in a try block to ensure session cleanup occurs in the case of error.
- try {
- mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache,
- packageName -> AppLabelProxy.Util.getAppLabel(
- mContext.getPackageManager(), packageName));
+ mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache,
+ packageName -> AppLabelProxy.Util.getAppLabel(
+ mContext.getPackageManager(), packageName));
- mContactsAsyncHelper = contactsAsyncHelperFactory.create(
- new ContactsAsyncHelper.ContentResolverAdapter() {
- @Override
- public InputStream openInputStream(Context context, Uri uri)
- throws FileNotFoundException {
- return context.getContentResolver().openInputStream(uri);
- }
- });
- BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
- new BluetoothAdapterProxy());
- BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
- bluetoothDeviceManager, new Timeouts.Adapter());
- BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
- bluetoothDeviceManager, bluetoothRouteManager);
- mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER);
+ mContactsAsyncHelper = contactsAsyncHelperFactory.create(
+ new ContactsAsyncHelper.ContentResolverAdapter() {
+ @Override
+ public InputStream openInputStream(Context context, Uri uri)
+ throws FileNotFoundException {
+ return context.getContentResolver().openInputStream(uri);
+ }
+ });
+ BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
+ new BluetoothAdapterProxy());
+ BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
+ bluetoothDeviceManager, new Timeouts.Adapter());
+ BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
+ bluetoothDeviceManager, bluetoothRouteManager);
+ mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER);
- WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
- SystemStateHelper systemStateHelper = new SystemStateHelper(mContext, mLock);
+ WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
+ SystemStateHelper systemStateHelper = new SystemStateHelper(mContext);
- mMissedCallNotifier = missedCallNotifierImplFactory
- .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar,
- defaultDialerCache,
- deviceIdleControllerAdapter);
- DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory =
- new DisconnectedCallNotifier.Default();
+ mMissedCallNotifier = missedCallNotifierImplFactory
+ .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, defaultDialerCache);
+ DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory =
+ new DisconnectedCallNotifier.Default();
- CallerInfoLookupHelper callerInfoLookupHelper =
- new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory,
- mContactsAsyncHelper, mLock);
+ CallerInfoLookupHelper callerInfoLookupHelper =
+ new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory,
+ mContactsAsyncHelper, mLock);
- EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
- defaultDialerCache, timeoutsAdapter);
+ EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
+ defaultDialerCache, timeoutsAdapter);
- InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
- @Override
- public InCallController create(Context context, SyncRoot lock,
- CallsManager callsManager, SystemStateHelper systemStateProvider,
- DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
- EmergencyCallHelper emergencyCallHelper) {
- return new InCallController(context, lock, callsManager, systemStateProvider,
- defaultDialerCache, timeoutsAdapter, emergencyCallHelper,
- new CarModeTracker(), clockProxy);
- }
- };
+ InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
+ @Override
+ public InCallController create(Context context, SyncRoot lock,
+ CallsManager callsManager, SystemStateHelper systemStateProvider,
+ DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
+ EmergencyCallHelper emergencyCallHelper) {
+ return new InCallController(context, lock, callsManager, systemStateProvider,
+ defaultDialerCache, timeoutsAdapter, emergencyCallHelper,
+ new CarModeTracker(), clockProxy);
+ }
+ };
- 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);
- }
+ AudioProcessingNotification audioProcessingNotification =
+ new AudioProcessingNotification(mContext);
- @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);
-
- ToastFactory toastFactory = new ToastFactory() {
- @Override
- public Toast makeText(Context context, int resId, int duration) {
- return Toast.makeText(context, context.getMainLooper(),
- context.getString(resId),
- duration);
- }
-
- @Override
- public Toast makeText(Context context, CharSequence text, int duration) {
- return Toast.makeText(context, context.getMainLooper(), text, duration);
- }
- };
-
- mCallsManager = new CallsManager(
- mContext,
- mLock,
- callerInfoLookupHelper,
- mMissedCallNotifier,
- disconnectedCallNotifierFactory,
- mPhoneAccountRegistrar,
- headsetMediaButtonFactory,
- proximitySensorManagerFactory,
- inCallWakeLockControllerFactory,
- connectionServiceFocusManagerFactory,
- audioServiceFactory,
- bluetoothRouteManager,
- wiredHeadsetManager,
- systemStateHelper,
- defaultDialerCache,
- timeoutsAdapter,
- asyncRingtonePlayer,
- phoneNumberUtilsAdapter,
- emergencyCallHelper,
- toneGeneratorFactory,
- clockProxy,
- audioProcessingNotification,
- bluetoothStateReceiver,
- callAudioRouteStateMachineFactory,
- callAudioModeStateMachineFactory,
- inCallControllerFactory,
- callDiagnosticServiceController,
- roleManagerAdapter,
- toastFactory);
-
- mIncomingCallNotifier = incomingCallNotifier;
- incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
- @Override
- public boolean hasUnholdableCallsForOtherConnectionService(
- PhoneAccountHandle phoneAccountHandle) {
- return mCallsManager.hasUnholdableCallsForOtherConnectionService(
- phoneAccountHandle);
- }
-
- @Override
- public int getNumUnholdableCallsForOtherConnectionService(
- PhoneAccountHandle phoneAccountHandle) {
- return mCallsManager.getNumUnholdableCallsForOtherConnectionService(
- phoneAccountHandle);
- }
-
- @Override
- public Call getActiveCall() {
- return mCallsManager.getActiveCall();
- }
- });
- mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);
-
- mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
- mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
-
- mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL,
- USER_SWITCHED_FILTER, null, null);
- mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL,
- USER_STARTING_FILTER, null, null);
- mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL,
- BOOT_COMPLETE_FILTER, null, null);
-
- // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at
- // startup
- synchronized (mLock) {
- UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
- mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
- mCallsManager.onUserSwitch(currentUserHandle);
+ ToastFactory toastFactory = new ToastFactory() {
+ @Override
+ public Toast makeText(Context context, int resId, int duration) {
+ return Toast.makeText(context, context.getMainLooper(), context.getString(resId),
+ duration);
}
- mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager,
- defaultDialerCache);
- mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
- mContext, mCallsManager);
+ @Override
+ public Toast makeText(Context context, CharSequence text, int duration) {
+ return Toast.makeText(context, context.getMainLooper(), text, duration);
+ }
+ };
- // Register the receiver for the dialer secret codes, used to enable extended logging.
- mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
- mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
- Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
+ mCallsManager = new CallsManager(
+ mContext,
+ mLock,
+ callerInfoLookupHelper,
+ mMissedCallNotifier,
+ disconnectedCallNotifierFactory,
+ mPhoneAccountRegistrar,
+ headsetMediaButtonFactory,
+ proximitySensorManagerFactory,
+ inCallWakeLockControllerFactory,
+ connectionServiceFocusManagerFactory,
+ audioServiceFactory,
+ bluetoothRouteManager,
+ wiredHeadsetManager,
+ systemStateHelper,
+ defaultDialerCache,
+ timeoutsAdapter,
+ asyncRingtonePlayer,
+ phoneNumberUtilsAdapter,
+ emergencyCallHelper,
+ toneGeneratorFactory,
+ clockProxy,
+ audioProcessingNotification,
+ bluetoothStateReceiver,
+ callAudioRouteStateMachineFactory,
+ callAudioModeStateMachineFactory,
+ inCallControllerFactory,
+ roleManagerAdapter,
+ incomingCallFilterFactory,
+ toastFactory);
- // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
- final UserManager userManager = UserManager.get(mContext);
- mTelecomServiceImpl = new TelecomServiceImpl(
- mContext, mCallsManager, mPhoneAccountRegistrar,
- new CallIntentProcessor.AdapterImpl(defaultDialerCache),
- new UserCallIntentProcessorFactory() {
- @Override
- public UserCallIntentProcessor create(Context context,
- UserHandle userHandle) {
- return new UserCallIntentProcessor(context, userHandle);
- }
- },
- defaultDialerCache,
- new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
- new TelecomServiceImpl.SettingsSecureAdapterImpl(),
- mLock);
- } finally {
- Log.endSession();
+ mIncomingCallNotifier = incomingCallNotifier;
+ incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
+ @Override
+ public boolean hasUnholdableCallsForOtherConnectionService(
+ PhoneAccountHandle phoneAccountHandle) {
+ return mCallsManager.hasUnholdableCallsForOtherConnectionService(
+ phoneAccountHandle);
+ }
+
+ @Override
+ public int getNumUnholdableCallsForOtherConnectionService(
+ PhoneAccountHandle phoneAccountHandle) {
+ return mCallsManager.getNumUnholdableCallsForOtherConnectionService(
+ phoneAccountHandle);
+ }
+
+ @Override
+ public Call getActiveCall() {
+ return mCallsManager.getActiveCall();
+ }
+ });
+ mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);
+
+ mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
+ mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
+
+ mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL,
+ USER_SWITCHED_FILTER, null, null);
+ mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL,
+ USER_STARTING_FILTER, null, null);
+ mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL,
+ BOOT_COMPLETE_FILTER, null, null);
+
+ // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at startup
+ synchronized(mLock) {
+ UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
+ mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
+ mCallsManager.onUserSwitch(currentUserHandle);
}
+
+ mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
+ mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
+ mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
+ mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
+ mContext, mCallsManager);
+
+ // Register the receiver for the dialer secret codes, used to enable extended logging.
+ mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
+ mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
+ Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
+
+ // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
+ final UserManager userManager = UserManager.get(mContext);
+ mTelecomServiceImpl = new TelecomServiceImpl(
+ mContext, mCallsManager, mPhoneAccountRegistrar,
+ new CallIntentProcessor.AdapterImpl(defaultDialerCache),
+ new UserCallIntentProcessorFactory() {
+ @Override
+ public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
+ return new UserCallIntentProcessor(context, userHandle);
+ }
+ },
+ defaultDialerCache,
+ new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
+ new TelecomServiceImpl.SettingsSecureAdapterImpl(),
+ mLock);
+ Log.endSession();
}
@VisibleForTesting
@@ -431,6 +390,10 @@
return mCallsManager;
}
+ public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
+ return mBluetoothPhoneServiceImpl;
+ }
+
public CallIntentProcessor getCallIntentProcessor() {
return mCallIntentProcessor;
}
diff --git a/src/com/android/server/telecom/Timeouts.java b/src/com/android/server/telecom/Timeouts.java
index 36caa25..a701b88 100644
--- a/src/com/android/server/telecom/Timeouts.java
+++ b/src/com/android/server/telecom/Timeouts.java
@@ -17,13 +17,8 @@
package com.android.server.telecom;
import android.content.ContentResolver;
-import android.provider.DeviceConfig;
import android.provider.Settings;
-import android.telecom.CallDiagnosticService;
import android.telecom.CallRedirectionService;
-import android.telecom.CallDiagnostics;
-import android.telephony.ims.ImsReasonInfo;
-
import java.util.concurrent.TimeUnit;
/**
@@ -72,14 +67,6 @@
public long getCallRecordingToneRepeatIntervalMillis(ContentResolver cr) {
return Timeouts.getCallRecordingToneRepeatIntervalMillis(cr);
}
-
- public long getCallDiagnosticServiceTimeoutMillis(ContentResolver cr) {
- return Timeouts.getCallDiagnosticServiceTimeoutMillis(cr);
- }
-
- public long getCallStartAppOpDebounceIntervalMillis() {
- return Timeouts.getCallStartAppOpDebounceIntervalMillis();
- }
}
/** A prefix to use for all keys so to not clobber the global namespace. */
@@ -98,8 +85,7 @@
* @return The timeout value from Settings or the default value if it hasn't been changed.
*/
private static long get(ContentResolver contentResolver, String key, long defaultValue) {
- return Settings.Secure.getLongForUser(contentResolver, PREFIX + key, defaultValue,
- contentResolver.getUserId());
+ return Settings.Secure.getLong(contentResolver, PREFIX + key, defaultValue);
}
/**
@@ -203,7 +189,7 @@
/**
* Returns the amount of time for an user-defined {@link CallRedirectionService}.
*
- * @param contentResolver The content resolver.
+ * @param contentResolver The content resolved.
*/
public static long getUserDefinedCallRedirectionTimeoutMillis(ContentResolver contentResolver) {
return get(contentResolver, "user_defined_call_redirection_timeout",
@@ -213,7 +199,7 @@
/**
* Returns the amount of time for a carrier {@link CallRedirectionService}.
*
- * @param contentResolver The content resolver.
+ * @param contentResolver The content resolved.
*/
public static long getCarrierCallRedirectionTimeoutMillis(ContentResolver contentResolver) {
return get(contentResolver, "carrier_call_redirection_timeout", 5000L /* 5 seconds */);
@@ -225,30 +211,4 @@
public static long getCallRecordingToneRepeatIntervalMillis(ContentResolver contentResolver) {
return get(contentResolver, "call_recording_tone_repeat_interval", 15000L /* 15 seconds */);
}
-
- /**
- * Returns the maximum amount of time a {@link CallDiagnosticService} is permitted to take to
- * return back from {@link CallDiagnostics#onCallDisconnected(ImsReasonInfo)} and
- * {@link CallDiagnostics#onCallDisconnected(int, int)}.
- * @param contentResolver The resolver for the config option.
- * @return The timeout in millis.
- */
- public static long getCallDiagnosticServiceTimeoutMillis(ContentResolver contentResolver) {
- return get(contentResolver, "call_diagnostic_service_timeout", 2000L /* 2 sec */);
- }
-
- public static long getCallStartAppOpDebounceIntervalMillis() {
- return DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY, "app_op_debounce_time", 250L);
- }
-
- /**
- * Returns the number of milliseconds for which the system should exempt the default dialer from
- * power save restrictions due to the dialer needing to handle a missed call notification
- * (update call log, check VVM, etc...).
- */
- public static long getDialerMissedCallPowerSaveExemptionTimeMillis(
- ContentResolver contentResolver) {
- return get(contentResolver, "dialer_missed_call_power_save_exemption_time_millis",
- 30000L /*30 seconds*/);
- }
}
diff --git a/src/com/android/server/telecom/TtyManager.java b/src/com/android/server/telecom/TtyManager.java
index 457ba36..2d04234 100644
--- a/src/com/android/server/telecom/TtyManager.java
+++ b/src/com/android/server/telecom/TtyManager.java
@@ -42,17 +42,14 @@
mWiredHeadsetManager = wiredHeadsetManager;
mWiredHeadsetManager.addListener(this);
- mPreferredTtyMode = Settings.Secure.getIntForUser(
+ mPreferredTtyMode = Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.PREFERRED_TTY_MODE,
- TelecomManager.TTY_MODE_OFF,
- mContext.getUserId());
+ TelecomManager.TTY_MODE_OFF);
IntentFilter intentFilter = new IntentFilter(
TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
- mContext.registerReceiver(mReceiver, intentFilter,
- android.Manifest.permission.MODIFY_PHONE_STATE,
- null);
+ mContext.registerReceiver(mReceiver, intentFilter);
updateCurrentTtyMode();
}
diff --git a/src/com/android/server/telecom/VideoProviderProxy.java b/src/com/android/server/telecom/VideoProviderProxy.java
index df11403..364e0f4 100644
--- a/src/com/android/server/telecom/VideoProviderProxy.java
+++ b/src/com/android/server/telecom/VideoProviderProxy.java
@@ -55,7 +55,6 @@
*/
public interface Listener {
void onSessionModifyRequestReceived(Call call, VideoProfile videoProfile);
- void onSetCamera(Call call, String cameraId);
}
/**
@@ -347,12 +346,6 @@
return;
}
}
-
- // Inform other Telecom components of the change in camera status.
- for (Listener listener : mListeners) {
- listener.onSetCamera(mCall, cameraId);
- }
-
try {
mConectionServiceVideoProvider.setCamera(cameraId, callingPackage,
targetSdkVersion);
diff --git a/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java b/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
index 1043774..052ce57 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, boolean timeout);
+ void onCallFilteringComplete(Call call, CallFilteringResult result);
}
diff --git a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
index 84ce4d4..d95d578 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
@@ -18,7 +18,6 @@
import android.provider.CallLog;
import android.provider.CallLog.Calls;
-import android.telecom.CallScreeningService;
import android.text.TextUtils;
import java.util.Objects;
@@ -35,8 +34,6 @@
private int mCallBlockReason = Calls.BLOCK_REASON_NOT_BLOCKED;
private CharSequence mCallScreeningAppName = null;
private String mCallScreeningComponentName = null;
- private CallScreeningService.ParcelableCallResponse mCallScreeningResponse = null;
- private boolean mIsResponseFromSystemDialer = false;
public Builder setShouldAllowCall(boolean shouldAllowCall) {
mShouldAllowCall = shouldAllowCall;
@@ -83,13 +80,6 @@
return this;
}
- public Builder setCallScreeningResponse(
- CallScreeningService.ParcelableCallResponse response, boolean isFromSystemDialer) {
- mCallScreeningResponse = response;
- mIsResponseFromSystemDialer = isFromSystemDialer;
- return this;
- }
-
public Builder setContactExists(boolean contactExists) {
mContactExists = contactExists;
return this;
@@ -106,16 +96,14 @@
.setShouldScreenViaAudio(result.shouldScreenViaAudio)
.setCallScreeningAppName(result.mCallScreeningAppName)
.setCallScreeningComponentName(result.mCallScreeningComponentName)
- .setCallScreeningResponse(result.mCallScreeningResponse,
- result.mIsResponseFromSystemDialer)
.setContactExists(result.contactExists);
}
public CallFilteringResult build() {
return new CallFilteringResult(mShouldAllowCall, mShouldReject, mShouldSilence,
mShouldAddToCallLog, mShouldShowNotification, mCallBlockReason,
- mCallScreeningAppName, mCallScreeningComponentName, mCallScreeningResponse,
- mIsResponseFromSystemDialer, mShouldScreenViaAudio, mContactExists);
+ mCallScreeningAppName, mCallScreeningComponentName, mShouldScreenViaAudio,
+ mContactExists);
}
}
@@ -128,15 +116,11 @@
public int mCallBlockReason;
public CharSequence mCallScreeningAppName;
public String mCallScreeningComponentName;
- public CallScreeningService.ParcelableCallResponse mCallScreeningResponse;
- public boolean mIsResponseFromSystemDialer;
public boolean contactExists;
private CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification, int
callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName,
- CallScreeningService.ParcelableCallResponse callScreeningResponse,
- boolean isResponseFromSystemDialer,
boolean shouldScreenViaAudio, boolean contactExists) {
this.shouldAllowCall = shouldAllowCall;
this.shouldReject = shouldReject;
@@ -147,8 +131,6 @@
this.mCallBlockReason = callBlockReason;
this.mCallScreeningAppName = callScreeningAppName;
this.mCallScreeningComponentName = callScreeningComponentName;
- this.mCallScreeningResponse = callScreeningResponse;
- this.mIsResponseFromSystemDialer = isResponseFromSystemDialer;
this.contactExists = contactExists;
}
@@ -166,25 +148,25 @@
if (isBlockedByProvider(mCallBlockReason)) {
return getCombinedCallFilteringResult(other, mCallBlockReason,
- null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+ null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
} else if (isBlockedByProvider(other.mCallBlockReason)) {
return getCombinedCallFilteringResult(other, other.mCallBlockReason,
- null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+ null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
}
if (mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL
- || other.mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL) {
+ || other.mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL) {
return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
- null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+ null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
}
if (shouldReject && mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE) {
return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
- mCallScreeningAppName, mCallScreeningComponentName);
+ mCallScreeningAppName, mCallScreeningComponentName);
} else if (other.shouldReject && other.mCallBlockReason == CallLog.Calls
- .BLOCK_REASON_CALL_SCREENING_SERVICE) {
+ .BLOCK_REASON_CALL_SCREENING_SERVICE) {
return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
- other.mCallScreeningAppName, other.mCallScreeningComponentName);
+ other.mCallScreeningAppName, other.mCallScreeningComponentName);
}
if (shouldScreenViaAudio) {
@@ -195,16 +177,15 @@
other.mCallScreeningAppName, other.mCallScreeningComponentName);
}
- Builder b = new Builder()
+ return new Builder()
.setShouldAllowCall(shouldAllowCall && other.shouldAllowCall)
.setShouldReject(shouldReject || other.shouldReject)
.setShouldSilence(shouldSilence || other.shouldSilence)
.setShouldAddToCallLog(shouldAddToCallLog && other.shouldAddToCallLog)
.setShouldShowNotification(shouldShowNotification && other.shouldShowNotification)
.setShouldScreenViaAudio(shouldScreenViaAudio || other.shouldScreenViaAudio)
- .setContactExists(contactExists || other.contactExists);
- combineScreeningResponses(b, this, other);
- return b.build();
+ .setContactExists(contactExists || other.contactExists)
+ .build();
}
private boolean isBlockedByProvider(int blockReason) {
@@ -220,9 +201,8 @@
}
private CallFilteringResult getCombinedCallFilteringResult(CallFilteringResult other,
- int callBlockReason, CharSequence callScreeningAppName,
- String callScreeningComponentName) {
- Builder b = new Builder()
+ int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) {
+ return new Builder()
.setShouldAllowCall(shouldAllowCall && other.shouldAllowCall)
.setShouldReject(shouldReject || other.shouldReject)
.setShouldSilence(shouldSilence || other.shouldSilence)
@@ -232,33 +212,10 @@
.setCallBlockReason(callBlockReason)
.setCallScreeningAppName(callScreeningAppName)
.setCallScreeningComponentName(callScreeningComponentName)
- .setContactExists(contactExists || other.contactExists);
- combineScreeningResponses(b, this, other);
- return b.build();
+ .setContactExists(contactExists || other.contactExists)
+ .build();
}
- private static void combineScreeningResponses(Builder builder, CallFilteringResult r1,
- CallFilteringResult r2) {
- if (r1.mIsResponseFromSystemDialer) {
- builder.setCallScreeningResponse(r1.mCallScreeningResponse, true);
- builder.setCallScreeningComponentName(r1.mCallScreeningComponentName);
- builder.setCallScreeningAppName(r1.mCallScreeningAppName);
- } else if (r2.mIsResponseFromSystemDialer) {
- builder.setCallScreeningResponse(r2.mCallScreeningResponse, true);
- builder.setCallScreeningComponentName(r2.mCallScreeningComponentName);
- builder.setCallScreeningAppName(r2.mCallScreeningAppName);
- } else {
- if (r1.mCallScreeningResponse != null) {
- builder.setCallScreeningResponse(r1.mCallScreeningResponse, false);
- builder.setCallScreeningComponentName(r1.mCallScreeningComponentName);
- builder.setCallScreeningAppName(r1.mCallScreeningAppName);
- } else {
- builder.setCallScreeningResponse(r2.mCallScreeningResponse, false);
- builder.setCallScreeningComponentName(r2.mCallScreeningComponentName);
- builder.setCallScreeningAppName(r2.mCallScreeningAppName);
- }
- }
- }
@Override
public boolean equals(Object o) {
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
index 4a308e0..1e52c5a 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
@@ -25,7 +25,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.CallLog;
-import android.telecom.CallScreeningService;
import android.telecom.Log;
import android.telecom.TelecomManager;
@@ -65,44 +64,15 @@
}
@Override
- public void onScreeningResponse(String callId, ComponentName componentName,
- CallScreeningService.ParcelableCallResponse callResponse) {
- if (callResponse == null) {
- Log.w(this, "Null responses are only supposed to happen for outgoing calls");
- return;
- }
- if (callResponse.shouldDisallowCall()) {
- disallowCall(callId, componentName, callResponse);
- } else if (callResponse.shouldSilenceCall()) {
- silenceCall(callId, componentName, callResponse);
- } else if (callResponse.shouldScreenCallViaAudioProcessing()) {
- screenCallFurther(callId, componentName, callResponse);
- } else {
- allowCall(callId, componentName, callResponse);
- }
- }
-
- public void allowCall(String callId, ComponentName componentName,
- CallScreeningService.ParcelableCallResponse response) {
- long token = Binder.clearCallingIdentity();
+ public void allowCall(String callId) {
+ Long token = Binder.clearCallingIdentity();
Log.startSession("NCSSF.aC");
try {
if (mCall == null || (!mCall.getId().equals(callId))) {
Log.w(this, "allowCall, unknown call id: %s", callId);
}
- CallFilteringResult result = new CallFilteringResult.Builder()
- .setShouldAllowCall(true)
- .setShouldReject(false)
- .setShouldSilence(false)
- .setShouldAddToCallLog(mPriorStageResult.shouldAddToCallLog)
- .setShouldShowNotification(mPriorStageResult.shouldShowNotification)
- .setCallScreeningAppName(mAppName)
- .setCallScreeningComponentName(componentName.flattenToString())
- .setCallScreeningResponse(response, isSystemDialer())
- .setContactExists(mPriorStageResult.contactExists)
- .build();
- Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, result);
- mResultFuture.complete(result);
+ Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, mPriorStageResult);
+ mResultFuture.complete(mPriorStageResult);
} finally {
unbindCallScreeningService();
Binder.restoreCallingIdentity(token);
@@ -110,23 +80,24 @@
}
}
- public void disallowCall(String callId, ComponentName componentName,
- CallScreeningService.ParcelableCallResponse response) {
+ @Override
+ public void disallowCall(String callId, boolean shouldReject,
+ boolean shouldAddToCallLog, boolean shouldShowNotification,
+ ComponentName componentName) {
long token = Binder.clearCallingIdentity();
Log.startSession("NCSSF.dC");
try {
if (mCall != null && mCall.getId().equals(callId)) {
CallFilteringResult result = new CallFilteringResult.Builder()
.setShouldAllowCall(false)
- .setShouldReject(response.shouldRejectCall())
+ .setShouldReject(shouldReject)
.setShouldSilence(false)
- .setShouldAddToCallLog(!response.shouldSkipCallLog()
+ .setShouldAddToCallLog(shouldAddToCallLog
|| packageTypeShouldAdd(mPackagetype))
- .setShouldShowNotification(!response.shouldSkipNotification())
+ .setShouldShowNotification(shouldShowNotification)
.setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
.setCallScreeningAppName(mAppName)
.setCallScreeningComponentName(componentName.flattenToString())
- .setCallScreeningResponse(response, isSystemDialer())
.setContactExists(mPriorStageResult.contactExists)
.build();
Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, result);
@@ -142,8 +113,8 @@
}
}
- public void silenceCall(String callId, ComponentName componentName,
- CallScreeningService.ParcelableCallResponse response) {
+ @Override
+ public void silenceCall(String callId) {
long token = Binder.clearCallingIdentity();
Log.startSession("NCSSF.sC");
try {
@@ -154,9 +125,6 @@
.setShouldSilence(true)
.setShouldAddToCallLog(true)
.setShouldShowNotification(true)
- .setCallScreeningResponse(response, isSystemDialer())
- .setCallScreeningAppName(mAppName)
- .setCallScreeningComponentName(componentName.flattenToString())
.setContactExists(mPriorStageResult.contactExists)
.build();
Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, result);
@@ -172,8 +140,8 @@
}
}
- public void screenCallFurther(String callId, ComponentName componentName,
- CallScreeningService.ParcelableCallResponse response) {
+ @Override
+ public void screenCallFurther(String callId) {
if (mPackagetype != PACKAGE_TYPE_DEFAULT_DIALER) {
throw new SecurityException("Only the default/system dialer may request screen via"
+ "background call audio");
@@ -190,8 +158,6 @@
.setShouldSilence(false)
.setShouldScreenViaAudio(true)
.setCallScreeningAppName(mAppName)
- .setCallScreeningComponentName(componentName.flattenToString())
- .setCallScreeningResponse(response, isSystemDialer())
.setContactExists(mPriorStageResult.contactExists)
.build();
Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, result);
@@ -323,12 +289,7 @@
public void unbindCallScreeningService() {
if (mConnection != null) {
- try {
- mContext.unbindService(mConnection);
- } catch (IllegalArgumentException e) {
- Log.i(this, "Exception when unbind service %s : %s", mConnection,
- e.getMessage());
- }
+ mContext.unbindService(mConnection);
}
mConnection = null;
}
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
new file mode 100644
index 0000000..860de1f
--- /dev/null
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
@@ -0,0 +1,126 @@
+/*
+ * 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 9fa864e..1543270 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
@@ -49,7 +49,7 @@
private final HandlerThread mHandlerThread;
private final TelecomSystem.SyncRoot mLock;
private List<CallFilter> mFiltersList;
- private CallFilter mCompletionSentinel;
+ private CallFilter mDummyComplete;
private boolean mFinished;
private CallFilteringResult mCurrentResult;
private Context mContext;
@@ -70,10 +70,10 @@
scheduleFilter(filter);
}
}
- if (mFilter.equals(mCompletionSentinel)) {
+ if (mFilter.equals(mDummyComplete)) {
synchronized (mLock) {
mFinished = true;
- mListener.onCallFilteringComplete(mCall, result, false);
+ mListener.onCallFilteringComplete(mCall, result);
Log.addEvent(mCall, LogUtils.Events.FILTERING_COMPLETED, result);
}
mHandlerThread.quit();
@@ -105,15 +105,15 @@
public void performFiltering() {
Log.addEvent(mCall, LogUtils.Events.FILTERING_INITIATED);
CallFilter dummyStart = new CallFilter();
- mCompletionSentinel = new CallFilter();
+ mDummyComplete = new CallFilter();
for (CallFilter filter : mFiltersList) {
addEdge(dummyStart, filter);
}
for (CallFilter filter : mFiltersList) {
- addEdge(filter, mCompletionSentinel);
+ addEdge(filter, mDummyComplete);
}
- addEdge(dummyStart, mCompletionSentinel);
+ addEdge(dummyStart, mDummyComplete);
scheduleFilter(dummyStart);
mHandler.postDelayed(new Runnable("ICFG.pF", mLock) {
@@ -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, true);
+ mListener.onCallFilteringComplete(mCall, mCurrentResult);
mFinished = true;
mHandlerThread.quit();
}
@@ -159,11 +159,7 @@
startFuture.thenComposeAsync(filter::startFilterLookup,
new LoggedHandlerExecutor(mHandler, "ICFG.sF", null))
.thenApplyAsync(postFilterTask::whenDone,
- new LoggedHandlerExecutor(mHandler, "ICFG.sF", null))
- .exceptionally((t) -> {
- Log.e(filter, t, "Encountered exception running filter");
- return null;
- });
+ new LoggedHandlerExecutor(mHandler, "ICFG.sF", null));
Log.i(TAG, "Filter %s scheduled.", filter);
}
diff --git a/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java b/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
index a1f357b..e93ef22 100644
--- a/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
+++ b/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
@@ -294,7 +294,7 @@
* The current rule to decide whether the implemented {@link CallRedirectionService} should
* allow interactive responses with users is only based on whether it is in car mode.
*/
- mAllowInteractiveResponse = !callsManager.getSystemStateHelper().isCarModeOrProjectionActive();
+ mAllowInteractiveResponse = !callsManager.getSystemStateHelper().isCarMode();
mCallRedirectionProcessorHelper = new CallRedirectionProcessorHelper(
context, callsManager, phoneAccountRegistrar);
mProcessedDestinationUri = mCallRedirectionProcessorHelper.formatNumberForRedirection(
diff --git a/src/com/android/server/telecom/components/BluetoothPhoneService.java b/src/com/android/server/telecom/components/BluetoothPhoneService.java
new file mode 100644
index 0000000..c5e195c
--- /dev/null
+++ b/src/com/android/server/telecom/components/BluetoothPhoneService.java
@@ -0,0 +1,42 @@
+/*
+ * 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 9ad0da4..e20da80 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -18,6 +18,7 @@
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;
@@ -29,11 +30,9 @@
import android.telecom.Log;
import android.telecom.CallerInfoAsyncQuery;
-
-import com.android.internal.telecom.IInternalServiceRetriever;
-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;
@@ -42,21 +41,21 @@
import com.android.server.telecom.ConnectionServiceFocusManager;
import com.android.server.telecom.ContactsAsyncHelper;
import com.android.server.telecom.DefaultDialerCache;
-import com.android.server.telecom.DeviceIdleControllerAdapter;
import com.android.server.telecom.HeadsetMediaButton;
import com.android.server.telecom.HeadsetMediaButtonFactory;
import com.android.server.telecom.InCallWakeLockControllerFactory;
import com.android.server.telecom.CallAudioManager;
-import com.android.server.telecom.InternalServiceRetrieverAdapter;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneNumberUtilsAdapterImpl;
import com.android.server.telecom.ProximitySensorManagerFactory;
import com.android.server.telecom.InCallWakeLockController;
import com.android.server.telecom.ProximitySensorManager;
+import com.android.server.telecom.R;
import com.android.server.telecom.RoleManagerAdapterImpl;
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;
@@ -69,17 +68,10 @@
@Override
public IBinder onBind(Intent intent) {
Log.d(this, "onBind");
- return new ITelecomLoader.Stub() {
- @Override
- public ITelecomService createTelecomService(IInternalServiceRetriever retriever) {
- InternalServiceRetrieverAdapter adapter =
- new InternalServiceRetrieverAdapter(retriever);
- initializeTelecomSystem(TelecomService.this, adapter);
- synchronized (getTelecomSystem().getLock()) {
- return getTelecomSystem().getTelecomServiceImpl().getBinder();
- }
- }
- };
+ initializeTelecomSystem(this);
+ synchronized (getTelecomSystem().getLock()) {
+ return getTelecomSystem().getTelecomServiceImpl().getBinder();
+ }
}
/**
@@ -92,8 +84,7 @@
*
* @param context
*/
- static void initializeTelecomSystem(Context context,
- InternalServiceRetrieverAdapter internalServiceRetriever) {
+ static void initializeTelecomSystem(Context context) {
if (TelecomSystem.getInstance() == null) {
NotificationChannelManager notificationChannelManager =
new NotificationChannelManager();
@@ -107,11 +98,9 @@
public MissedCallNotifierImpl makeMissedCallNotifierImpl(
Context context,
PhoneAccountRegistrar phoneAccountRegistrar,
- DefaultDialerCache defaultDialerCache,
- DeviceIdleControllerAdapter idleControllerAdapter) {
+ DefaultDialerCache defaultDialerCache) {
return new MissedCallNotifierImpl(context,
- phoneAccountRegistrar, defaultDialerCache,
- idleControllerAdapter);
+ phoneAccountRegistrar, defaultDialerCache);
}
},
new CallerInfoAsyncQueryFactory() {
@@ -169,6 +158,17 @@
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(),
@@ -190,8 +190,11 @@
},
new RoleManagerAdapterImpl(context,
(RoleManager) context.getSystemService(Context.ROLE_SERVICE)),
- new ContactsAsyncHelper.Factory(),
- internalServiceRetriever.getDeviceIdleController()));
+ new IncomingCallFilter.Factory(),
+ new ContactsAsyncHelper.Factory()));
+ }
+ if (BluetoothAdapter.getDefaultAdapter() != null) {
+ context.startService(new Intent(context, BluetoothPhoneService.class));
}
}
diff --git a/src/com/android/server/telecom/settings/BlockedNumbersActivity.java b/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
index 1fe7c5f..3549db5 100644
--- a/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
+++ b/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
@@ -38,7 +38,6 @@
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;
@@ -286,7 +285,7 @@
* Add blocked number if it does not exist.
*/
private void addBlockedNumber(String number) {
- if (isEmergencyNumber(this, number)) {
+ if (PhoneNumberUtils.isEmergencyNumber(number)) {
Toast.makeText(
this,
getString(R.string.blocked_numbers_block_emergency_number_message),
@@ -299,16 +298,6 @@
}
}
- 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/settings/BlockedNumbersUtil.java b/src/com/android/server/telecom/settings/BlockedNumbersUtil.java
index 4be75f8..67634e4 100644
--- a/src/com/android/server/telecom/settings/BlockedNumbersUtil.java
+++ b/src/com/android/server/telecom/settings/BlockedNumbersUtil.java
@@ -95,8 +95,7 @@
if (showNotification) {
Intent intent = new Intent(context, CallBlockDisabledActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
- context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT
- | PendingIntent.FLAG_IMMUTABLE);
+ context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
String title = context.getString(
R.string.phone_strings_call_blocking_turned_off_notification_title_txt);
diff --git a/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java b/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java
index 66f9fe4..3f54689 100644
--- a/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java
+++ b/src/com/android/server/telecom/ui/DisconnectedCallNotifier.java
@@ -333,8 +333,7 @@
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 | PendingIntent.FLAG_IMMUTABLE);
+ return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private boolean canRespondViaSms(@NonNull CallInfo call) {
@@ -355,7 +354,7 @@
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(mContext);
taskStackBuilder.addNextIntent(intent);
- return taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_IMMUTABLE, null, userHandle);
+ return taskStackBuilder.getPendingIntent(0, 0, null, userHandle);
}
/**
diff --git a/src/com/android/server/telecom/ui/IncomingCallNotifier.java b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
index 0c1c5a3..6e203aa 100644
--- a/src/com/android/server/telecom/ui/IncomingCallNotifier.java
+++ b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
@@ -41,7 +41,6 @@
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;
@@ -69,7 +68,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
@@ -105,10 +104,8 @@
@Override
public void onCallAdded(Call call) {
- synchronized (mLock) {
- if (!mCalls.contains(call)) {
- mCalls.add(call);
- }
+ if (!mCalls.contains(call)) {
+ mCalls.add(call);
}
updateIncomingCall();
@@ -116,11 +113,10 @@
@Override
public void onCallRemoved(Call call) {
- synchronized (mLock) {
- if (mCalls.contains(call)) {
- mCalls.remove(call);
- }
+ if (mCalls.contains(call)) {
+ mCalls.remove(call);
}
+
updateIncomingCall();
}
@@ -134,16 +130,11 @@
* UI.
*/
private void updateIncomingCall() {
- 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();
- }
-
+ Optional<Call> incomingCallOp = mCalls.stream()
+ .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(
@@ -282,12 +273,12 @@
R.anim.on_going_call,
getActionText(R.string.answer_incoming_call, R.color.notification_action_answer),
PendingIntent.getBroadcast(mContext, 0, answerIntent,
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE));
+ PendingIntent.FLAG_CANCEL_CURRENT));
builder.addAction(
R.drawable.ic_close_dk,
getActionText(R.string.decline_incoming_call, R.color.notification_action_decline),
PendingIntent.getBroadcast(mContext, 0, rejectIntent,
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE));
+ PendingIntent.FLAG_CANCEL_CURRENT));
return builder;
}
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index 12d3820..a0eca8f 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -19,10 +19,8 @@
import static android.Manifest.permission.READ_PHONE_STATE;
import android.annotation.NonNull;
-import android.app.BroadcastOptions;
import android.content.ContentProvider;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
import android.telecom.Logging.Runnable;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -31,13 +29,11 @@
import com.android.server.telecom.CallsManagerListenerBase;
import com.android.server.telecom.Constants;
import com.android.server.telecom.DefaultDialerCache;
-import com.android.server.telecom.DeviceIdleControllerAdapter;
import com.android.server.telecom.MissedCallNotifier;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.R;
import com.android.server.telecom.TelecomBroadcastIntentProcessor;
import com.android.server.telecom.TelecomSystem;
-import com.android.server.telecom.Timeouts;
import com.android.server.telecom.components.TelecomBroadcastReceiver;
import android.app.Notification;
@@ -67,15 +63,18 @@
import android.text.TextUtils;
import android.telecom.CallerInfo;
-import android.util.ArrayMap;
import java.lang.Override;
import java.lang.String;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+// TODO: Needed for move to system service: import com.android.internal.R;
/**
* Creates a notification for calls that the user missed (neither answered nor rejected).
@@ -87,8 +86,7 @@
public interface MissedCallNotifierImplFactory {
MissedCallNotifier makeMissedCallNotifierImpl(Context context,
PhoneAccountRegistrar phoneAccountRegistrar,
- DefaultDialerCache defaultDialerCache,
- DeviceIdleControllerAdapter deviceIdleControllerAdapter);
+ DefaultDialerCache defaultDialerCache);
}
public interface NotificationBuilderFactory {
@@ -126,44 +124,37 @@
private static final int MISSED_CALL_NOTIFICATION_ID = 1;
private static final String NOTIFICATION_TAG = MissedCallNotifierImpl.class.getSimpleName();
- private static final String MISSED_CALL_POWER_SAVE_REASON = "missed-call";
private final Context mContext;
private final PhoneAccountRegistrar mPhoneAccountRegistrar;
private final NotificationManager mNotificationManager;
private final NotificationBuilderFactory mNotificationBuilderFactory;
private final DefaultDialerCache mDefaultDialerCache;
- private final DeviceIdleControllerAdapter mDeviceIdleControllerAdapter;
private UserHandle mCurrentUserHandle;
- // Used to guard access to mMissedCallCounts
- private final Object mMissedCallCountsLock = new Object();
// Used to track the number of missed calls.
- private final Map<UserHandle, Integer> mMissedCallCounts;
+ private ConcurrentMap<UserHandle, AtomicInteger> mMissedCallCounts;
private List<UserHandle> mUsersToLoadAfterBootComplete = new ArrayList<>();
public MissedCallNotifierImpl(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
- DefaultDialerCache defaultDialerCache,
- DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
+ DefaultDialerCache defaultDialerCache) {
this(context, phoneAccountRegistrar, defaultDialerCache,
- new DefaultNotificationBuilderFactory(), deviceIdleControllerAdapter);
+ new DefaultNotificationBuilderFactory());
}
public MissedCallNotifierImpl(Context context,
PhoneAccountRegistrar phoneAccountRegistrar,
DefaultDialerCache defaultDialerCache,
- NotificationBuilderFactory notificationBuilderFactory,
- DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
+ NotificationBuilderFactory notificationBuilderFactory) {
mContext = context;
mPhoneAccountRegistrar = phoneAccountRegistrar;
mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- mDeviceIdleControllerAdapter = deviceIdleControllerAdapter;
mDefaultDialerCache = defaultDialerCache;
mNotificationBuilderFactory = notificationBuilderFactory;
- mMissedCallCounts = new ArrayMap<>();
+ mMissedCallCounts = new ConcurrentHashMap<>();
}
/** Clears missed call notification and marks the call log's missed calls as read. */
@@ -171,8 +162,7 @@
public void clearMissedCalls(UserHandle userHandle) {
// If the default dialer is showing the missed call notification then it will modify the
// call log and we don't have to do anything here.
- String dialerPackage = getDefaultDialerPackage(userHandle);
- if (!shouldManageNotificationThroughDefaultDialer(dialerPackage, userHandle)) {
+ if (!shouldManageNotificationThroughDefaultDialer(userHandle)) {
markMissedCallsAsRead(userHandle);
}
cancelMissedCallNotification(userHandle);
@@ -204,15 +194,6 @@
}.prepare());
}
- private String getDefaultDialerPackage(UserHandle userHandle) {
- String dialerPackage = mDefaultDialerCache.getDefaultDialerApplication(
- userHandle.getIdentifier());
- if (TextUtils.isEmpty(dialerPackage)) {
- return null;
- }
- return dialerPackage;
- }
-
/**
* Returns the missed-call notification intent to send to the default dialer for the given user.
* Note, the passed in userHandle is always the non-managed user for SIM calls (multi-user
@@ -223,16 +204,18 @@
* handle of the phone account. This could be a managed user. In that case we return the default
* dialer for the given user which could be a managed (work profile) dialer.
*/
- private Intent getShowMissedCallIntentForDefaultDialer(String dialerPackage) {
+ private Intent getShowMissedCallIntentForDefaultDialer(UserHandle userHandle) {
+ String dialerPackage = mDefaultDialerCache.getDefaultDialerApplication(
+ userHandle.getIdentifier());
+ if (TextUtils.isEmpty(dialerPackage)) {
+ return null;
+ }
return new Intent(TelecomManager.ACTION_SHOW_MISSED_CALLS_NOTIFICATION)
.setPackage(dialerPackage);
}
- private boolean shouldManageNotificationThroughDefaultDialer(String dialerPackage,
- UserHandle userHandle) {
- if (TextUtils.isEmpty(dialerPackage)) return false;
-
- Intent intent = getShowMissedCallIntentForDefaultDialer(dialerPackage);
+ private boolean shouldManageNotificationThroughDefaultDialer(UserHandle userHandle) {
+ Intent intent = getShowMissedCallIntentForDefaultDialer(userHandle);
if (intent == null) {
return false;
}
@@ -242,36 +225,17 @@
return receivers.size() > 0;
}
- /**
- * For dialers that manage missed call handling themselves, we must temporarily add them to the
- * power save exemption list, as they must perform operations such as modifying the call log and
- * power save restrictions can cause these types of operations to not complete (sometimes
- * causing ANRs).
- */
- private Bundle exemptFromPowerSavingTemporarily(String dialerPackage, UserHandle handle) {
- if (TextUtils.isEmpty(dialerPackage)) {
- return null;
- }
- BroadcastOptions bopts = BroadcastOptions.makeBasic();
- long duration = Timeouts.getDialerMissedCallPowerSaveExemptionTimeMillis(
- mContext.getContentResolver());
- mDeviceIdleControllerAdapter.exemptAppTemporarilyForEvent(dialerPackage, duration,
- handle.getIdentifier(), MISSED_CALL_POWER_SAVE_REASON);
- bopts.setTemporaryAppWhitelistDuration(duration);
- return bopts.toBundle();
- }
-
- private void sendNotificationThroughDefaultDialer(String dialerPackage, CallInfo callInfo,
- UserHandle userHandle, int missedCallCount) {
- Intent intent = getShowMissedCallIntentForDefaultDialer(dialerPackage)
+ private void sendNotificationThroughDefaultDialer(CallInfo callInfo, UserHandle userHandle) {
+ int count = mMissedCallCounts.get(userHandle).get();
+ Intent intent = getShowMissedCallIntentForDefaultDialer(userHandle)
.setFlags(Intent.FLAG_RECEIVER_FOREGROUND)
.putExtra(TelecomManager.EXTRA_CLEAR_MISSED_CALLS_INTENT,
createClearMissedCallsPendingIntent(userHandle))
- .putExtra(TelecomManager.EXTRA_NOTIFICATION_COUNT, missedCallCount)
+ .putExtra(TelecomManager.EXTRA_NOTIFICATION_COUNT, count)
.putExtra(TelecomManager.EXTRA_NOTIFICATION_PHONE_NUMBER,
callInfo == null ? null : callInfo.getPhoneNumber());
- if (missedCallCount == 1 && callInfo != null) {
+ if (count == 1 && callInfo != null) {
final Uri handleUri = callInfo.getHandle();
String handle = handleUri == null ? null : handleUri.getSchemeSpecificPart();
@@ -282,16 +246,15 @@
}
}
- Log.i(this, "sendNotificationThroughDefaultDialer; count=%d, dialerPackage=%s",
- missedCallCount, intent.getPackage());
- Bundle options = exemptFromPowerSavingTemporarily(dialerPackage, userHandle);
- mContext.sendBroadcastAsUser(intent, userHandle, READ_PHONE_STATE, options);
+
+ Log.w(this, "Showing missed calls through default dialer.");
+ mContext.sendBroadcastAsUser(intent, userHandle, READ_PHONE_STATE);
}
/**
* Create a system notification for the missed call.
*
- * @param callInfo The missed call.
+ * @param call The missed call.
*/
@Override
public void showMissedCallNotification(@NonNull CallInfo callInfo) {
@@ -309,21 +272,12 @@
}
private void showMissedCallNotification(@NonNull CallInfo callInfo, UserHandle userHandle) {
- int missedCallCounts;
- synchronized (mMissedCallCountsLock) {
- Integer currentCount = mMissedCallCounts.get(userHandle);
- missedCallCounts = currentCount == null ? 0 : currentCount;
- missedCallCounts++;
- mMissedCallCounts.put(userHandle, missedCallCounts);
- }
+ Log.i(this, "showMissedCallNotification: userHandle=%d", userHandle.getIdentifier());
+ mMissedCallCounts.putIfAbsent(userHandle, new AtomicInteger(0));
+ int missCallCounts = mMissedCallCounts.get(userHandle).incrementAndGet();
- Log.i(this, "showMissedCallNotification: userHandle=%d, missedCallCount=%d",
- userHandle.getIdentifier(), missedCallCounts);
-
- String dialerPackage = getDefaultDialerPackage(userHandle);
- if (shouldManageNotificationThroughDefaultDialer(dialerPackage, userHandle)) {
- sendNotificationThroughDefaultDialer(dialerPackage, callInfo, userHandle,
- missedCallCounts);
+ if (shouldManageNotificationThroughDefaultDialer(userHandle)) {
+ sendNotificationThroughDefaultDialer(callInfo, userHandle);
return;
}
@@ -333,7 +287,7 @@
// Display the first line of the notification:
// 1 missed call: <caller name || handle>
// More than 1 missed call: <number of calls> + "missed calls"
- if (missedCallCounts == 1) {
+ if (missCallCounts == 1) {
expandedText = getNameForMissedCallNotification(callInfo);
CallerInfo ci = callInfo.getCallerInfo();
@@ -345,7 +299,7 @@
} else {
titleResId = R.string.notification_missedCallsTitle;
expandedText =
- mContext.getString(R.string.notification_missedCallsMsg, missedCallCounts);
+ mContext.getString(R.string.notification_missedCallsMsg, missCallCounts);
}
// Create a public viewable version of the notification, suitable for display when sensitive
@@ -387,7 +341,7 @@
String handle = callInfo.getHandleSchemeSpecificPart();
// Add additional actions when there is only 1 missed call, like call-back and SMS.
- if (missedCallCounts == 1) {
+ if (missCallCounts == 1) {
Log.d(this, "Add actions with number %s.", Log.piiHandle(handle));
if (!TextUtils.isEmpty(handle)
@@ -416,7 +370,7 @@
}
} else {
Log.d(this, "Suppress actions. handle: %s, missedCalls: %d.", Log.piiHandle(handle),
- missedCallCounts);
+ missCallCounts);
}
Notification notification = builder.build();
@@ -436,14 +390,11 @@
/** Cancels the "missed call" notification. */
private void cancelMissedCallNotification(UserHandle userHandle) {
// Reset the number of missed calls to 0.
- synchronized(mMissedCallCountsLock) {
- mMissedCallCounts.put(userHandle, 0);
- }
+ mMissedCallCounts.putIfAbsent(userHandle, new AtomicInteger(0));
+ mMissedCallCounts.get(userHandle).set(0);
- String dialerPackage = getDefaultDialerPackage(userHandle);
- if (shouldManageNotificationThroughDefaultDialer(dialerPackage, userHandle)) {
- sendNotificationThroughDefaultDialer(dialerPackage, null, userHandle,
- 0 /* missedCallCount */);
+ if (shouldManageNotificationThroughDefaultDialer(userHandle)) {
+ sendNotificationThroughDefaultDialer(null, userHandle);
return;
}
@@ -567,8 +518,7 @@
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 | PendingIntent.FLAG_IMMUTABLE);
+ return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
@@ -620,9 +570,7 @@
Log.d(MissedCallNotifierImpl.this, "onQueryComplete()...");
if (cursor != null) {
try {
- synchronized(mMissedCallCountsLock) {
- mMissedCallCounts.remove(userHandle);
- }
+ mMissedCallCounts.remove(userHandle);
while (cursor.moveToNext()) {
// Get data about the missed call from the cursor
final String handleString = cursor.getString(CALL_LOG_COLUMN_NUMBER);
diff --git a/testapps/Android.bp b/testapps/Android.bp
index 11ea474..26347fe 100644
--- a/testapps/Android.bp
+++ b/testapps/Android.bp
@@ -14,10 +14,6 @@
// 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 dd8258a..4238191 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -15,48 +15,40 @@
-->
<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.TestCallDiagnosticService"
- android:permission="android.permission.BIND_CALL_DIAGNOSTIC_SERVICE"
- android:exported="true">
- <intent-filter>
- <action android:name="android.telecom.CallDiagnosticService"/>
- </intent-filter>
- </service>
<service android:name="com.android.server.telecom.testapps.TestConnectionService"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
- android:exported="true">
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
<intent-filter>
- <action android:name="android.telecom.ConnectionService"/>
+ <action android:name="android.telecom.ConnectionService" />
</intent-filter>
</service>
- <receiver android:name=".TestConnectionServiceReceiver"
- android:exported="true">
+ <receiver android:name=".TestConnectionServiceReceiver">
<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"/>
@@ -64,29 +56,23 @@
</receiver>
<service android:name="com.android.server.telecom.testapps.TestConnectionManager"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
- android:exported="true">
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
<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"
- 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" />
+ 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"/>
<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:exported="true">
+ android:process="com.android.server.telecom.testapps.TestInCallService" >
<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"/>
@@ -98,212 +84,201 @@
<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:exported="true">
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/inCallUiAppLabel"
+ android:launchMode="singleInstance">
<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:exported="true">
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/rttUiLabel"
+ android:launchMode="singleInstance">
<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:exported="true">
+ android:theme="@android:style/Theme.NoDisplay"
+ android:label="@string/testCallActivityLabel">
<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:exported="true">
+ android:label="@string/testDialerActivityLabel"
+ android:process="com.android.server.telecom.testapps.TestInCallService">
<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:exported="true">
+ android:label="@string/UssdUiAppLabel"
+ android:launchMode="singleInstance">
<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:exported="true">
+ android:label="@string/KeyUiAppLabel"
+ android:launchMode="singleInstance">
<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:exported="true">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:theme="@android:style/Theme.Material.Light">
<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:exported="true">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
<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:exported="true">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
<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:exported="true">
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
<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"
- android:exported="true">
+ <service
+ android:name=".TestCallScreeningService"
+ android:permission="android.permission.BIND_SCREENING_SERVICE">
<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"
- android:exported="true">
+ <service
+ android:name=".TestCallRedirectionService"
+ android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
<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:exported="true">
+ android:label="@string/postCallActivityLabel">
<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/callaudiotest/Android.bp b/testapps/callaudiotest/Android.bp
deleted file mode 100644
index 81164e6..0000000
--- a/testapps/callaudiotest/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test {
- name: "TelecomCallAudioTestApp",
- static_libs: [
- "androidx.legacy_legacy-support-v4",
- "guava",
- ],
- srcs: ["src/**/*.java"],
- platform_apis: true,
- certificate: "platform",
- privileged: true,
-}
diff --git a/testapps/callaudiotest/AndroidManifest.xml b/testapps/callaudiotest/AndroidManifest.xml
deleted file mode 100644
index 014ab29..0000000
--- a/testapps/callaudiotest/AndroidManifest.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- coreApp="true"
- package="com.android.server.telecom.callaudiotest">
-
- <uses-sdk android:minSdkVersion="28"
- android:targetSdkVersion="29"/>
- <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.READ_CALL_LOG"/>
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
- <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING"/>
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
- <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
-
- <application android:label="Telecom Call Audio Test">
- <uses-library android:name="android.test.runner"/>
-
- <service android:name="com.android.server.telecom.callaudiotest.CallAudioTestInCallService"
- android:permission="android.permission.BIND_INCALL_SERVICE"
- android:exported="true">
- <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
- android:value="false"/>
- <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
- android:value="false"/>
- <intent-filter>
- <action android:name="android.telecom.InCallService"/>
- </intent-filter>
- </service>
-
- <activity android:name="com.android.server.telecom.callaudiotest.CallAudioTestActivity"
- android:label="Call Audio Test"
- 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"/>
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/testapps/callaudiotest/res/layout/call_audio_test_activity.xml b/testapps/callaudiotest/res/layout/call_audio_test_activity.xml
deleted file mode 100644
index 0d847f0..0000000
--- a/testapps/callaudiotest/res/layout/call_audio_test_activity.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/appLabel"
- android:layout_gravity="left"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="25dp"
- android:text="Call Audio Testing" />
- <TextView
- android:id="@+id/appDescription"
- android:layout_gravity="left"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="12dp"
- android:text="You can enabled auto answer and calls will be answered and some awesome audio will be looped to the caller." />
- <CheckBox
- android:id="@+id/enableAutoAnswer"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Answer calls and loop audio" />
-</LinearLayout>
diff --git a/testapps/callaudiotest/res/raw/speech.m4a b/testapps/callaudiotest/res/raw/speech.m4a
deleted file mode 100644
index 4161ad6..0000000
--- a/testapps/callaudiotest/res/raw/speech.m4a
+++ /dev/null
Binary files differ
diff --git a/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java b/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java
deleted file mode 100644
index b75a498..0000000
--- a/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom.callaudiotest;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.EditText;
-
-/**
- * Activity to configure the auto answer behavior.
- */
-public class CallAudioTestActivity extends Activity {
- private static final int RESULT_PICK_FILE = 1;
- public static final String AUDIO_TEST_PREFS = "audio_test_prefs";
- public static final String AUTO_ANSWER_ENABLED = "auto_answer_enabled";
- private CheckBox mEnable;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.call_audio_test_activity);
- mEnable = findViewById(R.id.enableAutoAnswer);
- mEnable.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- SharedPreferences prefs = getSharedPreferences(AUDIO_TEST_PREFS, MODE_PRIVATE);
- SharedPreferences.Editor edit = prefs.edit();
- edit.putBoolean(AUTO_ANSWER_ENABLED, isChecked);
- edit.apply();
- }
- });
- loadPreferences();
- }
-
- private void loadPreferences() {
- SharedPreferences prefs = getSharedPreferences(AUDIO_TEST_PREFS, MODE_PRIVATE);
- mEnable.setChecked(prefs.getBoolean(AUTO_ANSWER_ENABLED, false));
- }
-}
diff --git a/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java b/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java
deleted file mode 100644
index bd98a7f..0000000
--- a/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.telecom.callaudiotest;
-
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.media.AudioAttributes;
-import android.media.AudioDeviceInfo;
-import android.media.AudioManager;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.IBinder;
-import android.telecom.Call;
-import android.telecom.InCallService;
-import android.telecom.Log;
-import android.telecom.VideoProfile;
-
-import java.io.IOException;
-import java.lang.String;
-
-/**
- * Simple test InCallService which answers a call automatically and plays back some looping audio.
- * Intended for testing call audio between devices.
- */
-public class CallAudioTestInCallService extends InCallService {
- private Call mIncomingCall;
- private boolean mIsAutoAnswerEnabled = false;
- private MediaPlayer mMediaPlayer;
- private Call.Callback mCallback = new Call.Callback() {
- @Override
- public void onStateChanged(Call call, int state) {
- if (state == Call.STATE_ACTIVE) {
- startPlaying();
- }
- }
- };
-
- @Override
- public IBinder onBind(Intent intent) {
- SharedPreferences prefs = getSharedPreferences(CallAudioTestActivity.AUDIO_TEST_PREFS,
- MODE_PRIVATE);
- mIsAutoAnswerEnabled = prefs.getBoolean(CallAudioTestActivity.AUTO_ANSWER_ENABLED, false);
- return super.onBind(intent);
- }
-
- @Override
- public void onCallAdded(Call call) {
- if (!mIsAutoAnswerEnabled) {
- Log.i(this, "onCallAdded - autoanswer disabled, skip");
- return;
- }
- if (call.getDetails().getState() == Call.STATE_RINGING) {
- mIncomingCall = call;
- mIncomingCall.registerCallback(mCallback);
- mIncomingCall.answer(VideoProfile.STATE_AUDIO_ONLY);
-
- Log.i(this, "onCallAdded - ringing call");
- } else {
- Log.i(this, "onCallAdded - nonringing call");
- }
- }
-
- @Override
- public void onCallRemoved(Call call) {
- if (mIncomingCall == call) {
- mIncomingCall = null;
- if (mMediaPlayer != null) {
- mMediaPlayer.stop();
- mMediaPlayer.release();
- }
- }
- }
-
- private void startPlaying() {
- AudioDeviceInfo telephonyDevice = getTelephonyDevice(getSystemService(AudioManager.class));
- if (telephonyDevice != null) {
- Log.i(this, "startPlaying: create player for speech");
- mMediaPlayer = new MediaPlayer();
- mMediaPlayer.setOnCompletionListener(mediaPlayer -> Log.w(this, "startPlaying: done"));
- mMediaPlayer.setOnErrorListener(
- (mediaPlayer, what, extra) -> {
- Log.w(this, "startPlaying: playback failed!");
- return true; // Error handled
- });
- mMediaPlayer.setLooping(true);
- mMediaPlayer.setVolume(1.0f);
- AudioAttributes audioAttributes = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build();
- mMediaPlayer.setAudioAttributes(audioAttributes);
- try {
- mMediaPlayer.setDataSource(getResources().openRawResourceFd(R.raw.speech));
- mMediaPlayer.prepare();
- } catch (IOException e) {
- mMediaPlayer.release();
- throw new IllegalStateException(e);
- }
- if (!mMediaPlayer.setPreferredDevice(telephonyDevice)) {
- Log.w(this, "startPlaying: setPreferredDevice failed");
- }
- mMediaPlayer.start();
-
- }
- }
-
- private AudioDeviceInfo getTelephonyDevice(AudioManager audioManager) {
- AudioDeviceInfo[] deviceList = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
- for (AudioDeviceInfo device: deviceList) {
- if (device.getType() == AudioDeviceInfo.TYPE_TELEPHONY) {
- return device;
- }
- }
- return null;
- }
-}
diff --git a/testapps/carmodedialer/Android.bp b/testapps/carmodedialer/Android.bp
index 9f65b8c..7179b1f 100644
--- a/testapps/carmodedialer/Android.bp
+++ b/testapps/carmodedialer/Android.bp
@@ -14,10 +14,6 @@
// 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 239726c..7f55f7e 100644
--- a/testapps/carmodedialer/AndroidManifest.xml
+++ b/testapps/carmodedialer/AndroidManifest.xml
@@ -15,79 +15,75 @@
-->
<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"
- 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"/>
+ android:permission="android.permission.BIND_INCALL_SERVICE" >
+ <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
+ 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:exported="true">
+ android:label="CarMode Dialer"
+ android:launchMode="singleInstance">
<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:exported="true">
+ android:label="CarMode Dialer">
<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/companionapp/Android.bp b/testapps/companionapp/Android.bp
deleted file mode 100644
index 8718b37..0000000
--- a/testapps/companionapp/Android.bp
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// 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 {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test {
- name: "TelecomCompanionApp",
- static_libs: [
- "androidx.legacy_legacy-support-v4",
- "guava",
- ],
- srcs: ["src/**/*.java"],
-}
diff --git a/testapps/companionapp/AndroidManifest.xml b/testapps/companionapp/AndroidManifest.xml
deleted file mode 100644
index 7569d8f..0000000
--- a/testapps/companionapp/AndroidManifest.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- coreApp="true"
- package="com.android.server.telecom.companionapp">
-
- <uses-sdk android:minSdkVersion="28"
- android:targetSdkVersion="29"/>
-
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.MANAGE_ONGOING_CALLS" />
- <uses-feature android:name="android.software.companion_device_setup"/>
-
- <application android:label="Telecom Companion">
- <uses-library android:name="android.test.runner"/>
-
- <activity android:name="com.android.server.telecom.companionapp.CompanionTestApp"
- android:label="CompanionTestApp">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <service android:name="com.android.server.telecom.companionapp.CompanionInCallServiceImpl"
- android:permission="android.permission.BIND_INCALL_SERVICE"
- android:exported="true">
- <intent-filter>
- <action android:name="android.telecom.InCallService"/>
- </intent-filter>
- </service>
- </application>
-</manifest>
diff --git a/testapps/companionapp/res/drawable-hdpi/ic_android_black_24dp.png b/testapps/companionapp/res/drawable-hdpi/ic_android_black_24dp.png
deleted file mode 100644
index ed3ee45..0000000
--- a/testapps/companionapp/res/drawable-hdpi/ic_android_black_24dp.png
+++ /dev/null
Binary files differ
diff --git a/testapps/companionapp/res/drawable-mdpi/ic_android_black_24dp.png b/testapps/companionapp/res/drawable-mdpi/ic_android_black_24dp.png
deleted file mode 100644
index a4add51..0000000
--- a/testapps/companionapp/res/drawable-mdpi/ic_android_black_24dp.png
+++ /dev/null
Binary files differ
diff --git a/testapps/companionapp/res/drawable-xhdpi/ic_android_black_24dp.png b/testapps/companionapp/res/drawable-xhdpi/ic_android_black_24dp.png
deleted file mode 100644
index 41558f2..0000000
--- a/testapps/companionapp/res/drawable-xhdpi/ic_android_black_24dp.png
+++ /dev/null
Binary files differ
diff --git a/testapps/companionapp/res/drawable-xxhdpi/ic_android_black_24dp.png b/testapps/companionapp/res/drawable-xxhdpi/ic_android_black_24dp.png
deleted file mode 100644
index 6006b12..0000000
--- a/testapps/companionapp/res/drawable-xxhdpi/ic_android_black_24dp.png
+++ /dev/null
Binary files differ
diff --git a/testapps/companionapp/res/drawable-xxxhdpi/ic_android_black_24dp.png b/testapps/companionapp/res/drawable-xxxhdpi/ic_android_black_24dp.png
deleted file mode 100644
index 4f935bf..0000000
--- a/testapps/companionapp/res/drawable-xxxhdpi/ic_android_black_24dp.png
+++ /dev/null
Binary files differ
diff --git a/testapps/companionapp/res/layout/main.xml b/testapps/companionapp/res/layout/main.xml
deleted file mode 100644
index e553754..0000000
--- a/testapps/companionapp/res/layout/main.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="This is a test app for companion in call service."
- android:padding="10dp"
- android:textColor="#FFFFFF"/>
- <Button
- android:id="@+id/buttonStart"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Start Association"/>
- <Button
- android:id="@+id/buttonStop"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Stop Association"/>
-</LinearLayout>
diff --git a/testapps/companionapp/src/com/android/server/telecom/companionapp/CompanionInCallServiceImpl.java b/testapps/companionapp/src/com/android/server/telecom/companionapp/CompanionInCallServiceImpl.java
deleted file mode 100644
index 890cd77..0000000
--- a/testapps/companionapp/src/com/android/server/telecom/companionapp/CompanionInCallServiceImpl.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.companionapp;
-
-import android.content.Intent;
-import android.telecom.Call;
-import android.telecom.InCallService;
-import android.telecom.Phone;
-import android.util.Log;
-import android.widget.Toast;
-
-import java.lang.Override;
-import java.lang.String;
-
-/**
- * Test Companion In-Call service implementation.
- */
-public class CompanionInCallServiceImpl extends InCallService {
- private static final String TAG = "CompanionInCallServiceImpl";
-
- private Phone mPhone;
-
- private Phone.Listener mPhoneListener = new Phone.Listener() {
- @Override
- public void onCallAdded(Phone phone, Call call) {
- Log.i(TAG, "onCallAdded: " + call.toString());
- Toast.makeText(
- CompanionInCallServiceImpl.this, "onCallAdded", Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onCallRemoved(Phone phone, Call call) {
- Log.i(TAG, "onCallRemoved: " + call.toString());
- Toast.makeText(
- CompanionInCallServiceImpl.this, "onCallRemoved", Toast.LENGTH_LONG).show();
- }
- };
-
- @Override
- public void onPhoneCreated(Phone phone) {
- Log.i(TAG, "onPhoneCreated");
- mPhone = phone;
- mPhone.addListener(mPhoneListener);
- }
-
- @Override
- public boolean onUnbind(Intent intent) {
- Log.i(TAG, "Companion TestApp InCallService unbind");
- mPhone.removeListener(mPhoneListener);
- mPhone = null;
- return super.onUnbind(intent);
- }
-
- /**
- * Used to bind a call
- * @param intent
- * @return
- */
- @Override
- public android.os.IBinder onBind(Intent intent) {
- Log.d(TAG, "Companion TestApp InCallService bind");
- return super.onBind(intent);
- }
-}
diff --git a/testapps/companionapp/src/com/android/server/telecom/companionapp/CompanionTestApp.java b/testapps/companionapp/src/com/android/server/telecom/companionapp/CompanionTestApp.java
deleted file mode 100644
index 7ed1e1e..0000000
--- a/testapps/companionapp/src/com/android/server/telecom/companionapp/CompanionTestApp.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2020 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.companionapp;
-
-import android.app.Activity;
-import android.bluetooth.BluetoothDevice;
-import android.companion.AssociationRequest;
-import android.companion.BluetoothDeviceFilter;
-import android.companion.CompanionDeviceManager;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.os.Bundle;
-import android.os.ParcelUuid;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.Toast;
-
-import java.util.UUID;
-import java.util.regex.Pattern;
-
-/**
- * Companion Test App in Telecom
- */
-public class CompanionTestApp extends Activity {
-
- private static String logtag = "CompanionTestApp";
- private CompanionDeviceManager mDeviceManager;
- private AssociationRequest mPairingRequest;
- private BluetoothDeviceFilter mDeviceFilter;
-
- private static final int SELECT_DEVICE_REQUEST_CODE = 42;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- setupDeviceAssociation();
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- Button buttonStart = (Button)findViewById(R.id.buttonStart);
- buttonStart.setOnClickListener(startListener);
-
- Button buttonStop = (Button)findViewById(R.id.buttonStop);
- buttonStop.setOnClickListener(stopListener);
- }
-
- private OnClickListener startListener = new OnClickListener() {
- public void onClick(View v) {
- Log.d(logtag,"onClick() called - start button");
- Toast.makeText(CompanionTestApp.this, "Start Association", Toast.LENGTH_LONG).show();
- assosicate();
- Log.d(logtag,"onClick() ended - start button");
- }
- };
-
- private OnClickListener stopListener = new OnClickListener() {
- public void onClick(View v) {
- Log.d(logtag,"onClick() called - stop button");
- Toast.makeText(CompanionTestApp.this, "Stop Association", Toast.LENGTH_LONG).show();
- disassosicate();
- Log.d(logtag,"onClick() ended - stop button");
- }
- };
-
- // Setup Device Association Preparation, per
- // https://developer.android.com/guide/topics/connectivity/companion-device-pairing
- private void setupDeviceAssociation() {
- mDeviceManager = getSystemService(CompanionDeviceManager.class);
-
- mDeviceFilter = new BluetoothDeviceFilter.Builder()
- .build();
-
- mPairingRequest = new AssociationRequest.Builder()
- .addDeviceFilter(mDeviceFilter)
- .setDeviceProfile(AssociationRequest.DEVICE_PROFILE_WATCH)
- .build();
-
- }
-
- // Associate bluetooth device, per
- // https://developer.android.com/guide/topics/connectivity/companion-device-pairing
- private void assosicate() {
- // When the app tries to pair with the Bluetooth device, show the
- // appropriate pairing request dialog to the user.
- mDeviceManager.associate(mPairingRequest,
- new CompanionDeviceManager.Callback() {
- @Override
- public void onDeviceFound(IntentSender chooserLauncher) {
- try {
- startIntentSenderForResult(chooserLauncher,
- SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0);
- } catch (Exception ex) {
- Log.d(logtag, "Callback onDeviceFound() Exception: " + ex);
- }
- }
-
- @Override
- public void onFailure(CharSequence error) {
- Log.d(logtag, "Callback onFailure() called - error: " + error);
- }
- },
- null);
- }
-
- // Disassociate the associated bluetooth device
- private void disassosicate() {
- for (String macAddress : mDeviceManager.getAssociations()) {
- mDeviceManager.disassociate(macAddress);
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == SELECT_DEVICE_REQUEST_CODE &&
- resultCode == Activity.RESULT_OK) {
- // User has chosen to pair with the Bluetooth device.
- BluetoothDevice deviceToPair =
- data.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE);
- deviceToPair.createBond();
- }
- }
-
- @Override
- protected void onStart() {
- Log.d(logtag,"onStart() called");
- super.onStart();
- }
-
- @Override
- protected void onResume() {
- Log.d(logtag,"onResume() called");
- super.onResume();
- }
-
- @Override
- protected void onPause() {
- Log.d(logtag,"onPause() called");
- super.onPause();
- }
-
- @Override
- protected void onStop() {
- Log.d(logtag,"onStop() called");
- super.onStop();
- }
-
- @Override
- protected void onDestroy() {
- Log.d(logtag,"onDestroy() called");
- super.onDestroy();
- }
-}
diff --git a/testapps/res/layout/incall_screen.xml b/testapps/res/layout/incall_screen.xml
index 22d3574..f8f919b 100644
--- a/testapps/res/layout/incall_screen.xml
+++ b/testapps/res/layout/incall_screen.xml
@@ -131,11 +131,6 @@
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"/>
</LinearLayout>
- <TextView
- android:id="@+id/incoming_composer_attachments"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="10dp"/>
<Button
android:id="@+id/disable_incallservice"
android:layout_width="wrap_content"
diff --git a/testapps/res/layout/self_managed_sample_main.xml b/testapps/res/layout/self_managed_sample_main.xml
index d26d629..28f4473 100644
--- a/testapps/res/layout/self_managed_sample_main.xml
+++ b/testapps/res/layout/self_managed_sample_main.xml
@@ -90,6 +90,7 @@
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
+
<Button
android:id="@+id/placeOutgoingCallButton"
android:layout_width="wrap_content"
@@ -112,35 +113,6 @@
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/res/layout/testdialer_main.xml b/testapps/res/layout/testdialer_main.xml
index 749d236..3f397b8 100644
--- a/testapps/res/layout/testdialer_main.xml
+++ b/testapps/res/layout/testdialer_main.xml
@@ -59,11 +59,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/startCallWithRtt"/>
- <CheckBox
- android:id="@+id/add_composer_attachments_checkbox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/addComposerAttachments"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/testapps/res/values/donottranslate_strings.xml b/testapps/res/values/donottranslate_strings.xml
index b1a1f80..7331d5a 100644
--- a/testapps/res/values/donottranslate_strings.xml
+++ b/testapps/res/values/donottranslate_strings.xml
@@ -44,8 +44,6 @@
<string name="startCallWithRtt">Start call with RTT</string>
- <string name="addComposerAttachments">Add call composer attachments</string>
-
<string name="rttIfaceButton">RTT</string>
<string name="endRttButton">End RTT</string>
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
index d4661ff..4b5fa57 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
@@ -46,10 +46,8 @@
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;
@@ -101,8 +99,6 @@
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,
@@ -114,9 +110,6 @@
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 44410d2..fd12a2e 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
@@ -16,12 +16,9 @@
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;
@@ -57,13 +54,9 @@
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;
@@ -126,20 +119,6 @@
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
@@ -155,14 +134,7 @@
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);
@@ -212,25 +184,6 @@
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();
@@ -261,37 +214,6 @@
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
deleted file mode 100644
index e1511e7..0000000
--- a/testapps/src/com/android/server/telecom/testapps/TestCallDiagnosticService.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-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.CallDiagnostics;
-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 TestCallDiagnostics extends CallDiagnostics {
- public Call.Details details;
-
- TestCallDiagnostics(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 "GSM/CDMA call dropped because " + disconnectCause;
- }
-
- @Nullable
- @Override
- public CharSequence onCallDisconnected(@NonNull ImsReasonInfo disconnectReason) {
- Log.i(this, "onCallDisconnected");
- return "ImsCall dropped because something happened " + disconnectReason.mExtraMessage;
- }
-
- @Override
- public void onCallQualityReceived(@NonNull CallQuality callQuality) {
- Log.i(this, "onCallQualityReceived %s", callQuality);
- }
- }
-
- @NonNull
- @Override
- public CallDiagnostics onInitializeCallDiagnostics(@NonNull Call.Details call) {
- Log.i(this, "onInitiatlizeDiagnosticCall %s", call);
- return new TestCallDiagnostics(call);
- }
-
- @Override
- public void onRemoveCallDiagnostics(@NonNull CallDiagnostics 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 5c78d52..abb9108 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
@@ -37,6 +37,7 @@
/**
* 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 3d1bc70..f6fa116 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -53,6 +53,7 @@
/**
* 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 {
/**
@@ -429,9 +430,9 @@
int videoState = extras.getInt(EXTRA_START_VIDEO_STATE, VideoProfile.STATE_AUDIO_ONLY);
Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
- // Use test number for testing incoming calls.
+ // Use dummy number for testing incoming calls.
Uri address = providedHandle == null ?
- Uri.fromParts(PhoneAccount.SCHEME_TEL, getRandomNumber(
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(
VideoProfile.isVideo(videoState)), null)
: providedHandle;
connection.setVideoState(videoState);
@@ -479,7 +480,7 @@
final Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
Uri handle = providedHandle == null ?
- Uri.fromParts(PhoneAccount.SCHEME_TEL, getRandomNumber(false), null)
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(false), null)
: providedHandle;
connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
@@ -612,7 +613,7 @@
* @param isVideo {@code True} if the call is a video call.
* @return The phone number.
*/
- private String getRandomNumber(boolean isVideo) {
+ private String getDummyNumber(boolean isVideo) {
int videoDigit = isVideo ? 1 : 0;
int number = mRandom.nextInt(999);
return String.format("555%s%03d", videoDigit, number);
diff --git a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
index 010d6ee..1e06387 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
@@ -9,7 +9,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
@@ -33,18 +32,8 @@
private EditText mNumberView;
private CheckBox mRttCheckbox;
- private CheckBox mComposerCheckbox;
private EditText mPriorityView;
- private static final String COMPOSER_SUBJECT = "Sample call composer subject";
- private static final Location COMPOSER_LOCATION;
- static {
- // Area 51
- COMPOSER_LOCATION = new Location("");
- COMPOSER_LOCATION.setLongitude(-115.806407);
- COMPOSER_LOCATION.setLatitude(37.236214);
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -79,7 +68,6 @@
mNumberView = (EditText) findViewById(R.id.number);
mRttCheckbox = (CheckBox) findViewById(R.id.call_with_rtt_checkbox);
- mComposerCheckbox = (CheckBox) findViewById(R.id.add_composer_attachments_checkbox);
findViewById(R.id.enable_car_mode).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -181,11 +169,6 @@
if (mRttCheckbox.isChecked()) {
extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, true);
}
- if (mComposerCheckbox.isChecked()) {
- extras.putInt(TelecomManager.EXTRA_PRIORITY, TelecomManager.PRIORITY_URGENT);
- extras.putParcelable(TelecomManager.EXTRA_LOCATION, COMPOSER_LOCATION);
- extras.putString(TelecomManager.EXTRA_CALL_SUBJECT, COMPOSER_SUBJECT);
- }
Bundle intentExtras = new Bundle();
intentExtras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras);
diff --git a/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java b/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
index bdd4c1a..3f3a2c8 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
@@ -21,7 +21,6 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.location.Location;
import android.os.Bundle;
import android.telecom.Call;
import android.telecom.CallAudioState;
@@ -29,7 +28,6 @@
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
-import android.telephony.ims.ImsCallProfile;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -250,47 +248,6 @@
enableInCallService();
}
});
-
- // Find the ringing call and populate the composer extras
- for (int i = 0; i < TestCallList.getInstance().size(); i++) {
- Call call = TestCallList.getInstance().getCall(i);
- if (call.getState() == Call.STATE_RINGING) {
- int priority = call.getDetails()
- .getIntentExtras().getInt(TelecomManager.EXTRA_PRIORITY, -1);
- Location location = call.getDetails()
- .getIntentExtras().getParcelable(TelecomManager.EXTRA_LOCATION);
- String subject = call.getDetails()
- .getIntentExtras().getString(TelecomManager.EXTRA_CALL_SUBJECT);
- boolean isBusiness = call.getDetails()
- .getExtras().getBoolean(ImsCallProfile.EXTRA_IS_BUSINESS_CALL);
-
- StringBuilder display = new StringBuilder();
- display.append("priority=");
- switch (priority) {
- case TelecomManager.PRIORITY_NORMAL:
- display.append("normal");
- break;
- case TelecomManager.PRIORITY_URGENT:
- display.append("urgent");
- break;
- default:
- display.append("unset");
- }
- display.append(";");
- if (location != null) {
- display.append("lat=" + location.getLatitude());
- display.append("lon=" + location.getLongitude());
- } else {
- display.append("loc=null");
- }
-
- display.append(" subject=" + subject);
- display.append(" isBusiness=" + isBusiness);
- TextView attachmentsTextView = findViewById(R.id.incoming_composer_attachments);
- attachmentsTextView.setText(display.toString());
- break;
- }
- }
}
public void updateCallAudioState(CallAudioState cas) {
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 60d38af..22f5348 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -36,13 +36,6 @@
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <!-- Used to access Projection State APIs -->
- <uses-permission android:name="android.permission.READ_PROJECTION_STATE"/>
-
- <!-- Used to access PlatformCompat APIs -->
- <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
- <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
-
<application android:label="@string/app_name"
android:debuggable="true">
<uses-library android:name="android.test.runner" />
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 02b35a4..3fb2a84 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -27,10 +27,4 @@
<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 2a304a4..ec5f7ba 100644
--- a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
+++ b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
@@ -16,9 +16,6 @@
package com.android.server.telecom.tests;
-import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
-import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -30,7 +27,6 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import android.content.ContentResolver;
import android.content.Context;
import android.os.Build;
import android.telecom.CallAudioState;
@@ -131,8 +127,7 @@
Analytics.dump(ip);
String dumpResult = sr.toString();
String[] expectedFields = {"startTime", "endTime", "direction", "isAdditionalCall",
- "isInterrupted", "callTechnologies", "callTerminationReason", "connectionService",
- "missedReason"};
+ "isInterrupted", "callTechnologies", "callTerminationReason", "connectionService"};
for (String field : expectedFields) {
assertTrue(dumpResult.contains(field));
}
@@ -186,8 +181,6 @@
@MediumTest
@Test
public void testAnalyticsTwoCalls() throws Exception {
- when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
- .thenReturn((long) TEST_TIMEOUT);
IdPair testCall1 = startAndMakeActiveIncomingCall(
"650-555-1212",
mPhoneAccountA0.getAccountHandle(),
@@ -207,10 +200,6 @@
assertTrue(callAnalytics2.startTime > 0);
assertEquals(0, callAnalytics1.endTime);
assertEquals(0, callAnalytics2.endTime);
- long missedReason1 = callAnalytics1.missedReason;
- assertTrue(missedReason1 == MISSED_REASON_NOT_MISSED
- || missedReason1 == USER_MISSED_CALL_FILTERS_TIMEOUT);
- 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 a3b8654..6fd53eb 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -63,7 +63,6 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -164,9 +163,6 @@
.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);
@@ -223,9 +219,6 @@
.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());
@@ -255,9 +248,6 @@
.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());
@@ -474,7 +464,6 @@
@LargeTest
@Test
@FlakyTest
- @Ignore("b/189904580")
public void testIncomingCallFromBlockedNumberIsRejected() throws Exception {
String phoneNumber = "650-555-1212";
blockNumber(phoneNumber);
@@ -494,7 +483,6 @@
waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
TEST_TIMEOUT);
-
assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
for (CallerInfoAsyncQueryFactoryFixture.Request request :
mCallerInfoAsyncQueryFactoryFixture.mRequests) {
@@ -638,10 +626,6 @@
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())
@@ -830,7 +814,8 @@
private void blockNumberWithAnswer(String phoneNumber, Answer answer) throws Exception {
when(getBlockedNumberProvider().call(
- any(),
+ anyString(),
+ nullable(String.class),
anyString(),
eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER),
eq(phoneNumber),
diff --git a/tests/src/com/android/server/telecom/tests/BlockedNumbersUtilTests.java b/tests/src/com/android/server/telecom/tests/BlockedNumbersUtilTests.java
deleted file mode 100644
index 56cb735..0000000
--- a/tests/src/com/android/server/telecom/tests/BlockedNumbersUtilTests.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.telecom.tests;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.verify;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.os.UserHandle;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.server.telecom.settings.BlockedNumbersUtil;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class BlockedNumbersUtilTests extends TelecomTestCase {
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- }
-
- @SmallTest
- @Test
- public void testPostNotification() {
- BlockedNumbersUtil.updateEmergencyCallNotification(mContext, true);
- NotificationManager mgr = mComponentContextFixture.getNotificationManager();
- verify(mgr).notifyAsUser(isNull(), anyInt(), any(Notification.class),
- any(UserHandle.class));
- }
-
- @SmallTest
- @Test
- public void testDismissNotification() {
- BlockedNumbersUtil.updateEmergencyCallNotification(mContext, false);
- NotificationManager mgr = mComponentContextFixture.getNotificationManager();
- verify(mgr).cancelAsUser(isNull(), anyInt(), any(UserHandle.class));
- }
-}
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
new file mode 100644
index 0000000..532cc7e
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
@@ -0,0 +1,1136 @@
+/*
+ * 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 91ec7f3..24476f0 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -17,10 +17,7 @@
package com.android.server.telecom.tests;
import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.IAudioService;
import android.os.HandlerThread;
@@ -154,49 +151,6 @@
@MediumTest
@Test
- public void testStreamRingMuteChange() {
- CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
- mContext,
- mockCallsManager,
- mockBluetoothRouteManager,
- mockWiredHeadsetManager,
- mockStatusBarNotifier,
- mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
- mThreadHandler.getLooper());
- stateMachine.setCallAudioManager(mockCallAudioManager);
- CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER,
- CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER);
- stateMachine.initialize(initState);
-
- // Make sure we register a receiver for the STREAM_MUTE_CHANGED_ACTION so we can see if the
- // ring stream unmutes.
- ArgumentCaptor<BroadcastReceiver> brCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
- verify(mContext, times(3)).registerReceiver(brCaptor.capture(), filterCaptor.capture());
- boolean foundValid = false;
- for (int ix = 0; ix < brCaptor.getAllValues().size(); ix++) {
- BroadcastReceiver receiver = brCaptor.getAllValues().get(ix);
- IntentFilter filter = filterCaptor.getAllValues().get(ix);
- if (!filter.hasAction(AudioManager.STREAM_MUTE_CHANGED_ACTION)) {
- continue;
- }
-
- // Fake out a call to the broadcast receiver and make sure we call into audio manager
- // to trigger re-evaluation of ringing.
- Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
- intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, false);
- intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, AudioManager.STREAM_RING);
- receiver.onReceive(mContext, intent);
- verify(mockCallAudioManager).onRingerModeChange();
- foundValid = true;
- }
- assertTrue(foundValid);
- }
-
- @MediumTest
- @Test
public void testSpeakerPersistence() {
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
@@ -322,10 +276,6 @@
waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
verifyNewSystemCallAudioState(initState, expectedMidState);
- // clear out the handler state before resetting mocks in order to avoid introducing a
- // CallAudioState that has a null list of supported BT devices
- waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
- waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
resetMocks();
// Now, switch back to BT explicitly
@@ -505,37 +455,6 @@
@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 879ed0f..58f1ee7 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
@@ -384,12 +384,8 @@
// rest of the system
verifyNoSystemAudioChanges();
- // Special case for SPEAKER_ON -- we don't expect any route transitions to happen when
- // there are no calls, so set the expected state to the initial route.
- int expectedRoute = (mParams.action == CallAudioRouteStateMachine.SPEAKER_ON)
- ? mParams.initialRoute : mParams.expectedRoute;
// Verify the end state
- CallAudioState expectedState = new CallAudioState(false, expectedRoute,
+ CallAudioState expectedState = new CallAudioState(false, mParams.expectedRoute,
mParams.expectedAvailableRoutes | CallAudioState.ROUTE_SPEAKER,
mParams.expectedBluetoothDevice, mParams.availableBluetoothDevices);
assertEquals(expectedState, stateMachine.getCurrentCallAudioState());
@@ -815,7 +811,7 @@
"Speakerphone turned off externally during speaker", // name
CallAudioState.ROUTE_SPEAKER, // initialRoute
CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
- OFF, // speakerInteraction
+ NONE, // 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
deleted file mode 100644
index d420f1d..0000000
--- a/tests/src/com/android/server/telecom/tests/CallDiagnosticServiceControllerTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-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 b9f5667..953c711 100644
--- a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
@@ -18,7 +18,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -41,9 +40,7 @@
import android.location.Country;
import android.location.CountryDetector;
import android.location.CountryListener;
-import android.location.Location;
import android.net.Uri;
-import android.os.Bundle;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.SystemClock;
@@ -55,7 +52,6 @@
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
@@ -64,7 +60,6 @@
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;
@@ -94,7 +89,6 @@
private PhoneAccountHandle mOtherUserAccountHandle;
private PhoneAccountHandle mManagedProfileAccountHandle;
private PhoneAccountHandle mSelfManagedAccountHandle;
- private Analytics.CallInfo mCallInfo;
private static final Uri TEL_PHONEHANDLE = Uri.parse("tel:5555551234");
@@ -154,7 +148,6 @@
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));
@@ -176,7 +169,7 @@
when(userManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
when(userManager.hasUserRestriction(any(String.class), any(UserHandle.class)))
.thenReturn(false);
- when(userManager.getAliveUsers())
+ when(userManager.getUsers(any(Boolean.class)))
.thenReturn(Arrays.asList(userInfo, otherUserInfo, managedProfileUserInfo));
when(userManager.getUserInfo(eq(CURRENT_USER_ID))).thenReturn(userInfo);
when(userManager.getUserInfo(eq(OTHER_USER_ID))).thenReturn(otherUserInfo);
@@ -823,54 +816,6 @@
@SmallTest
@Test
- public void testCallComposerElements() {
- Call fakeCall = makeFakeCall(
- DisconnectCause.LOCAL, // disconnectCauseCode
- false, // isConference
- true, // isIncoming
- 1L, // creationTimeMillis
- 1000L, // ageMillis
- TEL_PHONEHANDLE, // callHandle
- mDefaultAccountHandle, // phoneAccountHandle
- NO_VIDEO_STATE, // callVideoState
- POST_DIAL_STRING, // postDialDigits
- VIA_NUMBER_STRING, // viaNumber
- UserHandle.of(CURRENT_USER_ID)
- );
- String subject = "segmentation fault";
- // =)
- double lat = 40.649723;
- double lon = -80.082090;
- Location location = new Location("");
- location.setLatitude(lat);
- location.setLongitude(lon);
-
- Uri fakeProviderUri = Uri.parse("content://nothing_to_see_here/12345");
-
- Bundle extras = new Bundle();
- extras.putInt(TelecomManager.EXTRA_PRIORITY, TelecomManager.PRIORITY_URGENT);
- extras.putString(TelecomManager.EXTRA_CALL_SUBJECT, subject);
- extras.putParcelable(TelecomManager.EXTRA_LOCATION, location);
- extras.putParcelable(TelecomManager.EXTRA_PICTURE_URI, fakeProviderUri);
- when(fakeCall.getIntentExtras()).thenReturn(extras);
-
- mCallLogManager.onCallStateChanged(fakeCall, CallState.ACTIVE,
- CallState.DISCONNECTED);
- ContentValues locationValues = verifyLocationInsertionWithCapture(CURRENT_USER_ID);
- assertEquals(lat, locationValues.getAsDouble(CallLog.Locations.LATITUDE), 0);
- assertEquals(lon, locationValues.getAsDouble(CallLog.Locations.LONGITUDE), 0);
-
- ContentValues callLogValues = verifyInsertionWithCapture(CURRENT_USER_ID);
- assertEquals(subject, callLogValues.getAsString(Calls.SUBJECT));
- assertEquals(fakeProviderUri.toString(),
- callLogValues.getAsString(Calls.COMPOSER_PHOTO_URI));
- assertEquals(TelecomManager.PRIORITY_URGENT,
- (int) callLogValues.getAsInteger(Calls.PRIORITY));
- assertNotNull(callLogValues.getAsString(Calls.LOCATION));
- }
-
- @SmallTest
- @Test
public void testDoNotLogConferenceWithNoChildren() {
Call fakeCall = makeFakeCall(
DisconnectCause.LOCAL, // disconnectCauseCode
@@ -1028,14 +973,6 @@
return captor.getValue();
}
- private ContentValues verifyLocationInsertionWithCapture(int userId) {
- Uri uri = ContentProvider.maybeAddUserId(CallLog.Locations.CONTENT_URI, userId);
- ArgumentCaptor<ContentValues> captor = ArgumentCaptor.forClass(ContentValues.class);
- verify(mContentProvider, timeout(TEST_TIMEOUT_MILLIS).times(1)).insert(
- eq(uri), captor.capture());
- return captor.getValue();
- }
-
private Call makeFakeCall(int disconnectCauseCode, boolean isConference, boolean isIncoming,
long creationTimeMillis, long ageMillis, Uri callHandle,
PhoneAccountHandle phoneAccountHandle, int callVideoState,
@@ -1069,7 +1006,6 @@
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/CallRedirectionProcessorTest.java b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
index 0a896a8..ff16880 100644
--- a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
@@ -65,6 +65,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.ArrayList;
+
@RunWith(JUnit4.class)
public class CallRedirectionProcessorTest extends TelecomTestCase {
@Mock private Context mContext;
@@ -149,7 +151,7 @@
}
private void setIsInCarMode(boolean isInCarMode) {
- when(mSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(isInCarMode);
+ when(mSystemStateHelper.isCarMode()).thenReturn(isInCarMode);
}
private void enableUserDefinedCallRedirectionService() {
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
index 68caf67..1345c01 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
@@ -23,7 +23,6 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -93,16 +92,6 @@
.setShouldShowNotification(true)
.build();
- private static final CallFilteringResult PASS_RESULT_WITH_NAME =
- new CallFilteringResult.Builder()
- .setShouldAllowCall(true)
- .setShouldReject(false)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .setCallScreeningAppName(APP_NAME)
- .setCallScreeningComponentName(COMPONENT_NAME.flattenToString())
- .build();
-
@Override
@Before
public void setUp() throws Exception {
@@ -222,19 +211,6 @@
@SmallTest
@Test
- public void testUnbindingException() {
- // Make sure that exceptions when unbinding won't make the device crash.
- doThrow(new IllegalArgumentException()).when(mContext)
- .unbindService(nullable(ServiceConnection.class));
- CallScreeningServiceFilter filter = new CallScreeningServiceFilter(mCall, PKG_NAME,
- CallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
- mAppLabelProxy, mParcelableCallUtilsConverter);
- filter.startFilterLookup(inputResult);
- filter.unbindCallScreeningService();
- }
-
- @SmallTest
- @Test
public void testAllowCall() throws Exception {
CallScreeningServiceFilter filter = new CallScreeningServiceFilter(mCall, PKG_NAME,
CallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
@@ -245,14 +221,8 @@
serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
- CallScreeningService.CallResponse allowCallResponse =
- new CallScreeningService.CallResponse.Builder()
- .setDisallowCall(false)
- .setRejectCall(false)
- .setSilenceCall(false)
- .build();
- csAdapter.onScreeningResponse(CALL_ID, COMPONENT_NAME, allowCallResponse.toParcelable());
- assertEquals(PASS_RESULT_WITH_NAME,
+ csAdapter.allowCall(CALL_ID);
+ assertEquals(PASS_RESULT,
resultFuture.toCompletableFuture().get(
CallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
TimeUnit.MILLISECONDS));
@@ -280,16 +250,12 @@
ServiceConnection serviceConnection = verifyBindingIntent();
serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
- CallScreeningService.CallResponse disallowCallResponse =
- new CallScreeningService.CallResponse.Builder()
- .setDisallowCall(true)
- .setRejectCall(true)
- .setSkipCallLog(false)
- .setSkipNotification(false)
- .build();
ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
- csAdapter.onScreeningResponse(CALL_ID, COMPONENT_NAME, disallowCallResponse.toParcelable());
-
+ csAdapter.disallowCall(CALL_ID,
+ true, // shouldReject
+ true, //shouldAddToCallLog
+ true, // shouldShowNotification
+ COMPONENT_NAME);
assertEquals(expectedResult,
resultFuture.toCompletableFuture().get(
CallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
@@ -306,8 +272,6 @@
.setShouldSilence(true)
.setShouldAddToCallLog(true)
.setShouldShowNotification(true)
- .setCallScreeningAppName(APP_NAME)
- .setCallScreeningComponentName(COMPONENT_NAME.flattenToString())
.build();
CallScreeningServiceFilter filter = new CallScreeningServiceFilter(mCall, PKG_NAME,
CallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
@@ -318,13 +282,7 @@
serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
- CallScreeningService.CallResponse silenceCallResponse =
- new CallScreeningService.CallResponse.Builder()
- .setDisallowCall(false)
- .setRejectCall(false)
- .setSilenceCall(true)
- .build();
- csAdapter.onScreeningResponse(CALL_ID, COMPONENT_NAME, silenceCallResponse.toParcelable());
+ csAdapter.silenceCall(CALL_ID);
assertEquals(expectedResult,
resultFuture.toCompletableFuture().get(
CallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
@@ -342,7 +300,6 @@
.setShouldSilence(false)
.setShouldScreenViaAudio(true)
.setCallScreeningAppName(APP_NAME)
- .setCallScreeningComponentName(COMPONENT_NAME.flattenToString())
.build();
CallScreeningServiceFilter filter = new CallScreeningServiceFilter(mCall, PKG_NAME,
CallScreeningServiceFilter.PACKAGE_TYPE_DEFAULT_DIALER, mContext, mCallsManager,
@@ -352,17 +309,8 @@
ServiceConnection serviceConnection = verifyBindingIntent();
serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
-
- CallScreeningService.CallResponse additionalScreeningResponse =
- new CallScreeningService.CallResponse.Builder()
- .setDisallowCall(false)
- .setRejectCall(false)
- .setSilenceCall(false)
- .setShouldScreenCallViaAudioProcessing(true)
- .build();
ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
- csAdapter.onScreeningResponse(CALL_ID, COMPONENT_NAME,
- additionalScreeningResponse.toParcelable());
+ csAdapter.screenCallFurther(CALL_ID);
assertEquals(expectedResult,
resultFuture.toCompletableFuture().get(
CallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
diff --git a/tests/src/com/android/server/telecom/tests/CallTest.java b/tests/src/com/android/server/telecom/tests/CallTest.java
index d326a29..541d278 100644
--- a/tests/src/com/android/server/telecom/tests/CallTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallTest.java
@@ -19,17 +19,13 @@
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;
@@ -38,7 +34,6 @@
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;
@@ -49,8 +44,6 @@
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;
@@ -61,23 +54,17 @@
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(
- COMPONENT_NAME_1, "Sim1");
+ ComponentName.unflattenFromString("com.foo/.Blah"), "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 da72933..4dffe59 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -37,27 +36,19 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
-import android.content.ContentResolver;
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;
import android.telecom.CallerInfo;
import android.telecom.Connection;
-import android.telecom.DisconnectCause;
-import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -65,7 +56,6 @@
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;
@@ -73,7 +63,6 @@
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;
@@ -81,7 +70,6 @@
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceFocusManager;
import com.android.server.telecom.ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory;
-import com.android.server.telecom.ConnectionServiceWrapper;
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.EmergencyCallHelper;
import com.android.server.telecom.HeadsetMediaButton;
@@ -104,6 +92,7 @@
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;
@@ -118,6 +107,8 @@
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;
@@ -125,8 +116,6 @@
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;
@@ -204,9 +193,10 @@
@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;
@@ -229,14 +219,14 @@
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);
doNothing().when(mRoleManagerAdapter).setCurrentUserHandle(any());
when(mDisconnectedCallNotifierFactory.create(any(Context.class),any(CallsManager.class)))
.thenReturn(mDisconnectedCallNotifier);
- when(mTimeoutsAdapter.getCallDiagnosticServiceTimeoutMillis(any(ContentResolver.class)))
- .thenReturn(2000L);
mCallsManager = new CallsManager(
mComponentContextFixture.getTestDouble().getApplicationContext(),
mLock,
@@ -264,8 +254,8 @@
mCallAudioRouteStateMachineFactory,
mCallAudioModeStateMachineFactory,
mInCallControllerFactory,
- mCallDiagnosticServiceController,
mRoleManagerAdapter,
+ mIncomingCallFilterFactory,
mToastFactory);
when(mPhoneAccountRegistrar.getPhoneAccount(
@@ -1029,7 +1019,7 @@
@SmallTest
@Test
public void testHangupActiveCallWhenHeadsetMediaButtonLongPressDuringTwoCalls() {
- // GIVEN an ongoing call
+ // GIVEN an ongoing call
Call ongoingCall = addSpyCall();
doReturn(CallState.ACTIVE).when(ongoingCall).getState();
@@ -1115,46 +1105,6 @@
assertFalse(mCallsManager.isInEmergencyCall());
}
-
- @SmallTest
- @Test
- public void testBlockNonEmergencyCallDuringEmergencyCall() throws Exception {
- // Setup a call which the network identified as an emergency call.
- Call ongoingCall = addSpyCall();
- ongoingCall.setConnectionProperties(Connection.PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL);
- assertTrue(mCallsManager.isInEmergencyCall());
-
- Call newCall = addSpyCall(CallState.NEW);
- ConnectionServiceWrapper service = mock(ConnectionServiceWrapper.class);
- doReturn(SIM_2_HANDLE.getComponentName()).when(service).getComponentName();
-
- // 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)));
- mCallsManager.addConnectionServiceRepositoryCache(SIM_2_HANDLE.getComponentName(),
- SIM_2_HANDLE.getUserHandle(), service);
-
- CompletableFuture<Call> callFuture = mCallsManager.startOutgoingCall(
- newCall.getHandle(), newCall.getTargetPhoneAccount(), new Bundle(),
- UserHandle.CURRENT, new Intent(), "com.test.stuff");
-
- verify(service, timeout(TEST_TIMEOUT)).createConnectionFailed(any());
- Call result = callFuture.get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
- assertNull(result);
- }
-
@SmallTest
@Test
public void testHasEmergencyCallIncomingCallPermitted() {
@@ -1253,21 +1203,6 @@
verify(ringingCall).reject(anyBoolean(), any(), any());
}
- @SmallTest
- @Test
- public void testMakeRoomForOutgoingCallConnecting() {
- Call ongoingCall = addSpyCall(SIM_2_HANDLE, CallState.CONNECTING);
-
- Call newCall = createCall(SIM_1_HANDLE, CallState.NEW);
- when(mComponentContextFixture.getTelephonyManager().isEmergencyNumber(any()))
- .thenReturn(false);
- newCall.setHandle(Uri.fromParts("tel", "5551213", null),
- TelecomManager.PRESENTATION_ALLOWED);
-
- assertTrue(mCallsManager.makeRoomForOutgoingCall(newCall));
- verify(ongoingCall).disconnect(anyLong(), anyString());
- }
-
/**
* Verifies that changes to a {@link PhoneAccount}'s
* {@link PhoneAccount#CAPABILITY_VIDEO_CALLING} capability will be reflected on a call.
@@ -1397,8 +1332,6 @@
@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)
@@ -1409,7 +1342,7 @@
.setShouldShowNotification(true)
.setCallScreeningAppName(appName)
.build();
- mCallsManager.onCallFilteringComplete(screenedCall, result, false);
+ mCallsManager.onCallFilteringComplete(screenedCall, result);
verify(mConnectionSvrFocusMgr).requestFocus(eq(screenedCall),
nullable(ConnectionServiceFocusManager.RequestFocusCallback.class));
@@ -1448,80 +1381,6 @@
}
/**
- * 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
@@ -1572,59 +1431,6 @@
eq(CallState.ACTIVE));
}
- /**
- * Verifies where a call diagnostic service is NOT in use that we don't try to relay to the
- * CallDiagnosticService and that we get a synchronous disconnect.
- * @throws Exception
- */
- @MediumTest
- @Test
- public void testDisconnectCallSynchronous() throws Exception {
- Call callSpy = addSpyCall();
- callSpy.setIsSimCall(true);
- when(mCallDiagnosticServiceController.isConnected()).thenReturn(false);
- mCallsManager.markCallAsDisconnected(callSpy, new DisconnectCause(DisconnectCause.ERROR));
-
- verify(mCallDiagnosticServiceController, never()).onCallDisconnected(any(Call.class),
- any(DisconnectCause.class));
- verify(callSpy).setDisconnectCause(any(DisconnectCause.class));
- }
-
- @MediumTest
- @Test
- public void testDisconnectCallAsynchronous() throws Exception {
- Call callSpy = addSpyCall();
- callSpy.setIsSimCall(true);
- when(mCallDiagnosticServiceController.isConnected()).thenReturn(true);
- when(mCallDiagnosticServiceController.onCallDisconnected(any(Call.class),
- any(DisconnectCause.class))).thenReturn(true);
- mCallsManager.markCallAsDisconnected(callSpy, new DisconnectCause(DisconnectCause.ERROR));
-
- verify(mCallDiagnosticServiceController).onCallDisconnected(any(Call.class),
- any(DisconnectCause.class));
- verify(callSpy, never()).setDisconnectCause(any(DisconnectCause.class));
- }
-
- /**
- * Verifies that if call state goes from DIALING to DISCONNECTED, and a call diagnostic service
- * IS in use, it would call onCallDisconnected of the CallDiagnosticService
- * @throws Exception
- */
- @MediumTest
- @Test
- public void testDisconnectDialingCall() throws Exception {
- Call callSpy = addSpyCall(CallState.DIALING);
- callSpy.setIsSimCall(true);
- when(mCallDiagnosticServiceController.isConnected()).thenReturn(true);
- when(mCallDiagnosticServiceController.onCallDisconnected(any(Call.class),
- any(DisconnectCause.class))).thenReturn(true);
- mCallsManager.markCallAsDisconnected(callSpy, new DisconnectCause(DisconnectCause.ERROR));
-
- verify(mCallDiagnosticServiceController).onCallDisconnected(any(Call.class),
- any(DisconnectCause.class));
- verify(callSpy, never()).setDisconnectCause(any(DisconnectCause.class));
- }
-
private Call addSpyCall() {
return addSpyCall(SIM_2_HANDLE, CallState.ACTIVE);
}
@@ -1654,6 +1460,7 @@
// 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 4ad46ae..4ef4596 100644
--- a/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
@@ -17,10 +17,12 @@
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;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
import android.app.UiModeManager;
import com.android.server.telecom.CarModeTracker;
@@ -30,6 +32,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.Mock;
@RunWith(JUnit4.class)
public class CarModeTrackerTest extends TelecomTestCase {
@@ -101,17 +104,6 @@
}
/**
- * Ensure that we don't keep a package around after it's been removed from the device
- */
- @Test
- public void testForceExitCarMode() {
- testEnterCarModeBasic();
- mCarModeTracker.forceRemove(CAR_MODE_APP1_PACKAGE_NAME);
- assertFalse(mCarModeTracker.isInCarMode());
- assertNull(mCarModeTracker.getCurrentCarModePackage());
- }
-
- /**
* Verifies only the first app at the default priority gets tracked.
*/
@Test
@@ -222,109 +214,4 @@
CAR_MODE_APP3_PACKAGE_NAME);
assertNull(mCarModeTracker.getCurrentCarModePackage());
}
-
- /**
- * Verifies that setting automotive projection by itself works.
- */
- @Test
- public void testSetAutomotiveProjectionBasic() {
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME);
- assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
- // We should be tracking our car mode app.
- assertEquals(1, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- }
-
- /**
- * Verifies that if we set automotive projection more than once with the same package, nothing
- * changes.
- */
- @Test
- public void testSetAutomotiveProjectionMultipleTimes() {
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME);
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME);
- // Should still only have one app.
- assertEquals(1, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- // It should be the same one.
- assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
- }
-
- /**
- * Verifies that if we set automotive projection more than once, the new package overrides.
- */
- @Test
- public void testSetAutomotiveProjectionMultipleTimesDifferentPackages() {
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME);
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP2_PACKAGE_NAME);
- // Should still only have one app.
- assertEquals(1, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- // It should be the newer one.
- assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
- }
-
- /**
- * Verifies that releasing automotive projection works as expected.
- */
- @Test
- public void testReleaseAutomotiveProjectionBasic() {
- // Releasing before something's set shouldn't break anything.
- mCarModeTracker.handleReleaseAutomotiveProjection();
- assertEquals(0, mCarModeTracker.getCarModeApps().size());
- assertFalse(mCarModeTracker.isInCarMode());
-
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME);
- mCarModeTracker.handleReleaseAutomotiveProjection();
- // Should be gone now.
- assertEquals(0, mCarModeTracker.getCarModeApps().size());
- assertFalse(mCarModeTracker.isInCarMode());
- }
-
- /**
- * Verifies that setting automotive projection overrides but doesn't overwrite car mode apps.
- */
- @Test
- public void testAutomotiveProjectionOverridesCarMode() {
- mCarModeTracker.handleEnterCarMode(50, CAR_MODE_APP1_PACKAGE_NAME);
- mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP4_PACKAGE_NAME);
-
- // Should have two apps now, the car mode and the automotive projection one.
- assertEquals(2, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
-
- // Automotive projection takes priority.
- assertEquals(CAR_MODE_APP4_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
-
- // If we add another car mode app, automotive projection still has priority.
- mCarModeTracker.handleEnterCarMode(Integer.MAX_VALUE, CAR_MODE_APP2_PACKAGE_NAME);
- assertEquals(3, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- assertEquals(CAR_MODE_APP4_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
-
- // If we release automotive projection, we go back to the prioritized list of plain car
- // mode apps.
- mCarModeTracker.handleReleaseAutomotiveProjection();
- assertEquals(2, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
-
- // Make sure we didn't mess with the first app that was added.
- mCarModeTracker.handleExitCarMode(Integer.MAX_VALUE, CAR_MODE_APP2_PACKAGE_NAME);
- assertEquals(1, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
- }
-
- /**
- * Verifies that releasing automotive projection doesn't interfere with plain car mode apps.
- */
- @Test
- public void testReleaseAutomotiveProjectionNoopForCarModeApps() {
- mCarModeTracker.handleEnterCarMode(50, CAR_MODE_APP1_PACKAGE_NAME);
- mCarModeTracker.handleReleaseAutomotiveProjection();
- assertEquals(1, mCarModeTracker.getCarModeApps().size());
- assertTrue(mCarModeTracker.isInCarMode());
- assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage());
- }
}
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index ebb336e..7effc47 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -30,10 +30,7 @@
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.StatusBarManager;
-import android.app.UiModeManager;
import android.app.role.RoleManager;
-import android.content.AttributionSource;
-import android.content.AttributionSourceState;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -42,15 +39,12 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
-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;
import android.content.res.Resources;
-import android.hardware.SensorPrivacyManager;
import android.location.Country;
import android.location.CountryDetector;
import android.media.AudioManager;
@@ -58,12 +52,8 @@
import android.os.Handler;
import android.os.IInterface;
import android.os.PersistableBundle;
-import android.os.PowerWhitelistManager;
-import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.VibratorManager;
-import android.permission.PermissionCheckerManager;
import android.telecom.CallAudioState;
import android.telecom.ConnectionService;
import android.telecom.Log;
@@ -75,7 +65,6 @@
import android.telephony.TelephonyManager;
import android.telephony.TelephonyRegistryManager;
import android.test.mock.MockContext;
-import android.util.DisplayMetrics;
import java.io.File;
import java.io.IOException;
@@ -87,9 +76,7 @@
import java.util.Map;
import java.util.concurrent.Executor;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.matches;
-import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
@@ -216,14 +203,6 @@
return mRoleManager;
case Context.TELEPHONY_REGISTRY_SERVICE:
return mTelephonyRegistryManager;
- case Context.UI_MODE_SERVICE:
- return mUiModeManager;
- case Context.VIBRATOR_MANAGER_SERVICE:
- return mVibratorManager;
- case Context.PERMISSION_CHECKER_SERVICE:
- return mPermissionCheckerManager;
- case Context.SENSOR_PRIVACY_SERVICE:
- return mSensorPrivacyManager;
default:
return null;
}
@@ -245,14 +224,6 @@
return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
} else if (svcClass == TelephonyRegistryManager.class) {
return Context.TELEPHONY_REGISTRY_SERVICE;
- } else if (svcClass == UiModeManager.class) {
- return Context.UI_MODE_SERVICE;
- } else if (svcClass == VibratorManager.class) {
- return Context.VIBRATOR_MANAGER_SERVICE;
- } else if (svcClass == PermissionCheckerManager.class) {
- return Context.PERMISSION_CHECKER_SERVICE;
- } else if (svcClass == SensorPrivacyManager.class) {
- return Context.SENSOR_PRIVACY_SERVICE;
}
throw new UnsupportedOperationException();
}
@@ -278,11 +249,6 @@
}
@Override
- public AttributionSource getAttributionSource() {
- return mAttributionSource;
- }
-
- @Override
public ContentResolver getContentResolver() {
return new ContentResolver(mApplicationContextSpy) {
@Override
@@ -354,12 +320,6 @@
}
@Override
- public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
- Bundle options) {
- // Override so that this can be verified via spy.
- }
-
- @Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) {
@@ -391,11 +351,6 @@
}
@Override
- public int checkSelfPermission(String permission) {
- return PackageManager.PERMISSION_GRANTED;
- }
-
- @Override
public void enforceCallingOrSelfPermission(String permission, String message) {
// Don't bother enforcing anything in mock.
}
@@ -475,15 +430,10 @@
}
}
- private static final String PACKAGE_NAME = "com.android.server.telecom.tests";
- private final AttributionSource mAttributionSource =
- new AttributionSource.Builder(Process.myUid()).setPackageName(PACKAGE_NAME).build();
-
private final Multimap<String, ComponentName> mComponentNamesByAction =
ArrayListMultimap.create();
private final Map<ComponentName, IInterface> mServiceByComponentName = new HashMap<>();
private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName = new HashMap<>();
- private final Map<ComponentName, ActivityInfo> mActivityInfoByComponentName = new HashMap<>();
private final Map<IInterface, ComponentName> mComponentNameByService = new HashMap<>();
private final Map<ServiceConnection, IInterface> mServiceByServiceConnection = new HashMap<>();
@@ -509,7 +459,6 @@
private final Resources.Theme mResourcesTheme = mock(Resources.Theme.class);
private final Resources mResources = mock(Resources.class);
private final Context mApplicationContextSpy = spy(mApplicationContext);
- private final DisplayMetrics mDisplayMetrics = mock(DisplayMetrics.class);
private final PackageManager mPackageManager = mock(PackageManager.class);
private final Executor mMainExecutor = mock(Executor.class);
private final AudioManager mAudioManager = spy(new FakeAudioManager(mContext));
@@ -527,12 +476,6 @@
private final RoleManager mRoleManager = mock(RoleManager.class);
private final TelephonyRegistryManager mTelephonyRegistryManager =
mock(TelephonyRegistryManager.class);
- private final VibratorManager mVibratorManager = mock(VibratorManager.class);
- private final UiModeManager mUiModeManager = mock(UiModeManager.class);
- private final PermissionCheckerManager mPermissionCheckerManager =
- mock(PermissionCheckerManager.class);
- private final PermissionInfo mPermissionInfo = mock(PermissionInfo.class);
- private final SensorPrivacyManager mSensorPrivacyManager = mock(SensorPrivacyManager.class);
private TelecomManager mTelecomManager = mock(TelecomManager.class);
@@ -541,9 +484,6 @@
when(mResources.getConfiguration()).thenReturn(mResourceConfiguration);
when(mResources.getString(anyInt())).thenReturn("");
when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
- when(mResources.newTheme()).thenReturn(mResourcesTheme);
- when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
- mDisplayMetrics.density = 3.125f;
mResourceConfiguration.setLocale(Locale.TAIWAN);
// TODO: Move into actual tests
@@ -567,38 +507,10 @@
}
}).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());
- doAnswer(new Answer<List<ResolveInfo>>() {
- @Override
- public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
- return doQueryIntentReceivers(
- (Intent) invocation.getArguments()[0],
- (Integer) invocation.getArguments()[1]);
- }
- }).when(mPackageManager).queryBroadcastReceivers((Intent) any(), anyInt());
-
- doAnswer(new Answer<List<ResolveInfo>>() {
- @Override
- public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
- return doQueryIntentReceivers(
- (Intent) invocation.getArguments()[0],
- (Integer) invocation.getArguments()[1]);
- }
- }).when(mPackageManager).queryBroadcastReceiversAsUser((Intent) any(), anyInt(), anyInt());
-
// By default, tests use non-ui apps instead of 3rd party companion apps.
- when(mPermissionCheckerManager.checkPermission(
- matches(Manifest.permission.CALL_COMPANION_APP), any(AttributionSourceState.class),
- nullable(String.class), anyBoolean(), anyBoolean(), anyBoolean(), anyInt()))
- .thenReturn(PermissionCheckerManager.PERMISSION_HARD_DENIED);
-
- try {
- when(mPackageManager.getPermissionInfo(anyString(), anyInt())).thenReturn(
- mPermissionInfo);
- } catch (PackageManager.NameNotFoundException ex) {
- }
-
- when(mPermissionInfo.isAppOp()).thenReturn(true);
- when(mVibratorManager.getVibratorIds()).thenReturn(new int[0]);
+ when(mPackageManager.checkPermission(
+ matches(Manifest.permission.CALL_COMPANION_APP), anyString()))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
// 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
@@ -666,23 +578,11 @@
serviceInfo.name = componentName.getClassName();
mServiceInfoByComponentName.put(componentName, serviceInfo);
- // Used in InCallController to check permissions for CONTROL_INCALL_fvEXPERIENCE
+ // Used in InCallController to check permissions for CONTROL_INCALL_EXPERIENCE
when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[] {
componentName.getPackageName() });
when(mPackageManager.checkPermission(eq(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
eq(componentName.getPackageName()))).thenReturn(PackageManager.PERMISSION_GRANTED);
- when(mPermissionCheckerManager.checkPermission(
- eq(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
- any(AttributionSourceState.class), anyString(), anyBoolean(), anyBoolean(),
- anyBoolean(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- }
-
- public void addIntentReceiver(String action, ComponentName name) {
- mComponentNamesByAction.put(action, name);
- ActivityInfo activityInfo = new ActivityInfo();
- activityInfo.packageName = name.getPackageName();
- activityInfo.name = name.getClassName();
- mActivityInfoByComponentName.put(name, activityInfo);
}
public void putResource(int id, final String value) {
@@ -717,10 +617,6 @@
return mTelephonyManager;
}
- public NotificationManager getNotificationManager() {
- return mNotificationManager;
- }
-
private void addService(String action, ComponentName name, IInterface service) {
mComponentNamesByAction.put(action, name);
mServiceByComponentName.put(name, service);
@@ -739,14 +635,4 @@
}
return result;
}
-
- private List<ResolveInfo> doQueryIntentReceivers(Intent intent, int flags) {
- List<ResolveInfo> result = new ArrayList<>();
- for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
- ResolveInfo resolveInfo = new ResolveInfo();
- resolveInfo.activityInfo = mActivityInfoByComponentName.get(componentName);
- result.add(resolveInfo);
- }
- return result;
- }
}
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 6e6646f..46b1522 100755
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -34,7 +34,6 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.telecom.CallAudioState;
-import android.telecom.CallScreeningService;
import android.telecom.Conference;
import android.telecom.Connection;
import android.telecom.ConnectionRequest;
@@ -250,7 +249,6 @@
@Override
public void createConnectionComplete(String id, Session.Info info) throws RemoteException {
- Log.i(ConnectionServiceFixture.this, "createConnectionComplete: %s", id);
mConnectionServiceDelegateAdapter.createConnectionComplete(id, null /*Session.Info*/);
}
@@ -343,14 +341,6 @@
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 { }
@@ -438,10 +428,6 @@
@Override
public void handoverComplete(String callId, Session.Info sessionInfo) {}
-
- @Override
- public void onCallFilteringCompleted(String callId,
- Connection.CallFilteringCompletionInfo completionInfo, Session.Info sessionInfo) { }
}
FakeConnectionServiceDelegate mConnectionServiceDelegate;
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index 6cc19ad..e16b598 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -18,16 +18,12 @@
import static com.android.server.telecom.InCallController.IN_CALL_SERVICE_NOTIFICATION_ID;
import static com.android.server.telecom.InCallController.NOTIFICATION_TAG;
-import static com.android.server.telecom.tests.TelecomSystemTest.TEST_TIMEOUT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
@@ -38,29 +34,21 @@
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;
import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.UiModeManager;
-import android.content.AttributionSource;
-import android.content.AttributionSourceState;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.PermissionChecker;
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;
@@ -69,20 +57,16 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Process;
import android.os.UserHandle;
-import android.permission.PermissionCheckerManager;
-import android.telecom.CallAudioState;
import android.telecom.InCallService;
+import android.telecom.Log;
import android.telecom.ParcelableCall;
import android.telecom.PhoneAccountHandle;
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.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.telecom.IInCallAdapter;
import com.android.internal.telecom.IInCallService;
import com.android.server.telecom.Analytics;
@@ -107,18 +91,13 @@
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
import org.mockito.invocation.InvocationOnMock;
-import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;
import java.util.Collections;
import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
import java.util.concurrent.CompletableFuture;
@RunWith(JUnit4.class)
@@ -128,10 +107,8 @@
@Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
@Mock SystemStateHelper mMockSystemStateHelper;
@Mock PackageManager mMockPackageManager;
- @Mock PermissionCheckerManager mMockPermissionCheckerManager;
@Mock Call mMockCall;
@Mock Resources mMockResources;
- @Mock AppOpsManager mMockAppOpsManager;
@Mock MockContext mMockContext;
@Mock Timeouts.Adapter mTimeoutsAdapter;
@Mock DefaultDialerCache mDefaultDialerCache;
@@ -139,7 +116,6 @@
@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";
@@ -157,13 +133,6 @@
private static final String CAR2_CLASS = "carcls";
private static final int CAR_UID = 4;
private static final int CAR2_UID = 5;
- 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");
@@ -171,8 +140,6 @@
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
@@ -181,7 +148,6 @@
MockitoAnnotations.initMocks(this);
when(mMockCall.getAnalytics()).thenReturn(new Analytics.CallInfo());
doReturn(mMockResources).when(mMockContext).getResources();
- doReturn(mMockAppOpsManager).when(mMockContext).getSystemService(AppOpsManager.class);
doReturn(SYS_PKG).when(mMockResources).getString(
com.android.internal.R.string.config_defaultDialer);
doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class);
@@ -192,23 +158,11 @@
mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, mDefaultDialerCache,
mTimeoutsAdapter);
when(mMockCallsManager.getRoleManagerAdapter()).thenReturn(mMockRoleManagerAdapter);
- when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
- .thenReturn(mNotificationManager);
- when(mMockContext.getSystemService(eq(PermissionCheckerManager.class)))
- .thenReturn(mMockPermissionCheckerManager);
- when(mMockPackageManager.getPermissionInfo(anyString(), anyInt())).thenReturn(
- mMockPermissionInfo);
- when(mMockContext.getAttributionSource()).thenReturn(new AttributionSource(Process.myUid(),
- "com.android.server.telecom.tests", null));
mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter,
- mEmergencyCallHelper, mCarModeTracker, mClockProxy);
-
- ArgumentCaptor<SystemStateHelper.SystemStateListener> systemStateListenerArgumentCaptor
- = ArgumentCaptor.forClass(SystemStateHelper.SystemStateListener.class);
- verify(mMockSystemStateHelper).addListener(systemStateListenerArgumentCaptor.capture());
- mSystemStateListener = systemStateListenerArgumentCaptor.getValue();
-
+ mEmergencyCallHelper, new CarModeTracker(), mClockProxy);
+ when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
+ .thenReturn(mNotificationManager);
// Companion Apps don't have CONTROL_INCALL_EXPERIENCE permission.
doAnswer(invocation -> {
int uid = invocation.getArgument(0);
@@ -223,45 +177,18 @@
return new String[] { CAR_PKG };
case CAR2_UID:
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());
-
- when(mMockPermissionCheckerManager.checkPermission(
+ when(mMockPackageManager.checkPermission(
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
- matchesAttributionSourcePackage(COMPANION_PKG), nullable(String.class),
- anyBoolean(), anyBoolean(), anyBoolean(), anyInt()))
- .thenReturn(PackageManager.PERMISSION_DENIED);
-
- when(mMockPermissionCheckerManager.checkPermission(
+ matches(COMPANION_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
+ when(mMockPackageManager.checkPermission(
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
- matchesAttributionSourcePackage(CAR_PKG), nullable(String.class),
- anyBoolean(), anyBoolean(), anyBoolean(), anyInt()))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
-
- when(mMockPermissionCheckerManager.checkPermission(
+ matches(CAR_PKG))).thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mMockPackageManager.checkPermission(
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
- matchesAttributionSourcePackage(CAR2_PKG), nullable(String.class),
- anyBoolean(), anyBoolean(), anyBoolean(), anyInt()))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
-
- when(mMockPermissionCheckerManager.checkPermission(
- matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
- matchesAttributionSourcePackage(NONUI_PKG), nullable(String.class),
- anyBoolean(), anyBoolean(), anyBoolean(), anyInt()))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
-
- when(mMockPermissionCheckerManager.checkPermission(
- matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
- matchesAttributionSourcePackage(APPOP_NONUI_PKG), nullable(String.class),
- anyBoolean(), anyBoolean(), anyBoolean(), anyInt()))
- .thenReturn(PackageManager.PERMISSION_DENIED);
-
- when(mMockCallsManager.getAudioState()).thenReturn(new CallAudioState(false, 0, 0));
+ matches(CAR2_PKG))).thenReturn(PackageManager.PERMISSION_GRANTED);
}
@Override
@@ -272,63 +199,6 @@
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.isCarModeOrProjectionActive()).thenReturn(true);
-
- mSystemStateListener.onCarModeChanged(666, CAR_PKG, true);
- verify(mCarModeTracker).handleEnterCarMode(666, CAR_PKG);
- assertTrue(mCarModeTracker.isInCarMode());
-
- mSystemStateListener.onPackageUninstalled(CAR_PKG);
- verify(mCarModeTracker).forceRemove(CAR_PKG);
- assertFalse(mCarModeTracker.isInCarMode());
- }
-
- /**
- * Ensure that if we remove a random unrelated app we don't exit car mode.
- */
- @SmallTest
- @Test
- public void testRandomAppRemovalInCarMode() {
- setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
- when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
- when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
-
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
-
- mSystemStateListener.onCarModeChanged(666, CAR_PKG, true);
- verify(mCarModeTracker).handleEnterCarMode(666, CAR_PKG);
- assertTrue(mCarModeTracker.isInCarMode());
-
- mSystemStateListener.onPackageUninstalled("com.foo.test");
- verify(mCarModeTracker, never()).forceRemove(CAR_PKG);
- assertTrue(mCarModeTracker.isInCarMode());
- }
-
- @SmallTest
- @Test
- public void testAutomotiveProjectionAppRemoval() {
- setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
- when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
- when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
-
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
-
- mSystemStateListener.onAutomotiveProjectionStateSet(CAR_PKG);
- verify(mCarModeTracker).handleSetAutomotiveProjection(CAR_PKG);
- assertTrue(mCarModeTracker.isInCarMode());
-
- mSystemStateListener.onPackageUninstalled(CAR_PKG);
- verify(mCarModeTracker).forceRemove(CAR_PKG);
- assertFalse(mCarModeTracker.isInCarMode());
- }
-
@MediumTest
@Test
public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
@@ -421,8 +291,7 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
- eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -481,8 +350,7 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
- eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -514,7 +382,7 @@
// Pretend that the call has gone away.
when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
mInCallController.onCallRemoved(mMockCall);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(new Handler(Looper.getMainLooper()), TelecomSystemTest.TEST_TIMEOUT);
verify(mMockPackageManager).revokeRuntimePermission(eq(SYS_PKG),
eq(Manifest.permission.ACCESS_FINE_LOCATION), eq(mUserHandle));
@@ -560,8 +428,7 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
- eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -643,8 +510,7 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
- eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -715,7 +581,6 @@
any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
.thenReturn(true);
when(mMockContext.getApplicationInfo()).thenReturn(applicationInfo);
- when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
@@ -742,7 +607,7 @@
verify(mNotificationManager).notify(eq(NOTIFICATION_TAG),
eq(IN_CALL_SERVICE_NOTIFICATION_ID), any(Notification.class));
- verify(mCallInfo).addInCallService(eq(defDialerComponentName.flattenToShortString()),
+ verify(mCallInfo).addInCallService(eq(sysDialerComponentName.flattenToShortString()),
anyInt(), anyLong(), eq(true));
ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class);
@@ -752,7 +617,6 @@
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
| Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
eq(UserHandle.CURRENT));
- assertEquals(sysDialerComponentName, bindIntentCaptor2.getValue().getComponent());
}
/**
@@ -770,8 +634,7 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
- eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -861,7 +724,7 @@
setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
// Enable car mode
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true);
// Now bind; we should only bind to one app.
@@ -891,7 +754,7 @@
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
matches(CAR_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
// Enable car mode
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
// Register the fact that the invalid app entered car mode.
mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true);
@@ -909,85 +772,6 @@
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 {
- final MockitoSession mockitoSession = ExtendedMockito.mockitoSession()
- .strictness(Strictness.WARN)
- .spyStatic(PermissionChecker.class)
- .startMocking();
- try {
- 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
- ExtendedMockito.doReturn(PermissionChecker.PERMISSION_GRANTED).when(() ->
- PermissionChecker.checkPermissionForDataDeliveryFromDataSource(
- any(Context.class), eq(Manifest.permission.MANAGE_ONGOING_CALLS),
- anyInt(), any(AttributionSource.class), nullable(String.class)));
-
- // 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);
- } finally {
- mockitoSession.finishMocking();
- }
- }
-
- /**
- * 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 {
@@ -1032,31 +816,6 @@
*/
@MediumTest
@Test
- public void testRandomAppRemovalWhenNotInCarMode() throws Exception {
- setupMocks(true /* isExternalCall */);
- setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
- // Bind to default dialer.
- mInCallController.bindToServices(mMockCall);
-
- // Uninstall an unrelated app.
- mSystemStateListener.onPackageUninstalled("com.joe.stuff");
-
- // Bind InCallServices, just once; we should not re-bind to the same app.
- ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mMockContext).bindServiceAsUser(
- bindIntentCaptor.capture(),
- any(ServiceConnection.class),
- eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
- | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
- eq(UserHandle.CURRENT));
- }
-
- /**
- * Ensures that the {@link InCallController} will bind to a higher priority car mode service
- * when one becomes available.
- */
- @MediumTest
- @Test
public void testCarmodeRebindHigherPriority() throws Exception {
setupMocks(true /* isExternalCall */);
setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
@@ -1064,7 +823,7 @@
mInCallController.bindToServices(mMockCall);
// Enable car mode and enter car mode at default priority.
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true);
// And change to the second car mode app.
@@ -1125,15 +884,13 @@
nullable(ContentResolver.class))).thenReturn(500L);
when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
- setupMockPackageManager(true /* default */, true /* nonui */, false /* appop_nonui */ ,
- true /* system */, false /* external calls */,
- false /* self mgd in default*/, false /* self mgd in car*/);
+ setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
ArgumentCaptor.forClass(ServiceConnection.class);
- verify(mMockContext, times(2)).bindServiceAsUser(
+ verify(mMockContext, times(1)).bindServiceAsUser(
bindIntentCaptor.capture(),
serviceConnectionCaptor.capture(),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
@@ -1146,39 +903,13 @@
// Start the connection, make sure we don't unbind, and make sure that we don't send
// anything to the in-call service yet.
- List<ServiceConnection> serviceConnections = serviceConnectionCaptor.getAllValues();
- List<Intent> intents = bindIntentCaptor.getAllValues();
-
- // Find the non-ui service and have it connect first.
- int nonUiIdx = findFirstIndexMatching(intents,
- i -> NONUI_PKG.equals(i.getComponent().getPackageName()));
- if (nonUiIdx < 0) {
- fail("Did not bind to non-ui incall");
- }
-
- {
- ComponentName nonUiComponentName = new ComponentName(NONUI_PKG, NONUI_CLASS);
- IBinder mockBinder = mock(IBinder.class);
- IInCallService mockInCallService = mock(IInCallService.class);
- when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
- serviceConnections.get(nonUiIdx).onServiceConnected(nonUiComponentName, mockBinder);
-
- // Make sure the non-ui binding didn't trigger the future.
- assertFalse(bindTimeout.isDone());
- }
-
- int defDialerIdx = findFirstIndexMatching(intents,
- i -> DEF_PKG.equals(i.getComponent().getPackageName()));
- if (defDialerIdx < 0) {
- fail("Did not bind to default dialer incall");
- }
-
+ ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
IBinder mockBinder = mock(IBinder.class);
IInCallService mockInCallService = mock(IInCallService.class);
when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
- serviceConnections.get(defDialerIdx).onServiceConnected(defDialerComponentName, mockBinder);
+ serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
verify(mockInCallService).setInCallAdapter(nullable(IInCallAdapter.class));
// Make sure that the future completed without timing out.
@@ -1211,7 +942,7 @@
// Now switch to car mode.
// Enable car mode and enter car mode at default priority.
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true);
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -1251,7 +982,7 @@
// Now switch to car mode.
// Enable car mode and enter car mode at default priority.
- when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true);
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true);
// We currently will bind to the car-mode InCallService even if there are no calls available
@@ -1296,7 +1027,6 @@
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,
@@ -1308,7 +1038,6 @@
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);
@@ -1336,7 +1065,6 @@
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);
@@ -1358,7 +1086,6 @@
serviceInfo.name = SYS_CLASS;
serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.applicationInfo.uid = SYS_UID;
- serviceInfo.enabled = true;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
}};
}
@@ -1370,43 +1097,13 @@
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(boolean supportsSelfManaged) {
- return new ResolveInfo() {{
- serviceInfo = new ServiceInfo();
- serviceInfo.packageName = NONUI_PKG;
- serviceInfo.name = NONUI_CLASS;
- serviceInfo.applicationInfo = new ApplicationInfo();
- 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, false, useSystemDialer, includeExternalCalls,
+ setupMockPackageManager(useDefaultDialer, useSystemDialer, includeExternalCalls,
false /* self mgd */, false /* self mgd */);
}
@@ -1414,28 +1111,6 @@
final boolean useSystemDialer, final boolean includeExternalCalls,
final boolean includeSelfManagedCallsInDefaultDialer,
final boolean includeSelfManagedCallsInCarModeDialer) {
- setupMockPackageManager(useDefaultDialer, false /* nonui */, false /* appop_nonui */,
- useSystemDialer, includeExternalCalls, includeSelfManagedCallsInDefaultDialer,
- includeSelfManagedCallsInCarModeDialer);
- }
-
- private void setupMockPackageManager(final boolean useDefaultDialer,
- 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 {
@@ -1470,43 +1145,11 @@
resolveInfo.add(getCarModeResolveinfo(CAR2_PKG, CAR2_CLASS,
includeExternalCalls, includeSelfManagedCallsInCarModeDialer));
}
- } else {
- // InCallController uses a blank package name when querying for non-ui incalls
- if (useNonUiInCalls) {
- 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), anyInt(), eq(CURRENT_USER_ID));
-
- if (useDefaultDialer) {
- when(mMockPackageManager
- .getComponentEnabledSetting(new ComponentName(DEF_PKG, DEF_CLASS)))
- .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
- }
-
- when(mMockPackageManager
- .getComponentEnabledSetting(new ComponentName(SYS_PKG, SYS_CLASS)))
- .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
-
- when(mMockPackageManager
- .getComponentEnabledSetting(new ComponentName(CAR_PKG, CAR_CLASS)))
- .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
-
- when(mMockPackageManager
- .getComponentEnabledSetting(new ComponentName(COMPANION_PKG, COMPANION_CLASS)))
- .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
-
- when(mMockPackageManager
- .getComponentEnabledSetting(new ComponentName(CAR2_PKG, CAR2_CLASS)))
- .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+ any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
}
private void setupMockPackageManagerLocationPermission(final String pkg,
@@ -1516,24 +1159,4 @@
? PackageManager.PERMISSION_GRANTED
: PackageManager.PERMISSION_DENIED);
}
-
- private static AttributionSourceState matchesAttributionSourcePackage(
- @Nullable String packageName) {
- return argThat(new PackageNameArgumentMatcher(packageName));
- }
-
- private static class PackageNameArgumentMatcher implements
- ArgumentMatcher<AttributionSourceState> {
- @Nullable
- private final String mPackgeName;
-
- PackageNameArgumentMatcher(@Nullable String packageName) {
- mPackgeName = packageName;
- }
-
- @Override
- public boolean matches(@NonNull AttributionSourceState attributionSource) {
- return Objects.equals(mPackgeName, attributionSource.packageName);
- }
- }
}
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
index 9269836..8c0adfb 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, timeout) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result) -> 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, timeout) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result) -> 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, timeout) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result) -> 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, timeout) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result) -> 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
new file mode 100644
index 0000000..8e2d11e
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
@@ -0,0 +1,328 @@
+/*
+ * 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 2b05430..10a0194 100644
--- a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
@@ -16,10 +16,6 @@
package com.android.server.telecom.tests;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import android.app.BroadcastOptions;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -29,8 +25,6 @@
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
@@ -49,7 +43,6 @@
import com.android.server.telecom.CallerInfoLookupHelper;
import com.android.server.telecom.Constants;
import com.android.server.telecom.DefaultDialerCache;
-import com.android.server.telecom.DeviceIdleControllerAdapter;
import com.android.server.telecom.MissedCallNotifier;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelecomBroadcastIntentProcessor;
@@ -67,23 +60,18 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
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;
@@ -137,7 +125,6 @@
}
}
- private static final long TIMEOUT_DELAY = 5000;
private static final Uri TEL_CALL_HANDLE = Uri.parse("tel:+11915552620");
private static final Uri SIP_CALL_HANDLE = Uri.parse("sip:testaddress@testdomain.com");
private static final String CALLER_NAME = "Fake Name";
@@ -145,7 +132,6 @@
private static final String MISSED_CALLS_TITLE = "Missed Calls";
private static final String MISSED_CALLS_MSG = "%s missed calls";
private static final String USER_CALL_ACTIVITY_LABEL = "Phone";
- private static final String DEFAULT_DIALER_PACKAGE = "com.android.server.telecom.test";
private static final int REQUEST_ID = 0;
private static final long CALL_TIMESTAMP;
@@ -157,9 +143,6 @@
private static final UserHandle SECONARY_USER = UserHandle.of(12);
private static final int NO_CAPABILITY = 0;
private static final int TEST_TIMEOUT = 1000;
- private static final long TEST_POWER_EXEMPT_TIME_MS = 1000;
- private static final ComponentName COMPONENT_NAME = new ComponentName(
- "com.anything", "com.whatever");
@Mock
private NotificationManager mNotificationManager;
@@ -172,7 +155,6 @@
@Mock TelecomSystem mTelecomSystem;
@Mock private DefaultDialerCache mDefaultDialerCache;
- @Mock private DeviceIdleControllerAdapter mDeviceIdleControllerAdapter;
@Override
@Before
@@ -220,49 +202,6 @@
cancelNotificationTestInternal(SECONARY_USER);
}
- @SmallTest
- @Test
- public void testDefaultDialerClear() {
- MissedCallNotifier missedCallNotifier = setupMissedCallNotificationThroughDefaultDialer();
- missedCallNotifier.clearMissedCalls(PRIMARY_USER);
-
- ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).sendBroadcastAsUser(intentArgumentCaptor.capture(), any(),
- anyString(), any());
- Intent sentIntent = intentArgumentCaptor.getValue();
- assertEquals(0, sentIntent.getIntExtra(TelecomManager.EXTRA_NOTIFICATION_COUNT, -1));
- }
-
- @SmallTest
- @Test
- public void testDefaultDialerIncrement() {
- MissedCallNotifier missedCallNotifier = setupMissedCallNotificationThroughDefaultDialer();
- PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY);
- MissedCallNotifier.CallInfo fakeCall = makeFakeCallInfo(TEL_CALL_HANDLE, CALLER_NAME,
- CALL_TIMESTAMP, phoneAccount.getAccountHandle());
-
- missedCallNotifier.showMissedCallNotification(fakeCall);
- ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).sendBroadcastAsUser(intentArgumentCaptor.capture(), any(),
- anyString(), any());
-
- Intent sentIntent = intentArgumentCaptor.getValue();
- assertEquals(1, sentIntent.getIntExtra(TelecomManager.EXTRA_NOTIFICATION_COUNT, -1));
- }
-
- private MissedCallNotifier setupMissedCallNotificationThroughDefaultDialer() {
- mComponentContextFixture.addIntentReceiver(
- TelecomManager.ACTION_SHOW_MISSED_CALLS_NOTIFICATION, COMPONENT_NAME);
- when(mDefaultDialerCache.getDefaultDialerApplication(anyInt())).thenReturn(
- DEFAULT_DIALER_PACKAGE);
-
- Notification.Builder builder1 = makeNotificationBuilder("builder1");
- Notification.Builder builder2 = makeNotificationBuilder("builder2");
- MissedCallNotifierImpl.NotificationBuilderFactory fakeBuilderFactory =
- makeNotificationBuilderFactory(builder1, builder1, builder2, builder2);
- return makeMissedCallNotifier(fakeBuilderFactory, PRIMARY_USER);
- }
-
private void cancelNotificationTestInternal(UserHandle userHandle) {
Notification.Builder builder1 = makeNotificationBuilder("builder1");
Notification.Builder builder2 = makeNotificationBuilder("builder2");
@@ -307,8 +246,7 @@
makeNotificationBuilderFactory(builders);
MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext,
- mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory,
- mDeviceIdleControllerAdapter);
+ mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory);
missedCallNotifier.showMissedCallNotification(fakeCall);
missedCallNotifier.showMissedCallNotification(fakeCall);
@@ -450,9 +388,9 @@
TelecomBroadcastReceiver.class);
assertNotNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- callBackIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
+ callBackIntent, PendingIntent.FLAG_NO_CREATE));
assertNotNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- smsIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
+ smsIntent, PendingIntent.FLAG_NO_CREATE));
}
@SmallTest
@@ -463,8 +401,7 @@
makeNotificationBuilderFactory(builder1);
MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext,
- mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory,
- mDeviceIdleControllerAdapter);
+ mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory);
PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY);
MissedCallNotifier.CallInfo fakeCall =
@@ -487,9 +424,9 @@
TelecomBroadcastReceiver.class);
assertNotNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- callBackIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
+ callBackIntent, PendingIntent.FLAG_NO_CREATE));
assertNull(PendingIntent.getBroadcast(mContext, REQUEST_ID,
- smsIntent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE));
+ smsIntent, PendingIntent.FLAG_NO_CREATE));
}
@SmallTest
@@ -508,7 +445,7 @@
CallLog.Calls.PRESENTATION_ALLOWED, CALL_TIMESTAMP)
.build();
- when(cp.query(any(), eq(queryUri), nullable(String[].class),
+ when(cp.query(anyString(), nullable(String.class), eq(queryUri), nullable(String[].class),
nullable(Bundle.class), nullable(ICancellationSignal.class)))
.thenReturn(mockMissedCallsCursor);
@@ -524,8 +461,7 @@
makeNotificationBuilderFactory(builder1);
MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext,
- mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory,
- mDeviceIdleControllerAdapter);
+ mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory);
// AsyncQueryHandler used in reloadFromDatabase interacts poorly with the below
// timeout-verify, so run this in a new handler to mitigate that.
@@ -578,7 +514,7 @@
PRIMARY_USER.getIdentifier());
IContentProvider cp = getContentProviderForUser(PRIMARY_USER.getIdentifier());
- when(cp.query(any(), eq(queryUri), nullable(String[].class),
+ when(cp.query(anyString(), nullable(String.class), eq(queryUri), nullable(String[].class),
nullable(Bundle.class), nullable(ICancellationSignal.class)))
.thenReturn(mockMissedCallsCursor);
@@ -594,8 +530,7 @@
makeNotificationBuilderFactory(builder1);
MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext,
- mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory,
- mDeviceIdleControllerAdapter);
+ mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory);
// AsyncQueryHandler used in reloadFromDatabase interacts poorly with the below
// timeout-verify, so run this in a new handler to mitigate that.
@@ -625,49 +560,6 @@
nullable(Notification.class), eq(PRIMARY_USER));
}
- @SmallTest
- @Test
- public void testDialerHandleMissedCall() {
- // Configure Notifier to send missed call intent and let dialer handle
- enableDialerHandlesMissedCall();
-
- Notification.Builder builder1 = makeNotificationBuilder("builder1");
- MissedCallNotifierImpl.NotificationBuilderFactory fakeBuilderFactory =
- makeNotificationBuilderFactory(builder1);
-
- MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext,
- mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory,
- mDeviceIdleControllerAdapter);
- PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY);
-
- MissedCallNotifier.CallInfo fakeCall =
- makeFakeCallInfo(SIP_CALL_HANDLE, CALLER_NAME, CALL_TIMESTAMP,
- phoneAccount.getAccountHandle());
- missedCallNotifier.showMissedCallNotification(fakeCall);
-
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- ArgumentCaptor<Bundle> bundleCaptor =
- ArgumentCaptor.forClass(Bundle.class);
- verify(mDeviceIdleControllerAdapter).exemptAppTemporarilyForEvent(
- eq(COMPONENT_NAME.getPackageName()), anyLong(), anyInt(), any());
- verify(mContext).sendBroadcastAsUser(
- intentCaptor.capture(),
- any(),
- eq(android.Manifest.permission.READ_PHONE_STATE), bundleCaptor.capture());
- assertNotNull("Not expecting null intent", intentCaptor.getValue());
- assertEquals("Incorrect intent received",
- TelecomManager.ACTION_SHOW_MISSED_CALLS_NOTIFICATION,
- intentCaptor.getValue().getAction());
- assertNotNull("Not expecting null options bundle", bundleCaptor.getValue());
- BroadcastOptions options = new BroadcastOptions(bundleCaptor.getValue());
- assertTrue("App must have a temporary exemption set.",
- options.getTemporaryAppAllowlistDuration() > 0);
-
- // A notification should never be posted by Telecom
- verify(mNotificationManager, never()).notifyAsUser(nullable(String.class), anyInt(),
- nullable(Notification.class), eq(PRIMARY_USER));
- }
-
private Notification.Builder makeNotificationBuilder(String label) {
Notification.Builder builder = spy(new Notification.Builder(mContext));
Notification notification = mock(Notification.class);
@@ -700,14 +592,14 @@
private MissedCallNotifier makeMissedCallNotifier(
NotificationBuilderFactory fakeBuilderFactory, UserHandle currentUser) {
MissedCallNotifier missedCallNotifier = new MissedCallNotifierImpl(mContext,
- mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory,
- mDeviceIdleControllerAdapter);
+ mPhoneAccountRegistrar, mDefaultDialerCache, fakeBuilderFactory);
missedCallNotifier.setCurrentUserHandle(currentUser);
return missedCallNotifier;
}
private PhoneAccount makePhoneAccount(UserHandle userHandle, int capability) {
- PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(COMPONENT_NAME, "id",
+ ComponentName componentName = new ComponentName("com.anything", "com.whatever");
+ PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(componentName, "id",
userHandle);
PhoneAccount.Builder builder = new PhoneAccount.Builder(phoneAccountHandle, "test");
builder.setCapabilities(capability);
@@ -717,13 +609,6 @@
return phoneAccount;
}
- private void enableDialerHandlesMissedCall() {
- doReturn(COMPONENT_NAME.getPackageName()).when(mDefaultDialerCache).
- getDefaultDialerApplication(anyInt());
- mComponentContextFixture.addIntentReceiver(
- TelecomManager.ACTION_SHOW_MISSED_CALLS_NOTIFICATION, COMPONENT_NAME);
- }
-
private IContentProvider getContentProviderForUser(int userId) {
return mContext.getContentResolver().acquireProvider(userId + "@call_log");
}
diff --git a/tests/src/com/android/server/telecom/tests/MissedInformationTest.java b/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
deleted file mode 100644
index a8e1c5f..0000000
--- a/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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 e6c6bac..9470008 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -110,7 +110,7 @@
when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(
any(PhoneAccountHandle.class))).thenReturn(mPhoneAccount);
when(mPhoneAccount.isSelfManaged()).thenReturn(true);
- when(mSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(false);
+ when(mSystemStateHelper.isCarMode()).thenReturn(false);
}
@Override
@@ -229,7 +229,7 @@
mComponentContextFixture.putResource(R.string.dialer_default_class,
dialer_default_class_string);
when(mDefaultDialerCache.getSystemDialerApplication()).thenReturn(ui_package_string);
- when(mDefaultDialerCache.getDialtactsSystemDialerComponent()).thenReturn(
+ when(mDefaultDialerCache.getSystemDialerComponent()).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/ParcelableCallUtilsTest.java b/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
index a503283..6c941fe 100644
--- a/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
+++ b/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
@@ -1,12 +1,13 @@
package com.android.server.telecom.tests;
-import static com.android.server.telecom.TelecomSystem.SyncRoot;
+import static com.android.server.telecom.TelecomSystem.*;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
@@ -16,7 +17,6 @@
import android.telecom.Connection;
import android.telecom.ParcelableCall;
import android.telecom.PhoneAccountHandle;
-import android.telephony.ims.ImsCallProfile;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.Call;
@@ -26,6 +26,7 @@
import com.android.server.telecom.ParcelableCallUtils;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneNumberUtilsAdapter;
+import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.ui.ToastFactory;
import org.junit.After;
@@ -97,7 +98,6 @@
Bundle parceledExtras = call.getExtras();
assertFalse(parceledExtras.containsKey(Connection.EXTRA_SIP_INVITE));
- assertTrue(parceledExtras.containsKey(ImsCallProfile.EXTRA_IS_BUSINESS_CALL));
assertFalse(parceledExtras.containsKey("SomeExtra"));
assertTrue(parceledExtras.containsKey(Connection.EXTRA_CALL_SUBJECT));
}
@@ -115,7 +115,6 @@
Bundle parceledExtras = call.getExtras();
assertTrue(parceledExtras.containsKey(Connection.EXTRA_SIP_INVITE));
- assertTrue(parceledExtras.containsKey(ImsCallProfile.EXTRA_IS_BUSINESS_CALL));
assertTrue(parceledExtras.containsKey("SomeExtra"));
assertTrue(parceledExtras.containsKey(Connection.EXTRA_CALL_SUBJECT));
}
@@ -129,7 +128,6 @@
Bundle parceledExtras = call.getExtras();
assertTrue(parceledExtras.containsKey(Connection.EXTRA_SIP_INVITE));
- assertTrue(parceledExtras.containsKey(ImsCallProfile.EXTRA_IS_BUSINESS_CALL));
assertFalse(parceledExtras.containsKey("SomeExtra"));
assertFalse(parceledExtras.containsKey(Connection.EXTRA_CALL_SUBJECT));
}
@@ -143,7 +141,6 @@
Bundle parceledExtras = call.getExtras();
assertFalse(parceledExtras.containsKey(Connection.EXTRA_SIP_INVITE));
- assertFalse(parceledExtras.containsKey(ImsCallProfile.EXTRA_IS_BUSINESS_CALL));
assertFalse(parceledExtras.containsKey("SomeExtra"));
assertFalse(parceledExtras.containsKey(Connection.EXTRA_CALL_SUBJECT));
}
@@ -195,7 +192,6 @@
extras.putString(Connection.EXTRA_SIP_INVITE, "scary data");
extras.putString("SomeExtra", "Extra Extra");
extras.putString(Connection.EXTRA_CALL_SUBJECT, "Blah");
- extras.putBoolean(ImsCallProfile.EXTRA_IS_BUSINESS_CALL, true);
return extras;
}
}
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index a56036a..00ef87c 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -725,20 +725,16 @@
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(account1Extras)
+ .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "A"))
.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(account2Extras)
+ .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "B"))
.build();
PhoneAccount account3 = new PhoneAccount.Builder(
@@ -818,23 +814,18 @@
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(account1Extras)
+ .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "2"))
.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(account2Extras)
+ .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "1"))
.build();
PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(
diff --git a/tests/src/com/android/server/telecom/tests/RingerTest.java b/tests/src/com/android/server/telecom/tests/RingerTest.java
index 0e93481..38f63d2 100644
--- a/tests/src/com/android/server/telecom/tests/RingerTest.java
+++ b/tests/src/com/android/server/telecom/tests/RingerTest.java
@@ -79,16 +79,6 @@
}
@Override
- public VibrationEffect resolve(int defaultAmplitude) {
- return this;
- }
-
- @Override
- public VibrationEffect scale(float scaleFactor) {
- return this;
- }
-
- @Override
public void validate() {
// not needed
}
diff --git a/tests/src/com/android/server/telecom/tests/SessionTest.java b/tests/src/com/android/server/telecom/tests/SessionTest.java
index 4be3dad..6a14a64 100644
--- a/tests/src/com/android/server/telecom/tests/SessionTest.java
+++ b/tests/src/com/android/server/telecom/tests/SessionTest.java
@@ -173,36 +173,6 @@
}
/**
- * Ensure creating two sessions and setting the child as the parent to itself doesn't cause a
- * crash due to infinite recursion.
- */
- @SmallTest
- @Test
- public void testRecursion_toString_childCircDep() {
- Log.startSession("testParent");
- // Running in the same thread, so mark as invisible subsession
- Session childSession = Log.getSessionManager()
- .createSubsession(true /*isStartedFromActiveSession*/);
- Log.continueSession(childSession, "child");
- Session parentSession = childSession.getParentSession();
- // Create a circular dependency and ensure we do not crash
- childSession.setParentSession(childSession);
-
- // Make sure calling these methods does not result in a crash
- try {
- parentSession.toString();
- childSession.toString();
- } catch (Exception e) {
- fail("Exception: " + e.getMessage());
- } finally {
- // End child
- Log.endSession();
- // End parent
- Log.endSession();
- }
- }
-
- /**
* Ensure creating two sessions that are parent/child of each other does not lead to a crash
* or infinite recursion when using Session#getInfo.
*/
diff --git a/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java b/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
index dc7d1fd..2de3c83 100644
--- a/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
+++ b/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
@@ -16,8 +16,6 @@
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;
@@ -25,11 +23,9 @@
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;
@@ -43,12 +39,10 @@
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;
import com.android.server.telecom.SystemStateHelper.SystemStateListener;
-import com.android.server.telecom.TelecomSystem;
import org.junit.After;
import org.junit.Before;
@@ -59,11 +53,11 @@
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.util.List;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
/**
* Unit tests for SystemStateHelper
@@ -79,7 +73,6 @@
@Mock SensorManager mSensorManager;
@Mock Intent mIntentEnter;
@Mock Intent mIntentExit;
- TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
@Override
@Before
@@ -94,8 +87,6 @@
when(mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)).thenReturn(mGravitySensor);
when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn(mProxSensor);
- doReturn(mUiModeManager).when(mContext).getSystemService(UiModeManager.class);
-
mComponentContextFixture.putFloatResource(
R.dimen.device_on_ear_xy_gravity_threshold, 5.5f);
mComponentContextFixture.putFloatResource(
@@ -111,7 +102,7 @@
@SmallTest
@Test
public void testListeners() throws Exception {
- SystemStateHelper systemStateHelper = new SystemStateHelper(mContext, mLock);
+ SystemStateHelper systemStateHelper = new SystemStateHelper(mContext);
assertFalse(systemStateHelper.removeListener(mSystemStateListener));
systemStateHelper.addListener(mSystemStateListener);
@@ -122,104 +113,31 @@
@SmallTest
@Test
public void testQuerySystemForCarMode_True() {
+ when(mContext.getSystemService(Context.UI_MODE_SERVICE)).thenReturn(mUiModeManager);
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
- assertTrue(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
+ assertTrue(new SystemStateHelper(mContext).isCarMode());
}
@SmallTest
@Test
public void testQuerySystemForCarMode_False() {
+ when(mContext.getSystemService(Context.UI_MODE_SERVICE)).thenReturn(mUiModeManager);
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_NORMAL);
- assertFalse(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
- }
-
- @SmallTest
- @Test
- public void testQuerySystemForAutomotiveProjection_True() {
- when(mUiModeManager.getActiveProjectionTypes())
- .thenReturn(UiModeManager.PROJECTION_TYPE_AUTOMOTIVE);
- assertTrue(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
-
- when(mUiModeManager.getActiveProjectionTypes())
- .thenReturn(UiModeManager.PROJECTION_TYPE_ALL);
- assertTrue(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
- }
-
- @SmallTest
- @Test
- public void testQuerySystemForAutomotiveProjection_False() {
- when(mUiModeManager.getActiveProjectionTypes())
- .thenReturn(UiModeManager.PROJECTION_TYPE_NONE);
- assertFalse(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
- }
-
- @SmallTest
- @Test
- public void testQuerySystemForAutomotiveProjectionAndCarMode_True() {
- when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
- when(mUiModeManager.getActiveProjectionTypes())
- .thenReturn(UiModeManager.PROJECTION_TYPE_AUTOMOTIVE);
- assertTrue(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
- }
-
- @SmallTest
- @Test
- public void testQuerySystemForAutomotiveProjectionOrCarMode_nullService() {
- when(mContext.getSystemService(UiModeManager.class))
- .thenReturn(mUiModeManager) // Without this, class construction will throw NPE.
- .thenReturn(null);
- assertFalse(new SystemStateHelper(mContext, mLock).isCarModeOrProjectionActive());
- }
-
- @SmallTest
- @Test
- public void testPackageRemoved() {
- ArgumentCaptor<BroadcastReceiver> receiver =
- ArgumentCaptor.forClass(BroadcastReceiver.class);
- new SystemStateHelper(mContext, mLock).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");
+ assertFalse(new SystemStateHelper(mContext).isCarMode());
}
@SmallTest
@Test
public void testReceiverAndIntentFilter() {
- ArgumentCaptor<IntentFilter> intentFilterCaptor =
- ArgumentCaptor.forClass(IntentFilter.class);
- new SystemStateHelper(mContext, mLock);
- verify(mContext, times(2)).registerReceiver(
- any(BroadcastReceiver.class), intentFilterCaptor.capture());
+ ArgumentCaptor<IntentFilter> intentFilter = ArgumentCaptor.forClass(IntentFilter.class);
+ new SystemStateHelper(mContext);
+ verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.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);
- }
+ 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
@@ -227,10 +145,9 @@
public void testOnEnterExitCarMode() {
ArgumentCaptor<BroadcastReceiver> receiver =
ArgumentCaptor.forClass(BroadcastReceiver.class);
- new SystemStateHelper(mContext, mLock).addListener(mSystemStateListener);
+ new SystemStateHelper(mContext).addListener(mSystemStateListener);
- verify(mContext, atLeastOnce())
- .registerReceiver(receiver.capture(), any(IntentFilter.class));
+ verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
when(mIntentEnter.getAction()).thenReturn(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
receiver.getValue().onReceive(mContext, mIntentEnter);
@@ -245,40 +162,6 @@
@SmallTest
@Test
- public void testOnSetReleaseAutomotiveProjection() {
- SystemStateHelper systemStateHelper = new SystemStateHelper(mContext, mLock);
- // We don't care what listener is registered, that's an implementation detail, but we need
- // to call methods on whatever it is.
- ArgumentCaptor<UiModeManager.OnProjectionStateChangedListener> listenerCaptor =
- ArgumentCaptor.forClass(UiModeManager.OnProjectionStateChangedListener.class);
- verify(mUiModeManager).addOnProjectionStateChangedListener(
- eq(UiModeManager.PROJECTION_TYPE_AUTOMOTIVE), any(), listenerCaptor.capture());
- systemStateHelper.addListener(mSystemStateListener);
-
- String packageName1 = "Sufjan Stevens";
- String packageName2 = "The Ascension";
-
- // Should pay attention to automotive projection, though.
- listenerCaptor.getValue().onProjectionStateChanged(
- UiModeManager.PROJECTION_TYPE_AUTOMOTIVE, Set.of(packageName2));
- verify(mSystemStateListener).onAutomotiveProjectionStateSet(packageName2);
-
- // Without any automotive projection, it should see it as released.
- listenerCaptor.getValue().onProjectionStateChanged(
- UiModeManager.PROJECTION_TYPE_NONE, Set.of());
- verify(mSystemStateListener).onAutomotiveProjectionStateReleased();
-
- // Try the whole thing again, with different values.
- listenerCaptor.getValue().onProjectionStateChanged(
- UiModeManager.PROJECTION_TYPE_AUTOMOTIVE, Set.of(packageName1));
- verify(mSystemStateListener).onAutomotiveProjectionStateSet(packageName1);
- listenerCaptor.getValue().onProjectionStateChanged(
- UiModeManager.PROJECTION_TYPE_AUTOMOTIVE, Set.of());
- verify(mSystemStateListener, times(2)).onAutomotiveProjectionStateReleased();
- }
-
- @SmallTest
- @Test
public void testDeviceOnEarCorrectlyDetected() {
doAnswer(invocation -> {
SensorEventListener listener = invocation.getArgument(0);
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 3cec50b..0dfe29a 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -460,10 +460,10 @@
@Test
public void testGetPhoneAccount() throws RemoteException {
makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
- assertEquals(TEL_PA_HANDLE_16, mTSIBinder.getPhoneAccount(TEL_PA_HANDLE_16,
- mContext.getPackageName()).getAccountHandle());
- assertEquals(SIP_PA_HANDLE_17, mTSIBinder.getPhoneAccount(SIP_PA_HANDLE_17,
- mContext.getPackageName()).getAccountHandle());
+ assertEquals(TEL_PA_HANDLE_16, mTSIBinder.getPhoneAccount(TEL_PA_HANDLE_16)
+ .getAccountHandle());
+ assertEquals(SIP_PA_HANDLE_17, mTSIBinder.getPhoneAccount(SIP_PA_HANDLE_17)
+ .getAccountHandle());
}
@SmallTest
@@ -1202,39 +1202,6 @@
}
/**
- * Ensure self-managed calls cannot be ended using {@link TelecomManager#endCall()}.
- * @throws Exception
- */
- @SmallTest
- @Test
- public void testCannotEndSelfManagedCall() throws Exception {
- Call call = mock(Call.class);
- when(call.isSelfManaged()).thenReturn(true);
- when(call.getState()).thenReturn(CallState.ACTIVE);
- when(mFakeCallsManager.getFirstCallWithState(any()))
- .thenReturn(call);
- assertFalse(mTSIBinder.endCall(TEST_PACKAGE));
- verify(mFakeCallsManager, never()).disconnectCall(eq(call));
- }
-
- /**
- * Ensure self-managed calls cannot be answered using {@link TelecomManager#acceptRingingCall()}
- * or {@link TelecomManager#acceptRingingCall(int)}.
- * @throws Exception
- */
- @SmallTest
- @Test
- public void testCannotAnswerSelfManagedCall() throws Exception {
- Call call = mock(Call.class);
- when(call.isSelfManaged()).thenReturn(true);
- when(call.getState()).thenReturn(CallState.ACTIVE);
- when(mFakeCallsManager.getFirstCallWithState(any()))
- .thenReturn(call);
- mTSIBinder.acceptRingingCall(TEST_PACKAGE);
- verify(mFakeCallsManager, never()).answerCall(eq(call), anyInt());
- }
-
- /**
* Register phone accounts for the supplied PhoneAccountHandles to make them
* visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.
* @param handles the handles for which phone accounts should be created for.
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 7f462d4..442c310 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -38,7 +38,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -69,6 +68,7 @@
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;
@@ -78,7 +78,6 @@
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceFocusManager;
import com.android.server.telecom.ContactsAsyncHelper;
-import com.android.server.telecom.DeviceIdleControllerAdapter;
import com.android.server.telecom.HeadsetMediaButton;
import com.android.server.telecom.HeadsetMediaButtonFactory;
import com.android.server.telecom.InCallWakeLockController;
@@ -95,6 +94,8 @@
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;
@@ -200,12 +201,12 @@
@Mock HeadsetMediaButton mHeadsetMediaButton;
@Mock ProximitySensorManager mProximitySensorManager;
@Mock InCallWakeLockController mInCallWakeLockController;
+ @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
@Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
@Mock IncomingCallNotifier mIncomingCallNotifier;
@Mock ClockProxy mClockProxy;
@Mock RoleManagerAdapter mRoleManagerAdapter;
@Mock ToneGenerator mToneGenerator;
- @Mock DeviceIdleControllerAdapter mDeviceIdleControllerAdapter;
final ComponentName mInCallServiceComponentNameX =
new ComponentName(
@@ -347,8 +348,6 @@
doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
doNothing().when(mSpyContext).sendBroadcastAsUser(any(), any(), any());
- doReturn(mock(AppOpsManager.class)).when(mSpyContext).getSystemService(AppOpsManager.class);
-
mHandlerThread = new HandlerThread("TelecomHandlerThread");
mHandlerThread.start();
@@ -365,7 +364,7 @@
// Next, create the TelecomSystem, our system under test
setupTelecomSystem();
- // Need to reset testing tag here
+ // Need to reset teseting tag here
Log.setTag(TESTING_TAG);
// Finally, register the ConnectionServices with the PhoneAccountRegistrar of the
@@ -401,9 +400,11 @@
mConnectionServiceFixtureA.waitForHandlerToClear();
mConnectionServiceFixtureB.waitForHandlerToClear();
- // Forcefully clean all sessions at the end of the test, which will also log any stale
- // sessions for debugging.
- Log.getSessionManager().cleanupStaleSessions(0);
+ // Print out any incomplete sessions for debugging tests
+ String sessions = Log.getSessionManager().printActiveSessions();
+ if (!TextUtils.isEmpty(sessions)) {
+ Log.w(this, "Active Sessions:\n" + sessions);
+ }
mTelecomSystem = null;
super.tearDown();
@@ -474,13 +475,13 @@
when(mRoleManagerAdapter.getDefaultCallScreeningApp()).thenReturn(null);
mTelecomSystem = new TelecomSystem(
mComponentContextFixture.getTestDouble(),
- (context, phoneAccountRegistrar, defaultDialerCache, mDeviceIdleControllerAdapter)
- -> mMissedCallNotifier,
+ (context, phoneAccountRegistrar, defaultDialerCache) -> mMissedCallNotifier,
mCallerInfoAsyncQueryFactoryFixture.getTestDouble(),
headsetMediaButtonFactory,
proximitySensorManagerFactory,
inCallWakeLockControllerFactory,
() -> mAudioService,
+ (context, lock, callsManager, phoneAccountRegistrar) -> mBluetoothPhoneServiceImpl,
mConnServFMFactory,
mTimeoutsAdapter,
mAsyncRingtonePlayer,
@@ -518,13 +519,23 @@
},
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(
ContactsAsyncHelper.ContentResolverAdapter adapter) {
return new ContactsAsyncHelper(adapter, mHandlerThread.getLooper());
}
- }, mDeviceIdleControllerAdapter);
+ });
mComponentContextFixture.setTelecomManager(new TelecomManager(
mComponentContextFixture.getTestDouble(),
@@ -914,12 +925,7 @@
// 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());
@@ -1105,54 +1111,6 @@
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) {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
index 264e087..b0b1ec0 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
@@ -25,10 +25,8 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
public abstract class TelecomTestCase {
protected static final String TESTING_TAG = "Telecom-TEST";
@@ -77,13 +75,4 @@
}
}
}
-
- protected static <T> int findFirstIndexMatching(List<T> items, Predicate<T> matcher) {
- for (int i = 0; i < items.size(); i++) {
- if (matcher.test(items.get(i))) {
- return i;
- }
- }
- return -1;
- }
}