Merge mainline-release 6664920 to master - DO NOT MERGE
Merged-In: Ie5bbc8016e0bbb155e411f164c755f1905d49295
Change-Id: I3aa42cc7bd77e7ee42ed7bdbd267e346b691f923
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7c57599..327d0a2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,80 +15,75 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- package="com.android.server.telecom"
- coreApp="true"
- android:sharedUserId="android.uid.system">
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ package="com.android.server.telecom"
+ coreApp="true"
+ android:sharedUserId="android.uid.system">
- <protected-broadcast android:name="android.intent.action.SHOW_MISSED_CALLS_NOTIFICATION" />
- <protected-broadcast android:name="com.android.server.telecom.MESSAGE_SENT" />
+ <protected-broadcast android:name="android.intent.action.SHOW_MISSED_CALLS_NOTIFICATION"/>
+ <protected-broadcast android:name="com.android.server.telecom.MESSAGE_SENT"/>
<!-- Prevents the activity manager from delaying any activity-start
requests by this package, including requests immediately after
the user presses "home". -->
- <uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE" />
- <uses-permission android:name="android.permission.BIND_INCALL_SERVICE" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO" />
- <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION" />
- <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
- <uses-permission android:name="android.permission.HANDLE_CALL_INTENT" />
- <uses-permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
- <uses-permission android:name="android.permission.MANAGE_USERS" />
- <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE"/>
+ <uses-permission android:name="android.permission.BIND_INCALL_SERVICE"/>
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+ <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO"/>
+ <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION"/>
+ <uses-permission android:name="android.permission.CALL_PRIVILEGED"/>
+ <uses-permission android:name="android.permission.HANDLE_CALL_INTENT"/>
+ <uses-permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
+ <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS"/>
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<!-- Required to determine source of ongoing audio recordings. -->
- <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- <uses-permission android:name="android.permission.READ_CALL_LOG" />
- <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.SEND_SMS" />
- <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
- <uses-permission android:name="android.permission.VIBRATE" />
- <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="android.permission.READ_BLOCKED_NUMBERS" />
- <uses-permission android:name="android.permission.WRITE_BLOCKED_NUMBERS" />
- <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING"/>
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.SEND_SMS"/>
+ <uses-permission android:name="android.permission.STOP_APP_SWITCHES"/>
+ <uses-permission android:name="android.permission.VIBRATE"/>
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
+ <uses-permission android:name="android.permission.READ_BLOCKED_NUMBERS"/>
+ <uses-permission android:name="android.permission.WRITE_BLOCKED_NUMBERS"/>
+ <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
- <permission
- android:name="android.permission.BROADCAST_CALLLOG_INFO"
- android:label="Broadcast the call type/duration information"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.BROADCAST_CALLLOG_INFO"
+ android:label="Broadcast the call type/duration information"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.PROCESS_CALLLOG_INFO"
- android:label="Register to handle the broadcasted call type/duration information"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.PROCESS_CALLLOG_INFO"
+ android:label="Register to handle the broadcasted call type/duration information"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION"
- android:label="Broadcast phone account registration"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION"
+ android:label="Broadcast phone account registration"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"
- android:label="Process phone account registration"
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"
+ android:label="Process phone account registration"
+ android:protectionLevel="signature|system"/>
- <permission
- android:name="android.permission.HANDLE_CALL_INTENT"
- android:label="Protects handling the call intent via the TelecomManager API."
- android:protectionLevel="signature|system"/>
+ <permission android:name="android.permission.HANDLE_CALL_INTENT"
+ android:label="Protects handling the call intent via the TelecomManager API."
+ android:protectionLevel="signature|system"/>
<application android:label="@string/telecommAppLabel"
- android:icon="@mipmap/ic_launcher_phone"
- android:allowBackup="false"
- android:supportsRtl="true"
- android:process="system"
- android:usesCleartextTraffic="false"
- android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true">
+ android:icon="@mipmap/ic_launcher_phone"
+ android:allowBackup="false"
+ android:supportsRtl="true"
+ android:process="system"
+ android:usesCleartextTraffic="false"
+ android:defaultToDeviceProtectedStorage="true"
+ android:directBootAware="true">
<!-- CALL vs CALL_PRIVILEGED vs CALL_EMERGENCY
We have three different intents through which a call can be initiated each with its
@@ -104,60 +99,61 @@
<!-- Activity that displays UI for managing blocked numbers. -->
<activity android:name=".settings.BlockedNumbersActivity"
- android:label="@string/blocked_numbers"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Telecom.BlockedNumbers"
- android:process=":ui"
- android:exported="true">
+ android:label="@string/blocked_numbers"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.BlockedNumbers"
+ android:process=":ui"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.action.MANAGE_BLOCKED_NUMBERS" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.action.MANAGE_BLOCKED_NUMBERS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".settings.CallBlockDisabledActivity"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="keyboardHidden|orientation|screenSize"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<!-- Activity that starts the outgoing call process by listening to CALL intent which
- contain contact information in the intent's data. CallActivity handles any data
- URL with the schemes "tel", "sip", and "voicemail". It also handles URLs linked to
- contacts provider entries. Any data not fitting the schema described is ignored. -->
+ contain contact information in the intent's data. CallActivity handles any data
+ URL with the schemes "tel", "sip", and "voicemail". It also handles URLs linked to
+ contacts provider entries. Any data not fitting the schema described is ignored. -->
<activity android:name=".components.UserCallActivity"
- android:label="@string/userCallActivityLabel"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:permission="android.permission.CALL_PHONE"
- android:excludeFromRecents="true"
- android:process=":ui">
+ android:label="@string/userCallActivityLabel"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:permission="android.permission.CALL_PHONE"
+ android:excludeFromRecents="true"
+ android:process=":ui"
+ android:exported="true">
<!-- CALL action intent filters for the various ways of initiating an outgoing call. -->
<intent-filter>
- <action android:name="android.intent.action.CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<!-- Specify an icon for SIP calls so that quick contacts widget shows a special SIP
- icon for calls to SIP addresses. -->
+ icon for calls to SIP addresses. -->
<intent-filter android:icon="@drawable/ic_launcher_sip_call">
- <action android:name="android.intent.action.CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="sip" />
+ <action android:name="android.intent.action.CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<!-- Omit default category below so that all Intents sent to this filter must be
- explicit. -->
+ explicit. -->
<intent-filter>
- <action android:name="android.intent.action.CALL" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/phone_v2" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.CALL"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/phone_v2"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
</activity>
@@ -167,30 +163,30 @@
processed. High priority of 1000 is used in all intent filters to prevent anything but
the system from processing this intent (b/8871505). -->
<activity-alias android:name="PrivilegedCallActivity"
- android:targetActivity=".components.UserCallActivity"
- android:permission="android.permission.CALL_PRIVILEGED"
- android:process=":ui">
+ android:targetActivity=".components.UserCallActivity"
+ android:permission="android.permission.CALL_PRIVILEGED"
+ android:process=":ui">
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter android:priority="1000"
- android:icon="@drawable/ic_launcher_sip_call">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="sip" />
+ android:icon="@drawable/ic_launcher_sip_call">
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_PRIVILEGED" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/phone_v2" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.CALL_PRIVILEGED"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/phone_v2"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
</activity-alias>
@@ -200,123 +196,129 @@
1000 is used in all intent filters to prevent anything but the system from processing
this intent (b/8871505). -->
<!-- TODO: Is there really a notion of an emergency SIP number? If not, can
- that scheme be removed from this activity? -->
+ that scheme be removed from this activity? -->
<activity-alias android:name="EmergencyCallActivity"
- android:targetActivity=".components.UserCallActivity"
- android:permission="android.permission.CALL_PRIVILEGED"
- android:process=":ui">
+ android:targetActivity=".components.UserCallActivity"
+ android:permission="android.permission.CALL_PRIVILEGED"
+ android:process=":ui">
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter android:priority="1000"
- android:icon="@drawable/ic_launcher_sip_call">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="sip" />
+ android:icon="@drawable/ic_launcher_sip_call">
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter android:priority="1000">
- <action android:name="android.intent.action.CALL_EMERGENCY" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/phone_v2" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.CALL_EMERGENCY"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/phone_v2"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
</activity-alias>
- <receiver android:name=".components.TelecomBroadcastReceiver" android:exported="false"
- android:process="system">
+ <receiver android:name=".components.TelecomBroadcastReceiver"
+ android:exported="false"
+ android:process="system">
<intent-filter>
- <action android:name="com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS" />
- <action android:name="com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.ACTION_ANSWER_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION" />
- <action android:name="com.android.server.telecom.PROCEED_WITH_CALL" />
- <action android:name="com.android.server.telecom.CANCEL_CALL" />
- <action android:name="com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL" />
- <action android:name="com.android.server.telecom.CANCEL_REDIRECTED_CALL" />
+ <action android:name="com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS"/>
+ <action android:name="com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.ACTION_ANSWER_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION"/>
+ <action android:name="com.android.server.telecom.PROCEED_WITH_CALL"/>
+ <action android:name="com.android.server.telecom.CANCEL_CALL"/>
+ <action android:name="com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL"/>
+ <action android:name="com.android.server.telecom.CANCEL_REDIRECTED_CALL"/>
</intent-filter>
</receiver>
<receiver android:name=".components.AppUninstallBroadcastReceiver"
- android:process="system">
+ android:process="system"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
- <data android:scheme="package" />
+ <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED"/>
+ <data android:scheme="package"/>
</intent-filter>
</receiver>
<activity android:name=".RespondViaSmsSettings"
- android:label="@string/respond_via_sms_setting_title"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Telecom.DialerSettings"
- android:process=":ui">
+ android:label="@string/respond_via_sms_setting_title"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.DialerSettings"
+ android:process=":ui"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <action android:name="android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".settings.EnableAccountPreferenceActivity"
- android:label="@string/enable_account_preference_title"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Telecom.DialerSettings"
- android:process=":ui">
+ android:label="@string/enable_account_preference_title"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Telecom.DialerSettings"
+ android:process=":ui"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".components.ErrorDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<activity android:name=".ui.ConfirmCallDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<activity android:name=".ui.CallRedirectionTimeoutDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.Telecomm.Transparent"
- android:process=":ui">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Theme.Telecomm.Transparent"
+ android:process=":ui">
</activity>
<activity android:name=".ui.TelecomDeveloperMenu"
- android:label="@string/developer_title"
- android:exported="false"
- android:process=":ui" />
+ android:label="@string/developer_title"
+ android:exported="false"
+ android:process=":ui"/>
<service android:name=".components.BluetoothPhoneService"
- android:singleUser="true"
- android:process="system">
+ android:singleUser="true"
+ android:process="system"
+ android:exported="true">
<intent-filter>
- <action android:name="android.bluetooth.IBluetoothHeadsetPhone" />
+ <action android:name="android.bluetooth.IBluetoothHeadsetPhone"/>
</intent-filter>
</service>
<service android:name=".components.TelecomService"
- android:singleUser="true"
- android:process="system">
+ android:singleUser="true"
+ android:process="system"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ITelecomService" />
+ <action android:name="android.telecom.ITelecomService"/>
</intent-filter>
</service>
diff --git a/OWNERS b/OWNERS
index 94409ef..39be2c1 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,6 @@
breadley@google.com
hallliu@google.com
tgunn@google.com
-paulye@google.com
+xiaotonj@google.com
+shuoq@google.com
+rgreenwalt@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 75feeb6..02bd056 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -15,6 +15,14 @@
"exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
+ },
+ {
+ "name": "CtsTelecomTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
}
]
}
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 87bde1c..c434ecc 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -47,7 +47,7 @@
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Fehler beim Senden der Nachricht an <xliff:g id="PHONE_NUMBER">%s</xliff:g>"</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Anrufkonten"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Es sind nur Notrufe erlaubt."</string>
- <string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Diese App darf ohne die Berechtigung \"Standard-App für Telefonie\" keine ausgehenden Anrufe tätigen."</string>
+ <string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Diese App darf ohne die Berechtigung \"Telefon-App\" keine ausgehenden Anrufe tätigen."</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"Gib eine gültige Nummer ein."</string>
<string name="duplicate_video_call_not_allowed" msgid="5754746140185781159">"Der Anruf kann momentan nicht hinzugefügt werden."</string>
<string name="no_vm_number" msgid="2179959110602180844">"Fehlende Mailbox-Nummer"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 3acab47..e157655 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -112,7 +112,7 @@
<string name="phone_settings_private_num_summary_txt" msgid="6755758240544021037">"番号非通知の発信者をブロック"</string>
<string name="phone_settings_payphone_txt" msgid="5003987966052543965">"公衆電話"</string>
<string name="phone_settings_payphone_summary_txt" msgid="3936631076065563665">"公衆電話からの着信をブロック"</string>
- <string name="phone_settings_unknown_txt" msgid="3577926178354772728">"不明"</string>
+ <string name="phone_settings_unknown_txt" msgid="3577926178354772728">"不明な発信者"</string>
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"不明な発信者からの着信をブロック"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"着信のブロック"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"着信のブロックを無効にしました"</string>
diff --git a/res/xml/activity_blocked_numbers.xml b/res/xml/activity_blocked_numbers.xml
index f884ec9..df1a759 100644
--- a/res/xml/activity_blocked_numbers.xml
+++ b/res/xml/activity_blocked_numbers.xml
@@ -75,7 +75,7 @@
<TextView
android:id="@+id/add_blocked"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="48dp"
android:text="@string/block_number"
android:layout_marginBottom="@dimen/blocked_numbers_button_bottom_margin"
android:paddingTop="@dimen/blocked_numbers_button_large_padding"
diff --git a/res/xml/enhanced_call_blocking_settings.xml b/res/xml/enhanced_call_blocking_settings.xml
index 32c4c5d..73ed2af 100644
--- a/res/xml/enhanced_call_blocking_settings.xml
+++ b/res/xml/enhanced_call_blocking_settings.xml
@@ -41,8 +41,4 @@
android:persistent="false"
android:defaultValue="false"/>
<!--Add divider to separate this enhanced call blocking settings from other settings-->
- <Preference
- android:key="enhanced_call_blocking_divider"
- android:persistent="false"
- android:layout="@xml/layout_divider"/>
</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
old mode 100755
new mode 100644
index df6322c..0785502
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -545,7 +545,7 @@
private ParcelFileDescriptor[] mConnectionServiceToInCallStreams;
/**
- * True if we're supposed to start this call with RTT, either due to the master switch or due
+ * True if we're supposed to start this call with RTT, either due to the settings switch or due
* to an extra.
*/
private boolean mDidRequestToStartWithRtt = false;
@@ -1124,6 +1124,12 @@
case CallState.ANSWERED:
event = LogUtils.Events.SET_ANSWERED;
break;
+ case CallState.AUDIO_PROCESSING:
+ event = LogUtils.Events.SET_AUDIO_PROCESSING;
+ break;
+ case CallState.SIMULATED_RINGING:
+ event = LogUtils.Events.SET_SIMULATED_RINGING;
+ break;
}
if (event != null) {
// The string data should be just the tag.
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index a562021..69a870f 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -413,6 +413,8 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -459,6 +461,8 @@
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;
@@ -484,7 +488,6 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
- case SPEAKER_ON:
transitionTo(mQuiescentSpeakerRoute);
return HANDLED;
case SWITCH_FOCUS:
@@ -533,6 +536,7 @@
// This may be sent as a confirmation by the BT stack after switch off BT.
return HANDLED;
case CONNECT_DOCK:
+ setSpeakerphoneOn(true);
sendInternalMessage(SWITCH_SPEAKER);
return HANDLED;
case DISCONNECT_DOCK:
@@ -611,6 +615,8 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -677,12 +683,13 @@
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:
@@ -725,6 +732,7 @@
return HANDLED;
case DISCONNECT_WIRED_HEADSET:
if (mWasOnSpeaker) {
+ setSpeakerphoneOn(true);
sendInternalMessage(SWITCH_SPEAKER);
} else {
sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
@@ -796,6 +804,7 @@
transitionTo(mActiveHeadsetRoute);
break;
case SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
transitionTo(mActiveSpeakerRoute);
break;
default:
@@ -852,6 +861,8 @@
mHasUserExplicitlyLeftBluetooth = true;
// fall through
case SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
setBluetoothOff();
transitionTo(mActiveSpeakerRoute);
@@ -947,6 +958,8 @@
mHasUserExplicitlyLeftBluetooth = true;
// fall through
case SWITCH_SPEAKER:
+ setSpeakerphoneOn(true);
+ // fall through
case SPEAKER_ON:
transitionTo(mActiveSpeakerRoute);
return HANDLED;
@@ -1012,6 +1025,8 @@
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;
@@ -1025,7 +1040,6 @@
return HANDLED;
case SWITCH_SPEAKER:
case USER_SWITCH_SPEAKER:
- case SPEAKER_ON:
transitionTo(mQuiescentSpeakerRoute);
return HANDLED;
case SWITCH_FOCUS:
@@ -1105,8 +1119,9 @@
@Override
public void enter() {
super.enter();
+ // Don't set speakerphone on here -- we might end up in this state by following
+ // the speaker state that some other app commanded.
mWasOnSpeaker = true;
- setSpeakerphoneOn(true);
CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER,
mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
setSystemAudioState(newState, true);
@@ -1593,12 +1608,8 @@
}
private void setSpeakerphoneOn(boolean on) {
- if (mAudioManager.isSpeakerphoneOn() != on) {
- Log.i(this, "turning speaker phone %s", on);
- mAudioManager.setSpeakerphoneOn(on);
- } else {
- Log.i(this, "Ignoring speakerphone request -- already %s", on);
- }
+ Log.i(this, "turning speaker phone %s", on);
+ mAudioManager.setSpeakerphoneOn(on);
mStatusBarNotifier.notifySpeakerphone(on);
}
diff --git a/src/com/android/server/telecom/CallIdMapper.java b/src/com/android/server/telecom/CallIdMapper.java
index da2c199..2cd5c79 100644
--- a/src/com/android/server/telecom/CallIdMapper.java
+++ b/src/com/android/server/telecom/CallIdMapper.java
@@ -20,6 +20,7 @@
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. */
@@ -71,6 +72,10 @@
return mSecondaryMap.get(value);
}
+ public Collection<V> getValues() {
+ return mPrimaryMap.values();
+ }
+
public void clear() {
mPrimaryMap.clear();
mSecondaryMap.clear();
@@ -132,6 +137,10 @@
return mCalls.getValue(callId);
}
+ Collection<Call> getCalls() {
+ return mCalls.getValues();
+ }
+
void clear() {
mCalls.clear();
}
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 7a5af14..b19e269 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -605,7 +605,8 @@
for (int i = 0; i < result.length; i++) {
Uri uri = result[i];
/*
- Performs a simple sanity check to make sure the call was written in the database.
+ Performs a simple correctness check to make sure the call was written in the
+ database.
Typically there is only one result per call so it is easy to identify which one
failed.
*/
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 1c46209..ff3122f 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -3975,7 +3975,7 @@
+ " livecall = " + liveCall);
if (emergencyCall == liveCall) {
- // Not likely, but a good sanity check.
+ // Not likely, but a good correctness check.
return true;
}
@@ -3989,7 +3989,7 @@
return true;
}
if (outgoingCall.getState() == CallState.SELECT_PHONE_ACCOUNT) {
- // Sanity check: if there is an orphaned emergency call in the
+ // Correctness check: if there is an orphaned emergency call in the
// {@link CallState#SELECT_PHONE_ACCOUNT} state, just disconnect it since the user
// has explicitly started a new call.
emergencyCall.getAnalytics().setCallIsAdditional(true);
diff --git a/src/com/android/server/telecom/CarModeTracker.java b/src/com/android/server/telecom/CarModeTracker.java
index 0ec4917..e64ef5d 100644
--- a/src/com/android/server/telecom/CarModeTracker.java
+++ b/src/com/android/server/telecom/CarModeTracker.java
@@ -28,6 +28,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.PriorityQueue;
import java.util.stream.Collectors;
@@ -144,6 +145,28 @@
}
/**
+ * Force-removes a package from the car mode tracking list, no matter at which priority.
+ *
+ * This handles the case where packages are disabled or uninstalled. In those case, remove them
+ * from the tracking list so they don't cause a leak.
+ * @param packageName Package name of the app to force-remove
+ */
+ public void forceExitCarMode(@NonNull String packageName) {
+ Optional<CarModeApp> forcedApp = mCarModeApps.stream()
+ .filter(c -> c.getPackageName().equals(packageName))
+ .findAny();
+ if (forcedApp.isPresent()) {
+ String logString = String.format("forceExitCarMode: packageName=%s, was at priority=%s",
+ packageName, forcedApp.get().getPriority());
+ Log.i(this, logString);
+ mCarModeChangeLog.log(logString);
+ mCarModeApps.removeIf(c -> c.getPackageName().equals(packageName));
+ } else {
+ Log.i(this, "Package %s is not tracked as requesting car mode", packageName);
+ }
+ }
+
+ /**
* Retrieves a list of the apps which are currently in car mode, ordered by priority such that
* the highest priority app is first.
* @return List of apps in car mode.
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 01acdd1..72c3f24 100755
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -91,6 +91,7 @@
mServiceInterface.createConnectionComplete(callId,
Log.getExternalSession());
} catch (RemoteException e) {
+ logOutgoing("createConnectionComplete remote exception=%s", e);
}
}
}
@@ -1206,6 +1207,10 @@
mPendingResponses.put(callId, response);
Bundle extras = call.getIntentExtras();
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
Log.addEvent(call, LogUtils.Events.START_CONFERENCE,
Log.piiHandle(call.getHandle()));
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 700dac7..2221cb9 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -438,7 +438,10 @@
mPhoneAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
mCall.getHandle() == null
? null : mCall.getHandle().getScheme()));
- if (!mAttemptRecords.contains(callAttemptRecord)) {
+ // If the target phone account is null, we'll run into a NPE during the retry
+ // process, so skip it now if it's null.
+ if (callAttemptRecord.targetPhoneAccount != null
+ && !mAttemptRecords.contains(callAttemptRecord)) {
Log.i(this, "Will try Connection Manager account %s for emergency",
callManager);
mAttemptRecords.add(callAttemptRecord);
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 399c28a..14e5bf0 100644
--- a/src/com/android/server/telecom/CreateConnectionTimeout.java
+++ b/src/com/android/server/telecom/CreateConnectionTimeout.java
@@ -69,7 +69,7 @@
}
// Timeout is only supported for SIM call managers that are set by the carrier.
- if (!Objects.equals(connectionManager.getComponentName(),
+ if (connectionManager != null && !Objects.equals(connectionManager.getComponentName(),
mPhoneAccountRegistrar.getSystemSimCallManagerComponent())) {
Log.d(this, "isTimeoutNeededForCall, not a system sim call manager");
return false;
diff --git a/src/com/android/server/telecom/DefaultDialerCache.java b/src/com/android/server/telecom/DefaultDialerCache.java
index c2b78ee..a4a0242 100644
--- a/src/com/android/server/telecom/DefaultDialerCache.java
+++ b/src/com/android/server/telecom/DefaultDialerCache.java
@@ -217,6 +217,12 @@
return mSystemDialerComponentName;
}
+ public ComponentName getDialtactsSystemDialerComponent() {
+ final Resources resources = mContext.getResources();
+ return new ComponentName(getSystemDialerApplication(),
+ resources.getString(R.string.dialer_default_class));
+ }
+
public void observeDefaultDialerApplication(Executor executor, IntConsumer observer) {
mRoleManagerAdapter.observeDefaultDialerApp(executor, observer);
}
@@ -289,4 +295,8 @@
public ContentObserver getContentObserver() {
return mDefaultDialerObserver;
}
+
+ public RoleManagerAdapter getRoleManagerAdapter() {
+ return mRoleManagerAdapter;
+ }
}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 228cb3d..d685a53 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -20,9 +20,11 @@
import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -43,6 +45,7 @@
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
// TODO: Needed for move to system service: import com.android.internal.R;
@@ -58,6 +61,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -322,7 +326,10 @@
String packageName = mInCallServiceInfo.getComponentName().getPackageName();
mContext.unbindService(mServiceConnection);
mIsConnected = false;
- if (mIsNullBinding) {
+ 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.
sendCrashedInCallServiceNotification(packageName);
}
if (mCall != null) {
@@ -444,7 +451,7 @@
@Override
public void disconnect() {
- Log.i(this, "Disconnect forced!");
+ Log.i(this, "Disconnecting from InCallService");
if (mIsProxying) {
mSubConnection.disconnect();
} else {
@@ -721,6 +728,20 @@
}
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);
+ }
+ }
}
private final Call.Listener mCallListener = new Call.ListenerBase() {
@@ -847,9 +868,50 @@
}
};
- private final SystemStateListener mSystemStateListener =
- (priority, packageName, isCarMode) -> InCallController.this.handleCarModeChange(
- priority, packageName, isCarMode);
+ private BroadcastReceiver mPackageChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.startSession("ICC.pCR");
+ try {
+ if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) {
+ synchronized (mLock) {
+ String changedPackage = intent.getData().getSchemeSpecificPart();
+ List<InCallServiceBindingConnection> componentsToBind =
+ Arrays.stream(intent.getStringArrayExtra(
+ Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST))
+ .map((className) ->
+ ComponentName.createRelative(changedPackage,
+ className))
+ .filter(mKnownNonUiInCallServices::contains)
+ .flatMap(componentName -> getInCallServiceComponents(
+ componentName,
+ IN_CALL_SERVICE_TYPE_NON_UI).stream())
+ .map(InCallServiceBindingConnection::new)
+ .collect(Collectors.toList());
+
+ if (mNonUIInCallServiceConnections != null) {
+ mNonUIInCallServiceConnections.addConnections(componentsToBind);
+ }
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+ };
+
+ private final SystemStateListener mSystemStateListener = new SystemStateListener() {
+ @Override
+ public void onCarModeChanged(int priority, String packageName, boolean isCarMode) {
+ InCallController.this.handleCarModeChange(priority, packageName, isCarMode);
+ }
+
+ @Override
+ public void onPackageUninstalled(String packageName) {
+ mCarModeTracker.forceExitCarMode(packageName);
+ updateCarModeForSwitchingConnection();
+ }
+ };
private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
private static final int IN_CALL_SERVICE_TYPE_DIALER_UI = 1;
@@ -875,6 +937,11 @@
private NonUIInCallServiceConnectionCollection mNonUIInCallServiceConnections;
private final ClockProxy mClockProxy;
+ // A set of known non-UI in call services on the device, including those that are disabled.
+ // We track this so that we can efficiently bind to them when we're notified that a new
+ // component has been enabled.
+ private Set<ComponentName> mKnownNonUiInCallServices = new ArraySet<>();
+
// Future that's in a completed state unless we're in the middle of binding to a service.
// The future will complete with true if binding succeeds, false if it timed out.
private CompletableFuture<Boolean> mBindingFuture = CompletableFuture.completedFuture(true);
@@ -940,7 +1007,8 @@
ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(call,
true /* includeVideoProvider */, mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(), includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
@@ -1004,7 +1072,8 @@
ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(call,
true /* includeVideoProvider */, mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(), includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
@@ -1034,7 +1103,8 @@
false /* supportsExternalCalls */,
android.telecom.Call.STATE_DISCONNECTED /* overrideState */,
false /* includeRttCall */,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI
);
try {
@@ -1227,6 +1297,12 @@
* Unbinds an existing bound connection to the in-call app.
*/
private void unbindFromServices() {
+ try {
+ mContext.unregisterReceiver(mPackageChangedReceiver);
+ } catch (IllegalArgumentException e) {
+ // Ignore this -- we may or may not have registered it, but when we bind, we want to
+ // unregister no matter what.
+ }
if (mInCallServiceConnection != null) {
mInCallServiceConnection.disconnect();
mInCallServiceConnection = null;
@@ -1312,6 +1388,10 @@
}
mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
mNonUIInCallServiceConnections.connect(call);
+
+ IntentFilter packageChangedFilter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
+ packageChangedFilter.addDataScheme("package");
+ mContext.registerReceiver(mPackageChangedReceiver, packageChangedFilter);
}
private InCallServiceInfo getDefaultDialerComponent() {
@@ -1387,7 +1467,7 @@
PackageManager packageManager = mContext.getPackageManager();
for (ResolveInfo entry : packageManager.queryIntentServicesAsUser(
serviceIntent,
- PackageManager.GET_META_DATA,
+ PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS,
mCallsManager.getCurrentUserHandle().getIdentifier())) {
ServiceInfo serviceInfo = entry.serviceInfo;
if (serviceInfo != null) {
@@ -1400,14 +1480,13 @@
int currentType = getInCallServiceType(entry.serviceInfo, packageManager,
packageName);
- if (requestedType == 0 || requestedType == currentType) {
- if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
- // We enforce the rule that self-managed calls are not supported by non-ui
- // InCallServices.
- isSelfManageCallsSupported = false;
- }
- retval.add(new InCallServiceInfo(
- new ComponentName(serviceInfo.packageName, serviceInfo.name),
+ ComponentName foundComponentName =
+ new ComponentName(serviceInfo.packageName, serviceInfo.name);
+ if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
+ mKnownNonUiInCallServices.add(foundComponentName);
+ }
+ if (serviceInfo.enabled && (requestedType == 0 || requestedType == currentType)) {
+ retval.add(new InCallServiceInfo(foundComponentName,
isExternalCallsSupported, isSelfManageCallsSupported, requestedType));
}
}
@@ -1546,7 +1625,8 @@
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
}
@@ -1556,7 +1636,11 @@
inCallService.onCanAddCallChanged(mCallsManager.canAddCall());
} catch (RemoteException ignored) {
}
- mBindingFuture.complete(true);
+ // Don't complete the binding future for non-ui incalls
+ if (info.getType() != IN_CALL_SERVICE_TYPE_NON_UI) {
+ mBindingFuture.complete(true);
+ }
+
Log.i(this, "%s calls sent to InCallService.", numCallsSent);
return true;
}
@@ -1610,7 +1694,8 @@
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
rttInfoChanged && info.equals(mInCallServiceConnection.getInfo()),
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
+ info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
ComponentName componentName = info.getComponentName();
IInCallService inCallService = entry.getValue();
componentsUpdated.add(componentName);
@@ -1701,7 +1786,7 @@
if (TextUtils.isEmpty(ringingPackage)) {
// The current in-call UI returned nothing, so lets use the default dialer.
- ringingPackage = mDefaultDialerCache.getDefaultDialerApplication(
+ ringingPackage = mDefaultDialerCache.getRoleManagerAdapter().getDefaultDialerApp(
mCallsManager.getCurrentUserHandle().getIdentifier());
if (ringingPackage != null) {
Log.d(this, "doesConnectedDialerSupportRinging: notCurentlyConnectedPackage=%s",
@@ -1784,7 +1869,8 @@
public void handleCarModeChange(int priority, String packageName, boolean isCarMode) {
Log.i(this, "handleCarModeChange: packageName=%s, priority=%d, isCarMode=%b",
packageName, priority, isCarMode);
- if (!isCarModeInCallService(packageName)) {
+ // Don't ignore the signal if we are disabling car mode; package may be uninstalled.
+ if (isCarMode && !isCarModeInCallService(packageName)) {
Log.i(this, "handleCarModeChange: not a valid InCallService; packageName=%s",
packageName);
return;
@@ -1796,8 +1882,12 @@
mCarModeTracker.handleExitCarMode(priority, packageName);
}
+ updateCarModeForSwitchingConnection();
+ }
+
+ public void updateCarModeForSwitchingConnection() {
if (mInCallServiceConnection != null) {
- Log.i(this, "handleCarModeChange: car mode apps: %s",
+ Log.i(this, "updateCarModeForSwitchingConnection: car mode apps: %s",
mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
if (shouldUseCarModeUI()) {
mInCallServiceConnection.changeCarModeApp(
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index 5bb14e6..e4a414b 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -101,6 +101,8 @@
public static final String SET_DISCONNECTED = "SET_DISCONNECTED";
public static final String SET_DISCONNECTING = "SET_DISCONNECTING";
public static final String SET_SELECT_PHONE_ACCOUNT = "SET_SELECT_PHONE_ACCOUNT";
+ public static final String SET_AUDIO_PROCESSING = "SET_AUDIO_PROCESSING";
+ public static final String SET_SIMULATED_RINGING = "SET_SIMULATED_RINGING";
public static final String REQUEST_HOLD = "REQUEST_HOLD";
public static final String REQUEST_UNHOLD = "REQUEST_UNHOLD";
public static final String REQUEST_DISCONNECT = "REQUEST_DISCONNECT";
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index f0efe92..86fedd5 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -21,7 +21,6 @@
import android.app.Activity;
import android.app.BroadcastOptions;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -495,9 +494,7 @@
private void launchSystemDialer(Uri handle) {
Intent systemDialerIntent = new Intent();
- systemDialerIntent.setComponent(
- new ComponentName(mDefaultDialerCache.getSystemDialerApplication(),
- mContext.getResources().getString(R.string.dialer_default_class)));
+ systemDialerIntent.setComponent(mDefaultDialerCache.getDialtactsSystemDialerComponent());
systemDialerIntent.setAction(Intent.ACTION_DIAL);
systemDialerIntent.setData(handle);
systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index 5c821a4..a5291e7 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -42,9 +42,9 @@
/**
* A list of extra keys which should be removed from a {@link ParcelableCall} when it is being
- * generated for the purpose of sending to a dialer other than the system dialer.
+ * generated for the purpose of sending to a incallservice other than the system incallservice.
* By convention we only pass keys namespaced with android.*, however there are some keys which
- * should not be passed to non-system dialer apps either.
+ * should not be passed to non-system incallservice apps either.
*/
private static List<String> EXTRA_KEYS_TO_SANITIZE;
static {
@@ -90,9 +90,9 @@
* {@link InCallService} which supports external calls or not.
* @param includeRttCall {@code true} if the RTT call should be included, {@code false}
* otherwise.
- * @param isForSystemDialer {@code true} if this call is being parcelled for the system dialer,
- * {@code false} otherwise. When parceling for the system dialer, the entire call extras
- * is included. When parceling for anything other than the system dialer, some extra key
+ * @param isForSystemInCallService {@code true} if this call is being parcelled for the system incallservice,
+ * {@code false} otherwise. When parceling for the system incallservice, the entire call extras
+ * is included. When parceling for anything other than the system incallservice, some extra key
* values will be stripped for privacy sake.
*/
public static ParcelableCall toParcelableCall(
@@ -101,10 +101,10 @@
PhoneAccountRegistrar phoneAccountRegistrar,
boolean supportsExternalCalls,
boolean includeRttCall,
- boolean isForSystemDialer) {
+ boolean isForSystemInCallService) {
return toParcelableCall(call, includeVideoProvider, phoneAccountRegistrar,
supportsExternalCalls, CALL_STATE_OVERRIDE_NONE /* overrideState */,
- includeRttCall, isForSystemDialer);
+ includeRttCall, isForSystemInCallService);
}
/**
@@ -120,9 +120,9 @@
* {@link InCallService} which supports external calls or not.
* @param overrideState When not {@link #CALL_STATE_OVERRIDE_NONE}, use the provided state as an
* override to whatever is defined in the call.
- * @param isForSystemDialer {@code true} if this call is being parcelled for the system dialer,
- * {@code false} otherwise. When parceling for the system dialer, the entire call extras
- * is included. When parceling for anything other than the system dialer, some extra key
+ * @param isForSystemInCallService {@code true} if this call is being parcelled for the system incallservice,
+ * {@code false} otherwise. When parceling for the system incallservice, the entire call extras
+ * is included. When parceling for anything other than the system incallservice, some extra key
* values will be stripped for privacy sake.
* @return The {@link ParcelableCall} containing all call information from the {@link Call}.
*/
@@ -133,7 +133,7 @@
boolean supportsExternalCalls,
int overrideState,
boolean includeRttCall,
- boolean isForSystemDialer) {
+ boolean isForSystemInCallService) {
int state;
if (overrideState == CALL_STATE_OVERRIDE_NONE) {
state = getParcelableState(call, supportsExternalCalls);
@@ -216,7 +216,7 @@
}
Bundle extras;
- if (isForSystemDialer) {
+ if (isForSystemInCallService) {
extras = call.getExtras();
} else {
extras = sanitizeExtras(call.getExtras());
@@ -269,9 +269,9 @@
* <li>Caller number verification status (verstat)</li>
* </ul>
* All other fields are nulled or set to 0 values.
- * Where the call screening service is part of the system dialer, the
+ * Where the call screening service is part of the system incallservice, the
* {@link Connection#EXTRA_SIP_INVITE} header information is also sent to the call screening
- * service (since the system dialer has access to this anyways).
+ * service (since the system incallservice has access to this anyways).
* @param call The telecom call to send to a call screening service.
* @param areRestrictedExtrasIncluded {@code true} if the set of restricted extras defined in
* {@link #RESTRICTED_CALL_SCREENING_EXTRA_KEYS} are to
@@ -333,7 +333,7 @@
/**
* Sanitize the extras bundle passed in, removing keys which should not be sent to non-system
- * dialer apps.
+ * incallservice apps.
* @param oldExtras Extras bundle to sanitize.
* @return The sanitized extras bundle.
*/
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index ef2840a..e9ddfa0 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -485,6 +486,7 @@
* target phone account.
* @return phone account handle of sim call manager based on the ongoing call.
*/
+ @Nullable
public PhoneAccountHandle getSimCallManagerFromCall(Call call) {
if (call == null) {
return null;
@@ -1597,10 +1599,16 @@
return BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
}
+ @Nullable
protected Icon readIcon(XmlPullParser parser) throws IOException {
- byte[] iconByteArray = Base64.decode(parser.getText(), 0);
- ByteArrayInputStream stream = new ByteArrayInputStream(iconByteArray);
- return Icon.createFromStream(stream);
+ try {
+ byte[] iconByteArray = Base64.decode(parser.getText(), 0);
+ ByteArrayInputStream stream = new ByteArrayInputStream(iconByteArray);
+ return Icon.createFromStream(stream);
+ } catch (IllegalArgumentException e) {
+ Log.e(this, e, "Bitmap must not be null.");
+ return null;
+ }
}
}
diff --git a/src/com/android/server/telecom/SystemStateHelper.java b/src/com/android/server/telecom/SystemStateHelper.java
index 073b081..3be3d5e 100644
--- a/src/com/android/server/telecom/SystemStateHelper.java
+++ b/src/com/android/server/telecom/SystemStateHelper.java
@@ -26,6 +26,7 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.net.Uri;
import android.telecom.Log;
import java.util.Set;
@@ -38,7 +39,7 @@
* Provides various system states to the rest of the telecom codebase.
*/
public class SystemStateHelper {
- public static interface SystemStateListener {
+ public interface SystemStateListener {
/**
* Listener method to inform interested parties when a package name requests to enter or
* exit car mode.
@@ -48,6 +49,12 @@
* otherwise.
*/
void onCarModeChanged(int priority, String packageName, boolean isCarMode);
+
+ /**
+ * Notifies when a package has been uninstalled.
+ * @param packageName the package name of the uninstalled package
+ */
+ void onPackageUninstalled(String packageName);
}
private final Context mContext;
@@ -62,7 +69,7 @@
UiModeManager.DEFAULT_PRIORITY);
String callingPackage = intent.getStringExtra(
UiModeManager.EXTRA_CALLING_PACKAGE);
- Log.i(SystemStateHelper.this, "ENTER_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
+ Log.i(SystemStateHelper.this, "ENTER_CAR_MODE_PRIORITIZED; priority=%d, pkg=%s",
priority, callingPackage);
onEnterCarMode(priority, callingPackage);
} else if (UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED.equals(action)) {
@@ -70,11 +77,21 @@
UiModeManager.DEFAULT_PRIORITY);
String callingPackage = intent.getStringExtra(
UiModeManager.EXTRA_CALLING_PACKAGE);
- Log.i(SystemStateHelper.this, "EXIT_CAR_MODE_PRIVILEGED; priority=%d, pkg=%s",
+ Log.i(SystemStateHelper.this, "EXIT_CAR_MODE_PRIORITIZED; priority=%d, pkg=%s",
priority, callingPackage);
onExitCarMode(priority, callingPackage);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ Uri data = intent.getData();
+ if (data == null) {
+ Log.w(SystemStateHelper.this,
+ "Got null data for package removed, ignoring");
+ return;
+ }
+ mListeners.forEach(
+ l -> l.onPackageUninstalled(data.getEncodedSchemeSpecificPart()));
} else {
- Log.w(this, "Unexpected intent received: %s", intent.getAction());
+ Log.w(SystemStateHelper.this,
+ "Unexpected intent received: %s", intent.getAction());
}
} finally {
Log.endSession();
@@ -88,11 +105,16 @@
public SystemStateHelper(Context context) {
mContext = context;
- IntentFilter intentFilter = new IntentFilter(
+ IntentFilter intentFilter1 = new IntentFilter(
UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
- intentFilter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter);
- Log.i(this, "Registering car mode receiver: %s", intentFilter);
+ intentFilter1.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+
+ IntentFilter intentFilter2 = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter2.addDataScheme("package");
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter1);
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter2);
+ Log.i(this, "Registering broadcast receiver: %s", intentFilter1);
+ Log.i(this, "Registering broadcast receiver: %s", intentFilter2);
mIsCarMode = getSystemCarMode();
}
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 62e0f3f..1cf25a3 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -710,7 +710,7 @@
public ComponentName getDefaultPhoneApp() {
try {
Log.startSession("TSI.gDPA");
- return mDefaultDialerCache.getSystemDialerComponent();
+ return mDefaultDialerCache.getDialtactsSystemDialerComponent();
} finally {
Log.endSession();
}
@@ -1737,6 +1737,32 @@
}
}
+ /**
+ * A method intended for use in testing to clean up any calls that get stuck in the
+ * {@link CallState#DISCONNECTED} or {@link CallState#DISCONNECTING} states. Stuck calls
+ * during CTS cause cascading failures, so if the CTS test detects such a state, it should
+ * call this method via a shell command to clean up before moving on to the next test.
+ */
+ @Override
+ public void cleanupStuckCalls() {
+ Log.startSession("TCI.cSC");
+ try {
+ synchronized (mLock) {
+ enforceShellOnly(Binder.getCallingUid(), "cleanupStuckCalls");
+ Binder.withCleanCallingIdentity(() -> {
+ for (Call call : mCallsManager.getCalls()) {
+ if (call.getState() == CallState.DISCONNECTED
+ || call.getState() == CallState.DISCONNECTING) {
+ mCallsManager.markCallAsRemoved(call);
+ }
+ }
+ });
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
@Override
public void setTestDefaultCallRedirectionApp(String packageName) {
try {
diff --git a/src/com/android/server/telecom/settings/BlockedNumbersActivity.java b/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
index 3549db5..1fe7c5f 100644
--- a/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
+++ b/src/com/android/server/telecom/settings/BlockedNumbersActivity.java
@@ -38,6 +38,7 @@
import android.provider.ContactsContract;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
@@ -285,7 +286,7 @@
* Add blocked number if it does not exist.
*/
private void addBlockedNumber(String number) {
- if (PhoneNumberUtils.isEmergencyNumber(number)) {
+ if (isEmergencyNumber(this, number)) {
Toast.makeText(
this,
getString(R.string.blocked_numbers_block_emergency_number_message),
@@ -298,6 +299,16 @@
}
}
+ private boolean isEmergencyNumber(Context context, String number) {
+ try {
+ TelephonyManager tm = (TelephonyManager) context.getSystemService(
+ Context.TELEPHONY_SERVICE);
+ return tm.isEmergencyNumber(number);
+ } catch (IllegalStateException ise) {
+ return false;
+ }
+ }
+
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// no-op
diff --git a/src/com/android/server/telecom/ui/IncomingCallNotifier.java b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
index 6e203aa..edea89b 100644
--- a/src/com/android/server/telecom/ui/IncomingCallNotifier.java
+++ b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
@@ -41,6 +41,7 @@
import com.android.server.telecom.TelecomBroadcastIntentProcessor;
import com.android.server.telecom.components.TelecomBroadcastReceiver;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -68,7 +69,7 @@
public static final int NOTIFICATION_INCOMING_CALL = 1;
@VisibleForTesting
public static final String NOTIFICATION_TAG = IncomingCallNotifier.class.getSimpleName();
-
+ private final Object mLock = new Object();
public final Call.ListenerBase mCallListener = new Call.ListenerBase() {
@Override
@@ -104,8 +105,10 @@
@Override
public void onCallAdded(Call call) {
- if (!mCalls.contains(call)) {
- mCalls.add(call);
+ synchronized (mLock) {
+ if (!mCalls.contains(call)) {
+ mCalls.add(call);
+ }
}
updateIncomingCall();
@@ -113,10 +116,11 @@
@Override
public void onCallRemoved(Call call) {
- if (mCalls.contains(call)) {
- mCalls.remove(call);
+ synchronized (mLock) {
+ if (mCalls.contains(call)) {
+ mCalls.remove(call);
+ }
}
-
updateIncomingCall();
}
@@ -130,11 +134,16 @@
* UI.
*/
private void updateIncomingCall() {
- Optional<Call> incomingCallOp = mCalls.stream()
- .filter(call -> call.isSelfManaged() && call.isIncoming() &&
- call.getState() == CallState.RINGING &&
- call.getHandoverState() == HandoverState.HANDOVER_NONE)
- .findFirst();
+ Optional<Call> incomingCallOp;
+ synchronized (mLock) {
+ incomingCallOp = mCalls.stream()
+ .filter(Objects::nonNull)
+ .filter(call -> call.isSelfManaged() && call.isIncoming() &&
+ call.getState() == CallState.RINGING &&
+ call.getHandoverState() == HandoverState.HANDOVER_NONE)
+ .findFirst();
+ }
+
Call incomingCall = incomingCallOp.orElse(null);
if (incomingCall != null && mCallsManagerProxy != null &&
!mCallsManagerProxy.hasUnholdableCallsForOtherConnectionService(
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index 4238191..9c461ca 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -15,40 +15,41 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- coreApp="true"
- package="com.android.server.telecom.testapps">
+ coreApp="true"
+ package="com.android.server.telecom.testapps">
- <uses-sdk
- android:minSdkVersion="28"
- android:targetSdkVersion="30" />
+ <uses-sdk android:minSdkVersion="28"
+ android:targetSdkVersion="30"/>
- <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.CAMERA" />
- <uses-permission android:name="android.permission.CALL_PHONE" />
- <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
- <uses-permission android:name="android.permission.READ_CALL_LOG" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
- <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" />
- <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
- <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
+ <uses-permission android:name="android.permission.ACCEPT_HANDOVER"/>
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.CAMERA"/>
+ <uses-permission android:name="android.permission.CALL_PHONE"/>
+ <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
+ <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER"/>
+ <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"/>
+ <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<application android:label="@string/app_name">
- <uses-library android:name="android.test.runner" />
+ <uses-library android:name="android.test.runner"/>
<!-- Miscellaneous telecom app-related test activities. -->
<service android:name="com.android.server.telecom.testapps.TestConnectionService"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ConnectionService" />
+ <action android:name="android.telecom.ConnectionService"/>
</intent-filter>
</service>
- <receiver android:name=".TestConnectionServiceReceiver">
+ <receiver android:name=".TestConnectionServiceReceiver"
+ android:exported="true">
<intent-filter>
<action android:name="android.server.telecom.testapps.ACTION_SWITCH_PHONE_ACCOUNT"/>
<action android:name="android.server.telecom.testapps.ACTION_SWITCH_PHONE_ACCOUNT_WRONG"/>
@@ -56,23 +57,27 @@
</receiver>
<service android:name="com.android.server.telecom.testapps.TestConnectionManager"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ConnectionService" />
+ <action android:name="android.telecom.ConnectionService"/>
</intent-filter>
</service>
<service android:name="com.android.server.telecom.testapps.TestInCallServiceImpl"
- android:process="com.android.server.telecom.testapps.TestInCallService"
- android:permission="android.permission.BIND_INCALL_SERVICE" >
- <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true"/>
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:permission="android.permission.BIND_INCALL_SERVICE"
+ android:exported="true">
+ <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI"
+ android:value="true"/>
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
<receiver android:name="com.android.server.telecom.testapps.TestInCallServiceBroadcastReceiver"
- android:process="com.android.server.telecom.testapps.TestInCallService" >
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:exported="true">
<intent-filter>
<action android:name="android.server.telecom.testapps.ACTION_SEND_UPDATE_REQUEST_FROM_TEST_INCALL_SERVICE"/>
<action android:name="android.server.telecom.testapps.ACTION_SEND_UPGRADE_RESPONSE"/>
@@ -84,201 +89,212 @@
<activity android:name="com.android.server.telecom.testapps.TestInCallUI"
- android:process="com.android.server.telecom.testapps.TestInCallService"
- android:label="@string/inCallUiAppLabel"
- android:launchMode="singleInstance">
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/inCallUiAppLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestRttActivity"
- android:process="com.android.server.telecom.testapps.TestInCallService"
- android:label="@string/rttUiLabel"
- android:launchMode="singleInstance">
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:label="@string/rttUiLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestCallActivity"
- android:theme="@android:style/Theme.NoDisplay"
- android:label="@string/testCallActivityLabel">
+ android:theme="@android:style/Theme.NoDisplay"
+ android:label="@string/testCallActivityLabel"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_START_INCOMING_CALL" />
- <action android:name="android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
- <data android:scheme="sip" />
+ <action android:name="android.telecom.testapps.ACTION_START_INCOMING_CALL"/>
+ <action android:name="android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
+ <data android:scheme="sip"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_HANGUP_CALLS" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.testapps.ACTION_HANGUP_CALLS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_SEND_UPGRADE_REQUEST" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="int" />
+ <action android:name="android.telecom.testapps.ACTION_SEND_UPGRADE_REQUEST"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="int"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_RTT_CALL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
+ <action android:name="android.telecom.testapps.ACTION_RTT_CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter>
- <action android:name="android.telecom.testapps.ACTION_REMOTE_RTT_UPGRADE" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.testapps.ACTION_REMOTE_RTT_UPGRADE"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<receiver android:name="com.android.server.telecom.testapps.CallNotificationReceiver"
- android:exported="false">
+ android:exported="false">
<intent-filter>
- <action android:name="com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT" />
+ <action android:name="com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT"/>
</intent-filter>
</receiver>
<activity android:name="com.android.server.telecom.testapps.TestDialerActivity"
- android:label="@string/testDialerActivityLabel"
- android:process="com.android.server.telecom.testapps.TestInCallService">
+ android:label="@string/testDialerActivityLabel"
+ android:process="com.android.server.telecom.testapps.TestInCallService"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.VIEW"/>
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestUssdActivity"
- android:label="@string/UssdUiAppLabel"
- android:launchMode="singleInstance">
+ android:label="@string/UssdUiAppLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.TestCertActivity"
- android:label="@string/KeyUiAppLabel"
- android:launchMode="singleInstance">
+ android:label="@string/KeyUiAppLabel"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.SelfManagedCallingActivity"
- android:label="@string/selfManagedCallingActivityLabel"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
- android:theme="@android:style/Theme.Material.Light">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:theme="@android:style/Theme.Material.Light"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.IncomingSelfManagedCallActivity"
- android:label="@string/selfManagedCallingActivityLabel"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.testapps.HandoverActivity"
- android:label="@string/selfManagedCallingActivityLabel"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
+ android:label="@string/selfManagedCallingActivityLabel"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<service android:name="com.android.server.telecom.testapps.SelfManagedConnectionService"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp">
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.ConnectionService" />
+ <action android:name="android.telecom.ConnectionService"/>
</intent-filter>
</service>
<receiver android:exported="false"
- android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
- android:name="com.android.server.telecom.testapps.SelfManagedCallNotificationReceiver" />
+ android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
+ android:name="com.android.server.telecom.testapps.SelfManagedCallNotificationReceiver"/>
<receiver android:exported="true"
- android:name="com.android.server.telecom.testapps.NuisanceReportReceiver">
+ android:name="com.android.server.telecom.testapps.NuisanceReportReceiver">
<intent-filter>
- <action android:name="android.telecom.action.NUISANCE_CALL_STATUS_CHANGED" />
+ <action android:name="android.telecom.action.NUISANCE_CALL_STATUS_CHANGED"/>
</intent-filter>
</receiver>
- <service
- android:name=".TestCallScreeningService"
- android:permission="android.permission.BIND_SCREENING_SERVICE">
+ <service android:name=".TestCallScreeningService"
+ android:permission="android.permission.BIND_SCREENING_SERVICE"
+ android:exported="true">
<intent-filter>
<action android:name="android.telecom.CallScreeningService"/>
</intent-filter>
</service>
<activity android:name=".CallScreeningActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance">
</activity>
- <service
- android:name=".TestCallRedirectionService"
- android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
+ <service android:name=".TestCallRedirectionService"
+ android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE"
+ android:exported="true">
<intent-filter>
<action android:name="android.telecom.CallRedirectionService"/>
</intent-filter>
</service>
<activity android:name=".CallRedirectionActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance">
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance">
</activity>
<activity android:name=".PostCallActivity"
- android:label="@string/postCallActivityLabel">
+ android:label="@string/postCallActivityLabel"
+ android:exported="true">
<intent-filter>
- <action android:name="android.telecom.action.POST_CALL" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.telecom.action.POST_CALL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
diff --git a/testapps/carmodedialer/AndroidManifest.xml b/testapps/carmodedialer/AndroidManifest.xml
index 7f55f7e..f237211 100644
--- a/testapps/carmodedialer/AndroidManifest.xml
+++ b/testapps/carmodedialer/AndroidManifest.xml
@@ -15,75 +15,77 @@
-->
<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:permission="android.permission.BIND_INCALL_SERVICE"
+ android:exported="true">
<meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
- android:value="true"/>
+ android:value="true"/>
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
<activity android:name="com.android.server.telecom.carmodedialer.CarModeInCallUI"
- android:label="CarMode Dialer"
- android:launchMode="singleInstance">
+ android:label="CarMode Dialer"
+ android:launchMode="singleInstance"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.android.server.telecom.carmodedialer.CarModeDialerActivity"
- android:label="CarMode Dialer">
+ android:label="CarMode Dialer"
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/person" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="voicemail" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="voicemail"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="tel" />
+ <action android:name="android.intent.action.VIEW"/>
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="tel"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
index abb9108..5c78d52 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
@@ -37,7 +37,6 @@
/**
* Service which acts as a fake ConnectionManager if so configured.
- * TODO(santoscordon): Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
*/
public class TestConnectionManager extends ConnectionService {
public final class TestManagedConnection extends Connection {
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
index f6fa116..3d1bc70 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -53,7 +53,6 @@
/**
* Service which provides fake calls to test the ConnectionService interface.
- * TODO: Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
*/
public class TestConnectionService extends ConnectionService {
/**
@@ -430,9 +429,9 @@
int videoState = extras.getInt(EXTRA_START_VIDEO_STATE, VideoProfile.STATE_AUDIO_ONLY);
Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
- // Use dummy number for testing incoming calls.
+ // Use test number for testing incoming calls.
Uri address = providedHandle == null ?
- Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getRandomNumber(
VideoProfile.isVideo(videoState)), null)
: providedHandle;
connection.setVideoState(videoState);
@@ -480,7 +479,7 @@
final Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
Uri handle = providedHandle == null ?
- Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(false), null)
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getRandomNumber(false), null)
: providedHandle;
connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
@@ -613,7 +612,7 @@
* @param isVideo {@code True} if the call is a video call.
* @return The phone number.
*/
- private String getDummyNumber(boolean isVideo) {
+ private String getRandomNumber(boolean isVideo) {
int videoDigit = isVideo ? 1 : 0;
int number = mRandom.nextInt(999);
return String.format("555%s%03d", videoDigit, number);
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 3fb2a84..02b35a4 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -27,4 +27,10 @@
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
+ <object type="module_controller"
+ class="com.android.tradefed.testtype.suite.module.TestFailureModuleController">
+ <option name="screenshot-on-failure" value="false" />
+ <option name="bugreportz-on-failure" value="false" />
+ <option name="logcat-on-failure" value="true" />
+ </object>
</configuration>
diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
index 6fd53eb..a8e1c00 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -163,6 +163,9 @@
.getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
telecomManager.acceptRingingCall();
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
.answer(eq(ids.mConnectionId), any());
mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
@@ -219,6 +222,9 @@
.getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY);
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
// The generic answer method on the ConnectionService is used to answer audio-only calls.
verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
.answer(eq(ids.mConnectionId), any());
@@ -248,6 +254,9 @@
.getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
telecomManager.acceptRingingCall(999 /* invalid videostate */);
+ waitForHandlerAction(mTelecomSystem.getCallsManager()
+ .getConnectionServiceFocusManager().getHandler(), TEST_TIMEOUT);
+
// Answer video API should be called
verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
.answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any());
@@ -626,6 +635,10 @@
mConnectionServiceFixtureA.
sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE);
+ waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
+ .getCallAudioModeStateMachine().getHandler(), TEST_TIMEOUT);
+ waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
+ .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT);
verify(audioManager, timeout(TEST_TIMEOUT))
.abandonAudioFocusForCall();
verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce())
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
index 58f1ee7..879ed0f 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
@@ -384,8 +384,12 @@
// 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, mParams.expectedRoute,
+ CallAudioState expectedState = new CallAudioState(false, expectedRoute,
mParams.expectedAvailableRoutes | CallAudioState.ROUTE_SPEAKER,
mParams.expectedBluetoothDevice, mParams.availableBluetoothDevices);
assertEquals(expectedState, stateMachine.getCurrentCallAudioState());
@@ -811,7 +815,7 @@
"Speakerphone turned off externally during speaker", // name
CallAudioState.ROUTE_SPEAKER, // initialRoute
CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
- NONE, // speakerInteraction
+ OFF, // speakerInteraction
ON, // bluetoothInteraction
CallAudioRouteStateMachine.SPEAKER_OFF, // action
CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index 4dffe59..0cc04d6 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -1019,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();
diff --git a/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java b/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
index 4ef4596..dbfcdb1 100644
--- a/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CarModeTrackerTest.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.tests;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertNull;
@@ -104,6 +105,17 @@
}
/**
+ * Ensure that we don't keep a package around after it's been removed from the device
+ */
+ @Test
+ public void testForceExitCarMode() {
+ testEnterCarModeBasic();
+ mCarModeTracker.forceExitCarMode(CAR_MODE_APP1_PACKAGE_NAME);
+ assertFalse(mCarModeTracker.isInCarMode());
+ assertNull(mCarModeTracker.getCurrentCarModePackage());
+ }
+
+ /**
* Verifies only the first app at the default priority gets tracked.
*/
@Test
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 46b1522..26f24ef 100755
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -249,6 +249,7 @@
@Override
public void createConnectionComplete(String id, Session.Info info) throws RemoteException {
+ Log.i(ConnectionServiceFixture.this, "createConnectionComplete: %s", id);
mConnectionServiceDelegateAdapter.createConnectionComplete(id, null /*Session.Info*/);
}
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index e16b598..0e5ac27 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -23,6 +23,7 @@
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.anyLong;
import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.ArgumentMatchers.nullable;
@@ -34,6 +35,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -65,6 +67,7 @@
import android.telecom.TelecomManager;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
import com.android.internal.telecom.IInCallAdapter;
@@ -98,6 +101,7 @@
import java.util.Collections;
import java.util.LinkedList;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
@RunWith(JUnit4.class)
@@ -133,6 +137,10 @@
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 PhoneAccountHandle PA_HANDLE =
new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
@@ -140,6 +148,8 @@
private InCallController mInCallController;
private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
private EmergencyCallHelper mEmergencyCallHelper;
+ private SystemStateHelper.SystemStateListener mSystemStateListener;
+ private CarModeTracker mCarModeTracker = spy(new CarModeTracker());
@Override
@Before
@@ -160,7 +170,13 @@
when(mMockCallsManager.getRoleManagerAdapter()).thenReturn(mMockRoleManagerAdapter);
mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter,
- mEmergencyCallHelper, new CarModeTracker(), mClockProxy);
+ mEmergencyCallHelper, mCarModeTracker, mClockProxy);
+
+ ArgumentCaptor<SystemStateHelper.SystemStateListener> systemStateListenerArgumentCaptor
+ = ArgumentCaptor.forClass(SystemStateHelper.SystemStateListener.class);
+ verify(mMockSystemStateHelper).addListener(systemStateListenerArgumentCaptor.capture());
+ mSystemStateListener = systemStateListenerArgumentCaptor.getValue();
+
when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
.thenReturn(mNotificationManager);
// Companion Apps don't have CONTROL_INCALL_EXPERIENCE permission.
@@ -177,6 +193,8 @@
return new String[] { CAR_PKG };
case CAR2_UID:
return new String[] { CAR2_PKG };
+ case NONUI_UID:
+ return new String[] { NONUI_PKG };
}
return null;
}).when(mMockPackageManager).getPackagesForUid(anyInt());
@@ -189,6 +207,9 @@
when(mMockPackageManager.checkPermission(
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
matches(CAR2_PKG))).thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mMockPackageManager.checkPermission(
+ matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
+ matches(NONUI_PKG))).thenReturn(PackageManager.PERMISSION_GRANTED);
}
@Override
@@ -199,6 +220,24 @@
super.tearDown();
}
+ @SmallTest
+ @Test
+ public void testCarModeAppRemoval() {
+ setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
+ when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+
+ when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
+
+ mSystemStateListener.onCarModeChanged(666, CAR_PKG, true);
+ verify(mCarModeTracker).handleEnterCarMode(666, CAR_PKG);
+ assertTrue(mCarModeTracker.isInCarMode());
+
+ mSystemStateListener.onPackageUninstalled(CAR_PKG);
+ verify(mCarModeTracker).forceExitCarMode(CAR_PKG);
+ assertFalse(mCarModeTracker.isInCarMode());
+ }
+
@MediumTest
@Test
public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
@@ -291,7 +330,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -350,7 +390,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -428,7 +469,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -510,7 +552,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -634,7 +677,8 @@
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
- eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ eq(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS),
+ eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
@@ -884,13 +928,15 @@
nullable(ContentResolver.class))).thenReturn(500L);
when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
- setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
+ setupMockPackageManager(true /* default */, true /* nonui */, true /* system */,
+ false /* external calls */,
+ false /* self mgd in default*/, false /* self mgd in car*/);
mInCallController.bindToServices(mMockCall);
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
ArgumentCaptor.forClass(ServiceConnection.class);
- verify(mMockContext, times(1)).bindServiceAsUser(
+ verify(mMockContext, times(2)).bindServiceAsUser(
bindIntentCaptor.capture(),
serviceConnectionCaptor.capture(),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
@@ -903,13 +949,39 @@
// Start the connection, make sure we don't unbind, and make sure that we don't send
// anything to the in-call service yet.
- ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
+ 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");
+ }
+
ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
IBinder mockBinder = mock(IBinder.class);
IInCallService mockInCallService = mock(IInCallService.class);
when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
- serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
+ serviceConnections.get(defDialerIdx).onServiceConnected(defDialerComponentName, mockBinder);
verify(mockInCallService).setInCallAdapter(nullable(IInCallAdapter.class));
// Make sure that the future completed without timing out.
@@ -1038,6 +1110,7 @@
serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.applicationInfo.uid = DEF_UID;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
+ serviceInfo.enabled = true;
serviceInfo.metaData = new Bundle();
serviceInfo.metaData.putBoolean(
TelecomManager.METADATA_IN_CALL_SERVICE_UI, true);
@@ -1065,6 +1138,7 @@
serviceInfo.applicationInfo.uid = CAR2_UID;
}
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
+ serviceInfo.enabled = true;
serviceInfo.metaData = new Bundle();
serviceInfo.metaData.putBoolean(
TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI, true);
@@ -1086,6 +1160,7 @@
serviceInfo.name = SYS_CLASS;
serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.applicationInfo.uid = SYS_UID;
+ serviceInfo.enabled = true;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
}};
}
@@ -1097,13 +1172,26 @@
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() {
+ 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;
}};
}
private void setupMockPackageManager(final boolean useDefaultDialer,
final boolean useSystemDialer, final boolean includeExternalCalls) {
- setupMockPackageManager(useDefaultDialer, useSystemDialer, includeExternalCalls,
+ setupMockPackageManager(useDefaultDialer, false, useSystemDialer, includeExternalCalls,
false /* self mgd */, false /* self mgd */);
}
@@ -1111,6 +1199,16 @@
final boolean useSystemDialer, final boolean includeExternalCalls,
final boolean includeSelfManagedCallsInDefaultDialer,
final boolean includeSelfManagedCallsInCarModeDialer) {
+ setupMockPackageManager(useDefaultDialer, false /* nonui */, useSystemDialer,
+ includeExternalCalls, includeSelfManagedCallsInDefaultDialer,
+ includeSelfManagedCallsInCarModeDialer);
+ }
+
+ private void setupMockPackageManager(final boolean useDefaultDialer,
+ final boolean useNonUiInCalls,
+ final boolean useSystemDialer, final boolean includeExternalCalls,
+ final boolean includeSelfManagedCallsInDefaultDialer,
+ final boolean includeSelfManagedCallsInCarModeDialer) {
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
@@ -1145,11 +1243,17 @@
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());
+ }
}
+
return resolveInfo;
}
}).when(mMockPackageManager).queryIntentServicesAsUser(
- any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
+ any(Intent.class), anyInt(), eq(CURRENT_USER_ID));
}
private void setupMockPackageManagerLocationPermission(final String pkg,
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index 9470008..a5b78b7 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -229,7 +229,7 @@
mComponentContextFixture.putResource(R.string.dialer_default_class,
dialer_default_class_string);
when(mDefaultDialerCache.getSystemDialerApplication()).thenReturn(ui_package_string);
- when(mDefaultDialerCache.getSystemDialerComponent()).thenReturn(
+ when(mDefaultDialerCache.getDialtactsSystemDialerComponent()).thenReturn(
new ComponentName(ui_package_string, dialer_default_class_string));
int result = processIntent(intent, false).disconnectCause;
diff --git a/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java b/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
index 2de3c83..893ae3d 100644
--- a/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
+++ b/tests/src/com/android/server/telecom/tests/SystemStateHelperTest.java
@@ -16,6 +16,8 @@
package com.android.server.telecom.tests;
+import static junit.framework.Assert.fail;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -23,9 +25,11 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,6 +43,7 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.net.Uri;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.SystemStateHelper;
@@ -53,11 +58,10 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.util.reflection.FieldSetter;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
/**
* Unit tests for SystemStateHelper
@@ -128,16 +132,53 @@
@SmallTest
@Test
- public void testReceiverAndIntentFilter() {
- ArgumentCaptor<IntentFilter> intentFilter = ArgumentCaptor.forClass(IntentFilter.class);
- new SystemStateHelper(mContext);
- verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
+ public void testPackageRemoved() {
+ ArgumentCaptor<BroadcastReceiver> receiver =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ new SystemStateHelper(mContext).addListener(mSystemStateListener);
+ verify(mContext, atLeastOnce())
+ .registerReceiver(receiver.capture(), any(IntentFilter.class));
+ Intent packageRemovedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+ packageRemovedIntent.setData(Uri.fromParts("package", "com.android.test", null));
+ receiver.getValue().onReceive(mContext, packageRemovedIntent);
+ verify(mSystemStateListener).onPackageUninstalled("com.android.test");
+ }
- assertEquals(2, intentFilter.getValue().countActions());
- assertEquals(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED,
- intentFilter.getValue().getAction(0));
- assertEquals(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED,
- intentFilter.getValue().getAction(1));
+ @SmallTest
+ @Test
+ public void testReceiverAndIntentFilter() {
+ ArgumentCaptor<IntentFilter> intentFilterCaptor =
+ ArgumentCaptor.forClass(IntentFilter.class);
+ new SystemStateHelper(mContext);
+ verify(mContext, times(2)).registerReceiver(
+ any(BroadcastReceiver.class), intentFilterCaptor.capture());
+
+ Predicate<IntentFilter> carModeFilterTest = (intentFilter) ->
+ 2 == intentFilter.countActions()
+ && intentFilter.hasAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED)
+ && intentFilter.hasAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+
+ Predicate<IntentFilter> packageRemovedFilterTest = (intentFilter) ->
+ 1 == intentFilter.countActions()
+ && intentFilter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
+ && intentFilter.hasDataScheme("package");
+
+ List<IntentFilter> capturedFilters = intentFilterCaptor.getAllValues();
+ assertEquals(2, capturedFilters.size());
+ for (IntentFilter filter : capturedFilters) {
+ if (carModeFilterTest.test(filter)) {
+ carModeFilterTest = (i) -> false;
+ continue;
+ }
+ if (packageRemovedFilterTest.test(filter)) {
+ packageRemovedFilterTest = (i) -> false;
+ continue;
+ }
+ String failString = String.format("Registered intent filters not correct. Got %s",
+ capturedFilters.stream().map(IntentFilter::toString)
+ .collect(Collectors.joining("\n")));
+ fail(failString);
+ }
}
@SmallTest
@@ -147,7 +188,8 @@
ArgumentCaptor.forClass(BroadcastReceiver.class);
new SystemStateHelper(mContext).addListener(mSystemStateListener);
- verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
+ verify(mContext, atLeastOnce())
+ .registerReceiver(receiver.capture(), any(IntentFilter.class));
when(mIntentEnter.getAction()).thenReturn(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
receiver.getValue().onReceive(mContext, mIntentEnter);
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 442c310..152dfe5 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -925,7 +925,12 @@
// Wait for the handler to start the CallerInfo lookup
waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ // Wait a few more times to address flakiness due to timing issues.
+ waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+
// Ensure callback to CS on successful creation happened.
+
verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
.createConnectionComplete(anyString(), any());
diff --git a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
index b0b1ec0..264e087 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
@@ -25,8 +25,10 @@
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";
@@ -75,4 +77,13 @@
}
}
}
+
+ 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;
+ }
}