Merge "OTASP: use registraint instead of PhoneStateListener"
diff --git a/Android.bp b/Android.bp
index e8946da..76e910f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,7 +16,7 @@
// for the 'other' dialer.
android_app {
- name: "TeleServiceLib",
+ name: "TeleService",
libs: [
"telephony-common",
@@ -24,6 +24,7 @@
"ims-common",
"org.apache.http.legacy",
"libprotobuf-java-lite",
+ "unsupportedappusage",
],
static_libs: [
@@ -38,12 +39,15 @@
],
srcs: [
+ ":framework-telephony-stack-shared-srcs",
"src/**/*.java",
"sip/src/**/*.java",
"ecc/proto/**/*.proto",
"src/com/android/phone/EventLogTags.logtags",
],
+ jarjar_rules: ":jarjar-rules-shared",
+
resource_dirs: [
"res",
"sip/res",
@@ -56,12 +60,8 @@
aaptflags: [
"--extra-packages com.android.services.telephony.sip",
- "--shared-lib",
- "--extra-packages com.android.phone",
],
- export_package_resources: true,
-
platform_apis: true,
certificate: "platform",
@@ -71,7 +71,6 @@
proguard_flags_files: [
"proguard.flags",
"sip/proguard.flags",
- "proguard.proguard",
],
},
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bf80b91..1d32288 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,10 +15,613 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.phone.lib">
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ package="com.android.phone"
+ coreApp="true"
+ android:sharedUserId="android.uid.phone"
+ android:sharedUserLabel="@string/phoneAppLabel"
+>
- <application>
- <library android:name="com.android.phone.lib" />
+ <original-package android:name="com.android.phone" />
+
+ <protected-broadcast android:name="android.telecom.action.TTY_PREFERRED_MODE_CHANGED" />
+ <protected-broadcast android:name="android.telecom.action.CURRENT_TTY_MODE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.SERVICE_STATE" />
+ <protected-broadcast android:name="android.intent.action.RADIO_TECHNOLOGY" />
+ <protected-broadcast android:name="android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.EMERGENCY_CALL_STATE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.SIG_STR" />
+ <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
+ <protected-broadcast android:name="android.intent.action.DATA_CONNECTION_FAILED" />
+ <protected-broadcast android:name="android.intent.action.DATA_STALL_DETECTED" />
+ <protected-broadcast android:name="android.intent.action.SIM_STATE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.NETWORK_SET_TIME" />
+ <protected-broadcast android:name="com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS" />
+ <protected-broadcast android:name="android.intent.action.ACTION_MDN_STATE_CHANGED" />
+ <protected-broadcast android:name="android.provider.Telephony.SPN_STRINGS_UPDATED" />
+ <protected-broadcast android:name="android.provider.Telephony.SIM_FULL" />
+ <protected-broadcast android:name="com.android.internal.telephony.data-restart-trysetup" />
+ <protected-broadcast android:name="com.android.internal.telephony.data-stall" />
+ <protected-broadcast android:name="android.intent.action.DATA_SMS_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_DELIVER" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_REJECTED" />
+ <protected-broadcast android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
+ <protected-broadcast android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_CB_RECEIVED" />
+ <protected-broadcast android:name="android.provider.action.SMS_EMERGENCY_CB_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SECRET_CODE" />
+ <protected-broadcast android:name= "com.android.internal.stk.command" />
+ <protected-broadcast android:name= "com.android.internal.stk.session_end" />
+ <protected-broadcast android:name= "com.android.internal.stk.icc_status_change" />
+ <protected-broadcast android:name= "com.android.internal.stk.alpha_notify" />
+ <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
+ <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED" />
+ <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE" />
+ <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+ <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
+ <protected-broadcast android:name= "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED" />
+ <protected-broadcast android:name= "com.android.internal.telephony.ACTION_REPORT_RADIO_BUG" />
+ <protected-broadcast android:name= "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED" />
+ <protected-broadcast android:name= "com.android.intent.isim_refresh" />
+ <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_AVAILABLE" />
+ <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_UNAVAILABLE" />
+ <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_DIED" />
+ <protected-broadcast android:name= "com.android.ims.ACTION_PRESENCE_CHANGED" />
+ <protected-broadcast android:name= "com.android.ims.ACTION_PUBLISH_STATUS_CHANGED" />
+ <protected-broadcast android:name= "com.android.ims.IMS_SERVICE_UP" />
+ <protected-broadcast android:name= "com.android.ims.IMS_SERVICE_DOWN" />
+ <protected-broadcast android:name= "com.android.ims.IMS_INCOMING_CALL" />
+ <protected-broadcast android:name= "com.android.ims.internal.uce.UCE_SERVICE_UP" />
+ <protected-broadcast android:name= "com.android.ims.internal.uce.UCE_SERVICE_DOWN" />
+ <protected-broadcast android:name= "com.android.imsconnection.DISCONNECTED" />
+ <protected-broadcast android:name= "com.android.intent.action.IMS_FEATURE_CHANGED" />
+ <protected-broadcast android:name= "com.android.intent.action.IMS_CONFIG_CHANGED" />
+ <protected-broadcast android:name= "com.android.ims.REGISTRATION_ERROR" />
+ <protected-broadcast android:name= "com.android.phone.vvm.omtp.sms.REQUEST_SENT" />
+ <protected-broadcast android:name= "com.android.phone.vvm.ACTION_VISUAL_VOICEMAIL_SERVICE_EVENT" />
+ <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED" />
+ <protected-broadcast android:name= "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO" />
+ <protected-broadcast android:name= "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD" />
+ <protected-broadcast android:name= "com.android.internal.telephony.OPEN_DEFAULT_SMS_APP" />
+ <protected-broadcast android:name= "android.telephony.action.SIM_CARD_STATE_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.NETWORK_COUNTRY_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED" />
+
+ <!-- For Vendor Debugging in Telephony -->
+ <protected-broadcast android:name="android.telephony.action.ANOMALY_REPORTED" />
+
+ <!-- Allows granting runtime permissions to telephony related components. -->
+ <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS" />
+
+ <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.CALL_PHONE" />
+ <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
+ <!-- TELEPHONY_SECRET_CODE used to be sent by the Dialer app, but is now sent by
+ the phone process through an API added in O. Since the broadcast was unprotected prior to
+ O, apps may have required this permission (which only Dialer has) in their receivers.
+ So, declare this permission here for backwards compatibility so the phone process can send
+ the broadcasts to those same receivers. -->
+ <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
+ <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.READ_CALL_LOG" />
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+ <uses-permission android:name="android.permission.VIBRATE" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
+ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.STATUS_BAR" />
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+ <uses-permission android:name="android.permission.RECEIVE_SMS" />
+ <uses-permission android:name="android.permission.READ_SMS" />
+ <uses-permission android:name="android.permission.WRITE_SMS" />
+ <uses-permission android:name="android.permission.SEND_SMS" />
+ <uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" />
+ <uses-permission android:name="android.permission.SET_TIME" />
+ <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
+ <uses-permission android:name="android.permission.BROADCAST_SMS"/>
+ <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"/>
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.SHUTDOWN" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.PERFORM_CDMA_PROVISIONING" />
+ <uses-permission android:name="android.permission.USE_SIP" />
+ <uses-permission android:name="android.permission.REBOOT" />
+ <uses-permission android:name="android.permission.UPDATE_LOCK" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND" />
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
+ <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
+ <uses-permission android:name="android.permission.NETWORK_FACTORY" />
+ <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
+ <uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
+ <uses-permission android:name="android.permission.READ_SEARCH_INDEXABLES" />
+ <uses-permission android:name="android.permission.DUMP" />
+ <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
+ <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
+ <uses-permission android:name="android.permission.BIND_IMS_SERVICE" />
+ <uses-permission android:name="android.permission.BIND_CARRIER_SERVICES" />
+ <!-- BIND_CARRIER_MESSAGING_SERVICE has been deprecated in favor of BIND_CARRIER_SERVICES. -->
+ <uses-permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE" />
+ <uses-permission android:name="android.permission.BIND_EUICC_SERVICE" />
+ <uses-permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" />
+ <uses-permission android:name="android.permission.BIND_CELL_BROADCAST_SERVICE" />
+ <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
+ <uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL" />
+ <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL" />
+ <uses-permission android:name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
+ <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
+ <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST" />
+ <!-- Needed to block messages. -->
+ <uses-permission android:name="android.permission.READ_BLOCKED_NUMBERS" />
+ <!-- Needed for emergency contact notification. -->
+ <uses-permission android:name="android.permission.WRITE_BLOCKED_NUMBERS" />
+ <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
+
+ <!-- This tells the activity manager to not delay any of our activity
+ start requests, even if they happen immediately after the user
+ presses home. -->
+ <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
+ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+ <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+ <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+ <uses-permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE" />
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
+ <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
+ <!-- Allows us to whitelist receivers of the
+ ACTION_SIM_SLOT_STATUS_CHANGED broadcast to start activities
+ from the background. -->
+ <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
+
+ <application android:name="PhoneApp"
+ android:persistent="true"
+ android:label="@string/phoneAppLabel"
+ android:icon="@mipmap/ic_launcher_phone"
+ android:allowBackup="false"
+ android:supportsRtl="true"
+ android:usesCleartextTraffic="true"
+ android:defaultToDeviceProtectedStorage="true"
+ android:directBootAware="true">
+
+ <provider android:name="IccProvider"
+ android:authorities="icc"
+ android:multiprocess="true"
+ android:exported="true"
+ android:readPermission="android.permission.READ_CONTACTS"
+ android:writePermission="android.permission.WRITE_CONTACTS" />
+
+ <!-- Dialer UI that only allows emergency calls -->
+ <activity android:name="EmergencyDialer"
+ android:label="@string/emergencyDialerIconLabel"
+ android:theme="@style/EmergencyDialerTheme"
+ android:screenOrientation="portrait"
+ android:resizeableActivity="false">
+ <intent-filter>
+ <action android:name="com.android.phone.EmergencyDialer.DIAL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="com.android.phone.EmergencyDialer.DIAL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="tel" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="ADNList" />
+
+ <activity android:name="SimContacts"
+ android:label="@string/simContacts_title"
+ android:theme="@style/SimImportTheme"
+ android:screenOrientation="portrait"
+ android:icon="@mipmap/ic_launcher_contacts">
+
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.item/sim-contact" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="com.android.phone.settings.fdn.FdnList"
+ android:label="@string/fdnListLabel"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.item/sim-contact" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="com.android.internal.telephony.uicc.InstallCarrierAppTrampolineActivity"
+ android:theme="@android:style/Theme.Translucent.NoTitleBar"
+ android:exported="false"/>
+
+ <activity android:name="GsmUmtsCallOptions"
+ android:label="@string/gsm_umts_options"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="CdmaCallOptions"
+ android:label="@string/cdma_options"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="GsmUmtsCallForwardOptions"
+ android:label="@string/labelCF"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="GsmUmtsCallBarringOptions"
+ android:label="@string/labelCallBarring"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/CallSettingsWithoutDividerTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="GsmUmtsAdditionalCallOptions"
+ android:label="@string/labelGSMMore"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <!-- fdn setting -->
+ <activity android:name="com.android.phone.settings.fdn.FdnSetting"
+ android:label="@string/fdn"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <!-- SIM PIN setting -->
+ <activity android:name="EnableIccPinScreen"
+ android:label="@string/enable_pin"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="ChangeIccPinScreen"
+ android:label="@string/change_pin"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="com.android.phone.settings.fdn.GetPin2Screen"
+ android:label="@string/get_pin2"
+ android:theme="@style/DialerSettingsLight"
+ android:windowSoftInputMode="stateVisible">
+ </activity>
+
+ <activity android:name="com.android.phone.settings.fdn.EditFdnContactScreen"
+ android:theme="@style/DialerSettingsLight"
+ android:windowSoftInputMode="stateVisible">
+ </activity>
+
+ <activity android:name="com.android.phone.settings.fdn.DeleteFdnContactScreen"
+ android:theme="@style/DialerSettingsLight"
+ android:label="@string/delete_fdn_contact">
+ </activity>
+
+ <!-- "Call settings" UI, used only on voice-capable phone devices. -->
+ <activity android:name="CallFeaturesSetting"
+ android:label="@string/call_settings"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.telecom.action.SHOW_CALL_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!-- Activation service that trigger OTASP sim provisioning -->
+ <service android:name=".otasp.OtaspActivationService" android:launchMode="singleInstance"
+ androidprv:systemUserOnly="true"
+ android:permission="android.permission.MODIFY_PHONE_STATE">
+ <intent-filter>
+ <action android:name="android.service.simActivation.SimActivationService" />
+ </intent-filter>
+ </service>
+
+ <receiver android:name=".otasp.OtaspSimStateReceiver" androidprv:systemUserOnly="true"
+ android:exported ="false">
+ <intent-filter>
+ <action android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
+ </intent-filter>
+ </receiver>
+
+ <!-- "Accessibility" settings UI. Referenced by Dialer application. -->
+ <activity android:name="com.android.phone.settings.AccessibilitySettingsActivity"
+ android:label="@string/accessibility_settings_activity_title"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!-- CDMA Emergency Callback Mode -->
+ <service android:name="EmergencyCallbackModeService">
+ </service>
+
+ <!-- service to dump telephony information -->
+ <service android:name="com.android.phone.TelephonyDebugService"
+ android:permission="android.permission.DUMP">
+ <intent-filter>
+ <action android:name="com.android.phone.TelephonyDebugService" />
+ </intent-filter>
+ </service>
+
+ <!-- Handler for EuiccManager's public-facing intents. -->
+ <activity android:name=".euicc.EuiccUiDispatcherActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:permission="android.permission.MODIFY_PHONE_STATE">
+ <!-- Max out priority to ensure nobody else will handle these intents. -->
+ <intent-filter android:priority="1000">
+ <action android:name=
+ "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS" />
+ <action android:name=
+ "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!--
+ Handler for EuiccManager's resolution intents. These are locked down so that only
+ privileged processes can start them, which means we can trust the Intent used to start
+ it (which contains a description of the next step to perform after resolution).
+ -->
+ <activity android:name=".euicc.EuiccResolutionUiDispatcherActivity"
+ android:permission="android.permission.CALL_PRIVILEGED">
+ <!-- Max out priority to ensure nobody else will handle these intents. -->
+ <intent-filter android:priority="1000">
+ <action android:name=
+ "android.telephony.euicc.action.RESOLVE_ERROR" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!--
+ Handler for EuiccManager's privileged action intents. These are locked down so that only
+ privileged processes can start them.
+ -->
+ <activity android:name=".euicc.EuiccPrivilegedActionUiDispatcherActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:permission="android.permission.CALL_PRIVILEGED">
+ <!-- Max out priority to ensure nobody else will handle these intents. -->
+ <intent-filter android:priority="1000">
+ <action android:name=
+ "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED" />
+ <action android:name=
+ "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED" />
+ <action android:name=
+ "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!--
+ Handler for EuiccManager's public action intents. These are public and do not require
+ any special permissions to start, although the calling package name should be
+ whitelisted by the underlying eUICC service implementation (i.e. the LPA).
+ -->
+ <activity android:name=".euicc.EuiccPublicActionUiDispatcherActivity"
+ android:theme="@android:style/Theme.NoDisplay">
+ <!-- Max out priority to ensure nobody else will handle these intents. -->
+ <intent-filter android:priority="1000">
+ <action android:name=
+ "android.telephony.euicc.action.START_EUICC_ACTIVATION" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="EmergencyCallbackModeExitDialog"
+ android:excludeFromRecents="true"
+ android:label="@string/ecm_exit_dialog"
+ android:launchMode="singleTop"
+ android:theme="@android:style/Theme.Translucent.NoTitleBar">
+ <intent-filter>
+ <action android:name="com.android.phone.action.ACTION_SHOW_ECM_EXIT_DIALOG" />
+ <action android:name="com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!-- Start SIP -->
+ <service android:name="com.android.services.telephony.sip.SipConnectionService"
+ android:label="@string/sip_connection_service_label"
+ android:singleUser="true"
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+ <intent-filter>
+ <action android:name="android.telecom.ConnectionService" />
+ </intent-filter>
+ </service>
+
+ <receiver android:name="com.android.services.telephony.sip.SipIncomingCallReceiver">
+ <intent-filter>
+ <action android:name="com.android.phone.SIP_INCOMING_CALL" />
+ </intent-filter>
+ </receiver>
+
+ <activity android:name="com.android.services.telephony.sip.SipPhoneAccountSettingsActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:excludeFromRecents="true">
+ <intent-filter>
+ <action android:name="android.telecom.action.CONFIGURE_PHONE_ACCOUNT" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:label="Sip Settings"
+ android:name="com.android.services.telephony.sip.SipSettings"
+ android:theme="@style/DialerSettingsLight"
+ android:launchMode="singleTop"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:uiOptions="splitActionBarWhenNarrow"
+ android:parentActivityName="com.android.phone.CallFeaturesSetting" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.net.sip.NOTIFY" />
+ </intent-filter>
+ </activity>
+ <activity android:name="com.android.services.telephony.sip.SipEditor"
+ android:theme="@style/DialerSettingsLight"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:uiOptions="splitActionBarWhenNarrow">
+ </activity>
+
+ <!-- End SIP -->
+
+ <activity android:name="MMIDialogActivity"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@style/Empty">
+ </activity>
+
+ <activity android:name="com.android.phone.settings.PhoneAccountSettingsActivity"
+ android:label="@string/phone_accounts"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter>
+ <action android:name="android.telecom.action.CHANGE_PHONE_ACCOUNTS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="com.android.phone.settings.VoicemailSettingsActivity"
+ android:label="@string/voicemail"
+ android:configChanges="orientation|screenSize|keyboardHidden|screenLayout"
+ android:screenOrientation="portrait"
+ android:theme="@style/DialerSettingsLight">
+ <intent-filter >
+ <!-- DO NOT RENAME. There are existing apps which use this string. -->
+ <action android:name="com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.telephony.action.CONFIGURE_VOICEMAIL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <!-- Telecom integration -->
+ <service
+ android:singleUser="true"
+ android:name="com.android.services.telephony.TelephonyConnectionService"
+ android:label="@string/pstn_connection_service_label"
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+ <intent-filter>
+ <action android:name="android.telecom.ConnectionService" />
+ </intent-filter>
+ </service>
+
+ <receiver
+ android:name="com.android.phone.vvm.VvmSmsReceiver"
+ android:exported="false"
+ androidprv:systemUserOnly="true">
+ <intent-filter>
+ <action android:name="com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED"/>
+ </intent-filter>
+ </receiver>
+
+ <receiver
+ android:name="com.android.phone.vvm.VvmSimStateTracker"
+ android:exported="false"
+ androidprv:systemUserOnly="true">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>
+ <action android:name="android.telephony.action.CARRIER_CONFIG_CHANGED"/>
+ <action android:name="android.intent.action.SIM_STATE_CHANGED"/>
+ </intent-filter>
+ </receiver>
+
+ <receiver
+ android:name="com.android.internal.telephony.uicc.ShowInstallAppNotificationReceiver"
+ android:exported="false"/>
+
+ <activity
+ android:name="com.android.phone.settings.PickSmsSubscriptionActivity"
+ android:exported="false"
+ android:excludeFromRecents="true"
+ android:launchMode="singleTop"
+ android:configChanges="orientation|screenSize|keyboardHidden"
+ android:theme="@style/Theme.Transparent"/>
+
+ <service
+ android:name="com.android.phone.vvm.RemoteVvmTaskManager"
+ android:exported="false"/>
+ <service android:name="com.android.internal.telephony.CellularNetworkService"
+ android:permission="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" >
+ <intent-filter>
+ <action android:name="android.telephony.NetworkService" />
+ </intent-filter>
+ </service>
+ <service android:name="com.android.internal.telephony.dataconnection.CellularDataService"
+ android:permission="android.permission.BIND_TELEPHONY_DATA_SERVICE" >
+ <intent-filter>
+ <action android:name="android.telephony.data.DataService" />
+ </intent-filter>
+ </service>
</application>
-
</manifest>
diff --git a/client/Android.bp b/client/Android.bp
deleted file mode 100644
index 45c6527..0000000
--- a/client/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Build the Phone app which includes the emergency dialer. See Contacts
-// for the 'other' dialer.
-
-android_app {
- name: "TeleService",
-
- libs: [
- "telephony-common",
- "voip-common",
- "ims-common",
- "libprotobuf-java-lite",
- "TeleServiceLib",
- ],
-
- required: ["TeleServiceLib"],
-
- platform_apis: true,
-
- certificate: "platform",
- privileged: true,
-
- defaults: ["SettingsLibDefaults"],
-
- proto: {
- type: "lite",
- },
-}
diff --git a/client/AndroidManifest.xml b/client/AndroidManifest.xml
deleted file mode 100644
index c7974b4..0000000
--- a/client/AndroidManifest.xml
+++ /dev/null
@@ -1,649 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- package="com.android.phone"
- coreApp="true"
- android:sharedUserId="android.uid.phone"
- android:sharedUserLabel="@string/phoneAppLabel"
->
-
- <original-package android:name="com.android.phone" />
-
- <protected-broadcast android:name="android.telecom.action.TTY_PREFERRED_MODE_CHANGED" />
- <protected-broadcast android:name="android.telecom.action.CURRENT_TTY_MODE_CHANGED" />
- <protected-broadcast android:name="android.intent.action.SERVICE_STATE" />
- <protected-broadcast android:name="android.intent.action.RADIO_TECHNOLOGY" />
- <protected-broadcast android:name="android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED" />
- <protected-broadcast android:name="android.intent.action.EMERGENCY_CALL_STATE_CHANGED" />
- <protected-broadcast android:name="android.intent.action.SIG_STR" />
- <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
- <protected-broadcast android:name="android.intent.action.DATA_CONNECTION_FAILED" />
- <protected-broadcast android:name="android.intent.action.DATA_STALL_DETECTED" />
- <protected-broadcast android:name="android.intent.action.SIM_STATE_CHANGED" />
- <protected-broadcast android:name="android.intent.action.NETWORK_SET_TIME" />
- <protected-broadcast android:name="android.intent.action.NETWORK_SET_TIMEZONE" />
- <protected-broadcast android:name="com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS" />
- <protected-broadcast android:name="android.intent.action.ACTION_MDN_STATE_CHANGED" />
- <protected-broadcast android:name="android.provider.Telephony.SPN_STRINGS_UPDATED" />
- <protected-broadcast android:name="android.provider.Telephony.SIM_FULL" />
- <protected-broadcast android:name="com.android.internal.telephony.data-restart-trysetup" />
- <protected-broadcast android:name="com.android.internal.telephony.data-stall" />
- <protected-broadcast android:name="android.intent.action.DATA_SMS_RECEIVED" />
- <protected-broadcast android:name="android.provider.Telephony.SMS_RECEIVED" />
- <protected-broadcast android:name="android.provider.Telephony.SMS_DELIVER" />
- <protected-broadcast android:name="android.provider.Telephony.SMS_REJECTED" />
- <protected-broadcast android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
- <protected-broadcast android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
- <protected-broadcast android:name="android.provider.Telephony.SMS_CB_RECEIVED" />
- <protected-broadcast android:name="android.provider.action.SMS_EMERGENCY_CB_RECEIVED" />
- <protected-broadcast android:name="android.provider.Telephony.SECRET_CODE" />
- <protected-broadcast android:name= "com.android.internal.stk.command" />
- <protected-broadcast android:name= "com.android.internal.stk.session_end" />
- <protected-broadcast android:name= "com.android.internal.stk.icc_status_change" />
- <protected-broadcast android:name= "com.android.internal.stk.alpha_notify" />
- <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
- <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED" />
- <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE" />
- <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
- <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
- <protected-broadcast android:name= "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED" />
- <protected-broadcast android:name= "com.android.internal.telephony.ACTION_REPORT_RADIO_BUG" />
- <protected-broadcast android:name= "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED" />
- <protected-broadcast android:name= "com.android.intent.isim_refresh" />
- <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_AVAILABLE" />
- <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_UNAVAILABLE" />
- <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_DIED" />
- <protected-broadcast android:name= "com.android.ims.ACTION_PRESENCE_CHANGED" />
- <protected-broadcast android:name= "com.android.ims.ACTION_PUBLISH_STATUS_CHANGED" />
- <protected-broadcast android:name= "com.android.ims.IMS_SERVICE_UP" />
- <protected-broadcast android:name= "com.android.ims.IMS_SERVICE_DOWN" />
- <protected-broadcast android:name= "com.android.ims.IMS_INCOMING_CALL" />
- <protected-broadcast android:name= "com.android.ims.internal.uce.UCE_SERVICE_UP" />
- <protected-broadcast android:name= "com.android.ims.internal.uce.UCE_SERVICE_DOWN" />
- <protected-broadcast android:name= "com.android.imsconnection.DISCONNECTED" />
- <protected-broadcast android:name= "com.android.intent.action.IMS_FEATURE_CHANGED" />
- <protected-broadcast android:name= "com.android.intent.action.IMS_CONFIG_CHANGED" />
- <protected-broadcast android:name= "com.android.ims.REGISTRATION_ERROR" />
- <protected-broadcast android:name= "com.android.phone.vvm.omtp.sms.REQUEST_SENT" />
- <protected-broadcast android:name= "com.android.phone.vvm.ACTION_VISUAL_VOICEMAIL_SERVICE_EVENT" />
- <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED" />
- <protected-broadcast android:name= "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO" />
- <protected-broadcast android:name= "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD" />
- <protected-broadcast android:name= "com.android.internal.telephony.OPEN_DEFAULT_SMS_APP" />
- <protected-broadcast android:name= "android.telephony.action.SIM_CARD_STATE_CHANGED" />
- <protected-broadcast android:name= "android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
- <protected-broadcast android:name= "android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
- <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED" />
- <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED" />
- <protected-broadcast android:name= "android.telephony.action.NETWORK_COUNTRY_CHANGED" />
- <protected-broadcast android:name= "android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED" />
-
- <!-- For Vendor Debugging in Telephony -->
- <protected-broadcast android:name="android.telephony.action.ANOMALY_REPORTED" />
-
- <!-- Allows granting runtime permissions to telephony related components. -->
- <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS" />
-
- <uses-permission android:name="android.permission.BROADCAST_STICKY" />
- <uses-permission android:name="android.permission.CALL_PHONE" />
- <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
- <!-- TELEPHONY_SECRET_CODE used to be sent by the Dialer app, but is now sent by
- the phone process through an API added in O. Since the broadcast was unprotected prior to
- O, apps may have required this permission (which only Dialer has) in their receivers.
- So, declare this permission here for backwards compatibility so the phone process can send
- the broadcasts to those same receivers. -->
- <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
- <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.READ_CALL_LOG" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
- <uses-permission android:name="android.permission.VIBRATE" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.REORDER_TASKS" />
- <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
- <uses-permission android:name="android.permission.STATUS_BAR" />
- <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
- <uses-permission android:name="android.permission.RECEIVE_SMS" />
- <uses-permission android:name="android.permission.READ_SMS" />
- <uses-permission android:name="android.permission.WRITE_SMS" />
- <uses-permission android:name="android.permission.SEND_SMS" />
- <uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" />
- <uses-permission android:name="android.permission.SET_TIME" />
- <uses-permission android:name="android.permission.SET_TIME_ZONE" />
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- <uses-permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE" />
- <uses-permission android:name="android.permission.DEVICE_POWER" />
- <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
- <uses-permission android:name="android.permission.BROADCAST_SMS"/>
- <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <uses-permission android:name="android.permission.SHUTDOWN" />
- <uses-permission android:name="android.permission.RECORD_AUDIO" />
- <uses-permission android:name="android.permission.PERFORM_CDMA_PROVISIONING" />
- <uses-permission android:name="android.permission.USE_SIP" />
- <uses-permission android:name="android.permission.REBOOT" />
- <uses-permission android:name="android.permission.UPDATE_LOCK" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
- <uses-permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND" />
- <uses-permission android:name="android.permission.MANAGE_USERS" />
- <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
- <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
- <uses-permission android:name="android.permission.NETWORK_FACTORY" />
- <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
- <uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
- <uses-permission android:name="android.permission.READ_SEARCH_INDEXABLES" />
- <uses-permission android:name="android.permission.DUMP" />
- <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
- <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
- <uses-permission android:name="android.permission.BIND_IMS_SERVICE" />
- <uses-permission android:name="android.permission.BIND_CARRIER_SERVICES" />
- <!-- BIND_CARRIER_MESSAGING_SERVICE has been deprecated in favor of BIND_CARRIER_SERVICES. -->
- <uses-permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE" />
- <uses-permission android:name="android.permission.BIND_EUICC_SERVICE" />
- <uses-permission android:name="com.android.permission.BIND_TELEPHONY_NETWORK_SERVICE" />
- <uses-permission android:name="android.permission.BIND_CELL_BROADCAST_SERVICE" />
- <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
- <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
- <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
- <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
- <uses-permission android:name="android.permission.GET_ACCOUNTS" />
- <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
- <uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL" />
- <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL" />
- <uses-permission android:name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
- <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
- <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
- <uses-permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST" />
- <!-- Needed to block messages. -->
- <uses-permission android:name="android.permission.READ_BLOCKED_NUMBERS" />
- <!-- Needed for emergency contact notification. -->
- <uses-permission android:name="android.permission.WRITE_BLOCKED_NUMBERS" />
- <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
-
- <!-- This tells the activity manager to not delay any of our activity
- start requests, even if they happen immediately after the user
- presses home. -->
- <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
- <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
- <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
- <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
- <uses-permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE" />
- <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
- <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
- <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
- <!-- Allows us to whitelist receivers of the
- ACTION_SIM_SLOT_STATUS_CHANGED broadcast to start activities
- from the background. -->
- <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
-
- <application android:name="PhoneApp"
- android:persistent="true"
- android:label="@string/phoneAppLabel"
- android:icon="@mipmap/ic_launcher_phone"
- android:allowBackup="false"
- android:supportsRtl="true"
- android:usesCleartextTraffic="true"
- android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true">
-
- <uses-library android:name="com.android.phone.lib" />
-
- <provider android:name="IccProvider"
- android:authorities="icc"
- android:multiprocess="true"
- android:exported="true"
- android:readPermission="android.permission.READ_CONTACTS"
- android:writePermission="android.permission.WRITE_CONTACTS" />
-
- <!-- Dialer UI that only allows emergency calls -->
- <activity android:name="EmergencyDialer"
- android:label="@string/emergencyDialerIconLabel"
- android:theme="@style/EmergencyDialerTheme"
- android:screenOrientation="portrait"
- android:resizeableActivity="false">
- <intent-filter>
- <action android:name="com.android.phone.EmergencyDialer.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.android.phone.EmergencyDialer.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="tel" />
- </intent-filter>
- </activity>
-
- <activity android:name="ADNList" />
-
- <activity android:name="SimContacts"
- android:label="@string/simContacts_title"
- android:theme="@style/SimImportTheme"
- android:screenOrientation="portrait"
- android:icon="@mipmap/ic_launcher_contacts">
-
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/sim-contact" />
- </intent-filter>
- </activity>
-
- <activity android:name="com.android.phone.settings.fdn.FdnList"
- android:label="@string/fdnListLabel"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/sim-contact" />
- </intent-filter>
- </activity>
-
- <activity android:name="com.android.internal.telephony.uicc.InstallCarrierAppTrampolineActivity"
- android:theme="@android:style/Theme.Translucent.NoTitleBar"
- android:exported="false"/>
-
- <activity android:name="GsmUmtsCallOptions"
- android:label="@string/gsm_umts_options"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <activity android:name="CdmaCallOptions"
- android:label="@string/cdma_options"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <activity android:name="GsmUmtsCallForwardOptions"
- android:label="@string/labelCF"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <activity android:name="GsmUmtsCallBarringOptions"
- android:label="@string/labelCallBarring"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/CallSettingsWithoutDividerTheme">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <activity android:name="GsmUmtsAdditionalCallOptions"
- android:label="@string/labelGSMMore"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <!-- fdn setting -->
- <activity android:name="com.android.phone.settings.fdn.FdnSetting"
- android:label="@string/fdn"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <!-- SIM PIN setting -->
- <activity android:name="EnableIccPinScreen"
- android:label="@string/enable_pin"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
- </intent-filter>
- </activity>
-
- <activity android:name="ChangeIccPinScreen"
- android:label="@string/change_pin"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
- </intent-filter>
- </activity>
-
- <activity android:name="com.android.phone.settings.fdn.GetPin2Screen"
- android:label="@string/get_pin2"
- android:theme="@style/DialerSettingsLight"
- android:windowSoftInputMode="stateVisible">
- </activity>
-
- <activity android:name="com.android.phone.settings.fdn.EditFdnContactScreen"
- android:theme="@style/DialerSettingsLight"
- android:windowSoftInputMode="stateVisible">
- </activity>
-
- <activity android:name="com.android.phone.settings.fdn.DeleteFdnContactScreen"
- android:theme="@style/DialerSettingsLight"
- android:label="@string/delete_fdn_contact">
- </activity>
-
- <!-- "Call settings" UI, used only on voice-capable phone devices. -->
- <activity android:name="CallFeaturesSetting"
- android:label="@string/call_settings"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.MAIN" />
- <action android:name="android.telecom.action.SHOW_CALL_SETTINGS" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!-- Activation service that trigger OTASP sim provisioning -->
- <service android:name=".otasp.OtaspActivationService" android:launchMode="singleInstance"
- androidprv:systemUserOnly="true"
- android:permission="android.permission.MODIFY_PHONE_STATE">
- <intent-filter>
- <action android:name="android.service.simActivation.SimActivationService" />
- </intent-filter>
- </service>
-
- <receiver android:name=".otasp.OtaspSimStateReceiver" androidprv:systemUserOnly="true"
- android:exported ="false">
- <intent-filter>
- <action android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
- </intent-filter>
- </receiver>
-
- <!-- "Accessibility" settings UI. Referenced by Dialer application. -->
- <activity android:name="com.android.phone.settings.AccessibilitySettingsActivity"
- android:label="@string/accessibility_settings_activity_title"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <action android:name="android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!-- CDMA Emergency Callback Mode -->
- <service android:name="EmergencyCallbackModeService">
- </service>
-
- <!-- service to dump telephony information -->
- <service android:name="com.android.phone.TelephonyDebugService"
- android:permission="android.permission.DUMP">
- <intent-filter>
- <action android:name="com.android.phone.TelephonyDebugService" />
- </intent-filter>
- </service>
-
- <!-- Handler for EuiccManager's public-facing intents. -->
- <activity android:name=".euicc.EuiccUiDispatcherActivity"
- android:theme="@android:style/Theme.NoDisplay"
- android:permission="android.permission.MODIFY_PHONE_STATE">
- <!-- Max out priority to ensure nobody else will handle these intents. -->
- <intent-filter android:priority="1000">
- <action android:name=
- "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS" />
- <action android:name=
- "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!--
- Handler for EuiccManager's resolution intents. These are locked down so that only
- privileged processes can start them, which means we can trust the Intent used to start
- it (which contains a description of the next step to perform after resolution).
- -->
- <activity android:name=".euicc.EuiccResolutionUiDispatcherActivity"
- android:permission="android.permission.CALL_PRIVILEGED">
- <!-- Max out priority to ensure nobody else will handle these intents. -->
- <intent-filter android:priority="1000">
- <action android:name=
- "android.telephony.euicc.action.RESOLVE_ERROR" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!--
- Handler for EuiccManager's privileged action intents. These are locked down so that only
- privileged processes can start them.
- -->
- <activity android:name=".euicc.EuiccPrivilegedActionUiDispatcherActivity"
- android:theme="@android:style/Theme.NoDisplay"
- android:permission="android.permission.CALL_PRIVILEGED">
- <!-- Max out priority to ensure nobody else will handle these intents. -->
- <intent-filter android:priority="1000">
- <action android:name=
- "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED" />
- <action android:name=
- "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED" />
- <action android:name=
- "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!--
- Handler for EuiccManager's public action intents. These are public and do not require
- any special permissions to start, although the calling package name should be
- whitelisted by the underlying eUICC service implementation (i.e. the LPA).
- -->
- <activity android:name=".euicc.EuiccPublicActionUiDispatcherActivity"
- android:theme="@android:style/Theme.NoDisplay">
- <!-- Max out priority to ensure nobody else will handle these intents. -->
- <intent-filter android:priority="1000">
- <action android:name=
- "android.telephony.euicc.action.START_EUICC_ACTIVATION" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <activity android:name="EmergencyCallbackModeExitDialog"
- android:excludeFromRecents="true"
- android:label="@string/ecm_exit_dialog"
- android:launchMode="singleTop"
- android:theme="@android:style/Theme.Translucent.NoTitleBar">
- <intent-filter>
- <action android:name="com.android.phone.action.ACTION_SHOW_ECM_EXIT_DIALOG" />
- <action android:name="com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!-- Start SIP -->
- <service android:name="com.android.services.telephony.sip.SipConnectionService"
- android:label="@string/sip_connection_service_label"
- android:singleUser="true"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
- <intent-filter>
- <action android:name="android.telecom.ConnectionService" />
- </intent-filter>
- </service>
-
- <receiver android:name="com.android.services.telephony.sip.SipIncomingCallReceiver">
- <intent-filter>
- <action android:name="com.android.phone.SIP_INCOMING_CALL" />
- </intent-filter>
- </receiver>
-
- <activity android:name="com.android.services.telephony.sip.SipPhoneAccountSettingsActivity"
- android:theme="@android:style/Theme.NoDisplay"
- android:excludeFromRecents="true">
- <intent-filter>
- <action android:name="android.telecom.action.CONFIGURE_PHONE_ACCOUNT" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <activity android:label="Sip Settings"
- android:name="com.android.services.telephony.sip.SipSettings"
- android:theme="@style/DialerSettingsLight"
- android:launchMode="singleTop"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:uiOptions="splitActionBarWhenNarrow"
- android:parentActivityName="com.android.phone.CallFeaturesSetting" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <action android:name="android.net.sip.NOTIFY" />
- </intent-filter>
- </activity>
- <activity android:name="com.android.services.telephony.sip.SipEditor"
- android:theme="@style/DialerSettingsLight"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:uiOptions="splitActionBarWhenNarrow">
- </activity>
-
- <!-- End SIP -->
-
- <activity android:name="MMIDialogActivity"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:excludeFromRecents="true"
- android:launchMode="singleInstance"
- android:theme="@style/Empty">
- </activity>
-
- <activity android:name="com.android.phone.settings.PhoneAccountSettingsActivity"
- android:label="@string/phone_accounts"
- android:theme="@style/DialerSettingsLight">
- <intent-filter>
- <action android:name="android.telecom.action.CHANGE_PHONE_ACCOUNTS" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <activity android:name="com.android.phone.settings.VoicemailSettingsActivity"
- android:label="@string/voicemail"
- android:configChanges="orientation|screenSize|keyboardHidden|screenLayout"
- android:screenOrientation="portrait"
- android:theme="@style/DialerSettingsLight">
- <intent-filter >
- <!-- DO NOT RENAME. There are existing apps which use this string. -->
- <action android:name="com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.telephony.action.CONFIGURE_VOICEMAIL" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
- <!-- Telecom integration -->
- <service
- android:singleUser="true"
- android:name="com.android.services.telephony.TelephonyConnectionService"
- android:label="@string/pstn_connection_service_label"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
- <intent-filter>
- <action android:name="android.telecom.ConnectionService" />
- </intent-filter>
- </service>
-
- <receiver
- android:name="com.android.phone.vvm.VvmSmsReceiver"
- android:exported="false"
- androidprv:systemUserOnly="true">
- <intent-filter>
- <action android:name="com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED"/>
- </intent-filter>
- </receiver>
-
- <receiver
- android:name="com.android.phone.vvm.VvmSimStateTracker"
- android:exported="false"
- androidprv:systemUserOnly="true">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- <action android:name="android.telephony.action.CARRIER_CONFIG_CHANGED"/>
- <action android:name="android.intent.action.SIM_STATE_CHANGED"/>
- </intent-filter>
- </receiver>
-
- <receiver
- android:name="com.android.internal.telephony.uicc.ShowInstallAppNotificationReceiver"
- android:exported="false"/>
-
- <activity
- android:name="com.android.phone.settings.PickSmsSubscriptionActivity"
- android:exported="false"
- android:excludeFromRecents="true"
- android:launchMode="singleTop"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:theme="@style/Theme.Transparent"/>
-
- <service
- android:name="com.android.phone.vvm.RemoteVvmTaskManager"
- android:exported="false"/>
- <service android:name="com.android.internal.telephony.CellularNetworkService"
- android:permission="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" >
- <intent-filter>
- <action android:name="android.telephony.NetworkService" />
- </intent-filter>
- </service>
- <service android:name="com.android.internal.telephony.dataconnection.CellularDataService"
- android:permission="android.permission.BIND_TELEPHONY_DATA_SERVICE" >
- <intent-filter>
- <action android:name="android.telephony.data.DataService" />
- </intent-filter>
- </service>
-
- <activity
- android:name=".settings.RadioInfo"
- android:label="@string/phone_info_label"
- android:theme="@style/Theme.AppCompat.DayNight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
- </intent-filter>
- </activity>
-
- <activity android:name=".settings.BandMode"
- android:label="@string/band_mode_title"
- android:theme="@style/Theme.AppCompat.DayNight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.VOICE_LAUNCH" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/client/res/color/settings_text_color_primary.xml b/client/res/color/settings_text_color_primary.xml
deleted file mode 100644
index 381465e..0000000
--- a/client/res/color/settings_text_color_primary.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:color="@color/setting_disabled_color" />
- <item android:color="@color/setting_primary_color" />
-</selector>
diff --git a/client/res/color/settings_text_color_secondary.xml b/client/res/color/settings_text_color_secondary.xml
deleted file mode 100644
index 7fa4435..0000000
--- a/client/res/color/settings_text_color_secondary.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:color="@color/setting_disabled_color" />
- <item android:color="@color/setting_secondary_color" />
-</selector>
diff --git a/client/res/drawable-hdpi/ic_arrow_back_24dp.png b/client/res/drawable-hdpi/ic_arrow_back_24dp.png
deleted file mode 100644
index 86cb894..0000000
--- a/client/res/drawable-hdpi/ic_arrow_back_24dp.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-hdpi/ic_overflow_menu.png b/client/res/drawable-hdpi/ic_overflow_menu.png
deleted file mode 100644
index 262e9df..0000000
--- a/client/res/drawable-hdpi/ic_overflow_menu.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-mdpi/ic_arrow_back_24dp.png b/client/res/drawable-mdpi/ic_arrow_back_24dp.png
deleted file mode 100644
index dc81cd1..0000000
--- a/client/res/drawable-mdpi/ic_arrow_back_24dp.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-mdpi/ic_overflow_menu.png b/client/res/drawable-mdpi/ic_overflow_menu.png
deleted file mode 100644
index 0e720dd..0000000
--- a/client/res/drawable-mdpi/ic_overflow_menu.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-xhdpi/ic_arrow_back_24dp.png b/client/res/drawable-xhdpi/ic_arrow_back_24dp.png
deleted file mode 100644
index 4f4fbaa..0000000
--- a/client/res/drawable-xhdpi/ic_arrow_back_24dp.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-xhdpi/ic_overflow_menu.png b/client/res/drawable-xhdpi/ic_overflow_menu.png
deleted file mode 100644
index 9156076..0000000
--- a/client/res/drawable-xhdpi/ic_overflow_menu.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-xxhdpi/ic_arrow_back_24dp.png b/client/res/drawable-xxhdpi/ic_arrow_back_24dp.png
deleted file mode 100644
index 46e90f7..0000000
--- a/client/res/drawable-xxhdpi/ic_arrow_back_24dp.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-xxhdpi/ic_overflow_menu.png b/client/res/drawable-xxhdpi/ic_overflow_menu.png
deleted file mode 100644
index 92526f5..0000000
--- a/client/res/drawable-xxhdpi/ic_overflow_menu.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-xxxhdpi/ic_arrow_back_24dp.png b/client/res/drawable-xxxhdpi/ic_arrow_back_24dp.png
deleted file mode 100644
index 3b72636..0000000
--- a/client/res/drawable-xxxhdpi/ic_arrow_back_24dp.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable-xxxhdpi/ic_overflow_menu.png b/client/res/drawable-xxxhdpi/ic_overflow_menu.png
deleted file mode 100644
index 9028bd4..0000000
--- a/client/res/drawable-xxxhdpi/ic_overflow_menu.png
+++ /dev/null
Binary files differ
diff --git a/client/res/drawable/ic_back_arrow.xml b/client/res/drawable/ic_back_arrow.xml
deleted file mode 100644
index 72997b0..0000000
--- a/client/res/drawable/ic_back_arrow.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_arrow_back_24dp"
- android:autoMirrored="true"
- android:tint="@color/actionbar_icon_color" />
\ No newline at end of file
diff --git a/client/res/drawable/overflow_menu.xml b/client/res/drawable/overflow_menu.xml
deleted file mode 100644
index 0467d6b..0000000
--- a/client/res/drawable/overflow_menu.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2014 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_overflow_menu"
- android:autoMirrored="true"
- android:tint="@color/actionbar_icon_color" />
diff --git a/client/res/mipmap-hdpi/ic_launcher_contacts.png b/client/res/mipmap-hdpi/ic_launcher_contacts.png
deleted file mode 100644
index 64eff00..0000000
--- a/client/res/mipmap-hdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-hdpi/ic_launcher_phone.png b/client/res/mipmap-hdpi/ic_launcher_phone.png
deleted file mode 100644
index 15c4142..0000000
--- a/client/res/mipmap-hdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-mdpi/ic_launcher_contacts.png b/client/res/mipmap-mdpi/ic_launcher_contacts.png
deleted file mode 100644
index b4ee821..0000000
--- a/client/res/mipmap-mdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-mdpi/ic_launcher_phone.png b/client/res/mipmap-mdpi/ic_launcher_phone.png
deleted file mode 100644
index 3088f75..0000000
--- a/client/res/mipmap-mdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-xhdpi/ic_launcher_contacts.png b/client/res/mipmap-xhdpi/ic_launcher_contacts.png
deleted file mode 100644
index 6feeadf..0000000
--- a/client/res/mipmap-xhdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-xhdpi/ic_launcher_phone.png b/client/res/mipmap-xhdpi/ic_launcher_phone.png
deleted file mode 100644
index e87de01..0000000
--- a/client/res/mipmap-xhdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-xxhdpi/ic_launcher_contacts.png b/client/res/mipmap-xxhdpi/ic_launcher_contacts.png
deleted file mode 100644
index 01a3fde..0000000
--- a/client/res/mipmap-xxhdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-xxhdpi/ic_launcher_phone.png b/client/res/mipmap-xxhdpi/ic_launcher_phone.png
deleted file mode 100644
index b866b79..0000000
--- a/client/res/mipmap-xxhdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-xxxhdpi/ic_launcher_contacts.png b/client/res/mipmap-xxxhdpi/ic_launcher_contacts.png
deleted file mode 100644
index 328e067..0000000
--- a/client/res/mipmap-xxxhdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/client/res/mipmap-xxxhdpi/ic_launcher_phone.png b/client/res/mipmap-xxxhdpi/ic_launcher_phone.png
deleted file mode 100644
index 26f51f1..0000000
--- a/client/res/mipmap-xxxhdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/client/res/values/attrs.xml b/client/res/values/attrs.xml
deleted file mode 100644
index b4ef5d0..0000000
--- a/client/res/values/attrs.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <attr name="emergencyButtonBackgroundColor" format="color" />
- <attr name="dialpadTheme" format="reference" />
- <declare-styleable name="Theme.Dialpad">
- <attr name="dialpad_text_color" format="color" />
- <attr name="dialpad_text_color_primary" format="color" />
- <attr name="dialpad_text_color_secondary" format="color" />
- <attr name="dialpad_icon_tint" format="color" />
- <attr name="dialpad_voicemail_tint" format="color" />
- <attr name="dialpad_background" format="color" />
- <attr name="dialpad_separator_color" format="color" />
- <attr name="dialpad_margin_style" format="reference"/>
- <attr name="dialpad_delete_padding" format="dimension" />
- </declare-styleable>
-</resources>
\ No newline at end of file
diff --git a/client/res/values/colors.xml b/client/res/values/colors.xml
deleted file mode 100644
index 4cf4bd0..0000000
--- a/client/res/values/colors.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <!-- Color matches dialer settings light M2 theme.-->
- <color name="dialer_background_color">#ffffff</color>
- <color name="dialer_divider_color">#d8d8d8</color>
- <color name="dialer_primary_text_color">#202124</color>
-
- <!-- Settings screen should use the same colors as the Dialer -->
- <color name="phone_settings_background_color">#f5f5f5</color>
- <!-- Action bar text color. Ensure this stays in sync with dialer_icon_color in action bar. -->
- <color name="phone_settings_actionbar_text_color">#5f6368</color>
- <!-- Background color of action bars. Ensure this stays in sync with Dialer
- actionbar_background_color. -->
- <color name="actionbar_background_color">#ffffff</color>
- <!-- Dark variant of the action bar color. Ensure this stays in sync with Dialer version. -->
- <color name="actionbar_background_color_dark">#ffffff</color>
- <!-- Color for icons in the actionbar. Ensure this stays in sync with Dialer version. -->
- <color name="actionbar_icon_color">#5f6368</color>
-
- <!-- Color for the setting text. -->
- <color name="setting_primary_color">#333333</color>
- <!-- Color for the setting description text. -->
- <color name="setting_secondary_color">#737373</color>
- <color name="setting_disabled_color">#aaaaaa</color>
-
- <color name="dialer_theme_color">#2A56C6</color>
- <color name="dialer_theme_color_dark">#1C3AA9</color>
- <color name="dialpad_icon_tint">#b3b3b3</color>
-
-</resources>
\ No newline at end of file
diff --git a/client/res/values/dimens.xml b/client/res/values/dimens.xml
deleted file mode 100644
index c6acbd7..0000000
--- a/client/res/values/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <!-- Action bar dimensions. Keep in sync with same value in Dialer. -->
- <dimen name="action_bar_height">56dp</dimen>
- <dimen name="action_bar_elevation">2dp</dimen>
- <dimen name="actionbar_contentInsetStart">72dp</dimen>
- <!-- The text size for titles in settings page.-->
- <dimen name="dialer_head1_font_size">18dp</dimen>
-</resources>
\ No newline at end of file
diff --git a/client/res/values/strings.xml b/client/res/values/strings.xml
deleted file mode 100644
index 1d002a2..0000000
--- a/client/res/values/strings.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Official label of the phone app, as seen in "Manage Applications"
- and other settings UIs. This is the version of the label for
- tablet devices, where the phone app handles mobile data but not
- actual phone calls. -->
- <string name="phoneAppLabel" product="tablet">Mobile Data</string>
-
- <!-- Official label of the phone app, as seen in "Manage Applications"
- and other settings UIs. -->
- <string name="phoneAppLabel" product="default">Phone Services</string>
-
- <!-- Screen title for Emergency Dialer UI -->
- <string name="emergencyDialerIconLabel">Emergency Dialer</string>
-
- <!-- Title of FDN list screen -->
- <string name="fdnListLabel">FDN list</string>
-
- <!-- Call settings: title of the dialog that lets you select contacts from the SIM. -->
- <string name="simContacts_title">Select contacts to import</string>
-
- <string name="gsm_umts_options">GSM/UMTS Options</string>
- <string name="cdma_options">CDMA Options</string>
-
- <!-- Call settings screen title -->
- <string name="call_settings">Call settings</string>
-
- <!-- Call settings screen, setting option name -->
- <string name="labelCF">Call forwarding</string>
-
- <!-- Call settings screen, setting option name -->
- <string name="labelCallBarring">Call barring</string>
-
- <!-- GSM Call settings screen, setting option name. [CHAR LIMIT=40] -->
- <string name="labelGSMMore">GSM call settings</string>
-
- <!-- Label for "Fixed Dialing Number" settings in call settings. -->
- <string name="fdn">Fixed Dialing Numbers</string>
- <!-- Label for PIN2 entry screen -->
- <string name="get_pin2">Type PIN2</string>
- <!-- Title of "Delete FDN Contact" screen -->
- <string name="delete_fdn_contact">Delete fixed dialing number</string>
-
- <!-- Title of "Enable/disable SIM PIN" screen -->
- <string name="enable_pin">Enable/disable SIM PIN</string>
- <!-- Title of "Change SIM PIN" screen -->
- <string name="change_pin">Change SIM PIN</string>
-
- <!-- Title for activity to control accessibility settings such as TTY mode and hearing aid
- compatibility. [CHAR LIMIT=40] -->
- <string name="accessibility_settings_activity_title">Accessibility</string>
-
- <!-- Emergency Callback Mode (ECM) -->
- <string name="ecm_exit_dialog">EcmExitDialog</string>
-
- <!-- Label for SIP connection service. -->
- <string name="sip_connection_service_label">Built-in SIP calling</string>
-
- <!-- Label for settings screen for phone accounts. -->
- <string name="phone_accounts">Calling accounts</string>
-
- <!-- Call settings screen, setting option name -->
- <string name="voicemail">Voicemail</string>
-
- <!-- Label for PSTN connection service. -->
- <string name="pstn_connection_service_label">Built-in SIM cards</string>
-
- <!-- The title of the activity to see phone info -->
- <string name="phone_info_label" product="tablet">Tablet info</string>
- <!-- The title of the activity to see phone info -->
- <string name="phone_info_label" product="default">Phone info</string>
-
- <!-- Band mode screen. Title of activity. -->
- <string name="band_mode_title">Set Radio Band Mode</string>
-</resources>
\ No newline at end of file
diff --git a/client/res/values/styles.xml b/client/res/values/styles.xml
deleted file mode 100644
index f8aebd9..0000000
--- a/client/res/values/styles.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="EmergencyDialerTheme" parent="@*android:style/Theme.DeviceDefault.Settings.Dark.NoActionBar">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:colorPrimaryDark">?android:attr/colorPrimary</item>
- <item name="android:colorBackgroundCacheHint">@null</item>
- <item name="android:windowShowWallpaper">true</item>
- <item name="android:statusBarColor">@android:color/transparent</item>
- <item name="android:navigationBarColor">@android:color/transparent</item>
- <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
- <item name="emergencyButtonBackgroundColor">#3cffffff</item>
- <item name="dialpadTheme">@style/Dialpad_DarkTransparent</item>
- </style>
-
- <!-- Action bar overflow menu icon. -->
- <style name="DialtactsActionBarOverflow"
- parent="@android:style/Widget.Holo.ActionButton.Overflow">
- <item name="android:src">@drawable/overflow_menu</item>
- </style>
-
- <!-- Style for the call settings action bar. Should be kept in sync with Dialer. -->
- <style name="DialtactsActionBarStyle" parent="@style/TelephonyActionBarStyle">
- <!-- Shift the title text to the right -->
- <item name="android:contentInsetStart">@dimen/actionbar_contentInsetStart</item>
- </style>
-
- <!-- Text in the action bar at the top of the screen. Should be kept in sync with Dialer. -->
- <style name="DialtactsActionBarTitleText"
- parent="@android:style/TextAppearance.Material.Widget.ActionBar.Title">
- <item name="android:textColor">@color/dialer_primary_text_color</item>
- <item name="android:textSize">@dimen/dialer_head1_font_size</item>
- <item name="android:fontFamily">sans-serif-regular</item>
- </style>
-
- <style name="TelephonyActionBarStyle" parent="android:Widget.Material.ActionBar">
- <item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
- <item name="android:background">@color/actionbar_background_color</item>
- <item name="android:titleTextStyle">@style/DialtactsActionBarTitleText</item>
- <item name="android:height">@dimen/action_bar_height</item>
- <item name="android:elevation">@dimen/action_bar_elevation</item>
- <!-- Empty icon -->
- <item name="android:icon">@android:color/transparent</item>
- </style>
-
- <style name="SimImportTheme" parent="@android:style/Theme.Material.Light">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:actionBarStyle">@style/TelephonyActionBarStyle</item>
- <item name="android:colorPrimaryDark">@color/dialer_theme_color_dark</item>
- <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
- <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
- </style>
-
- <style name="SettingsLight" parent="android:Theme.Material.Light">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:windowBackground">@color/phone_settings_background_color</item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
- <item name="android:actionMenuTextColor">@color/phone_settings_actionbar_text_color</item>
- <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
- <item name="android:windowActionBarOverlay">false</item>
- <item name="android:colorPrimaryDark">@color/actionbar_background_color_dark</item>
- <!-- Setting text. -->
- <item name="android:textColorPrimary">@color/settings_text_color_primary</item>
- <!-- Setting description. -->
- <item name="android:textColorSecondary">@color/settings_text_color_secondary</item>
- </style>
-
- <style name="DialerSettingsLight" parent="SettingsLight">
- <!-- Action bar.-->
- <item name="android:windowBackground">@color/dialer_background_color</item>
- <item name="android:actionModeBackground">@color/dialer_background_color</item>
- <item name="android:windowLightStatusBar">true</item>
- <!-- Navigation bar.-->
- <item name="android:navigationBarColor">@color/dialer_background_color</item>
- <item name="android:navigationBarDividerColor">@color/dialer_divider_color</item>
- <item name="android:windowLightNavigationBar">true</item>
- <item name="android:colorAccent">@color/dialer_theme_color</item>
- <item name="android:dialogTheme">@style/DialerAlertDialogTheme</item>
- <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
- </style>
-
- <style name="DialerAlertDialogTheme"
- parent="@android:style/Theme.Material.Light.Dialog">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:colorAccent">@color/dialer_theme_color</item>
- <item name="android:textColor">?android:attr/textColorPrimaryInverseDisableOnly</item>
- </style>
-
- <style name="CallSettingsWithoutDividerTheme" parent="SettingsLight">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:listDivider">@null</item>
- </style>
-
- <style name="Empty" parent="@android:style/Theme.Material.Light">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowIsFloating">true</item>
- <item name="android:backgroundDimEnabled">true</item>
- </style>
-
- <style name="Theme.Transparent" parent="android:Theme">
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowIsFloating">true</item>
- <item name="android:backgroundDimEnabled">false</item>
- </style>
-
- <style name="DialpadNoSpaceStyle">
- <item name="android:layout_width">0dp</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:visibility">gone</item>
- </style>
-
- <style name="Dialpad_DarkTransparent">
- <item name="dialpad_text_color">?android:textColorPrimary</item>
- <item name="dialpad_text_color_primary">?android:textColorPrimary</item>
- <item name="dialpad_text_color_secondary">?android:textColorSecondary</item>
- <item name="dialpad_icon_tint">@android:color/white</item>
- <item name="dialpad_voicemail_tint">@color/dialpad_icon_tint</item>
- <item name="dialpad_background">@android:color/transparent</item>
- <item name="dialpad_separator_color">@color/dialpad_icon_tint</item>
- <item name="dialpad_margin_style">@style/DialpadNoSpaceStyle</item>
- <item name="dialpad_delete_padding">1dp</item>
- </style>
-</resources>
\ No newline at end of file
diff --git a/proguard.proguard b/proguard.proguard
deleted file mode 100644
index 2a823d8..0000000
--- a/proguard.proguard
+++ /dev/null
@@ -1,7 +0,0 @@
--keepparameternames
--keepattributes Exceptions,InnerClasses,Signature,Deprecated,
- SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-
--keep public class * {
- public protected *;
-}
\ No newline at end of file
diff --git a/res/layout/band_mode.xml b/res/layout/band_mode.xml
new file mode 100644
index 0000000..b43dd1d
--- /dev/null
+++ b/res/layout/band_mode.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ListView android:id="@+id/band"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="7sp">
+ </ListView>
+
+</LinearLayout>
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
new file mode 100644
index 0000000..40c2e53
--- /dev/null
+++ b/res/layout/radio_info.xml
@@ -0,0 +1,414 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/Settings/assets/res/any/layout/radio_info.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout style="@style/info_layout"
+ android:descendantFocusability="beforeDescendants"
+ android:focusableInTouchMode="true">
+
+ <!-- Phone index -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/phone_index_label"
+ style="@style/info_label"
+ />
+
+ <Spinner android:id="@+id/phoneIndex"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <!-- IMEI -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_imei_label" style="@style/info_label" />
+ <TextView android:id="@+id/imei" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Phone Number -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_phone_number_label" style="@style/info_label" />
+ <TextView android:id="@+id/number" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Subscription ID -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_subid" style="@style/info_label" />
+ <TextView android:id="@+id/subid" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Default data subscription -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_dds" style="@style/info_label" />
+ <TextView android:id="@+id/dds" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- IMSI -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_imsi_label" style="@style/info_label" />
+ <TextView android:id="@+id/imsi" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Network Identifier -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_current_network_label" style="@style/info_label" />
+ <TextView android:id="@+id/operator" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Roaming -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_roaming_label" style="@style/info_label" />
+ <TextView android:id="@+id/roaming" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Data Service Status -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_gprs_service_label" style="@style/info_label" />
+ <TextView android:id="@+id/gprs" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Data Network Type -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_data_network_type_label" style="@style/info_label" />
+ <TextView android:id="@+id/data_network" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Voice Service Status -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_gsm_service_label" style="@style/info_label" />
+ <TextView android:id="@+id/gsm" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Voice Network Type -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_voice_network_type_label" style="@style/info_label" />
+ <TextView android:id="@+id/voice_network" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Signal Strength -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_signal_strength_label" style="@style/info_label" />
+ <TextView android:id="@+id/dbm" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Link Bandwidth -->
+ <LinearLayout style="@style/RadioInfo_entry_layout" android:orientation="horizontal">
+ <TextView android:text="@string/radio_info_dl_kbps" style="@style/info_label" />
+ <TextView android:id="@+id/dl_kbps" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Link Bandwidth -->
+ <LinearLayout style="@style/RadioInfo_entry_layout" android:orientation="horizontal">
+ <TextView android:text="@string/radio_info_ul_kbps" style="@style/info_label" />
+ <TextView android:id="@+id/ul_kbps" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Physical Channel Config -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_phy_chan_config" style="@style/info_label" />
+ <TextView android:id="@+id/phy_chan_config" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Preferred Network Type -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_set_perferred_label"
+ style="@style/info_label"
+ />
+
+ <Spinner android:id="@+id/preferredNetworkType"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Radio Power -->
+ <Switch android:id="@+id/radio_power"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_radio_power"/>
+
+ <!-- VoLTE provisioned -->
+ <Switch android:id="@+id/volte_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/volte_provisioned_switch_string"/>
+
+ <!-- VT provisioned -->
+ <Switch android:id="@+id/vt_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/vt_provisioned_switch_string"/>
+
+ <!-- Wifi Calling provisioned -->
+ <Switch android:id="@+id/wfc_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/wfc_provisioned_switch_string"/>
+
+ <!-- EAB/Presence provisioned -->
+ <Switch android:id="@+id/eab_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/eab_provisioned_switch_string"/>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Enable/Disable CBRS data -->
+ <Switch android:id="@+id/cbrs_data_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/cbrs_data_switch_string" />
+
+ <!-- Switch between SSSS(single sim single standby) and DSDS(dual sim dual standby). -->
+ <Switch android:id="@+id/dsds_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/dsds_switch_string" />
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Ping stats -->
+ <Button android:id="@+id/ping_test"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ping_test_label"
+ />
+
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ping_hostname_v4" style="@style/info_label" />
+ <TextView android:id="@+id/pingHostnameV4" style="@style/info_value" />
+ </LinearLayout>
+
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ping_hostname_v6" style="@style/info_label" />
+ <TextView android:id="@+id/pingHostnameV6" style="@style/info_value" />
+ </LinearLayout>
+
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_http_client_test" style="@style/info_label" />
+ <TextView android:id="@+id/httpClientTest" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- PPP Sent -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ppp_sent_label"
+ style="@style/info_label" />
+ <TextView android:id="@+id/sent" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- PPP Received -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ppp_received_label"
+ style="@style/info_label" />
+ <TextView android:id="@+id/received" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- PPP Sent since last received -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ppp_resets_label"
+ style="@style/info_label" />
+ <TextView android:id="@+id/sentSinceReceived" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Call Status -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_call_status_label" style="@style/info_label" />
+ <TextView android:id="@+id/call" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Message Waiting Indicator -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_message_waiting_label" style="@style/info_label" />
+ <TextView android:id="@+id/mwi" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Call Forwarding Indicator -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_call_redirect_label" style="@style/info_label" />
+ <TextView android:id="@+id/cfi" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- CellInfoListRate Selection -->
+ <!-- Location -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_signal_location_label" style="@style/info_label" />
+ <TextView android:id="@+id/location" style="@style/info_value" />
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_cell_info_refresh_rate"
+ style="@style/info_label"
+ />
+
+ <Spinner android:id="@+id/cell_info_rate_select"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <!-- CellInfo -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_cellinfo_label"
+ style="@style/info_label" />
+ </LinearLayout>
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:id="@+id/cellinfo"
+ style="@style/info_value"
+ android:minHeight="300dip"
+ android:textSize="12sp" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Launch OEM-specific Info/Settings Activity (if any) -->
+ <!-- Carrier Provisioning -->
+ <LinearLayout style="@style/RadioInfo_entry_layout"
+ android:orientation="horizontal" >
+ <Button android:id="@+id/carrier_provisioning"
+ android:layout_marginTop="8dip"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/carrier_provisioning"
+ android:textSize="14sp"/>
+ <Button android:id="@+id/trigger_carrier_provisioning"
+ android:layout_marginTop="8dip"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/trigger_carrier_provisioning"
+ android:textSize="14sp"/>
+ <Button android:id="@+id/oem_info"
+ android:layout_marginTop="8dip"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/oem_radio_info_label"
+ android:textSize="14sp"/>
+ </LinearLayout>
+
+ <!-- SMSC -->
+ <RelativeLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView android:id="@+id/smsc_label"
+ android:text="@string/radio_info_smsc_label"
+ android:layout_alignBaseline="@+id/update_smsc"
+ style="@style/info_label" />
+ <Button android:id="@+id/refresh_smsc"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_smsc_refresh_label"
+ android:layout_alignParentEnd="true"
+ />
+ <Button android:id="@+id/update_smsc"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_smsc_update_label"
+ android:layout_toStartOf="@+id/refresh_smsc"
+ android:layout_alignBaseline="@+id/refresh_smsc"
+ />
+ <EditText android:id="@+id/smsc"
+ style="@style/form_value"
+ android:layout_alignBaseline="@+id/refresh_smsc"
+ android:layout_toStartOf="@id/update_smsc"
+ android:layout_toEndOf="@id/smsc_label" />
+ </RelativeLayout>
+
+ <!-- Test setting to ignore bad DNS, useful in lab environments -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <Button android:id="@+id/dns_check_toggle"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_toggle_dns_check_label"
+ />
+ <TextView android:id="@+id/dnsCheckState" style="@style/info_value" />
+ </LinearLayout>
+
+
+ </LinearLayout>
+</ScrollView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 52ac891..b97ef10 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -16,10 +16,22 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Official label of the phone app, as seen in "Manage Applications"
+ and other settings UIs. This is the version of the label for
+ tablet devices, where the phone app handles mobile data but not
+ actual phone calls. -->
+ <string name="phoneAppLabel" product="tablet">Mobile Data</string>
+
+ <!-- Official label of the phone app, as seen in "Manage Applications"
+ and other settings UIs. -->
+ <string name="phoneAppLabel" product="default">Phone Services</string>
+
<!-- Screen title for Emergency Dialer UI -->
<string name="emergencyDialerIconLabel">Emergency Dialer</string>
<!-- Activity label for the in-call UI -->
<string name="phoneIconLabel">Phone</string>
+ <!-- Title of FDN list screen -->
+ <string name="fdnListLabel">FDN list</string>
<!-- Call status -->
<!-- Incoming call screen, name of "unknown" caller -->
@@ -608,6 +620,9 @@
<!-- USSD aggregation dialog box: separator strings between messages (new-lines will be added before and after) -->
<string name="ussd_dialog_sep" translatable="false">----------</string>
+ <string name="gsm_umts_options">GSM/UMTS Options</string>
+ <string name="cdma_options">CDMA Options</string>
+
<!-- Screen option on the mobile network settings to go into data usage settings -->
<string name="throttle_data_usage">Data usage</string>
<!-- Data usage settings screen option for checking the current usage -->
@@ -977,6 +992,8 @@
<string name="simContacts_emptyLoading">Reading from SIM card\u2026</string>
<!-- Call settings, string that appears on FDN contact list when there are no contacts on the SIM. -->
<string name="simContacts_empty">No contacts on your SIM card.</string>
+ <!-- Call settings: title of the dialog that lets you select contacts from the SIM. -->
+ <string name="simContacts_title">Select contacts to import</string>
<!-- Appears when user tries to import contacts in SIM during airplane mode [CHAR LIMIT=NONE] -->
<string name="simContacts_airplaneMode">Turn off airplane mode to import contacts from the SIM card.</string>
@@ -1759,7 +1776,7 @@
<!-- Call barring settings screen, change password -->
<string name="call_barring_change_pwd_description">Change call barring password</string>
<!-- Call barring settings screen, not possible to change call barring password -->
- <string name="call_barring_change_pwd_description_disabled">Cannot change call barring password.</string>
+ <string name="call_barring_change_pwd_description_disabled">Cannot change call barring password</string>
<!-- Call barring settings screen, change password -->
<string name="call_barring_pwd_not_match">Passwords do not match</string>
<!-- Call barring settings screen, change password -->
@@ -1873,4 +1890,209 @@
<string name="supp_service_over_ut_precautions_roaming_dual_sim">To use <xliff:g id="supp service">%1$s</xliff:g>, make sure mobile data and data roaming are turned on for SIM <xliff:g id="sim number">%2$d</xliff:g>. You can change these in mobile network settings.</string>
<!-- supplementary services over ut precaution exit dialog choice -->
<string name="supp_service_over_ut_precautions_dialog_dismiss">Dismiss</string>
+
+ <!-- Data Connection Enable. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="radio_info_data_connection_enable">Enable Data Connection</string>
+ <!-- Data Connection Disable. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="radio_info_data_connection_disable">Disable Data Connection</string>
+
+ <!-- VoLTE provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="volte_provisioned_switch_string">VoLTE Provisioned</string>
+
+ <!-- Video calling provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="vt_provisioned_switch_string">Video Calling Provisioned</string>
+
+ <!-- Wifi Calling provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="wfc_provisioned_switch_string">Wifi Calling Provisioned</string>
+
+ <!-- EAB provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="eab_provisioned_switch_string">EAB/Presence Provisioned</string>
+
+ <!-- Cbrs enable disable flag. Only shown in diagnostic screen, so precise translation is not needed -->
+ <string name="cbrs_data_switch_string">Cbrs Data</string>
+
+ <!-- Dsds enable/disable flag. Only shown in diagnostic screen, so precise translation is not needed, [CHAR LIMIT=none] -->
+ <string name="dsds_switch_string">Enable DSDS</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_title">Restart Device?</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_message">You need to restart your device to change this setting.</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_confirm">Restart</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_cancel">Cancel</string>
+
+ <!-- Title for controlling on/off for Mobile phone's radio power. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="radio_info_radio_power">Mobile Radio Power</string>
+
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_viewADN">View SIM Address Book</string>
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_viewFDN">View Fixed Dialing Numbers</string>
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_viewSDN">View Service Dialing Numbers</string>
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_getIMS">IMS Service Status</string>
+
+ <!-- Phone Info screen. IMS Registration Title. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status_title">IMS Status</string>
+
+ <!-- Phone Info screen. IMS Status - Registered. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status_registered">Registered</string>
+ <!-- Phone Info screen. Ims Status - Unregistered. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status_not_registered">Not Registered</string>
+
+ <!-- Phone Info screen. Ims Feature Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_feature_status_available">Available</string>
+ <!-- Phone Info screen. Ims Feature status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_feature_status_unavailable">Unavailable</string>
+
+ <!-- Phone Info screen. IMS Registration. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status">IMS Registration: <xliff:g id="status" example="registered">%1$s</xliff:g>\u000AVoice over LTE: <xliff:g id="availability" example="available">%2$s</xliff:g>\u000AVoice over WiFi: <xliff:g id="availability" example="available">%3$s</xliff:g>\u000AVideo Calling: <xliff:g id="availability" example="available">%4$s</xliff:g>\u000AUT Interface: <xliff:g id="availability" example="available">%5$s</xliff:g></string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_in">In Service</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_out">Out of Service</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_emergency">Emergency Calls Only</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_off">Radio Off</string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_roaming_in">Roaming</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_roaming_not">Not Roaming</string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_phone_idle">Idle</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_phone_ringing">Ringing</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_phone_offhook">Call in Progress</string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_disconnected">Disconnected</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_connecting">Connecting</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_connected">Connected</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_suspended">Suspended</string>
+
+ <!-- Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_unknown">Unknown</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_packets">pkts</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_bytes">bytes</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_dbm">dBm</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_asu">asu</string>
+ <!-- Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_lac">LAC</string>
+ <!-- Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_cid">CID</string>
+
+
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_subid">Current subId:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_dds">SubId of default data SIM:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_dl_kbps">DL Bandwidth (kbps):</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ul_kbps">UL Bandwidth (kbps):</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_signal_location_label">Cell Location Info (deprecated):</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_phy_chan_config">LTE Physical Channel Configuration:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_cell_info_refresh_rate">Cell Info Refresh Rate:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_cellinfo_label">All Cell Measurement Info:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_gprs_service_label">Data Service:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_roaming_label">Roaming:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_imei_label">IMEI:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, DO NOT TRANSLATE. -->
+ <string name="radio_info_imsi_label">IMSI:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_call_redirect_label">Call Redirect:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ppp_resets_label">Number of PPP Reset Since Boot:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_current_network_label">Current Network:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ppp_received_label">Data Received:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_gsm_service_label">Voice Service:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_signal_strength_label">Signal Strength:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_call_status_label">Voice Call Status:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ppp_sent_label">Data Sent:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_message_waiting_label">Message Waiting:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_phone_number_label">Phone Number:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_band_mode_label">Select Radio Band</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_voice_network_type_label">Voice Network Type:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_data_network_type_label">Data Network Type:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="phone_index_label">Select phone index</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_set_perferred_label">Set Preferred Network Type:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ping_hostname_v4">Ping Hostname(www.google.com) IPv4:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ping_hostname_v6">Ping Hostname(www.google.com) IPv6:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_http_client_test">HTTP Client Test:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="ping_test_label">Run Ping Test</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_smsc_label">SMSC:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_smsc_update_label">Update</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_smsc_refresh_label">Refresh</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_toggle_dns_check_label">Toggle DNS Check</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="oem_radio_info_label">OEM-specific Info/Settings</string>
+
+ <!-- Band Mode Selection -->
+ <!-- Band mode screen. Title of activity. -->
+ <string name="band_mode_title">Set Radio Band Mode</string>
+ <!-- Band mode screen. Loading message. -->
+ <string name="band_mode_loading">Loading Band List\u2026</string>
+ <!-- Band mode screen. Button caption to set the bandmode. -->
+ <string name="band_mode_set">Set</string>
+ <!-- Band mode screen. Status message when unsuccessful. -->
+ <string name="band_mode_failed">Unsuccessful</string>
+ <!-- Band mode screen. Statusm essage when successful. -->
+ <string name="band_mode_succeeded">Successful</string>
+
+ <!-- The title of the activity to see phone info -->
+ <string name="phone_info_label" product="tablet">Tablet info</string>
+ <!-- The title of the activity to see phone info -->
+ <string name="phone_info_label" product="default">Phone info</string>
+
+ <!-- Carrier Provisioning Info [CHAR LIMIT=NONE] -->
+ <string name="carrier_provisioning">Carrier Provisioning Info</string>
+ <!-- Trigger Carrier Provisioning [CHAR LIMIT=NONE] -->
+ <string name="trigger_carrier_provisioning">Trigger Carrier Provisioning</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index fc95803..e95142b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -45,6 +45,23 @@
<item name="android:layout_height">wrap_content</item>
</style>
+ <style name="RadioInfo_entry_layout">
+ <item name="android:orientation">horizontal</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+
+ <style name="info_value">
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:textAppearance">@style/TextAppearance.info_value</item>
+ </style>
+
+ <style name="form_value">
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_width">match_parent</item>
+ </style>
+
<style name="TextAppearance" parent="android:TextAppearance">
</style>
@@ -53,6 +70,11 @@
<item name="android:textStyle">bold</item>
</style>
+ <style name="TextAppearance.info_value">
+ <item name="android:textSize">14sp</item>
+ <item name="android:textStyle">normal</item>
+ </style>
+
<!-- Preference Style for the phone number preferences -->
<style name="EditPhoneNumberPreference">
<item name="enableButtonText">@string/enable</item>
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index e5e02fa..3f57cae 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -19,10 +19,12 @@
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
@@ -110,6 +112,50 @@
* Click Listeners, handle click based on objects attached to UI.
*/
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ log("onReceive: " + intent.getAction());
+
+ if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
+ log("ACTION_AIRPLANE_MODE_CHANGED");
+
+ boolean isAirplaneModeOn = intent.getBooleanExtra("state", false);
+ handleAirplaneModeChange(isAirplaneModeOn);
+ }
+ }
+ };
+
+ private void handleAirplaneModeChange(boolean isAirplaneModeOn) {
+ PersistableBundle b = null;
+ if (mSubscriptionInfoHelper.hasSubId()) {
+ b = PhoneGlobals.getInstance().getCarrierConfigForSubId(
+ mSubscriptionInfoHelper.getSubId());
+ } else {
+ b = PhoneGlobals.getInstance().getCarrierConfig();
+ }
+
+ if (b != null && b.getBoolean(
+ CarrierConfigManager.KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL)) {
+ PreferenceScreen preferenceScreen = getPreferenceScreen();
+ Preference callForwarding = preferenceScreen.findPreference(
+ GsmUmtsCallOptions.CALL_FORWARDING_KEY);
+ Preference callBarring = preferenceScreen.findPreference(
+ GsmUmtsCallOptions.CALL_BARRING_KEY);
+ Preference additional = preferenceScreen.findPreference(
+ GsmUmtsCallOptions.ADDITIONAL_GSM_SETTINGS_KEY);
+ if (callForwarding != null) {
+ callForwarding.setEnabled(!isAirplaneModeOn);
+ }
+ if (callBarring != null) {
+ callBarring.setEnabled(!isAirplaneModeOn);
+ }
+ if (additional != null) {
+ additional.setEnabled(!isAirplaneModeOn);
+ }
+ }
+ }
+
// Click listener for all toggle events
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
@@ -266,6 +312,7 @@
protected void onPause() {
super.onPause();
listenPhoneState(false);
+ unregisterReceiver(mReceiver);
// Remove callback for provisioning changes.
try {
@@ -378,6 +425,10 @@
} catch (ImsException e) {
Log.w(LOG_TAG, "onResume: Unable to register callback for provisioning changes.");
}
+
+ IntentFilter intentFilter =
+ new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ registerReceiver(mReceiver, intentFilter);
}
private void updateVtWfc() {
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index ab78357..d451ccf 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -56,7 +56,7 @@
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.SubscriptionInfoUpdater;
import com.android.internal.telephony.TelephonyPermissions;
-import com.android.internal.util.ArrayUtils;
+import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
@@ -110,7 +110,7 @@
private final BroadcastReceiver mBootReceiver = new ConfigLoaderBroadcastReceiver();
// Broadcast receiver for SIM and pkg intents, register intent filter in constructor.
private final BroadcastReceiver mPackageReceiver = new ConfigLoaderBroadcastReceiver();
- private final LocalLog mCarrierConfigLoadingLog = new LocalLog(50);
+ private final LocalLog mCarrierConfigLoadingLog = new LocalLog(100);
// Message codes; see mHandler below.
@@ -200,6 +200,7 @@
// have sent it before unlock. This will avoid we try to load carrier config
// when SIM is still loading when unlock happens.
if (mHasSentConfigChange[i]) {
+ logWithLocalLog("System unlocked");
updateConfigForPhoneId(i);
}
}
@@ -214,6 +215,8 @@
if (clearCachedConfigForPackage(carrierPackageName)) {
int numPhones = TelephonyManager.from(mContext).getActiveModemCount();
for (int i = 0; i < numPhones; ++i) {
+ logWithLocalLog("Package changed: " + carrierPackageName
+ + ", phone=" + i);
updateConfigForPhoneId(i);
}
}
@@ -975,7 +978,10 @@
PersistableBundle config = mConfigFromDefaultApp[phoneId];
if (config != null) {
retConfig.putAll(config);
- retConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ if (getCarrierPackageForPhoneId(phoneId) == null) {
+ retConfig.putBoolean(
+ CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ }
}
config = mConfigFromCarrierApp[phoneId];
if (config != null) {
@@ -990,7 +996,6 @@
config = mOverrideConfigs[phoneId];
if (config != null) {
retConfig.putAll(config);
- retConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
}
}
return retConfig;
diff --git a/src/com/android/phone/GsmUmtsCallOptions.java b/src/com/android/phone/GsmUmtsCallOptions.java
index 88cae54..51d1b66 100644
--- a/src/com/android/phone/GsmUmtsCallOptions.java
+++ b/src/com/android/phone/GsmUmtsCallOptions.java
@@ -21,6 +21,7 @@
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
+import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.view.MenuItem;
@@ -32,7 +33,7 @@
public static final String CALL_FORWARDING_KEY = "call_forwarding_key";
public static final String CALL_BARRING_KEY = "call_barring_key";
- private static final String ADDITIONAL_GSM_SETTINGS_KEY = "additional_gsm_call_settings_key";
+ public static final String ADDITIONAL_GSM_SETTINGS_KEY = "additional_gsm_call_settings_key";
@Override
protected void onCreate(Bundle icicle) {
@@ -69,12 +70,22 @@
b = PhoneGlobals.getInstance().getCarrierConfig();
}
+ boolean isAirplaneModeOff = true;
+ if (b != null && b.getBoolean(
+ CarrierConfigManager.KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL)) {
+ int airplaneMode = Settings.Global.getInt(
+ subInfoHelper.getPhone().getContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, PhoneGlobals.AIRPLANE_OFF);
+ isAirplaneModeOff = PhoneGlobals.AIRPLANE_ON != airplaneMode;
+ }
+
Preference callForwardingPref = prefScreen.findPreference(CALL_FORWARDING_KEY);
if (callForwardingPref != null) {
if (b != null && b.getBoolean(
CarrierConfigManager.KEY_CALL_FORWARDING_VISIBILITY_BOOL)) {
callForwardingPref.setIntent(
subInfoHelper.getIntent(GsmUmtsCallForwardOptions.class));
+ callForwardingPref.setEnabled(isAirplaneModeOff);
} else {
prefScreen.removePreference(callForwardingPref);
}
@@ -89,6 +100,7 @@
CarrierConfigManager.KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL))) {
additionalGsmSettingsPref.setIntent(
subInfoHelper.getIntent(GsmUmtsAdditionalCallOptions.class));
+ additionalGsmSettingsPref.setEnabled(isAirplaneModeOff);
} else {
prefScreen.removePreference(additionalGsmSettingsPref);
}
@@ -98,6 +110,7 @@
if (callBarringPref != null) {
if (b != null && b.getBoolean(CarrierConfigManager.KEY_CALL_BARRING_VISIBILITY_BOOL)) {
callBarringPref.setIntent(subInfoHelper.getIntent(GsmUmtsCallBarringOptions.class));
+ callBarringPref.setEnabled(isAirplaneModeOff);
} else {
prefScreen.removePreference(callBarringPref);
}
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index d1ff56f..06d2367 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -18,13 +18,22 @@
import android.content.Context;
import android.net.Uri;
+import android.os.Binder;
+import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
+import android.telephony.ims.ImsException;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.aidl.IRcsUceControllerCallback;
import android.telephony.ims.feature.RcsFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.Log;
+import com.android.ims.RcsFeatureManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.imsphone.ImsPhone;
+
import java.util.List;
/**
@@ -60,28 +69,94 @@
ServiceManager.addService(Context.TELEPHONY_IMS_SERVICE, this);
}
+ /**
+ * Register a capability callback which will provide RCS availability updates for the
+ * subscription specified.
+ *
+ * @param subId the subscription ID
+ * @param callback The ImsCapabilityCallback to be registered.
+ */
@Override
- public void registerRcsAvailabilityCallback(IImsCapabilityCallback c) {
+ public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback)
+ throws RemoteException {
enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ getRcsFeatureManager(subId).registerRcsAvailabilityCallback(callback);
+ } catch (com.android.ims.ImsException e) {
+ Log.e(TAG, "registerRcsAvailabilityCallback: sudId=" + subId + ", " + e.getMessage());
+ throw new ServiceSpecificException(e.getCode());
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
+ /**
+ * Remove the registered capability callback.
+ *
+ * @param subId the subscription ID
+ * @param callback The ImsCapabilityCallback to be removed.
+ */
@Override
- public void unregisterRcsAvailabilityCallback(IImsCapabilityCallback c) {
+ public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ getRcsFeatureManager(subId).unregisterRcsAvailabilityCallback(callback);
+ } catch (com.android.ims.ImsException e) {
+ Log.e(TAG, "unregisterRcsAvailabilityCallback: sudId=" + subId + "," + e.getMessage());
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
+ /**
+ * Query for the capability of an IMS RCS service
+ *
+ * @param subId the subscription ID
+ * @param capability the RCS capability to query.
+ * @param radioTech the radio tech that this capability failed for
+ * @return true if the RCS capability is capable for this subscription, false otherwise.
+ */
@Override
public boolean isCapable(int subId,
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
+ @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+ @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
enforceReadPrivilegedPermission("isCapable");
- return false;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getRcsFeatureManager(subId).isCapable(capability, radioTech);
+ } catch (com.android.ims.ImsException e) {
+ Log.e(TAG, "isCapable: sudId=" + subId
+ + ", capability=" + capability + ", " + e.getMessage());
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
+ /**
+ * Query the availability of an IMS RCS capability.
+ *
+ * @param subId the subscription ID
+ * @param capability the RCS capability to query.
+ * @return true if the RCS capability is currently available for the associated subscription,
+ * false otherwise.
+ */
@Override
public boolean isAvailable(int subId,
@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
enforceReadPrivilegedPermission("isAvailable");
- return false;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getRcsFeatureManager(subId).isAvailable(capability);
+ } catch (com.android.ims.ImsException e) {
+ Log.e(TAG, "isAvailable: sudId=" + subId
+ + ", capability=" + capability + ", " + e.getMessage());
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
@@ -125,4 +200,30 @@
private void enforceModifyPermission() {
mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
}
+
+ /**
+ * Retrieve RcsFeatureManager instance.
+ *
+ * @param subId the subscription ID
+ * @return The RcsFeatureManager instance
+ * @throws SecurityException if getting Phone or RcsFeatureManager instance failed.
+ */
+ private RcsFeatureManager getRcsFeatureManager(int subId) {
+ Phone phone = PhoneGlobals.getPhone(subId);
+ if (phone == null) {
+ throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
+ "Invalid subscription Id: " + subId);
+ }
+ ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
+ if (imsPhone == null) {
+ throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+ "Cannot find ImsPhone instance: " + subId);
+ }
+ RcsFeatureManager rcsFeatureManager = imsPhone.getRcsManager();
+ if (rcsFeatureManager == null) {
+ throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
+ "Cannot find RcsFeatureManager instance: " + subId);
+ }
+ return rcsFeatureManager;
+ }
}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index e30078c..fe55335 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -375,12 +375,11 @@
final Notification notification = builder.build();
List<UserInfo> users = mUserManager.getUsers(true);
- for (int i = 0; i < users.size(); i++) {
- final UserInfo user = users.get(i);
+ for (UserInfo user : users) {
final UserHandle userHandle = user.getUserHandle();
if (!hasUserRestriction(
UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
- && !user.isManagedProfile()) {
+ && !mUserManager.isManagedProfile(userHandle.getIdentifier())) {
if (!maybeSendVoicemailNotificationUsingDefaultDialer(phone, vmCount, vmNumber,
pendingIntent, isSettingsIntent, userHandle, isRefresh)) {
notifyAsUser(
@@ -393,12 +392,11 @@
}
} else {
List<UserInfo> users = mUserManager.getUsers(true /* excludeDying */);
- for (int i = 0; i < users.size(); i++) {
- final UserInfo user = users.get(i);
+ for (UserInfo user : users) {
final UserHandle userHandle = user.getUserHandle();
if (!hasUserRestriction(
UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
- && !user.isManagedProfile()) {
+ && !mUserManager.isManagedProfile(userHandle.getIdentifier())) {
if (!maybeSendVoicemailNotificationUsingDefaultDialer(phone, 0, null, null,
false, userHandle, isRefresh)) {
cancelAsUser(
@@ -559,7 +557,7 @@
} else {
List<UserInfo> users = mUserManager.getUsers(true);
for (UserInfo user : users) {
- if (user.isManagedProfile()) {
+ if (mUserManager.isManagedProfile(user.getUserHandle().getIdentifier())) {
continue;
}
UserHandle userHandle = user.getUserHandle();
@@ -691,7 +689,7 @@
.setContentText(contentText)
.setOnlyAlertOnce(true)
.setOngoing(true)
- .setChannel(NotificationChannelController.CHANNEL_ID_SIM_HIGH_PRIORITY)
+ .setChannelId(NotificationChannelController.CHANNEL_ID_SIM_HIGH_PRIORITY)
.setContentIntent(contentIntent);
final Notification notification = new Notification.BigTextStyle(builder).bigText(
contentText).build();
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 1eb5f50..5d4d9b3 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -577,7 +577,9 @@
if (tm != null && tm.isInEmergencyCall()) {
// Switch airplane mode back to off.
- ConnectivityManager.from(this).setAirplaneMode(false);
+ ConnectivityManager cm =
+ (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
+ cm.setAirplaneMode(false);
Toast.makeText(this, R.string.radio_off_during_emergency_call, Toast.LENGTH_LONG)
.show();
Log.i(LOG_TAG, "Ignoring airplane mode: emergency call. Turning airplane off");
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 2c0c5de..296525d 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -1223,6 +1223,7 @@
((SIMRecords) uiccApp.getIccRecords())
.setForbiddenPlmns(onCompleted, fplmns);
}
+ break;
case CMD_ERASE_MODEM_CONFIG:
request = (MainThreadRequest) msg.obj;
onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
@@ -1777,6 +1778,7 @@
}
public boolean needMobileRadioShutdown() {
+ enforceReadPrivilegedPermission("needMobileRadioShutdown");
/*
* If any of the Radios are available, it will need to be
* shutdown. So return true if any Radio is available.
@@ -2031,7 +2033,15 @@
}
@Override
- public String getNetworkCountryIsoForPhone(int phoneId) {
+ public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage) {
+ if (!TextUtils.isEmpty(callingPackage)) {
+ final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+ mApp, subId, callingPackage, "getNetworkCountryIsoForPhone")) {
+ return "";
+ }
+ }
+
// Reporting the correct network country is ambiguous when IWLAN could conflict with
// registered cell info, so return a NULL country instead.
final long identity = Binder.clearCallingIdentity();
diff --git a/src/com/android/phone/ShortcutViewUtils.java b/src/com/android/phone/ShortcutViewUtils.java
index 47ca5ee..e3c5b64 100644
--- a/src/com/android/phone/ShortcutViewUtils.java
+++ b/src/com/android/phone/ShortcutViewUtils.java
@@ -33,7 +33,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.util.ArrayUtils;
+import com.android.internal.telephony.util.ArrayUtils;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 672a27f..0806fd1 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -55,6 +55,9 @@
private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
+ private static final String DATA_TEST_MODE = "data";
+ private static final String DATA_ENABLE = "enable";
+ private static final String DATA_DISABLE = "disable";
private static final String IMS_SET_CARRIER_SERVICE = "set-ims-service";
private static final String IMS_GET_CARRIER_SERVICE = "get-ims-service";
@@ -146,6 +149,8 @@
case CARRIER_CONFIG_SUBCOMMAND: {
return handleCcCommand();
}
+ case DATA_TEST_MODE:
+ return handleDataTestModeCommand();
default: {
return handleDefaultCommands(cmd);
}
@@ -162,10 +167,13 @@
pw.println(" IMS Commands.");
pw.println(" emergency-number-test-mode");
pw.println(" Emergency Number Test Mode Commands.");
+ pw.println(" data");
+ pw.println(" Data Test Mode Commands.");
pw.println(" cc");
pw.println(" Carrier Config Commands.");
onHelpIms();
onHelpEmergencyNumber();
+ onHelpDataTestMode();
onHelpCc();
}
@@ -207,6 +215,13 @@
pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
}
+ private void onHelpDataTestMode() {
+ PrintWriter pw = getOutPrintWriter();
+ pw.println("Mobile Data Test Mode Commands:");
+ pw.println(" data enable: enable mobile data connectivity");
+ pw.println(" data disable: disable mobile data connectivity");
+ }
+
private void onHelpEmergencyNumber() {
PrintWriter pw = getOutPrintWriter();
pw.println("Emergency Number Test Mode Commands:");
@@ -277,6 +292,41 @@
return -1;
}
+ private int handleDataTestModeCommand() {
+ PrintWriter errPw = getErrPrintWriter();
+ String arg = getNextArgRequired();
+ if (arg == null) {
+ onHelpDataTestMode();
+ return 0;
+ }
+ switch (arg) {
+ case DATA_ENABLE: {
+ try {
+ mInterface.enableDataConnectivity();
+ } catch (RemoteException ex) {
+ Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
+ errPw.println("Exception: " + ex.getMessage());
+ return -1;
+ }
+ break;
+ }
+ case DATA_DISABLE: {
+ try {
+ mInterface.disableDataConnectivity();
+ } catch (RemoteException ex) {
+ Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
+ errPw.println("Exception: " + ex.getMessage());
+ return -1;
+ }
+ break;
+ }
+ default:
+ onHelpDataTestMode();
+ break;
+ }
+ return 0;
+ }
+
private int handleEmergencyNumberTestModeCommand() {
PrintWriter errPw = getErrPrintWriter();
String opt = getNextOption();
diff --git a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
index 96f04e1..c47e014 100644
--- a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
+++ b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -95,7 +96,7 @@
grantDefaultPermissionsToActiveLuiApp(activityInfo);
- euiccUiIntent.setComponent(activityInfo.getComponentName());
+ euiccUiIntent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));
return euiccUiIntent;
}
diff --git a/src/com/android/phone/settings/BandMode.java b/src/com/android/phone/settings/BandMode.java
new file mode 100644
index 0000000..853075a
--- /dev/null
+++ b/src/com/android/phone/settings/BandMode.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.settings;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.phone.R;
+
+/**
+ * Radio Band Mode Selection Class
+ *
+ * It will query baseband about all available band modes and display them
+ * in screen. It will display all six band modes if the query failed.
+ *
+ * After user select one band, it will send the selection to baseband.
+ *
+ * It will alter user the result of select operation and exit, no matter success
+ * or not.
+ *
+ */
+public class BandMode extends Activity {
+ private static final String LOG_TAG = "phone";
+ private static final boolean DBG = false;
+
+ private static final int EVENT_BAND_SCAN_COMPLETED = 100;
+ private static final int EVENT_BAND_SELECTION_DONE = 200;
+
+ //Directly maps to RIL_RadioBandMode from ril.h
+ private static final String[] BAND_NAMES = new String[] {
+ "Automatic",
+ "Europe",
+ "United States",
+ "Japan",
+ "Australia",
+ "Australia 2",
+ "Cellular 800",
+ "PCS",
+ "Class 3 (JTACS)",
+ "Class 4 (Korea-PCS)",
+ "Class 5",
+ "Class 6 (IMT2000)",
+ "Class 7 (700Mhz-Upper)",
+ "Class 8 (1800Mhz-Upper)",
+ "Class 9 (900Mhz)",
+ "Class 10 (800Mhz-Secondary)",
+ "Class 11 (Europe PAMR 400Mhz)",
+ "Class 15 (US-AWS)",
+ "Class 16 (US-2500Mhz)"
+ };
+
+ private ListView mBandList;
+ private ArrayAdapter mBandListAdapter;
+ private BandListItem mTargetBand = null;
+ private DialogInterface mProgressPanel;
+
+ private Phone mPhone = null;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setContentView(R.layout.band_mode);
+
+ mPhone = PhoneFactory.getDefaultPhone();
+
+ mBandList = (ListView) findViewById(R.id.band);
+ mBandListAdapter = new ArrayAdapter<BandListItem>(this,
+ android.R.layout.simple_list_item_1);
+ mBandList.setAdapter(mBandListAdapter);
+ mBandList.setOnItemClickListener(mBandSelectionHandler);
+
+ loadBandList();
+ }
+
+ private AdapterView.OnItemClickListener mBandSelectionHandler =
+ new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView parent, View v,
+ int position, long id) {
+
+ getWindow().setFeatureInt(
+ Window.FEATURE_INDETERMINATE_PROGRESS,
+ Window.PROGRESS_VISIBILITY_ON);
+
+ mTargetBand = (BandListItem) parent.getAdapter().getItem(position);
+
+ if (DBG) log("Select band : " + mTargetBand.toString());
+
+ Message msg =
+ mHandler.obtainMessage(EVENT_BAND_SELECTION_DONE);
+ mPhone.setBandMode(mTargetBand.getBand(), msg);
+ }
+ };
+
+ private static class BandListItem {
+ private int mBandMode = Phone.BM_UNSPECIFIED;
+
+ BandListItem(int bm) {
+ mBandMode = bm;
+ }
+
+ public int getBand() {
+ return mBandMode;
+ }
+
+ public String toString() {
+ if (mBandMode >= BAND_NAMES.length) return "Band mode " + mBandMode;
+ return BAND_NAMES[mBandMode];
+ }
+ }
+
+ private void loadBandList() {
+ String str = getString(R.string.band_mode_loading);
+
+ if (DBG) log(str);
+
+
+ //ProgressDialog.show(this, null, str, true, true, null);
+ mProgressPanel = new AlertDialog.Builder(this)
+ .setMessage(str)
+ .show();
+
+ Message msg = mHandler.obtainMessage(EVENT_BAND_SCAN_COMPLETED);
+ mPhone.queryAvailableBandMode(msg);
+
+ }
+
+ private void bandListLoaded(AsyncResult result) {
+ if (DBG) log("network list loaded");
+
+ if (mProgressPanel != null) mProgressPanel.dismiss();
+
+ clearList();
+
+ boolean addBandSuccess = false;
+ BandListItem item;
+
+ if (result.result != null) {
+ int [] bands = (int []) result.result;
+
+ if (bands.length == 0) {
+ Log.wtf(LOG_TAG, "No Supported Band Modes");
+ return;
+ }
+
+ int size = bands[0];
+
+ if (size > 0) {
+ mBandListAdapter.add(
+ new BandListItem(Phone.BM_UNSPECIFIED)); //Always include AUTOMATIC
+ for (int i = 1; i <= size; i++) {
+ if (bands[i] == Phone.BM_UNSPECIFIED) {
+ continue;
+ }
+ item = new BandListItem(bands[i]);
+ mBandListAdapter.add(item);
+ if (DBG) log("Add " + item.toString());
+ }
+ addBandSuccess = true;
+ }
+ }
+
+ if (!addBandSuccess) {
+ if (DBG) log("Error in query, add default list");
+ for (int i = 0; i < Phone.BM_NUM_BAND_MODES; i++) {
+ item = new BandListItem(i);
+ mBandListAdapter.add(item);
+ if (DBG) log("Add default " + item.toString());
+ }
+ }
+ mBandList.requestFocus();
+ }
+
+ private void displayBandSelectionResult(Throwable ex) {
+ String status = getString(R.string.band_mode_set)
+ + " [" + mTargetBand.toString() + "] ";
+
+ if (ex != null) {
+ status = status + getString(R.string.band_mode_failed);
+ } else {
+ status = status + getString(R.string.band_mode_succeeded);
+ }
+
+ mProgressPanel = new AlertDialog.Builder(this)
+ .setMessage(status)
+ .setPositiveButton(android.R.string.ok, null).show();
+ }
+
+ private void clearList() {
+ while (mBandListAdapter.getCount() > 0) {
+ mBandListAdapter.remove(
+ mBandListAdapter.getItem(0));
+ }
+ }
+
+ private void log(String msg) {
+ Log.d(LOG_TAG, "[BandsList] " + msg);
+ }
+
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ switch (msg.what) {
+ case EVENT_BAND_SCAN_COMPLETED:
+ ar = (AsyncResult) msg.obj;
+
+ bandListLoaded(ar);
+ break;
+
+ case EVENT_BAND_SELECTION_DONE:
+ ar = (AsyncResult) msg.obj;
+
+ getWindow().setFeatureInt(
+ Window.FEATURE_INDETERMINATE_PROGRESS,
+ Window.PROGRESS_VISIBILITY_OFF);
+
+ if (!isFinishing()) {
+ displayBandSelectionResult(ar.exception);
+ }
+ break;
+ }
+ }
+ };
+
+
+}
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
new file mode 100644
index 0000000..ce5b839
--- /dev/null
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -0,0 +1,1772 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.settings;
+
+import static android.net.ConnectivityManager.NetworkCallback;
+import static android.provider.Settings.Global.PREFERRED_NETWORK_MODE;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.TrafficStats;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.CellLocation;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.PhoneStateListener;
+import android.telephony.PhysicalChannelConfig;
+import android.telephony.PreciseCallState;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.cdma.CdmaCellLocation;
+import android.telephony.gsm.GsmCellLocation;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AlertDialog.Builder;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.phone.R;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Radio Information Class
+ *
+ * Allows user to read and alter some of the radio related information.
+ *
+ */
+public class RadioInfo extends AppCompatActivity {
+ private static final String TAG = "RadioInfo";
+
+ private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
+
+ private static final String[] PREFERRED_NETWORK_LABELS = {
+ "WCDMA preferred",
+ "GSM only",
+ "WCDMA only",
+ "GSM auto (PRL)",
+ "CDMA auto (PRL)",
+ "CDMA only",
+ "EvDo only",
+ "Global auto (PRL)",
+ "LTE/CDMA auto (PRL)",
+ "LTE/UMTS auto (PRL)",
+ "LTE/CDMA/UMTS auto (PRL)",
+ "LTE only",
+ "LTE/WCDMA",
+ "TD-SCDMA only",
+ "TD-SCDMA/WCDMA",
+ "LTE/TD-SCDMA",
+ "TD-SCDMA/GSM",
+ "TD-SCDMA/UMTS",
+ "LTE/TD-SCDMA/WCDMA",
+ "LTE/TD-SCDMA/UMTS",
+ "TD-SCDMA/CDMA/UMTS",
+ "Global/TD-SCDMA",
+ "Unknown"
+ };
+
+ private static String[] sPhoneIndexLabels;
+
+ private static final int sCellInfoListRateDisabled = Integer.MAX_VALUE;
+ private static final int sCellInfoListRateMax = 0;
+
+ private static final String OEM_RADIO_INFO_INTENT =
+ "com.android.phone.settings.OEM_RADIO_INFO";
+
+ private static final String DSDS_MODE_PROPERTY = "ro.boot.hardware.dsds";
+
+ /**
+ * A value indicates the device is always on dsds mode.
+ * @see {@link #DSDS_MODE_PROPERTY}
+ */
+ private static final int ALWAYS_ON_DSDS_MODE = 1;
+
+ private static final int IMS_VOLTE_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.VLT_SETTING_ENABLED;
+
+ private static final int IMS_VT_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.LVC_SETTING_ENABLED;
+
+ private static final int IMS_WFC_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED;
+
+ private static final int EAB_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.EAB_SETTING_ENABLED;
+
+ //Values in must match CELL_INFO_REFRESH_RATES
+ private static final String[] CELL_INFO_REFRESH_RATE_LABELS = {
+ "Disabled",
+ "Immediate",
+ "Min 5s",
+ "Min 10s",
+ "Min 60s"
+ };
+
+ //Values in seconds, must match CELL_INFO_REFRESH_RATE_LABELS
+ private static final int [] CELL_INFO_REFRESH_RATES = {
+ sCellInfoListRateDisabled,
+ sCellInfoListRateMax,
+ 5000,
+ 10000,
+ 60000
+ };
+
+ private static void log(String s) {
+ Log.d(TAG, s);
+ }
+
+ private static final int EVENT_CFI_CHANGED = 302;
+
+ private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
+ private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
+ private static final int EVENT_QUERY_SMSC_DONE = 1005;
+ private static final int EVENT_UPDATE_SMSC_DONE = 1006;
+ private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 1007;
+
+ private static final int MENU_ITEM_SELECT_BAND = 0;
+ private static final int MENU_ITEM_VIEW_ADN = 1;
+ private static final int MENU_ITEM_VIEW_FDN = 2;
+ private static final int MENU_ITEM_VIEW_SDN = 3;
+ private static final int MENU_ITEM_GET_IMS_STATUS = 4;
+ private static final int MENU_ITEM_TOGGLE_DATA = 5;
+
+ private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
+ private TextView mLine1Number;
+ private TextView mSubscriptionId;
+ private TextView mDds;
+ private TextView mSubscriberId;
+ private TextView mCallState;
+ private TextView mOperatorName;
+ private TextView mRoamingState;
+ private TextView mGsmState;
+ private TextView mGprsState;
+ private TextView mVoiceNetwork;
+ private TextView mDataNetwork;
+ private TextView mDBm;
+ private TextView mMwi;
+ private TextView mCfi;
+ private TextView mLocation;
+ private TextView mCellInfo;
+ private TextView mSent;
+ private TextView mReceived;
+ private TextView mPingHostnameV4;
+ private TextView mPingHostnameV6;
+ private TextView mHttpClientTest;
+ private TextView mPhyChanConfig;
+ private TextView mDnsCheckState;
+ private TextView mDownlinkKbps;
+ private TextView mUplinkKbps;
+ private EditText mSmsc;
+ private Switch mRadioPowerOnSwitch;
+ private Button mCellInfoRefreshRateButton;
+ private Button mDnsCheckToggleButton;
+ private Button mPingTestButton;
+ private Button mUpdateSmscButton;
+ private Button mRefreshSmscButton;
+ private Button mOemInfoButton;
+ private Button mCarrierProvisioningButton;
+ private Button mTriggerCarrierProvisioningButton;
+ private Switch mImsVolteProvisionedSwitch;
+ private Switch mImsVtProvisionedSwitch;
+ private Switch mImsWfcProvisionedSwitch;
+ private Switch mEabProvisionedSwitch;
+ private Switch mCbrsDataSwitch;
+ private Switch mDsdsSwitch;
+ private Spinner mPreferredNetworkType;
+ private Spinner mSelectPhoneIndex;
+ private Spinner mCellInfoRefreshRateSpinner;
+
+ private static final long RUNNABLE_TIMEOUT_MS = 5 * 60 * 1000L;
+
+ private ThreadPoolExecutor mQueuedWork;
+
+ private ConnectivityManager mConnectivityManager;
+ private TelephonyManager mTelephonyManager;
+ private ImsManager mImsManager = null;
+ private Phone mPhone = null;
+
+ private String mPingHostnameResultV4;
+ private String mPingHostnameResultV6;
+ private String mHttpClientTestResult;
+ private boolean mMwiValue = false;
+ private boolean mCfiValue = false;
+
+ private List<CellInfo> mCellInfoResult = null;
+ private CellLocation mCellLocationResult = null;
+
+ private int mPreferredNetworkTypeResult;
+ private int mCellInfoRefreshRateIndex;
+ private int mSelectedPhoneIndex;
+
+ private final NetworkRequest mDefaultNetworkRequest = new NetworkRequest.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build();
+
+ private final NetworkCallback mNetworkCallback = new NetworkCallback() {
+ public void onCapabilitiesChanged(Network n, NetworkCapabilities nc) {
+ int dlbw = nc.getLinkDownstreamBandwidthKbps();
+ int ulbw = nc.getLinkUpstreamBandwidthKbps();
+ updateBandwidths(dlbw, ulbw);
+ }
+ };
+
+ // not final because we need to recreate this object to register on a new subId (b/117555407)
+ private PhoneStateListener mPhoneStateListener = new RadioInfoPhoneStateListener();
+ private class RadioInfoPhoneStateListener extends PhoneStateListener {
+ @Override
+ public void onDataConnectionStateChanged(int state) {
+ updateDataState();
+ updateNetworkType();
+ }
+
+ @Override
+ public void onDataActivity(int direction) {
+ updateDataStats2();
+ }
+
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ updateNetworkType();
+ updatePhoneState(state);
+ }
+
+ @Override
+ public void onPreciseCallStateChanged(PreciseCallState preciseState) {
+ updateNetworkType();
+ }
+
+ @Override
+ public void onCellLocationChanged(CellLocation location) {
+ updateLocation(location);
+ }
+
+ @Override
+ public void onMessageWaitingIndicatorChanged(boolean mwi) {
+ mMwiValue = mwi;
+ updateMessageWaiting();
+ }
+
+ @Override
+ public void onCallForwardingIndicatorChanged(boolean cfi) {
+ mCfiValue = cfi;
+ updateCallRedirect();
+ }
+
+ @Override
+ public void onCellInfoChanged(List<CellInfo> arrayCi) {
+ log("onCellInfoChanged: arrayCi=" + arrayCi);
+ mCellInfoResult = arrayCi;
+ updateCellInfo(mCellInfoResult);
+ }
+
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ log("onSignalStrengthChanged: SignalStrength=" + signalStrength);
+ updateSignalStrength(signalStrength);
+ }
+
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+ log("onServiceStateChanged: ServiceState=" + serviceState);
+ updateServiceState(serviceState);
+ updateRadioPowerState();
+ updateNetworkType();
+ updateImsProvisionedState();
+ }
+
+ }
+
+ private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
+ StringBuilder sb = new StringBuilder();
+ String div = "";
+ sb.append("{");
+ if (configs != null) {
+ for (PhysicalChannelConfig c : configs) {
+ sb.append(div).append(c);
+ div = ",";
+ }
+ }
+ sb.append("}");
+ mPhyChanConfig.setText(sb.toString());
+ }
+
+ private void updatePreferredNetworkType(int type) {
+ if (type >= PREFERRED_NETWORK_LABELS.length || type < 0) {
+ log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown "
+ + "type=" + type);
+ type = PREFERRED_NETWORK_LABELS.length - 1; //set to Unknown
+ }
+ mPreferredNetworkTypeResult = type;
+
+ mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
+ }
+
+ private void updatePhoneIndex(int phoneIndex, int subId) {
+ // unregister listeners on the old subId
+ unregisterPhoneStateListener();
+ mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled);
+
+ // update the subId
+ mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
+
+ // update the phoneId
+ mImsManager = ImsManager.getInstance(getApplicationContext(), phoneIndex);
+ mPhone = PhoneFactory.getPhone(phoneIndex);
+
+ updateAllFields();
+ }
+
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ switch (msg.what) {
+ case EVENT_QUERY_PREFERRED_TYPE_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception == null && ar.result != null) {
+ updatePreferredNetworkType(((int []) ar.result)[0]);
+ } else {
+ //In case of an exception, we will set this to unknown
+ updatePreferredNetworkType(PREFERRED_NETWORK_LABELS.length - 1);
+ }
+ break;
+ case EVENT_SET_PREFERRED_TYPE_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ log("Set preferred network type failed.");
+ }
+ break;
+ case EVENT_QUERY_SMSC_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ mSmsc.setText("refresh error");
+ } else {
+ mSmsc.setText((String) ar.result);
+ }
+ break;
+ case EVENT_UPDATE_SMSC_DONE:
+ mUpdateSmscButton.setEnabled(true);
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ mSmsc.setText("update error");
+ }
+ break;
+ case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ mPhyChanConfig.setText(("update error"));
+ }
+ updatePhysicalChannelConfiguration((List<PhysicalChannelConfig>) ar.result);
+ break;
+ default:
+ super.handleMessage(msg);
+ break;
+
+ }
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ if (!android.os.Process.myUserHandle().isSystem()) {
+ Log.e(TAG, "Not run from system user, don't do anything.");
+ finish();
+ return;
+ }
+
+ setContentView(R.layout.radio_info);
+
+ log("Started onCreate");
+
+ mQueuedWork = new ThreadPoolExecutor(1, 1, RUNNABLE_TIMEOUT_MS, TimeUnit.MICROSECONDS,
+ new LinkedBlockingDeque<Runnable>());
+ mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ mConnectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
+ mPhone = PhoneFactory.getDefaultPhone();
+
+ mImsManager = ImsManager.getInstance(getApplicationContext(),
+ SubscriptionManager.getDefaultVoicePhoneId());
+
+ sPhoneIndexLabels = getPhoneIndexLabels(mTelephonyManager);
+
+ mDeviceId = (TextView) findViewById(R.id.imei);
+ mLine1Number = (TextView) findViewById(R.id.number);
+ mSubscriptionId = (TextView) findViewById(R.id.subid);
+ mDds = (TextView) findViewById(R.id.dds);
+ mSubscriberId = (TextView) findViewById(R.id.imsi);
+ mCallState = (TextView) findViewById(R.id.call);
+ mOperatorName = (TextView) findViewById(R.id.operator);
+ mRoamingState = (TextView) findViewById(R.id.roaming);
+ mGsmState = (TextView) findViewById(R.id.gsm);
+ mGprsState = (TextView) findViewById(R.id.gprs);
+ mVoiceNetwork = (TextView) findViewById(R.id.voice_network);
+ mDataNetwork = (TextView) findViewById(R.id.data_network);
+ mDBm = (TextView) findViewById(R.id.dbm);
+ mMwi = (TextView) findViewById(R.id.mwi);
+ mCfi = (TextView) findViewById(R.id.cfi);
+ mLocation = (TextView) findViewById(R.id.location);
+ mCellInfo = (TextView) findViewById(R.id.cellinfo);
+ mCellInfo.setTypeface(Typeface.MONOSPACE);
+
+ mSent = (TextView) findViewById(R.id.sent);
+ mReceived = (TextView) findViewById(R.id.received);
+ mSmsc = (EditText) findViewById(R.id.smsc);
+ mDnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
+ mPingHostnameV4 = (TextView) findViewById(R.id.pingHostnameV4);
+ mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6);
+ mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
+
+ mPhyChanConfig = (TextView) findViewById(R.id.phy_chan_config);
+
+ mPreferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
+ ArrayAdapter<String> mPreferredNetworkTypeAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, PREFERRED_NETWORK_LABELS);
+ mPreferredNetworkTypeAdapter
+ .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mPreferredNetworkType.setAdapter(mPreferredNetworkTypeAdapter);
+
+ mSelectPhoneIndex = (Spinner) findViewById(R.id.phoneIndex);
+ ArrayAdapter<String> phoneIndexAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, sPhoneIndexLabels);
+ phoneIndexAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mSelectPhoneIndex.setAdapter(phoneIndexAdapter);
+
+ mCellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select);
+ ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, CELL_INFO_REFRESH_RATE_LABELS);
+ cellInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mCellInfoRefreshRateSpinner.setAdapter(cellInfoAdapter);
+
+ mImsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch);
+ mImsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch);
+ mImsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
+ mEabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
+
+ if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
+ mImsVolteProvisionedSwitch.setVisibility(View.GONE);
+ mImsVtProvisionedSwitch.setVisibility(View.GONE);
+ mImsWfcProvisionedSwitch.setVisibility(View.GONE);
+ mEabProvisionedSwitch.setVisibility(View.GONE);
+ }
+
+ mCbrsDataSwitch = (Switch) findViewById(R.id.cbrs_data_switch);
+ mCbrsDataSwitch.setVisibility(isCbrsSupported() ? View.VISIBLE : View.GONE);
+
+ mDsdsSwitch = findViewById(R.id.dsds_switch);
+ if (isDsdsSupported() && !dsdsModeOnly()) {
+ mDsdsSwitch.setVisibility(View.VISIBLE);
+ mDsdsSwitch.setOnClickListener(v -> {
+ if (mTelephonyManager.doesSwitchMultiSimConfigTriggerReboot()) {
+ // Undo the click action until user clicks the confirm dialog.
+ mDsdsSwitch.toggle();
+ showDsdsChangeDialog();
+ } else {
+ performDsdsSwitch();
+ }
+ });
+ mDsdsSwitch.setChecked(isDsdsEnabled());
+ } else {
+ mDsdsSwitch.setVisibility(View.GONE);
+ }
+
+ mRadioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
+
+ mDownlinkKbps = (TextView) findViewById(R.id.dl_kbps);
+ mUplinkKbps = (TextView) findViewById(R.id.ul_kbps);
+ updateBandwidths(0, 0);
+
+ mPingTestButton = (Button) findViewById(R.id.ping_test);
+ mPingTestButton.setOnClickListener(mPingButtonHandler);
+ mUpdateSmscButton = (Button) findViewById(R.id.update_smsc);
+ mUpdateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
+ mRefreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
+ mRefreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
+ mDnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
+ mDnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
+ mCarrierProvisioningButton = (Button) findViewById(R.id.carrier_provisioning);
+ mCarrierProvisioningButton.setOnClickListener(mCarrierProvisioningButtonHandler);
+ mTriggerCarrierProvisioningButton = (Button) findViewById(
+ R.id.trigger_carrier_provisioning);
+ mTriggerCarrierProvisioningButton.setOnClickListener(
+ mTriggerCarrierProvisioningButtonHandler);
+
+ mOemInfoButton = (Button) findViewById(R.id.oem_info);
+ mOemInfoButton.setOnClickListener(mOemInfoButtonHandler);
+ PackageManager pm = getPackageManager();
+ Intent oemInfoIntent = new Intent(OEM_RADIO_INFO_INTENT);
+ List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
+ if (oemInfoIntentList.size() == 0) {
+ mOemInfoButton.setEnabled(false);
+ }
+
+ mCellInfoRefreshRateIndex = 0; //disabled
+ mPreferredNetworkTypeResult = PREFERRED_NETWORK_LABELS.length - 1; //Unknown
+ mSelectedPhoneIndex = 0; //phone 0
+
+ //FIXME: Replace with TelephonyManager call
+ mPhone.getPreferredNetworkType(
+ mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
+
+ restoreFromBundle(icicle);
+ }
+
+ @Override
+ public Intent getParentActivityIntent() {
+ Intent parentActivity = super.getParentActivityIntent();
+ if (parentActivity == null) {
+ parentActivity = (new Intent()).setClassName("com.android.settings",
+ "com.android.settings.Settings$TestingSettingsActivity");
+ }
+ return parentActivity;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ log("Started onResume");
+
+ updateAllFields();
+ }
+
+ private void updateAllFields() {
+ updateMessageWaiting();
+ updateCallRedirect();
+ updateDataState();
+ updateDataStats2();
+ updateRadioPowerState();
+ updateImsProvisionedState();
+ updateProperties();
+ updateDnsCheckState();
+ updateNetworkType();
+
+ updateLocation(mCellLocationResult);
+ updateCellInfo(mCellInfoResult);
+ updateSubscriptionIds();
+
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+
+ mCellInfoRefreshRateSpinner.setOnItemSelectedListener(mCellInfoRefreshRateHandler);
+ //set selection after registering listener to force update
+ mCellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex);
+
+ //set selection before registering to prevent update
+ mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
+ mPreferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
+
+ // set phone index
+ mSelectPhoneIndex.setSelection(mSelectedPhoneIndex, true);
+ mSelectPhoneIndex.setOnItemSelectedListener(mSelectPhoneIndexHandler);
+
+ mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
+ mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
+ mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
+ mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
+ mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
+
+ if (isCbrsSupported()) {
+ mCbrsDataSwitch.setChecked(getCbrsDataState());
+ mCbrsDataSwitch.setOnCheckedChangeListener(mCbrsDataSwitchChangeListener);
+ }
+
+ unregisterPhoneStateListener();
+ registerPhoneStateListener();
+ mPhone.registerForPhysicalChannelConfig(mHandler,
+ EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, null);
+
+ mConnectivityManager.registerNetworkCallback(
+ mDefaultNetworkRequest, mNetworkCallback, mHandler);
+
+ mSmsc.clearFocus();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ log("onPause: unregister phone & data intents");
+
+ mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+ mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled);
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+
+ }
+
+ private void restoreFromBundle(Bundle b) {
+ if (b == null) {
+ return;
+ }
+
+ mPingHostnameResultV4 = b.getString("mPingHostnameResultV4", "");
+ mPingHostnameResultV6 = b.getString("mPingHostnameResultV6", "");
+ mHttpClientTestResult = b.getString("mHttpClientTestResult", "");
+
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+
+ mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
+ PREFERRED_NETWORK_LABELS.length - 1);
+
+ mSelectedPhoneIndex = b.getInt("mSelectedPhoneIndex", 0);
+
+ mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putString("mPingHostnameResultV4", mPingHostnameResultV4);
+ outState.putString("mPingHostnameResultV6", mPingHostnameResultV6);
+ outState.putString("mHttpClientTestResult", mHttpClientTestResult);
+
+ outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
+ outState.putInt("mSelectedPhoneIndex", mSelectedPhoneIndex);
+ outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
+ .setOnMenuItemClickListener(mSelectBandCallback)
+ .setAlphabeticShortcut('b');
+ menu.add(1, MENU_ITEM_VIEW_ADN, 0,
+ R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
+ menu.add(1, MENU_ITEM_VIEW_FDN, 0,
+ R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
+ menu.add(1, MENU_ITEM_VIEW_SDN, 0,
+ R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
+ if (ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
+ menu.add(1, MENU_ITEM_GET_IMS_STATUS,
+ 0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus);
+ }
+ menu.add(1, MENU_ITEM_TOGGLE_DATA,
+ 0, R.string.radio_info_data_connection_disable)
+ .setOnMenuItemClickListener(mToggleData);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ // Get the TOGGLE DATA menu item in the right state.
+ MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
+ int state = mTelephonyManager.getDataState();
+ boolean visible = true;
+
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ case TelephonyManager.DATA_SUSPENDED:
+ item.setTitle(R.string.radio_info_data_connection_disable);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ item.setTitle(R.string.radio_info_data_connection_enable);
+ break;
+ default:
+ visible = false;
+ break;
+ }
+ item.setVisible(visible);
+ return true;
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mQueuedWork.shutdown();
+ }
+
+ // returns array of string labels for each phone index. The array index is equal to the phone
+ // index.
+ private static String[] getPhoneIndexLabels(TelephonyManager tm) {
+ int phones = tm.getPhoneCount();
+ String[] labels = new String[phones];
+ for (int i = 0; i < phones; i++) {
+ labels[i] = "Phone " + i;
+ }
+ return labels;
+ }
+
+ private void unregisterPhoneStateListener() {
+ mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+ mPhone.unregisterForPhysicalChannelConfig(mHandler);
+
+ // clear all fields so they are blank until the next listener event occurs
+ mOperatorName.setText("");
+ mGprsState.setText("");
+ mDataNetwork.setText("");
+ mVoiceNetwork.setText("");
+ mSent.setText("");
+ mReceived.setText("");
+ mCallState.setText("");
+ mLocation.setText("");
+ mMwiValue = false;
+ mMwi.setText("");
+ mCfiValue = false;
+ mCfi.setText("");
+ mCellInfo.setText("");
+ mDBm.setText("");
+ mGsmState.setText("");
+ mRoamingState.setText("");
+ mPhyChanConfig.setText("");
+ }
+
+ // register mPhoneStateListener for relevant fields using the current TelephonyManager
+ private void registerPhoneStateListener() {
+ mPhoneStateListener = new RadioInfoPhoneStateListener();
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_CALL_STATE
+ //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
+ // | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
+ | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_DATA_ACTIVITY
+ | PhoneStateListener.LISTEN_CELL_LOCATION
+ | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
+ | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
+ | PhoneStateListener.LISTEN_CELL_INFO
+ | PhoneStateListener.LISTEN_SERVICE_STATE
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+ }
+
+ private void updateDnsCheckState() {
+ //FIXME: Replace with a TelephonyManager call
+ mDnsCheckState.setText(mPhone.isDnsCheckDisabled()
+ ? "0.0.0.0 allowed" : "0.0.0.0 not allowed");
+ }
+
+ private void updateBandwidths(int dlbw, int ulbw) {
+ dlbw = (dlbw < 0 || dlbw == Integer.MAX_VALUE) ? -1 : dlbw;
+ ulbw = (ulbw < 0 || ulbw == Integer.MAX_VALUE) ? -1 : ulbw;
+ mDownlinkKbps.setText(String.format("%-5d", dlbw));
+ mUplinkKbps.setText(String.format("%-5d", ulbw));
+ }
+
+
+ private void updateSignalStrength(SignalStrength signalStrength) {
+ Resources r = getResources();
+
+ int signalDbm = signalStrength.getDbm();
+
+ int signalAsu = signalStrength.getAsuLevel();
+
+ if (-1 == signalAsu) signalAsu = 0;
+
+ mDBm.setText(String.valueOf(signalDbm) + " "
+ + r.getString(R.string.radioInfo_display_dbm) + " "
+ + String.valueOf(signalAsu) + " "
+ + r.getString(R.string.radioInfo_display_asu));
+ }
+
+ private void updateLocation(CellLocation location) {
+ Resources r = getResources();
+ if (location instanceof GsmCellLocation) {
+ GsmCellLocation loc = (GsmCellLocation) location;
+ int lac = loc.getLac();
+ int cid = loc.getCid();
+ mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
+ + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
+ + " "
+ + r.getString(R.string.radioInfo_cid) + " = "
+ + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
+ } else if (location instanceof CdmaCellLocation) {
+ CdmaCellLocation loc = (CdmaCellLocation) location;
+ int bid = loc.getBaseStationId();
+ int sid = loc.getSystemId();
+ int nid = loc.getNetworkId();
+ int lat = loc.getBaseStationLatitude();
+ int lon = loc.getBaseStationLongitude();
+ mLocation.setText("BID = "
+ + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
+ + " "
+ + "SID = "
+ + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
+ + " "
+ + "NID = "
+ + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
+ + "\n"
+ + "LAT = "
+ + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
+ + " "
+ + "LONG = "
+ + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
+ } else {
+ mLocation.setText("unknown");
+ }
+
+
+ }
+
+ private String getCellInfoDisplayString(int i) {
+ return (i != Integer.MAX_VALUE) ? Integer.toString(i) : "";
+ }
+
+ private String getCellInfoDisplayString(long i) {
+ return (i != Long.MAX_VALUE) ? Long.toString(i) : "";
+ }
+
+ private String getConnectionStatusString(CellInfo ci) {
+ String regStr = "";
+ String connStatStr = "";
+ String connector = "";
+
+ if (ci.isRegistered()) {
+ regStr = "R";
+ }
+ switch (ci.getCellConnectionStatus()) {
+ case CellInfo.CONNECTION_PRIMARY_SERVING: connStatStr = "P"; break;
+ case CellInfo.CONNECTION_SECONDARY_SERVING: connStatStr = "S"; break;
+ case CellInfo.CONNECTION_NONE: connStatStr = "N"; break;
+ case CellInfo.CONNECTION_UNKNOWN: /* Field is unsupported */ break;
+ default: break;
+ }
+ if (!TextUtils.isEmpty(regStr) && !TextUtils.isEmpty(connStatStr)) {
+ connector = "+";
+ }
+
+ return regStr + connector + connStatStr;
+ }
+
+ private String buildCdmaInfoString(CellInfoCdma ci) {
+ CellIdentityCdma cidCdma = ci.getCellIdentity();
+ CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength();
+
+ return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidCdma.getSystemId()),
+ getCellInfoDisplayString(cidCdma.getNetworkId()),
+ getCellInfoDisplayString(cidCdma.getBasestationId()),
+ getCellInfoDisplayString(ssCdma.getCdmaDbm()),
+ getCellInfoDisplayString(ssCdma.getCdmaEcio()),
+ getCellInfoDisplayString(ssCdma.getEvdoDbm()),
+ getCellInfoDisplayString(ssCdma.getEvdoEcio()),
+ getCellInfoDisplayString(ssCdma.getEvdoSnr()));
+ }
+
+ private String buildGsmInfoString(CellInfoGsm ci) {
+ CellIdentityGsm cidGsm = ci.getCellIdentity();
+ CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength();
+
+ return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidGsm.getMcc()),
+ getCellInfoDisplayString(cidGsm.getMnc()),
+ getCellInfoDisplayString(cidGsm.getLac()),
+ getCellInfoDisplayString(cidGsm.getCid()),
+ getCellInfoDisplayString(cidGsm.getArfcn()),
+ getCellInfoDisplayString(cidGsm.getBsic()),
+ getCellInfoDisplayString(ssGsm.getDbm()));
+ }
+
+ private String buildLteInfoString(CellInfoLte ci) {
+ CellIdentityLte cidLte = ci.getCellIdentity();
+ CellSignalStrengthLte ssLte = ci.getCellSignalStrength();
+
+ return String.format(
+ "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidLte.getMcc()),
+ getCellInfoDisplayString(cidLte.getMnc()),
+ getCellInfoDisplayString(cidLte.getTac()),
+ getCellInfoDisplayString(cidLte.getCi()),
+ getCellInfoDisplayString(cidLte.getPci()),
+ getCellInfoDisplayString(cidLte.getEarfcn()),
+ getCellInfoDisplayString(cidLte.getBandwidth()),
+ getCellInfoDisplayString(ssLte.getDbm()),
+ getCellInfoDisplayString(ssLte.getRsrq()),
+ getCellInfoDisplayString(ssLte.getTimingAdvance()));
+ }
+
+ private String buildWcdmaInfoString(CellInfoWcdma ci) {
+ CellIdentityWcdma cidWcdma = ci.getCellIdentity();
+ CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength();
+
+ return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidWcdma.getMcc()),
+ getCellInfoDisplayString(cidWcdma.getMnc()),
+ getCellInfoDisplayString(cidWcdma.getLac()),
+ getCellInfoDisplayString(cidWcdma.getCid()),
+ getCellInfoDisplayString(cidWcdma.getUarfcn()),
+ getCellInfoDisplayString(cidWcdma.getPsc()),
+ getCellInfoDisplayString(ssWcdma.getDbm()));
+ }
+
+ private String buildCellInfoString(List<CellInfo> arrayCi) {
+ String value = new String();
+ StringBuilder cdmaCells = new StringBuilder(),
+ gsmCells = new StringBuilder(),
+ lteCells = new StringBuilder(),
+ wcdmaCells = new StringBuilder();
+
+ if (arrayCi != null) {
+ for (CellInfo ci : arrayCi) {
+
+ if (ci instanceof CellInfoLte) {
+ lteCells.append(buildLteInfoString((CellInfoLte) ci));
+ } else if (ci instanceof CellInfoWcdma) {
+ wcdmaCells.append(buildWcdmaInfoString((CellInfoWcdma) ci));
+ } else if (ci instanceof CellInfoGsm) {
+ gsmCells.append(buildGsmInfoString((CellInfoGsm) ci));
+ } else if (ci instanceof CellInfoCdma) {
+ cdmaCells.append(buildCdmaInfoString((CellInfoCdma) ci));
+ }
+ }
+ if (lteCells.length() != 0) {
+ value += String.format(
+ "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s"
+ + " %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n",
+ "SRV", "MCC", "MNC", "TAC", "CID", "PCI",
+ "EARFCN", "BW", "RSRP", "RSRQ", "TA");
+ value += lteCells.toString();
+ }
+ if (wcdmaCells.length() != 0) {
+ value += String.format(
+ "WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
+ "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP");
+ value += wcdmaCells.toString();
+ }
+ if (gsmCells.length() != 0) {
+ value += String.format(
+ "GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
+ "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI");
+ value += gsmCells.toString();
+ }
+ if (cdmaCells.length() != 0) {
+ value += String.format(
+ "CDMA/EVDO\n%-3.3s %-5.5s %-5.5s %-5.5s"
+ + " %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s\n",
+ "SRV", "SID", "NID", "BSID",
+ "C-RSSI", "C-ECIO", "E-RSSI", "E-ECIO", "E-SNR");
+ value += cdmaCells.toString();
+ }
+ } else {
+ value = "unknown";
+ }
+
+ return value.toString();
+ }
+
+ private void updateCellInfo(List<CellInfo> arrayCi) {
+ mCellInfo.setText(buildCellInfoString(arrayCi));
+ }
+
+ private void updateSubscriptionIds() {
+ mSubscriptionId.setText(Integer.toString(mPhone.getSubId()));
+ mDds.setText(Integer.toString(SubscriptionManager.getDefaultDataSubscriptionId()));
+ }
+
+ private void updateMessageWaiting() {
+ mMwi.setText(String.valueOf(mMwiValue));
+ }
+
+ private void updateCallRedirect() {
+ mCfi.setText(String.valueOf(mCfiValue));
+ }
+
+
+ private void updateServiceState(ServiceState serviceState) {
+ int state = serviceState.getState();
+ Resources r = getResources();
+ String display = r.getString(R.string.radioInfo_unknown);
+
+ switch (state) {
+ case ServiceState.STATE_IN_SERVICE:
+ display = r.getString(R.string.radioInfo_service_in);
+ break;
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ case ServiceState.STATE_EMERGENCY_ONLY:
+ display = r.getString(R.string.radioInfo_service_emergency);
+ break;
+ case ServiceState.STATE_POWER_OFF:
+ display = r.getString(R.string.radioInfo_service_off);
+ break;
+ }
+
+ mGsmState.setText(display);
+
+ if (serviceState.getRoaming()) {
+ mRoamingState.setText(R.string.radioInfo_roaming_in);
+ } else {
+ mRoamingState.setText(R.string.radioInfo_roaming_not);
+ }
+
+ mOperatorName.setText(serviceState.getOperatorAlphaLong());
+ }
+
+ private void updatePhoneState(int state) {
+ Resources r = getResources();
+ String display = r.getString(R.string.radioInfo_unknown);
+
+ switch (state) {
+ case TelephonyManager.CALL_STATE_IDLE:
+ display = r.getString(R.string.radioInfo_phone_idle);
+ break;
+ case TelephonyManager.CALL_STATE_RINGING:
+ display = r.getString(R.string.radioInfo_phone_ringing);
+ break;
+ case TelephonyManager.CALL_STATE_OFFHOOK:
+ display = r.getString(R.string.radioInfo_phone_offhook);
+ break;
+ }
+
+ mCallState.setText(display);
+ }
+
+ private void updateDataState() {
+ int state = mTelephonyManager.getDataState();
+ Resources r = getResources();
+ String display = r.getString(R.string.radioInfo_unknown);
+
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ display = r.getString(R.string.radioInfo_data_connected);
+ break;
+ case TelephonyManager.DATA_CONNECTING:
+ display = r.getString(R.string.radioInfo_data_connecting);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ display = r.getString(R.string.radioInfo_data_disconnected);
+ break;
+ case TelephonyManager.DATA_SUSPENDED:
+ display = r.getString(R.string.radioInfo_data_suspended);
+ break;
+ }
+
+ mGprsState.setText(display);
+ }
+
+ private void updateNetworkType() {
+ if (mPhone != null) {
+ ServiceState ss = mPhone.getServiceState();
+ mDataNetwork.setText(ServiceState.rilRadioTechnologyToString(
+ mPhone.getServiceState().getRilDataRadioTechnology()));
+ mVoiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
+ mPhone.getServiceState().getRilVoiceRadioTechnology()));
+ }
+ }
+
+ private void updateProperties() {
+ String s;
+ Resources r = getResources();
+
+ s = mPhone.getDeviceId();
+ if (s == null) s = r.getString(R.string.radioInfo_unknown);
+ mDeviceId.setText(s);
+
+ s = mPhone.getSubscriberId();
+ if (s == null) s = r.getString(R.string.radioInfo_unknown);
+ mSubscriberId.setText(s);
+
+ //FIXME: Replace with a TelephonyManager call
+ s = mPhone.getLine1Number();
+ if (s == null) s = r.getString(R.string.radioInfo_unknown);
+ mLine1Number.setText(s);
+ }
+
+ private void updateDataStats2() {
+ Resources r = getResources();
+
+ long txPackets = TrafficStats.getMobileTxPackets();
+ long rxPackets = TrafficStats.getMobileRxPackets();
+ long txBytes = TrafficStats.getMobileTxBytes();
+ long rxBytes = TrafficStats.getMobileRxBytes();
+
+ String packets = r.getString(R.string.radioInfo_display_packets);
+ String bytes = r.getString(R.string.radioInfo_display_bytes);
+
+ mSent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
+ mReceived.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
+ }
+
+ /**
+ * Ping a host name
+ */
+ private void pingHostname() {
+ try {
+ try {
+ Process p4 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
+ int status4 = p4.waitFor();
+ if (status4 == 0) {
+ mPingHostnameResultV4 = "Pass";
+ } else {
+ mPingHostnameResultV4 = String.format("Fail(%d)", status4);
+ }
+ } catch (IOException e) {
+ mPingHostnameResultV4 = "Fail: IOException";
+ }
+ try {
+ Process p6 = Runtime.getRuntime().exec("ping6 -c 1 www.google.com");
+ int status6 = p6.waitFor();
+ if (status6 == 0) {
+ mPingHostnameResultV6 = "Pass";
+ } else {
+ mPingHostnameResultV6 = String.format("Fail(%d)", status6);
+ }
+ } catch (IOException e) {
+ mPingHostnameResultV6 = "Fail: IOException";
+ }
+ } catch (InterruptedException e) {
+ mPingHostnameResultV4 = mPingHostnameResultV6 = "Fail: InterruptedException";
+ }
+ }
+
+ /**
+ * This function checks for basic functionality of HTTP Client.
+ */
+ private void httpClientTest() {
+ HttpURLConnection urlConnection = null;
+ try {
+ // TODO: Hardcoded for now, make it UI configurable
+ URL url = new URL("https://www.google.com");
+ urlConnection = (HttpURLConnection) url.openConnection();
+ if (urlConnection.getResponseCode() == 200) {
+ mHttpClientTestResult = "Pass";
+ } else {
+ mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage();
+ }
+ } catch (IOException e) {
+ mHttpClientTestResult = "Fail: IOException";
+ } finally {
+ if (urlConnection != null) {
+ urlConnection.disconnect();
+ }
+ }
+ }
+
+ private void refreshSmsc() {
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ //FIXME: Replace with a TelephonyManager call
+ mPhone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
+ }
+ });
+ }
+
+ private void updateAllCellInfo() {
+
+ mCellInfo.setText("");
+ mLocation.setText("");
+
+ final Runnable updateAllCellInfoResults = new Runnable() {
+ public void run() {
+ updateLocation(mCellLocationResult);
+ updateCellInfo(mCellInfoResult);
+ }
+ };
+
+ mQueuedWork.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCellInfoResult = mTelephonyManager.getAllCellInfo();
+ mCellLocationResult = mTelephonyManager.getCellLocation();
+
+ mHandler.post(updateAllCellInfoResults);
+ }
+ });
+ }
+
+ private void updatePingState() {
+ // Set all to unknown since the threads will take a few secs to update.
+ mPingHostnameResultV4 = getResources().getString(R.string.radioInfo_unknown);
+ mPingHostnameResultV6 = getResources().getString(R.string.radioInfo_unknown);
+ mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
+
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+
+ final Runnable updatePingResults = new Runnable() {
+ public void run() {
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+ }
+ };
+
+ Thread hostname = new Thread() {
+ @Override
+ public void run() {
+ pingHostname();
+ mHandler.post(updatePingResults);
+ }
+ };
+ hostname.start();
+
+ Thread httpClient = new Thread() {
+ @Override
+ public void run() {
+ httpClientTest();
+ mHandler.post(updatePingResults);
+ }
+ };
+ httpClient.start();
+ }
+
+ private MenuItem.OnMenuItemClickListener mViewADNCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ // XXX We need to specify the component here because if we don't
+ // the activity manager will try to resolve the type by calling
+ // the content provider, which causes it to be loaded in a process
+ // other than the Dialer process, which causes a lot of stuff to
+ // break.
+ intent.setClassName("com.android.phone", "com.android.phone.SimContacts");
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mViewFDNCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ // XXX We need to specify the component here because if we don't
+ // the activity manager will try to resolve the type by calling
+ // the content provider, which causes it to be loaded in a process
+ // other than the Dialer process, which causes a lot of stuff to
+ // break.
+ intent.setClassName("com.android.phone", "com.android.phone.settings.fdn.FdnList");
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mViewSDNCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent(
+ Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
+ // XXX We need to specify the component here because if we don't
+ // the activity manager will try to resolve the type by calling
+ // the content provider, which causes it to be loaded in a process
+ // other than the Dialer process, which causes a lot of stuff to
+ // break.
+ intent.setClassName("com.android.phone", "com.android.phone.ADNList");
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mGetImsStatus =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ boolean isImsRegistered = mPhone.isImsRegistered();
+ boolean availableVolte = mPhone.isVolteEnabled();
+ boolean availableWfc = mPhone.isWifiCallingEnabled();
+ boolean availableVt = mPhone.isVideoEnabled();
+ boolean availableUt = mPhone.isUtEnabled();
+
+ final String imsRegString = isImsRegistered
+ ? getString(R.string.radio_info_ims_reg_status_registered)
+ : getString(R.string.radio_info_ims_reg_status_not_registered);
+
+ final String available = getString(R.string.radio_info_ims_feature_status_available);
+ final String unavailable = getString(
+ R.string.radio_info_ims_feature_status_unavailable);
+
+ String imsStatus = getString(R.string.radio_info_ims_reg_status,
+ imsRegString,
+ availableVolte ? available : unavailable,
+ availableWfc ? available : unavailable,
+ availableVt ? available : unavailable,
+ availableUt ? available : unavailable);
+
+ AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this)
+ .setMessage(imsStatus)
+ .setTitle(getString(R.string.radio_info_ims_reg_status_title))
+ .create();
+
+ imsDialog.show();
+
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mSelectBandCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent();
+ intent.setClass(RadioInfo.this, BandMode.class);
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mToggleData =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ int state = mTelephonyManager.getDataState();
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ mTelephonyManager.setDataEnabled(false);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ mTelephonyManager.setDataEnabled(true);
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ return true;
+ }
+ };
+
+ private boolean isRadioOn() {
+ //FIXME: Replace with a TelephonyManager call
+ return mPhone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
+ }
+
+ private void updateRadioPowerState() {
+ //delightful hack to prevent on-checked-changed calls from
+ //actually forcing the radio preference to its transient/current value.
+ mRadioPowerOnSwitch.setOnCheckedChangeListener(null);
+ mRadioPowerOnSwitch.setChecked(isRadioOn());
+ mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
+ }
+
+ void setImsVolteProvisionedState(boolean state) {
+ Log.d(TAG, "setImsVolteProvisioned state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(IMS_VOLTE_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setImsVtProvisionedState(boolean state) {
+ Log.d(TAG, "setImsVtProvisioned() state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(IMS_VT_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setImsWfcProvisionedState(boolean state) {
+ Log.d(TAG, "setImsWfcProvisioned() state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(IMS_WFC_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setEabProvisionedState(boolean state) {
+ Log.d(TAG, "setEabProvisioned() state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(EAB_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setImsConfigProvisionedState(int configItem, boolean state) {
+ if (mPhone != null && mImsManager != null) {
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ try {
+ mImsManager.getConfigInterface().setProvisionedValue(
+ configItem, state ? 1 : 0);
+ } catch (ImsException e) {
+ Log.e(TAG, "setImsConfigProvisioned() exception:", e);
+ }
+ }
+ });
+ }
+ }
+
+ OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ log("toggle radio power: currently " + (isRadioOn() ? "on" : "off"));
+ mPhone.setRadioPower(isChecked);
+ }
+ };
+
+ private boolean isImsVolteProvisioned() {
+ if (mPhone != null && mImsManager != null) {
+ return mImsManager.isVolteEnabledByPlatform(mPhone.getContext())
+ && mImsManager.isVolteProvisionedOnDevice(mPhone.getContext());
+ }
+ return false;
+ }
+
+ OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setImsVolteProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isImsVtProvisioned() {
+ if (mPhone != null && mImsManager != null) {
+ return mImsManager.isVtEnabledByPlatform(mPhone.getContext())
+ && mImsManager.isVtProvisionedOnDevice(mPhone.getContext());
+ }
+ return false;
+ }
+
+ OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setImsVtProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isImsWfcProvisioned() {
+ if (mPhone != null && mImsManager != null) {
+ return mImsManager.isWfcEnabledByPlatform(mPhone.getContext())
+ && mImsManager.isWfcProvisionedOnDevice(mPhone.getContext());
+ }
+ return false;
+ }
+
+ OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setImsWfcProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isEabProvisioned() {
+ return isFeatureProvisioned(EAB_PROVISIONED_CONFIG_ID, false);
+ }
+
+ OnCheckedChangeListener mEabCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setEabProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isFeatureProvisioned(int featureId, boolean defaultValue) {
+ boolean provisioned = defaultValue;
+ if (mImsManager != null) {
+ try {
+ ImsConfig imsConfig = mImsManager.getConfigInterface();
+ if (imsConfig != null) {
+ provisioned =
+ (imsConfig.getProvisionedValue(featureId)
+ == ImsConfig.FeatureValueConstants.ON);
+ }
+ } catch (ImsException ex) {
+ Log.e(TAG, "isFeatureProvisioned() exception:", ex);
+ }
+ }
+
+ log("isFeatureProvisioned() featureId=" + featureId + " provisioned=" + provisioned);
+ return provisioned;
+ }
+
+ private static boolean isEabEnabledByPlatform(Context context) {
+ if (context != null) {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null && configManager.getConfig().getBoolean(
+ CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void updateImsProvisionedState() {
+ if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
+ return;
+ }
+ log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
+ //delightful hack to prevent on-checked-changed calls from
+ //actually forcing the ims provisioning to its transient/current value.
+ mImsVolteProvisionedSwitch.setOnCheckedChangeListener(null);
+ mImsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned());
+ mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
+ mImsVolteProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && mImsManager.isVolteEnabledByPlatform(mPhone.getContext()));
+
+ mImsVtProvisionedSwitch.setOnCheckedChangeListener(null);
+ mImsVtProvisionedSwitch.setChecked(isImsVtProvisioned());
+ mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
+ mImsVtProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && mImsManager.isVtEnabledByPlatform(mPhone.getContext()));
+
+ mImsWfcProvisionedSwitch.setOnCheckedChangeListener(null);
+ mImsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned());
+ mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
+ mImsWfcProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && mImsManager.isWfcEnabledByPlatform(mPhone.getContext()));
+
+ mEabProvisionedSwitch.setOnCheckedChangeListener(null);
+ mEabProvisionedSwitch.setChecked(isEabProvisioned());
+ mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
+ mEabProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && isEabEnabledByPlatform(mPhone.getContext()));
+ }
+
+ OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ //FIXME: Replace with a TelephonyManager call
+ mPhone.disableDnsCheck(!mPhone.isDnsCheckDisabled());
+ updateDnsCheckState();
+ }
+ };
+
+ OnClickListener mOemInfoButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(OEM_RADIO_INFO_INTENT);
+ try {
+ startActivity(intent);
+ } catch (android.content.ActivityNotFoundException ex) {
+ log("OEM-specific Info/Settings Activity Not Found : " + ex);
+ // If the activity does not exist, there are no OEM
+ // settings, and so we can just do nothing...
+ }
+ }
+ };
+
+ OnClickListener mPingButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ updatePingState();
+ }
+ };
+
+ OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ mUpdateSmscButton.setEnabled(false);
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ mPhone.setSmscAddress(mSmsc.getText().toString(),
+ mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
+ }
+ });
+ }
+ };
+
+ OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ refreshSmsc();
+ }
+ };
+
+ OnClickListener mCarrierProvisioningButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ final Intent intent = new Intent("com.android.settings.CARRIER_PROVISIONING");
+ final ComponentName serviceComponent = ComponentName.unflattenFromString(
+ "com.android.omadm.service/.DMIntentReceiver");
+ intent.setComponent(serviceComponent);
+ sendBroadcast(intent);
+ }
+ };
+
+ OnClickListener mTriggerCarrierProvisioningButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ final Intent intent = new Intent("com.android.settings.TRIGGER_CARRIER_PROVISIONING");
+ final ComponentName serviceComponent = ComponentName.unflattenFromString(
+ "com.android.omadm.service/.DMIntentReceiver");
+ intent.setComponent(serviceComponent);
+ sendBroadcast(intent);
+ }
+ };
+
+ AdapterView.OnItemSelectedListener mPreferredNetworkHandler =
+ new AdapterView.OnItemSelectedListener() {
+
+ public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+ if (mPreferredNetworkTypeResult != pos && pos >= 0
+ && pos <= PREFERRED_NETWORK_LABELS.length - 2) {
+ mPreferredNetworkTypeResult = pos;
+
+ // TODO: Possibly migrate this to TelephonyManager.setPreferredNetworkType()
+ // which today still has some issues (mostly that the "set" is conditional
+ // on a successful modem call, which is not what we want). Instead we always
+ // want this setting to be set, so that if the radio hiccups and this setting
+ // is for some reason unsuccessful, future calls to the radio will reflect
+ // the users's preference which is set here.
+ final int subId = mPhone.getSubId();
+ if (SubscriptionManager.isUsableSubIdValue(subId)) {
+ Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+ PREFERRED_NETWORK_MODE + subId, mPreferredNetworkTypeResult);
+ }
+ log("Calling setPreferredNetworkType(" + mPreferredNetworkTypeResult + ")");
+ Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
+ mPhone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
+ }
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ AdapterView.OnItemSelectedListener mSelectPhoneIndexHandler =
+ new AdapterView.OnItemSelectedListener() {
+
+ public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+ if (pos >= 0 && pos <= sPhoneIndexLabels.length - 1) {
+ // the array position is equal to the phone index
+ int phoneIndex = pos;
+ Phone[] phones = PhoneFactory.getPhones();
+ if (phones == null || phones.length <= phoneIndex) {
+ return;
+ }
+ // getSubId says it takes a slotIndex, but it actually takes a phone index
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ int[] subIds = SubscriptionManager.getSubId(phoneIndex);
+ if (subIds != null && subIds.length > 0) {
+ subId = subIds[0];
+ }
+ mSelectedPhoneIndex = phoneIndex;
+
+ updatePhoneIndex(phoneIndex, subId);
+ }
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler =
+ new AdapterView.OnItemSelectedListener() {
+
+ public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+ mCellInfoRefreshRateIndex = pos;
+ mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[pos]);
+ updateAllCellInfo();
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ boolean isCbrsSupported() {
+ return getResources().getBoolean(
+ com.android.internal.R.bool.config_cbrs_supported);
+ }
+
+ void updateCbrsDataState(boolean state) {
+ Log.d(TAG, "setCbrsDataSwitchState() state:" + ((state) ? "on" : "off"));
+ if (mTelephonyManager != null) {
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ mTelephonyManager.setOpportunisticNetworkState(state);
+ mCbrsDataSwitch.setChecked(getCbrsDataState());
+ }
+ });
+ }
+ }
+
+ boolean getCbrsDataState() {
+ boolean state = false;
+ if (mTelephonyManager != null) {
+ state = mTelephonyManager.isOpportunisticNetworkEnabled();
+ }
+ Log.d(TAG, "getCbrsDataState() state:" + ((state) ? "on" : "off"));
+ return state;
+ }
+
+ OnCheckedChangeListener mCbrsDataSwitchChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ updateCbrsDataState(isChecked);
+ }
+ };
+
+ private void showDsdsChangeDialog() {
+ final AlertDialog confirmDialog = new Builder(RadioInfo.this)
+ .setTitle(R.string.dsds_dialog_title)
+ .setMessage(R.string.dsds_dialog_message)
+ .setPositiveButton(R.string.dsds_dialog_confirm, mOnDsdsDialogConfirmedListener)
+ .setNegativeButton(R.string.dsds_dialog_cancel, mOnDsdsDialogConfirmedListener)
+ .create();
+ confirmDialog.show();
+ }
+
+ private static boolean isDsdsSupported() {
+ return (TelephonyManager.getDefault().isMultiSimSupported()
+ == TelephonyManager.MULTISIM_ALLOWED);
+ }
+
+ private static boolean isDsdsEnabled() {
+ return TelephonyManager.getDefault().getPhoneCount() > 1;
+ }
+
+ private void performDsdsSwitch() {
+ mTelephonyManager.switchMultiSimConfig(mDsdsSwitch.isChecked() ? 2 : 1);
+ }
+
+ /**
+ * @return {@code True} if the device is only supported dsds mode.
+ */
+ private boolean dsdsModeOnly() {
+ String dsdsMode = SystemProperties.get(DSDS_MODE_PROPERTY);
+ return !TextUtils.isEmpty(dsdsMode) && Integer.parseInt(dsdsMode) == ALWAYS_ON_DSDS_MODE;
+ }
+
+ DialogInterface.OnClickListener mOnDsdsDialogConfirmedListener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ mDsdsSwitch.toggle();
+ performDsdsSwitch();
+ }
+ }
+ };
+}
diff --git a/src/com/android/phone/vvm/RemoteVvmTaskManager.java b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
index 14030a1..6b60303 100644
--- a/src/com/android/phone/vvm/RemoteVvmTaskManager.java
+++ b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
@@ -38,6 +39,7 @@
import android.telephony.VisualVoicemailSms;
import android.text.TextUtils;
+import com.android.internal.telephony.util.TelephonyUtils;
import com.android.phone.Assert;
import com.android.phone.R;
@@ -167,7 +169,8 @@
}
if (info.serviceInfo == null) {
VvmLog.w(TAG,
- "Component " + info.getComponentInfo() + " is not a service, ignoring");
+ "Component " + TelephonyUtils.getComponentInfo(info)
+ + " is not a service, ignoring");
continue;
}
if (!android.Manifest.permission.BIND_VISUAL_VOICEMAIL_SERVICE
@@ -180,7 +183,8 @@
VvmLog.w(TAG, "target package " + targetPackage
+ " is no longer the active VisualVoicemailService, ignoring");
}
- return info.getComponentInfo().getComponentName();
+ ComponentInfo componentInfo = TelephonyUtils.getComponentInfo(info);
+ return new ComponentName(componentInfo.packageName, componentInfo.name);
}
return null;
@@ -199,7 +203,8 @@
if (info.isEmpty()) {
return null;
}
- return info.get(0).getComponentInfo().getComponentName();
+ ComponentInfo componentInfo = TelephonyUtils.getComponentInfo(info.get(0));
+ return new ComponentName(componentInfo.packageName, componentInfo.name);
}
@Override
diff --git a/src/com/android/services/telephony/DeviceState.java b/src/com/android/services/telephony/DeviceState.java
new file mode 100644
index 0000000..7cd2d7e
--- /dev/null
+++ b/src/com/android/services/telephony/DeviceState.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+
+import com.android.internal.telephony.PhoneConstants;
+import com.android.phone.R;
+
+/**
+ * Abstracts device state and settings for better testability.
+ */
+public class DeviceState {
+
+ public boolean shouldCheckSimStateBeforeOutgoingCall(Context context) {
+ return context.getResources().getBoolean(
+ R.bool.config_checkSimStateBeforeOutgoingCall);
+ }
+
+ public boolean isSuplDdsSwitchRequiredForEmergencyCall(Context context) {
+ return context.getResources().getBoolean(
+ R.bool.config_gnss_supl_requires_default_data_for_emergency);
+ }
+
+ public boolean isRadioPowerDownAllowedOnBluetooth(Context context) {
+ return context.getResources().getBoolean(R.bool.config_allowRadioPowerDownOnBluetooth);
+ }
+
+ public boolean isAirplaneModeOn(Context context) {
+ return Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) > 0;
+ }
+
+ public int getCellOnStatus(Context context) {
+ return Settings.Global.getInt(context.getContentResolver(), Settings.Global.CELL_ON,
+ PhoneConstants.CELL_ON_FLAG);
+ }
+
+ public boolean isTtyModeEnabled(Context context) {
+ return android.provider.Settings.Secure.getInt(context.getContentResolver(),
+ android.provider.Settings.Secure.PREFERRED_TTY_MODE,
+ TelecomManager.TTY_MODE_OFF) != TelecomManager.TTY_MODE_OFF;
+ }
+}
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index f397dce..2dfeaed 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -41,8 +41,6 @@
import com.android.phone.NumberVerificationManager;
import com.android.phone.PhoneUtils;
-import com.google.common.base.Preconditions;
-
import java.util.Objects;
/**
@@ -96,7 +94,9 @@
* @param phone The phone object for listening to incoming calls.
*/
PstnIncomingCallNotifier(Phone phone) {
- Preconditions.checkNotNull(phone);
+ if (phone == null) {
+ throw new NullPointerException();
+ }
mPhone = phone;
diff --git a/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java b/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java
index b9cbf6e..4038dd1 100644
--- a/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java
+++ b/src/com/android/services/telephony/PstnPhoneCapabilitiesNotifier.java
@@ -21,7 +21,6 @@
import android.os.Message;
import com.android.internal.telephony.Phone;
-import com.android.internal.util.Preconditions;
/**
* Listens to phone's capabilities changed event and notifies Telecomm. One instance of these exists
@@ -55,7 +54,9 @@
/*package*/
PstnPhoneCapabilitiesNotifier(Phone phone, Listener listener) {
- Preconditions.checkNotNull(phone);
+ if (phone == null) {
+ throw new NullPointerException();
+ }
mPhone = phone;
mListener = listener;
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 092e08b..5a1e6a6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -35,7 +35,6 @@
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
@@ -806,10 +805,7 @@
int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
UserHandle currentUserHandle = UserHandle.of(userHandleId);
- UserManager userManager =
- (UserManager) context.getSystemService(Context.USER_SERVICE);
- mIsPrimaryUser = userManager.getPrimaryUser().getUserHandle()
- .equals(currentUserHandle);
+ mIsPrimaryUser = currentUserHandle.isSystem();
// Any time the user changes, re-register the accounts.
tearDownAccounts();
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 55b1e26..fb865b4 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -52,6 +52,7 @@
import com.android.ims.ImsCall;
import com.android.ims.internal.ConferenceParticipant;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallFailCause;
@@ -202,6 +203,7 @@
// whether the call should have the HD audio property set.
refreshConferenceSupported();
refreshDisableAddCall();
+ refreshHoldSupported();
updateConnectionProperties();
break;
@@ -408,14 +410,26 @@
}
}
if (messageId != -1 && getPhone() != null && getPhone().getContext() != null) {
- Resources res = SubscriptionManager.getResourcesForSubId(
- getPhone().getContext(), getPhone().getSubId());
- return res.getText(messageId);
+ return getResourceText(messageId);
} else {
return null;
}
}
+ @VisibleForTesting
+ public CharSequence getResourceText(int id) {
+ Resources resources = SubscriptionManager.getResourcesForSubId(getPhone().getContext(),
+ getPhone().getSubId());
+ return resources.getText(id);
+ }
+
+ @VisibleForTesting
+ public String getResourceString(int id) {
+ Resources resources = SubscriptionManager.getResourcesForSubId(getPhone().getContext(),
+ getPhone().getSubId());
+ return resources.getString(id);
+ }
+
/**
* @return {@code true} if carrier video conferencing is supported, {@code false} otherwise.
*/
@@ -1332,6 +1346,18 @@
}
}
+ private void refreshHoldSupported() {
+ if (mOriginalConnection == null) {
+ Log.w(this, "refreshHoldSupported org conn is null");
+ return;
+ }
+
+ if (!mOriginalConnection.shouldAllowHoldingVideoCall() && canHoldImsCalls() !=
+ ((getConnectionCapabilities() & (CAPABILITY_HOLD | CAPABILITY_SUPPORT_HOLD)) != 0)) {
+ updateConnectionCapabilities();
+ }
+ }
+
private void refreshDisableAddCall() {
if (shouldSetDisableAddCallExtra()) {
Bundle newExtras = getExtras();
@@ -1488,11 +1514,14 @@
private boolean canHoldImsCalls() {
PersistableBundle b = getCarrierConfig();
// Return true if the CarrierConfig is unavailable
- return !doesDeviceRespectHoldCarrierConfig() || b == null ||
- b.getBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL);
+ return (!doesDeviceRespectHoldCarrierConfig() || b == null ||
+ b.getBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL)) &&
+ ((mOriginalConnection != null && mOriginalConnection.shouldAllowHoldingVideoCall())
+ || !VideoProfile.isVideo(getVideoState()));
}
- private PersistableBundle getCarrierConfig() {
+ @VisibleForTesting
+ public PersistableBundle getCarrierConfig() {
Phone phone = getPhone();
if (phone == null) {
return null;
@@ -2279,10 +2308,8 @@
: R.string.status_hint_label_wifi_call;
Context context = getPhone().getContext();
- Resources res =
- SubscriptionManager.getResourcesForSubId(context, getPhone().getSubId());
setTelephonyStatusHints(new StatusHints(
- res.getString(labelId),
+ getResourceString(labelId),
Icon.createWithResource(
context, R.drawable.ic_signal_wifi_4_bar_24dp),
null /* extras */));
@@ -2365,7 +2392,8 @@
* 3. If call is a video call, carrier supports video conference calls.
* 4. If call is a wifi call and VoWIFI is disabled and carrier supports merging these calls.
*/
- private void refreshConferenceSupported() {
+ @VisibleForTesting
+ void refreshConferenceSupported() {
boolean isVideoCall = VideoProfile.isVideo(getVideoState());
Phone phone = getPhone();
if (phone == null) {
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 9de4a2c..40b941e 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -28,7 +28,6 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
-import android.provider.Settings;
import android.telecom.Conference;
import android.telecom.Connection;
import android.telecom.ConnectionRequest;
@@ -148,12 +147,7 @@
new TelephonyConferenceController(mTelephonyConnectionServiceProxy);
private final CdmaConferenceController mCdmaConferenceController =
new CdmaConferenceController(this);
- private final ImsConferenceController mImsConferenceController =
- new ImsConferenceController(TelecomAccountRegistry.getInstance(this),
- mTelephonyConnectionServiceProxy,
- // FeatureFlagProxy; used to determine if standalone call emulation is enabled.
- // TODO: Move to carrier config
- () -> true);
+ private ImsConferenceController mImsConferenceController;
private ComponentName mExpectedComponentName = null;
private RadioOnHelper mRadioOnHelper;
@@ -170,6 +164,7 @@
public Pair<WeakReference<TelephonyConnection>, Queue<Phone>> mEmergencyRetryCache;
private Handler mDdsSwitchHandler;
private HandlerThread mHandlerThread;
+ private DeviceState mDeviceState = new DeviceState();
/**
* Keeps track of the status of a SIM slot.
@@ -191,7 +186,10 @@
}
}
- // SubscriptionManager Proxy interface for testing
+ /**
+ * SubscriptionManager dependencies for testing.
+ */
+ @VisibleForTesting
public interface SubscriptionManagerProxy {
int getDefaultVoicePhoneId();
int getSimStateForSlotIdx(int slotId);
@@ -215,7 +213,9 @@
}
};
- // TelephonyManager Proxy interface for testing
+ /**
+ * TelephonyManager dependencies for testing.
+ */
@VisibleForTesting
public interface TelephonyManagerProxy {
int getPhoneCount();
@@ -255,7 +255,9 @@
}
}
- //PhoneFactory proxy interface for testing
+ /**
+ * PhoneFactory Dependencies for testing.
+ */
@VisibleForTesting
public interface PhoneFactoryProxy {
Phone getPhone(int index);
@@ -280,22 +282,185 @@
}
};
+ /**
+ * PhoneUtils dependencies for testing.
+ */
+ @VisibleForTesting
+ public interface PhoneUtilsProxy {
+ int getSubIdForPhoneAccountHandle(PhoneAccountHandle accountHandle);
+ PhoneAccountHandle makePstnPhoneAccountHandle(Phone phone);
+ PhoneAccountHandle makePstnPhoneAccountHandleWithPrefix(Phone phone, String prefix,
+ boolean isEmergency);
+ }
+
+ private PhoneUtilsProxy mPhoneUtilsProxy = new PhoneUtilsProxy() {
+ @Override
+ public int getSubIdForPhoneAccountHandle(PhoneAccountHandle accountHandle) {
+ return PhoneUtils.getSubIdForPhoneAccountHandle(accountHandle);
+ }
+
+ @Override
+ public PhoneAccountHandle makePstnPhoneAccountHandle(Phone phone) {
+ return PhoneUtils.makePstnPhoneAccountHandle(phone);
+ }
+
+ @Override
+ public PhoneAccountHandle makePstnPhoneAccountHandleWithPrefix(Phone phone, String prefix,
+ boolean isEmergency) {
+ return PhoneUtils.makePstnPhoneAccountHandleWithPrefix(phone, prefix, isEmergency);
+ }
+ };
+
+ /**
+ * PhoneNumberUtils dependencies for testing.
+ */
+ @VisibleForTesting
+ public interface PhoneNumberUtilsProxy {
+ String convertToEmergencyNumber(Context context, String number);
+ }
+
+ private PhoneNumberUtilsProxy mPhoneNumberUtilsProxy = new PhoneNumberUtilsProxy() {
+ @Override
+ public String convertToEmergencyNumber(Context context, String number) {
+ return PhoneNumberUtils.convertToEmergencyNumber(context, number);
+ }
+ };
+
+ /**
+ * PhoneSwitcher dependencies for testing.
+ */
+ @VisibleForTesting
+ public interface PhoneSwitcherProxy {
+ PhoneSwitcher getPhoneSwitcher();
+ }
+
+ private PhoneSwitcherProxy mPhoneSwitcherProxy = new PhoneSwitcherProxy() {
+ @Override
+ public PhoneSwitcher getPhoneSwitcher() {
+ return PhoneSwitcher.getInstance();
+ }
+ };
+
+ /**
+ * Factory for Handler creation in order to remove flakiness during t esting.
+ */
+ @VisibleForTesting
+ public interface HandlerFactory {
+ HandlerThread createHandlerThread(String name);
+ Handler createHandler(Looper looper);
+ }
+
+ private HandlerFactory mHandlerFactory = new HandlerFactory() {
+ @Override
+ public HandlerThread createHandlerThread(String name) {
+ return new HandlerThread(name);
+ }
+
+ @Override
+ public Handler createHandler(Looper looper) {
+ return new Handler(looper);
+ }
+ };
+
+ /**
+ * DisconnectCause depends on PhoneGlobals in order to get a system context. Mock out
+ * dependency for testing.
+ */
+ @VisibleForTesting
+ public interface DisconnectCauseFactory {
+ DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause, String reason);
+ DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause,
+ String reason, int phoneId);
+ }
+
+ private DisconnectCauseFactory mDisconnectCauseFactory = new DisconnectCauseFactory() {
+ @Override
+ public DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause,
+ String reason) {
+ return DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause, reason);
+ }
+
+ @Override
+ public DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause, String reason,
+ int phoneId) {
+ return DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause, reason,
+ phoneId);
+ }
+ };
+
+ /**
+ * Overrides SubscriptionManager dependencies for testing.
+ */
@VisibleForTesting
public void setSubscriptionManagerProxy(SubscriptionManagerProxy proxy) {
mSubscriptionManagerProxy = proxy;
}
+ /**
+ * Overrides TelephonyManager dependencies for testing.
+ */
@VisibleForTesting
public void setTelephonyManagerProxy(TelephonyManagerProxy proxy) {
mTelephonyManagerProxy = proxy;
}
+ /**
+ * Overrides PhoneFactory dependencies for testing.
+ */
@VisibleForTesting
public void setPhoneFactoryProxy(PhoneFactoryProxy proxy) {
mPhoneFactoryProxy = proxy;
}
/**
+ * Overrides configuration and settings dependencies for testing.
+ */
+ @VisibleForTesting
+ public void setDeviceState(DeviceState state) {
+ mDeviceState = state;
+ }
+
+ /**
+ * Overrides PhoneSwitcher dependencies for testing.
+ */
+ @VisibleForTesting
+ public void setPhoneSwitcherProxy(PhoneSwitcherProxy proxy) {
+ mPhoneSwitcherProxy = proxy;
+ }
+
+ /**
+ * Overrides PhoneNumberUtils dependencies for testing.
+ */
+ @VisibleForTesting
+ public void setPhoneNumberUtilsProxy(PhoneNumberUtilsProxy proxy) {
+ mPhoneNumberUtilsProxy = proxy;
+ }
+
+ /**
+ * Overrides PhoneUtils dependencies for testing.
+ */
+ @VisibleForTesting
+ public void setPhoneUtilsProxy(PhoneUtilsProxy proxy) {
+ mPhoneUtilsProxy = proxy;
+ }
+
+ /**
+ * Override Handler creation factory for testing.
+ */
+ @VisibleForTesting
+ public void setHandlerFactory(HandlerFactory handlerFactory) {
+ mHandlerFactory = handlerFactory;
+ }
+
+ /**
+ * Override DisconnectCause creation for testing.
+ */
+ @VisibleForTesting
+ public void setDisconnectCauseFactory(DisconnectCauseFactory factory) {
+ mDisconnectCauseFactory = factory;
+ }
+
+ /**
* A listener to actionable events specific to the TelephonyConnection.
*/
private final TelephonyConnection.TelephonyConnectionListener mTelephonyConnectionListener =
@@ -322,21 +487,26 @@
@Override
public void onCreate() {
super.onCreate();
+ mImsConferenceController = new ImsConferenceController(
+ TelecomAccountRegistry.getInstance(this),
+ mTelephonyConnectionServiceProxy,
+ // FeatureFlagProxy; used to determine if standalone call emulation is enabled.
+ // TODO: Move to carrier config
+ () -> true);
setTelephonyManagerProxy(new TelephonyManagerProxyImpl(getApplicationContext()));
mExpectedComponentName = new ComponentName(this, this.getClass());
mEmergencyTonePlayer = new EmergencyTonePlayer(this);
TelecomAccountRegistry.getInstance(this).setTelephonyConnectionService(this);
mHoldTracker = new HoldTracker();
- mIsTtyEnabled = isTtyModeEnabled(getApplicationContext());
+ mIsTtyEnabled = mDeviceState.isTtyModeEnabled(this);
IntentFilter intentFilter = new IntentFilter(
TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
registerReceiver(mTtyBroadcastReceiver, intentFilter);
-
- mHandlerThread = new HandlerThread("DdsSwitchHandlerThread");
+ mHandlerThread = mHandlerFactory.createHandlerThread("DdsSwitchHandlerThread");
mHandlerThread.start();
Looper looper = mHandlerThread.getLooper();
- mDdsSwitchHandler = new Handler(looper);
+ mDdsSwitchHandler = mHandlerFactory.createHandler(looper);
}
@Override
@@ -356,7 +526,7 @@
if (handle == null) {
Log.d(this, "onCreateOutgoingConnection, handle is null");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.NO_PHONE_NUMBER_SUPPLIED,
"No phone number supplied"));
}
@@ -371,7 +541,7 @@
if (phone == null) {
Log.d(this, "onCreateOutgoingConnection, phone is null");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE,
"Phone is null"));
}
@@ -379,7 +549,7 @@
if (TextUtils.isEmpty(number)) {
Log.d(this, "onCreateOutgoingConnection, no voicemail number set.");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING,
"Voicemail scheme provided but no voicemail number set.",
phone.getPhoneId()));
@@ -391,7 +561,7 @@
if (!PhoneAccount.SCHEME_TEL.equals(scheme)) {
Log.d(this, "onCreateOutgoingConnection, Handle %s is not type tel", scheme);
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.INVALID_NUMBER,
"Handle scheme is not type tel"));
}
@@ -400,7 +570,7 @@
if (TextUtils.isEmpty(number)) {
Log.d(this, "onCreateOutgoingConnection, unable to parse number");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.INVALID_NUMBER,
"Unable to parse number"));
}
@@ -421,7 +591,7 @@
if (disableActivation) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause
.CDMA_ALREADY_ACTIVATED,
"Tried to dial *228",
@@ -445,7 +615,8 @@
// service.
if (phone == null || phone.getServiceState().getState()
!= ServiceState.STATE_IN_SERVICE) {
- String convertedNumber = PhoneNumberUtils.convertToEmergencyNumber(this, number);
+ String convertedNumber = mPhoneNumberUtilsProxy.convertToEmergencyNumber(this,
+ number);
if (!TextUtils.equals(convertedNumber, number)) {
Log.i(this, "onCreateOutgoingConnection, converted to emergency number");
number = convertedNumber;
@@ -456,8 +627,7 @@
final String numberToDial = number;
- final boolean isAirplaneModeOn = Settings.Global.getInt(getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON, 0) > 0;
+ final boolean isAirplaneModeOn = mDeviceState.isAirplaneModeOn(this);
boolean needToTurnOnRadio = (isEmergencyNumber && (!isRadioOn() || isAirplaneModeOn))
|| isRadioPowerDownOnBluetooth();
@@ -466,7 +636,7 @@
final Uri resultHandle = handle;
// By default, Connection based on the default Phone, since we need to return to Telecom
// now.
- final int originalPhoneType = PhoneFactory.getDefaultPhone().getPhoneType();
+ final int originalPhoneType = mPhoneFactoryProxy.getDefaultPhone().getPhoneType();
final Connection resultConnection = getTelephonyConnection(request, numberToDial,
isEmergencyNumber, resultHandle, PhoneFactory.getDefaultPhone());
if (mRadioOnHelper == null) {
@@ -583,12 +753,8 @@
* Whether the cellular radio is power off because the device is on Bluetooth.
*/
private boolean isRadioPowerDownOnBluetooth() {
- final Context context = getApplicationContext();
- final boolean allowed = context.getResources().getBoolean(
- R.bool.config_allowRadioPowerDownOnBluetooth);
- final int cellOn = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.CELL_ON,
- PhoneConstants.CELL_ON_FLAG);
+ final boolean allowed = mDeviceState.isRadioPowerDownAllowedOnBluetooth(this);
+ final int cellOn = mDeviceState.getCellOnStatus(this);
return (allowed && cellOn == PhoneConstants.CELL_ON_FLAG && !isRadioOn());
}
@@ -627,7 +793,7 @@
} else {
Log.w(this, "onCreateOutgoingConnection, failed to turn on radio");
closeOrDestroyConnection(originalConnection,
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.POWER_OFF,
"Failed to turn on radio."));
}
@@ -652,11 +818,11 @@
boolean noActiveSimCard = SubscriptionController.getInstance()
.getActiveSubInfoCount(phone.getContext().getOpPackageName()) == 0;
// If there's no active sim card and the device is in emergency mode, use E account.
- addExistingConnection(PhoneUtils.makePstnPhoneAccountHandleWithPrefix(
+ addExistingConnection(mPhoneUtilsProxy.makePstnPhoneAccountHandleWithPrefix(
phone, "", isEmergencyNumber && noActiveSimCard), repConnection);
// Remove the old connection from Telecom after.
closeOrDestroyConnection(connectionToEvaluate,
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_CANCELED,
"Reconnecting outgoing Emergency Call.",
phone.getPhoneId()));
@@ -685,7 +851,7 @@
if (phone == null) {
final Context context = getApplicationContext();
- if (context.getResources().getBoolean(R.bool.config_checkSimStateBeforeOutgoingCall)) {
+ if (mDeviceState.shouldCheckSimStateBeforeOutgoingCall(this)) {
// Check SIM card state before the outgoing call.
// Start the SIM unlock activity if PIN_REQUIRED.
final Phone defaultPhone = mPhoneFactoryProxy.getDefaultPhone();
@@ -710,7 +876,7 @@
}
}
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE,
"SIM_STATE_PIN_REQUIRED"));
}
@@ -718,7 +884,7 @@
Log.d(this, "onCreateOutgoingConnection, phone is null");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE, "Phone is null"));
}
@@ -746,7 +912,7 @@
if (!allowNonEmergencyCalls) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.CDMA_NOT_EMERGENCY,
"Cannot make non-emergency call in ECM mode.",
phone.getPhoneId()));
@@ -764,7 +930,7 @@
break;
} else {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE,
"ServiceState.STATE_OUT_OF_SERVICE",
phone.getPhoneId()));
@@ -775,25 +941,24 @@
break;
}
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.POWER_OFF,
"ServiceState.STATE_POWER_OFF",
phone.getPhoneId()));
default:
Log.d(this, "onCreateOutgoingConnection, unknown service state: %d", state);
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_FAILURE,
"Unknown service state " + state,
phone.getPhoneId()));
}
}
- final Context context = getApplicationContext();
- final boolean isTtyModeEnabled = isTtyModeEnabled(context);
+ final boolean isTtyModeEnabled = mDeviceState.isTtyModeEnabled(this);
if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled
&& !isEmergencyNumber) {
- return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
+ return Connection.createFailedConnection(mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED,
null, phone.getPhoneId()));
}
@@ -807,7 +972,7 @@
// Check roaming status to see if we should block custom call forwarding codes
if (blockCallForwardingNumberWhileRoaming(phone, number)) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.DIALED_CALL_FORWARDING_WHILE_ROAMING,
"Call forwarding while roaming",
phone.getPhoneId()));
@@ -819,7 +984,7 @@
request.getTelecomCallId());
if (connection == null) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_FAILURE,
"Invalid phone type",
phone.getPhoneId()));
@@ -852,7 +1017,7 @@
request.getAddress() == null ? null : request.getAddress().getSchemeSpecificPart());
if (phone == null) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
"Phone is null"));
}
@@ -861,7 +1026,7 @@
if (!call.getState().isRinging()) {
Log.i(this, "onCreateIncomingConnection, no ringing call");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.INCOMING_MISSED,
"Found no ringing call",
phone.getPhoneId()));
@@ -882,7 +1047,7 @@
if (connection == null) {
return Connection.createCanceledConnection();
} else {
- connection.setTtyEnabled(isTtyModeEnabled(getApplicationContext()));
+ connection.setTtyEnabled(mDeviceState.isTtyModeEnabled(getApplicationContext()));
return connection;
}
}
@@ -1015,7 +1180,7 @@
request.getAddress() == null ? null : request.getAddress().getSchemeSpecificPart());
if (phone == null) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
"Phone is null"));
}
@@ -1268,7 +1433,7 @@
}
private void updatePhoneAccount(TelephonyConnection connection, Phone phone) {
- PhoneAccountHandle pHandle = PhoneUtils.makePstnPhoneAccountHandle(phone);
+ PhoneAccountHandle pHandle = mPhoneUtilsProxy.makePstnPhoneAccountHandle(phone);
// For ECall handling on MSIM, until the request reaches here (i.e PhoneApp), we don't know
// on which phone account ECall can be placed. After deciding, we should notify Telecom of
// the change so that the proper PhoneAccount can be displayed.
@@ -1292,16 +1457,32 @@
phone.getEmergencyNumberTracker().getEmergencyNumber(number);
if (emergencyNumber != null) {
phone.notifyOutgoingEmergencyCall(emergencyNumber);
- // If we do not support holding ongoing calls for an outgoing emergency call,
- // disconnect the ongoing calls.
- if (!shouldHoldForEmergencyCall(phone) && !getAllConnections().isEmpty()) {
- for (Connection c : getAllConnections()) {
- if (!c.equals(connection)
- && c.getState() != Connection.STATE_DISCONNECTED
- && c instanceof TelephonyConnection) {
- ((TelephonyConnection) c).hangup(
- android.telephony.DisconnectCause
- .OUTGOING_EMERGENCY_CALL_PLACED);
+ if (!getAllConnections().isEmpty()) {
+ if (!shouldHoldForEmergencyCall(phone)) {
+ // If we do not support holding ongoing calls for an outgoing
+ // emergency call, disconnect the ongoing calls.
+ for (Connection c : getAllConnections()) {
+ if (!c.equals(connection)
+ && c.getState() != Connection.STATE_DISCONNECTED
+ && c instanceof TelephonyConnection) {
+ ((TelephonyConnection) c).hangup(
+ android.telephony.DisconnectCause
+ .OUTGOING_EMERGENCY_CALL_PLACED);
+ }
+ }
+ } else if (!isVideoCallHoldAllowed(phone)) {
+ // If we do not support holding ongoing video call for an outgoing
+ // emergency call, disconnect the ongoing video call.
+ for (Connection c : getAllConnections()) {
+ if (!c.equals(connection)
+ && c.getState() == Connection.STATE_ACTIVE
+ && VideoProfile.isVideo(c.getVideoState())
+ && c instanceof TelephonyConnection) {
+ ((TelephonyConnection) c).hangup(
+ android.telephony.DisconnectCause
+ .OUTGOING_EMERGENCY_CALL_PLACED);
+ break;
+ }
}
}
}
@@ -1339,7 +1520,7 @@
break;
}
connection.setTelephonyConnectionDisconnected(
- DisconnectCauseUtil.toTelecomDisconnectCause(cause, e.getMessage(),
+ mDisconnectCauseFactory.toTelecomDisconnectCause(cause, e.getMessage(),
phone.getPhoneId()));
connection.close();
return;
@@ -1363,7 +1544,7 @@
}
Log.d(this, "placeOutgoingConnection, phone.dial returned null");
connection.setTelephonyConnectionDisconnected(
- DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause,
+ mDisconnectCauseFactory.toTelecomDisconnectCause(telephonyDisconnectCause,
"Connection is null", phone.getPhoneId()));
connection.close();
} else {
@@ -1371,6 +1552,18 @@
}
}
+ private boolean isVideoCallHoldAllowed(Phone phone) {
+ CarrierConfigManager cfgManager = (CarrierConfigManager)
+ phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (cfgManager == null) {
+ // For some reason CarrierConfigManager is unavailable, return default
+ Log.w(this, "isVideoCallHoldAllowed: couldn't get CarrierConfigManager");
+ return true;
+ }
+ return cfgManager.getConfigForSubId(phone.getSubId()).getBoolean(
+ CarrierConfigManager.KEY_ALLOW_HOLDING_VIDEO_CALL_BOOL, true);
+ }
+
private boolean shouldHoldForEmergencyCall(Phone phone) {
CarrierConfigManager cfgManager = (CarrierConfigManager)
phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -1445,7 +1638,7 @@
private Phone getPhoneForAccount(PhoneAccountHandle accountHandle, boolean isEmergency,
@Nullable String emergencyNumberAddress) {
Phone chosenPhone = null;
- int subId = PhoneUtils.getSubIdForPhoneAccountHandle(accountHandle);
+ int subId = mPhoneUtilsProxy.getSubIdForPhoneAccountHandle(accountHandle);
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
int phoneId = mSubscriptionManagerProxy.getPhoneId(subId);
chosenPhone = mPhoneFactoryProxy.getPhone(phoneId);
@@ -1475,7 +1668,7 @@
return possiblyOverrideDefaultDataForEmergencyCall(phone).get(
DEFAULT_DATA_SWITCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (Exception e) {
- Log.w(this, "onCreateOutgoingConn - delayDialForDdsSwitch exception= "
+ Log.w(this, "delayDialForDdsSwitch - exception= "
+ e.getMessage());
return false;
}
@@ -1495,13 +1688,21 @@
*/
private CompletableFuture<Boolean> possiblyOverrideDefaultDataForEmergencyCall(
@NonNull Phone phone) {
- TelephonyManager telephony = TelephonyManager.from(phone.getContext());
- int phoneCount = telephony.getPhoneCount();
+ int phoneCount = mTelephonyManagerProxy.getPhoneCount();
// Do not override DDS if this is a single SIM device.
if (phoneCount <= PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM) {
return CompletableFuture.completedFuture(Boolean.TRUE);
}
+ // Do not switch Default data if this device supports emergency SUPL on non-DDS.
+ final boolean gnssSuplRequiresDefaultData =
+ mDeviceState.isSuplDdsSwitchRequiredForEmergencyCall(this);
+ if (!gnssSuplRequiresDefaultData) {
+ Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS, does not "
+ + "require DDS switch.");
+ return CompletableFuture.completedFuture(Boolean.TRUE);
+ }
+
CarrierConfigManager cfgManager = (CarrierConfigManager)
phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (cfgManager == null) {
@@ -1510,34 +1711,41 @@
+ "CarrierConfigManager");
return CompletableFuture.completedFuture(Boolean.TRUE);
}
- // Only override default data if we are IN_SERVICE and on a home network. We don't want to
- // perform a DDS switch of we are on a roaming network, where SUPL may not be available.
- boolean isPhoneAvailableForEmergency = isAvailableForEmergencyCalls(phone);
+
+ // Only override default data if we are IN_SERVICE already.
+ if (!isAvailableForEmergencyCalls(phone)) {
+ Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS");
+ return CompletableFuture.completedFuture(Boolean.TRUE);
+ }
+
+ // Only override default data if we are not roaming, we do not want to switch onto a network
+ // that only supports data plane only (if we do not know).
boolean isRoaming = phone.getServiceState().getVoiceRoaming();
- if (!isPhoneAvailableForEmergency || isRoaming) {
- Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS, avail = "
- + isPhoneAvailableForEmergency + ", roaming = " + isRoaming);
+ // In some roaming conditions, we know the roaming network doesn't support control plane
+ // fallback even though the home operator does. For these operators we will need to do a DDS
+ // switch anyway to make sure the SUPL request doesn't fail.
+ boolean roamingNetworkSupportsControlPlaneFallback = true;
+ String[] dataPlaneRoamPlmns = cfgManager.getConfigForSubId(phone.getSubId()).getStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY);
+ if (dataPlaneRoamPlmns != null && Arrays.asList(dataPlaneRoamPlmns).contains(
+ phone.getServiceState().getOperatorNumeric())) {
+ roamingNetworkSupportsControlPlaneFallback = false;
+ }
+ if (isRoaming && roamingNetworkSupportsControlPlaneFallback) {
+ Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: roaming network is assumed "
+ + "to support CP fallback, not switching DDS.");
return CompletableFuture.completedFuture(Boolean.TRUE);
}
-
- // Do not switch Default data if this device supports emergency SUPL on non-DDS.
- final boolean gnssSuplRequiresDefaultData = phone.getContext().getResources().getBoolean(
- R.bool.config_gnss_supl_requires_default_data_for_emergency);
- if (!gnssSuplRequiresDefaultData) {
- Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS, does not "
- + "require DDS switch.");
- return CompletableFuture.completedFuture(Boolean.TRUE);
- }
-
+ // Do not try to swap default data if we support CS fallback or it is assumed that the
+ // roaming network supports control plane fallback, we do not want to introduce
+ // a lag in emergency call setup time if possible.
final boolean supportsCpFallback = cfgManager.getConfigForSubId(phone.getSubId())
.getInt(CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_ONLY)
!= CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY;
- if (supportsCpFallback) {
+ if (supportsCpFallback && roamingNetworkSupportsControlPlaneFallback) {
Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS, carrier "
+ "supports CP fallback.");
- // Do not try to swap default data if we support CS fallback, do not want to introduce
- // a lag in emergency call setup time if possible.
return CompletableFuture.completedFuture(Boolean.TRUE);
}
@@ -1545,7 +1753,7 @@
// CarrierConfig default if format fails.
int extensionTime = 0;
try {
- extensionTime = Integer.valueOf(cfgManager.getConfigForSubId(phone.getSubId())
+ extensionTime = Integer.parseInt(cfgManager.getConfigForSubId(phone.getSubId())
.getString(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"));
} catch (NumberFormatException e) {
// Just use default.
@@ -1554,12 +1762,13 @@
try {
Log.d(this, "possiblyOverrideDefaultDataForEmergencyCall: overriding DDS for "
+ extensionTime + "seconds");
- PhoneSwitcher.getInstance().overrideDefaultDataForEmergency(phone.getPhoneId(),
- extensionTime, modemResultFuture);
+ mPhoneSwitcherProxy.getPhoneSwitcher().overrideDefaultDataForEmergency(
+ phone.getPhoneId(), extensionTime, modemResultFuture);
// Catch all exceptions, we want to continue with emergency call if possible.
} catch (Exception e) {
Log.w(this, "possiblyOverrideDefaultDataForEmergencyCall: exception = "
+ e.getMessage());
+ modemResultFuture = CompletableFuture.completedFuture(Boolean.FALSE);
}
return modemResultFuture;
}
@@ -1875,13 +2084,6 @@
return null; // null means nothing went wrong, and call should continue.
}
- private boolean isTtyModeEnabled(Context context) {
- return (android.provider.Settings.Secure.getInt(
- context.getContentResolver(),
- android.provider.Settings.Secure.PREFERRED_TTY_MODE,
- TelecomManager.TTY_MODE_OFF) != TelecomManager.TTY_MODE_OFF);
- }
-
/**
* For outgoing dialed calls, potentially send a ConnectionEvent if the user is on WFC and is
* dialing an international number.
diff --git a/tests/Android.bp b/tests/Android.bp
index 42d88eb..22b40b5 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -20,6 +20,7 @@
srcs: ["src/**/*.java"],
libs: [
+ "android.test.mock",
"android.test.runner",
"telephony-common",
"android.test.base",
@@ -28,7 +29,7 @@
platform_apis: true,
certificate: "platform",
- instrumentation_for: "TeleServiceLib",
+ instrumentation_for: "TeleService",
static_libs: [
"androidx.test.rules",
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 17f4a8f..d434650 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -61,6 +61,6 @@
-->
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.phone.lib"
+ android:targetPackage="com.android.phone"
android:label="Phone application tests." />
</manifest>
diff --git a/tests/src/com/android/TelephonyTestBase.java b/tests/src/com/android/TelephonyTestBase.java
index d30ae6b..01267d8 100644
--- a/tests/src/com/android/TelephonyTestBase.java
+++ b/tests/src/com/android/TelephonyTestBase.java
@@ -16,13 +16,10 @@
package com.android;
-import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
-import androidx.test.InstrumentationRegistry;
-
import org.mockito.MockitoAnnotations;
import java.util.concurrent.CountDownLatch;
@@ -33,11 +30,11 @@
*/
public class TelephonyTestBase {
- protected Context mContext;
+ protected TestContext mContext;
public void setUp() throws Exception {
- mContext = InstrumentationRegistry.getTargetContext();
MockitoAnnotations.initMocks(this);
+ mContext = new TestContext();
// Set up the looper if it does not exist on the test thread.
if (Looper.myLooper() == null) {
Looper.prepare();
@@ -86,4 +83,8 @@
Log.e("TelephonyTestBase", "InterruptedException while waiting: " + e);
}
}
+
+ protected TestContext getTestContext() {
+ return mContext;
+ }
}
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
new file mode 100644
index 0000000..776ec6a
--- /dev/null
+++ b/tests/src/com/android/TestContext.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.PersistableBundle;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContext;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class TestContext extends MockContext {
+
+ @Mock CarrierConfigManager mMockCarrierConfigManager;
+ @Mock TelecomManager mMockTelecomManager;
+ @Mock TelephonyManager mMockTelephonyManager;
+ @Mock SubscriptionManager mMockSubscriptionManager;
+
+ private PersistableBundle mCarrierConfig = new PersistableBundle();
+
+ public TestContext() {
+ MockitoAnnotations.initMocks(this);
+ doReturn(mCarrierConfig).when(mMockCarrierConfigManager).getConfigForSubId(anyInt());
+ }
+
+ @Override
+ public Context getApplicationContext() {
+ return this;
+ }
+
+ @Override
+ public String getPackageName() {
+ return "com.android.phone.tests";
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+ String broadcastPermission, Handler scheduler) {
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+ String broadcastPermission, Handler scheduler, int flags) {
+ return null;
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ switch (name) {
+ case (Context.CARRIER_CONFIG_SERVICE) : {
+ return mMockCarrierConfigManager;
+ }
+ case (Context.TELECOM_SERVICE) : {
+ return mMockTelecomManager;
+ }
+ case (Context.TELEPHONY_SERVICE) : {
+ return mMockTelephonyManager;
+ }
+ case (Context.TELEPHONY_SUBSCRIPTION_SERVICE) : {
+ return mMockSubscriptionManager;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ if (serviceClass == CarrierConfigManager.class) {
+ return Context.CARRIER_CONFIG_SERVICE;
+ }
+ if (serviceClass == TelecomManager.class) {
+ return Context.TELECOM_SERVICE;
+ }
+ if (serviceClass == TelephonyManager.class) {
+ return Context.TELEPHONY_SERVICE;
+ }
+ if (serviceClass == SubscriptionManager.class) {
+ return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
+ }
+ return null;
+ }
+
+ public PersistableBundle getCarrierConfig() {
+ return mCarrierConfig;
+ }
+}
diff --git a/tests/src/com/android/phone/LocationAccessPolicyTest.java b/tests/src/com/android/phone/LocationAccessPolicyTest.java
index 181f4c8..9938bf2 100644
--- a/tests/src/com/android/phone/LocationAccessPolicyTest.java
+++ b/tests/src/com/android/phone/LocationAccessPolicyTest.java
@@ -34,7 +34,6 @@
import android.telephony.LocationAccessPolicy;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -171,7 +170,7 @@
mScenario = scenario;
}
- @Ignore
+
@Test
public void test() {
setupScenario(mScenario);
diff --git a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
index 19e802b..edfc34f 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
@@ -30,7 +30,6 @@
import com.android.internal.telephony.PhoneConstants;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -110,7 +109,6 @@
* is PhoneConstants.PHONE_TYPE_IMS
* Expected: addConference for ImsConference is called twice
*/
- @Ignore
@Test
@SmallTest
public void testMergeMultiPartyCalls() {
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index d294604..7251402 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -38,7 +38,6 @@
import com.android.ims.internal.ConferenceParticipant;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -66,7 +65,6 @@
.thenReturn(null);
}
- @Ignore
@Test
@SmallTest
public void testSinglePartyEmulation() {
@@ -114,7 +112,6 @@
/**
* Tests CEPs with disconnected participants present with disconnected state.
*/
- @Ignore
@Test
@SmallTest
public void testDisconnectParticipantViaDisconnectState() {
@@ -178,7 +175,6 @@
/**
* Tests CEPs with removed participants.
*/
- @Ignore
@Test
@SmallTest
public void testDisconnectParticipantViaRemoval() {
@@ -236,7 +232,6 @@
*
* This test verifies that we can still enter single party emulation in this case.
*/
- @Ignore
@Test
@SmallTest
public void testSinglePartyEmulationEnterOnDisconnectParticipant() {
@@ -295,7 +290,6 @@
* it triggered exiting single party conference mode (due to a bug) and caused the call to not
* be logged.
*/
- @Ignore
@Test
@SmallTest
public void testSinglePartyEmulationWithPreDisconnectParticipantUpdate() {
@@ -352,7 +346,6 @@
* Verify that the single party emulate correctly when the conference start with only
* one participant.
*/
- @Ignore
@Test
@SmallTest
public void testSinglePartyEmulationWithOneParticipantAtBeginning() {
@@ -377,7 +370,6 @@
/**
* Verify that we do not use single party emulation when a sim call manager is in use.
*/
- @Ignore
@Test
@SmallTest
public void testNoSinglePartyEmulationWithSimCallManager() {
@@ -416,7 +408,6 @@
assertEquals(2, imsConference.getNumberOfParticipants());
}
- @Ignore
@Test
@SmallTest
public void testNormalConference() {
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 166f2fb..6e11e51 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -17,10 +17,13 @@
package com.android.services.telephony;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
@@ -29,38 +32,45 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.telecom.ConnectionRequest;
import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
import android.test.suitebuilder.annotation.SmallTest;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.TelephonyTestBase;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneSwitcher;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
/**
@@ -74,20 +84,72 @@
private static final int SLOT_0_PHONE_ID = 0;
private static final int SLOT_1_PHONE_ID = 1;
+ private static final ComponentName TEST_COMPONENT_NAME = new ComponentName(
+ "com.android.phone.tests", TelephonyConnectionServiceTest.class.getName());
+ private static final String TEST_ACCOUNT_ID1 = "id1";
+ private static final String TEST_ACCOUNT_ID2 = "id2";
+ private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE_1 = new PhoneAccountHandle(
+ TEST_COMPONENT_NAME, TEST_ACCOUNT_ID1);
+ private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE_2 = new PhoneAccountHandle(
+ TEST_COMPONENT_NAME, TEST_ACCOUNT_ID2);
+ private static final Uri TEST_ADDRESS = Uri.parse("tel:+16505551212");
+
@Mock TelephonyConnectionService.TelephonyManagerProxy mTelephonyManagerProxy;
@Mock TelephonyConnectionService.SubscriptionManagerProxy mSubscriptionManagerProxy;
@Mock TelephonyConnectionService.PhoneFactoryProxy mPhoneFactoryProxy;
+ @Mock DeviceState mDeviceState;
+ @Mock TelephonyConnectionService.PhoneSwitcherProxy mPhoneSwitcherProxy;
+ @Mock TelephonyConnectionService.PhoneNumberUtilsProxy mPhoneNumberUtilsProxy;
+ @Mock TelephonyConnectionService.PhoneUtilsProxy mPhoneUtilsProxy;
+ @Mock TelephonyConnectionService.HandlerFactory mHandlerFactory;
+ @Mock TelephonyConnectionService.DisconnectCauseFactory mDisconnectCauseFactory;
+ @Mock Handler mMockHandler;
@Mock EmergencyNumberTracker mEmergencyNumberTracker;
+ @Mock PhoneSwitcher mPhoneSwitcher;
- TelephonyConnectionService mTestConnectionService;
+ private static class TestTelephonyConnectionService extends TelephonyConnectionService {
+
+ private final Context mContext;
+
+ TestTelephonyConnectionService(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onCreate() {
+ // attach test context.
+ attachBaseContext(mContext);
+ super.onCreate();
+ }
+ }
+
+ private TelephonyConnectionService mTestConnectionService;
@Before
public void setUp() throws Exception {
super.setUp();
- mTestConnectionService = new TelephonyConnectionService();
+ mTestConnectionService = new TestTelephonyConnectionService(mContext);
mTestConnectionService.setPhoneFactoryProxy(mPhoneFactoryProxy);
- mTestConnectionService.setTelephonyManagerProxy(mTelephonyManagerProxy);
mTestConnectionService.setSubscriptionManagerProxy(mSubscriptionManagerProxy);
+ // Set configurations statically
+ doReturn(false).when(mDeviceState).shouldCheckSimStateBeforeOutgoingCall(any());
+ mTestConnectionService.setPhoneSwitcherProxy(mPhoneSwitcherProxy);
+ doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher();
+ mTestConnectionService.setPhoneNumberUtilsProxy(mPhoneNumberUtilsProxy);
+ mTestConnectionService.setPhoneUtilsProxy(mPhoneUtilsProxy);
+ HandlerThread mockHandlerThread = mock(HandlerThread.class);
+ doReturn(mockHandlerThread).when(mHandlerFactory).createHandlerThread(anyString());
+ doReturn(null).when(mockHandlerThread).getLooper();
+ doReturn(mMockHandler).when(mHandlerFactory).createHandler(any());
+ mTestConnectionService.setHandlerFactory(mHandlerFactory);
+ mTestConnectionService.setDeviceState(mDeviceState);
+ doReturn(new DisconnectCause(DisconnectCause.UNKNOWN)).when(mDisconnectCauseFactory)
+ .toTelecomDisconnectCause(anyInt(), any());
+ doReturn(new DisconnectCause(DisconnectCause.UNKNOWN)).when(mDisconnectCauseFactory)
+ .toTelecomDisconnectCause(anyInt(), any(), anyInt());
+ mTestConnectionService.setDisconnectCauseFactory(mDisconnectCauseFactory);
+ mTestConnectionService.onCreate();
+ mTestConnectionService.setTelephonyManagerProxy(mTelephonyManagerProxy);
}
@After
@@ -103,7 +165,6 @@
*
* Result: getFirstPhoneForEmergencyCall returns the default Voice SIM choice.
*/
- @Ignore
@Test
@SmallTest
public void testDefaultVoiceSimInService() {
@@ -126,7 +187,6 @@
*
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone
*/
- @Ignore
@Test
@SmallTest
public void testSlot1EmergencyOnly() {
@@ -149,7 +209,6 @@
*
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone
*/
- @Ignore
@Test
@SmallTest
public void testSlot1InService() {
@@ -174,7 +233,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone. Although Slot 0 is more
* capable, it is locked, so use the other slot.
*/
- @Ignore
@Test
@SmallTest
public void testSlot0PukLocked() {
@@ -205,7 +263,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone. Although Slot 0 is more
* capable, it is locked, so use the other slot.
*/
- @Ignore
@Test
@SmallTest
public void testSlot0PinLocked() {
@@ -236,7 +293,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 0 phone. Although Slot 1 is more
* capable, it is locked, so use the other slot.
*/
- @Ignore
@Test
@SmallTest
public void testSlot1PukLocked() {
@@ -267,7 +323,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 0 phone. Although Slot 1 is more
* capable, it is locked, so use the other slot.
*/
- @Ignore
@Test
@SmallTest
public void testSlot1PinLocked() {
@@ -297,7 +352,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one
* with a SIM inserted (even if it is PUK locked)
*/
- @Ignore
@Test
@SmallTest
public void testSlot1PinLockedAndSlot0Absent() {
@@ -328,7 +382,6 @@
*
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is more capable
*/
- @Ignore
@Test
@SmallTest
public void testSlot1HigherCapablity() {
@@ -357,7 +410,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it has more
* capabilities.
*/
- @Ignore
@Test
@SmallTest
public void testSlot1MoreCapabilities() {
@@ -388,7 +440,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 0 phone because it is more capable,
* ignoring that both SIMs are PUK locked.
*/
- @Ignore
@Test
@SmallTest
public void testSlot0MoreCapableBothPukLocked() {
@@ -416,7 +467,6 @@
*
* Result: getFirstPhoneForEmergencyCall returns the slot 0 phone because it is the first slot.
*/
- @Ignore
@Test
@SmallTest
public void testEqualCapabilityTwoSimsInserted() {
@@ -448,7 +498,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 0 phone because it is the only one
* with a SIM inserted
*/
- @Ignore
@Test
@SmallTest
public void testEqualCapabilitySim0Inserted() {
@@ -480,7 +529,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one
* with a SIM inserted
*/
- @Ignore
@Test
@SmallTest
public void testEqualCapabilitySim1Inserted() {
@@ -512,7 +560,6 @@
* Result: getFirstPhoneForEmergencyCall returns the slot 1 phone, since it is a higher
* capability
*/
- @Ignore
@Test
@SmallTest
public void testSim1HigherCapabilityNoSimsInserted() {
@@ -543,7 +590,6 @@
*
* Result: getFirstPhoneForEmergencyCall returns the slot 0 phone, since it is the first slot.
*/
- @Ignore
@Test
@SmallTest
public void testEqualCapabilityNoSimsInserted() {
@@ -574,9 +620,7 @@
* Verify that dial is called on the same phone again when retryOutgoingOriginalConnection is
* called.
*/
- @Ignore
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialTempFailOneSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -585,7 +629,7 @@
List<Phone> phones = new ArrayList<>(1);
phones.add(slot0Phone);
setPhones(phones);
- c.setAddress(Uri.parse("tel:+16505551212"), TelecomManager.PRESENTATION_ALLOWED);
+ c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
mTestConnectionService.retryOutgoingOriginalConnection(c, false /*isPermanentFailure*/);
@@ -607,9 +651,7 @@
* Verify that the connection is set to disconnected with an error disconnect cause and dial is
* not called.
*/
- @Ignore
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialPermFailOneSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -618,7 +660,7 @@
List<Phone> phones = new ArrayList<>(1);
phones.add(slot0Phone);
setPhones(phones);
- c.setAddress(Uri.parse("tel:+16505551212"), TelecomManager.PRESENTATION_ALLOWED);
+ c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
mTestConnectionService.retryOutgoingOriginalConnection(c, true /*isPermanentFailure*/);
@@ -642,9 +684,7 @@
* Verify that the emergency call is dialed on the other slot and telecom is notified of the new
* PhoneAccount.
*/
- @Ignore
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialTempFailTwoSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -653,11 +693,15 @@
Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
false /*isEmergencyOnly*/);
setPhonesDialConnection(slot1Phone, c.getOriginalConnection());
- c.setAddress(Uri.parse("tel:+16505551212"), TelecomManager.PRESENTATION_ALLOWED);
+ c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
List<Phone> phones = new ArrayList<>(2);
phones.add(slot0Phone);
phones.add(slot1Phone);
setPhones(phones);
+ doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot0Phone);
+ doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot1Phone);
mTestConnectionService.retryOutgoingOriginalConnection(c, false /*isPermanentFailure*/);
@@ -681,9 +725,7 @@
* Verify that the emergency call is dialed on the other slot and telecom is notified of the new
* PhoneAccount.
*/
- @Ignore
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialPermFailTwoSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -692,11 +734,15 @@
Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
false /*isEmergencyOnly*/);
setPhonesDialConnection(slot1Phone, c.getOriginalConnection());
- c.setAddress(Uri.parse("tel:+16505551212"), TelecomManager.PRESENTATION_ALLOWED);
+ c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
List<Phone> phones = new ArrayList<>(2);
phones.add(slot0Phone);
phones.add(slot1Phone);
setPhones(phones);
+ doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot0Phone);
+ doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot1Phone);
mTestConnectionService.retryOutgoingOriginalConnection(c, true /*isPermanentFailure*/);
@@ -720,9 +766,7 @@
* Verify that the emergency call is dialed on slot 1 and then on slot 0 and telecom is
* notified of this twice.
*/
- @Ignore
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialTempFailTwoSlot_twoFailure() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -731,11 +775,15 @@
Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
false /*isEmergencyOnly*/);
setPhonesDialConnection(slot1Phone, c.getOriginalConnection());
- c.setAddress(Uri.parse("tel:+16505551212"), TelecomManager.PRESENTATION_ALLOWED);
+ c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
List<Phone> phones = new ArrayList<>(2);
phones.add(slot0Phone);
phones.add(slot1Phone);
setPhones(phones);
+ doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot0Phone);
+ doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot1Phone);
// First Temporary failure
mTestConnectionService.retryOutgoingOriginalConnection(c, false /*isPermanentFailure*/);
@@ -773,9 +821,7 @@
* Verify that the emergency call is dialed on slot 1 and then disconnected and telecom is
* notified of the change to slot 1.
*/
- @Ignore
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialPermFailTwoSlot_twoFailure() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -784,11 +830,15 @@
Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
false /*isEmergencyOnly*/);
setPhonesDialConnection(slot1Phone, c.getOriginalConnection());
- c.setAddress(Uri.parse("tel:+16505551212"), TelecomManager.PRESENTATION_ALLOWED);
+ c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
List<Phone> phones = new ArrayList<>(2);
phones.add(slot0Phone);
phones.add(slot1Phone);
setPhones(phones);
+ doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot0Phone);
+ doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle(
+ slot1Phone);
// First Permanent failure
mTestConnectionService.retryOutgoingOriginalConnection(c, true /*isPermanentFailure*/);
@@ -817,7 +867,6 @@
}
}
- @Ignore
@Test
@SmallTest
public void testSuppServiceNotification() {
@@ -827,11 +876,7 @@
// registration to occur.
Phone phone = c.getPhone();
c.setOriginalConnection(c.getOriginalConnection());
-
- // Use a real context since the method SubscriptionManager.getResourcesForSubId()
- // needs to interact with a real context.
- Context targetContext = InstrumentationRegistry.getTargetContext();
- doReturn(targetContext).when(phone).getContext();
+ doReturn(mContext).when(phone).getContext();
// When the registration occurs, we'll capture the handler and message so we can post our
// own messages to it.
@@ -868,6 +913,239 @@
extras.getInt(TelephonyManager.EXTRA_NOTIFICATION_CODE));
}
+ /**
+ * Test that the TelephonyConnectionService successfully performs a DDS switch before a call
+ * when we are not roaming and the carrier only supports SUPL over the data plane.
+ */
+ @Test
+ @SmallTest
+ public void testCreateOutgoingEmergencyConnection_delayDial_carrierconfig_dds() {
+ Phone testPhone = setupConnectionServiceForDelayDial();
+ Runnable delayDialRunnable = verifyRunnablePosted();
+
+ // Setup test to not support SUPL on the non-DDS subscription
+ doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
+ getTestContext().getCarrierConfig().putStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+ null);
+ testPhone.getServiceState().setRoaming(false);
+ getTestContext().getCarrierConfig().putInt(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+ CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
+ getTestContext().getCarrierConfig().putString(
+ CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "150");
+ delayDialRunnable.run();
+
+ verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
+ eq(150) /*extensionTime*/, any());
+ }
+
+ /**
+ * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier
+ * supports control-plane fallback.
+ */
+ @Test
+ @SmallTest
+ public void testCreateOutgoingEmergencyConnection_delayDial_nocarrierconfig() {
+ Phone testPhone = setupConnectionServiceForDelayDial();
+ Runnable delayDialRunnable = verifyRunnablePosted();
+
+ // Setup test to not support SUPL on the non-DDS subscription
+ doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
+ getTestContext().getCarrierConfig().putStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+ null);
+ testPhone.getServiceState().setRoaming(false);
+ getTestContext().getCarrierConfig().putInt(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+ CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
+ getTestContext().getCarrierConfig().putString(
+ CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
+ delayDialRunnable.run();
+
+ verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
+ }
+
+ /**
+ * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier
+ * supports control-plane fallback.
+ */
+ @Test
+ @SmallTest
+ public void testCreateOutgoingEmergencyConnection_delayDial_supportsuplondds() {
+ Phone testPhone = setupConnectionServiceForDelayDial();
+ Runnable delayDialRunnable = verifyRunnablePosted();
+
+ // If the non-DDS supports SUPL, dont switch data
+ doReturn(false).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
+ getTestContext().getCarrierConfig().putStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+ null);
+ testPhone.getServiceState().setRoaming(false);
+ getTestContext().getCarrierConfig().putInt(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+ CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
+ getTestContext().getCarrierConfig().putString(
+ CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
+ delayDialRunnable.run();
+
+ verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
+ }
+
+ /**
+ * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier does
+ * not support control-plane fallback CarrierConfig while roaming.
+ */
+ @Test
+ @SmallTest
+ public void testCreateOutgoingEmergencyConnection_delayDial_roaming_nocarrierconfig() {
+ Phone testPhone = setupConnectionServiceForDelayDial();
+ Runnable delayDialRunnable = verifyRunnablePosted();
+
+ // Setup test to not support SUPL on the non-DDS subscription
+ doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
+ getTestContext().getCarrierConfig().putStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+ null);
+ testPhone.getServiceState().setRoaming(true);
+ getTestContext().getCarrierConfig().putInt(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+ CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
+ getTestContext().getCarrierConfig().putString(
+ CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
+ delayDialRunnable.run();
+
+ verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
+ }
+
+ /**
+ * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier
+ * supports control-plane fallback CarrierConfig and the roaming partner is configured to look
+ * like a home network.
+ */
+ @Test
+ @SmallTest
+ public void testCreateOutgoingEmergencyConnection_delayDial_roamingcarrierconfig() {
+ Phone testPhone = setupConnectionServiceForDelayDial();
+ Runnable delayDialRunnable = verifyRunnablePosted();
+
+ // Setup voice roaming scenario
+ String testRoamingOperator = "001001";
+ // In some roaming conditions, we are not technically "roaming"
+ testPhone.getServiceState().setRoaming(false);
+ testPhone.getServiceState().setOperatorName("TestTel", "TestTel", testRoamingOperator);
+ // Setup test to not support SUPL on the non-DDS subscription
+ doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
+ String[] roamingPlmns = new String[1];
+ roamingPlmns[0] = testRoamingOperator;
+ getTestContext().getCarrierConfig().putStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+ roamingPlmns);
+ getTestContext().getCarrierConfig().putInt(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+ CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
+ getTestContext().getCarrierConfig().putString(
+ CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
+ delayDialRunnable.run();
+
+ verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
+ eq(0) /*extensionTime*/, any());
+ }
+
+ /**
+ * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier
+ * supports control-plane fallback CarrierConfig if we are roaming and the roaming partner is
+ * configured to use data plane only SUPL.
+ */
+ @Test
+ @SmallTest
+ public void testCreateOutgoingEmergencyConnection_delayDial__roaming_roamingcarrierconfig() {
+ Phone testPhone = setupConnectionServiceForDelayDial();
+ Runnable delayDialRunnable = verifyRunnablePosted();
+
+ // Setup voice roaming scenario
+ String testRoamingOperator = "001001";
+ testPhone.getServiceState().setRoaming(true);
+ testPhone.getServiceState().setOperatorName("TestTel", "TestTel", testRoamingOperator);
+ // Setup test to not support SUPL on the non-DDS subscription
+ doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
+ String[] roamingPlmns = new String[1];
+ roamingPlmns[0] = testRoamingOperator;
+ getTestContext().getCarrierConfig().putStringArray(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+ roamingPlmns);
+ getTestContext().getCarrierConfig().putInt(
+ CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+ CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
+ getTestContext().getCarrierConfig().putString(
+ CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
+ delayDialRunnable.run();
+
+ verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
+ eq(0) /*extensionTime*/, any());
+ }
+
+ /**
+ * Set up a mock MSIM device with TEST_ADDRESS set as an emergency number.
+ * @return the Phone associated with slot 0.
+ */
+ private Phone setupConnectionServiceForDelayDial() {
+ ConnectionRequest connectionRequest = new ConnectionRequest.Builder()
+ .setAccountHandle(PHONE_ACCOUNT_HANDLE_1)
+ .setAddress(TEST_ADDRESS)
+ .build();
+ Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_IN_SERVICE,
+ false /*isEmergencyOnly*/);
+ Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_OUT_OF_SERVICE,
+ false /*isEmergencyOnly*/);
+ List<Phone> phones = new ArrayList<>(2);
+ doReturn(true).when(testPhone0).isRadioOn();
+ doReturn(true).when(testPhone1).isRadioOn();
+ phones.add(testPhone0);
+ phones.add(testPhone1);
+ setPhones(phones);
+ setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0);
+ setupDeviceConfig(testPhone0, testPhone1, 1);
+ doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(
+ TEST_ADDRESS.getSchemeSpecificPart());
+ HashMap<Integer, List<EmergencyNumber>> emergencyNumbers = new HashMap<>(1);
+ List<EmergencyNumber> numbers = new ArrayList<>();
+ numbers.add(setupEmergencyNumber(TEST_ADDRESS));
+ emergencyNumbers.put(0 /*subId*/, numbers);
+ doReturn(emergencyNumbers).when(mTelephonyManagerProxy).getCurrentEmergencyNumberList();
+ doReturn(2).when(mTelephonyManagerProxy).getPhoneCount();
+
+ android.telecom.Connection testConnection = mTestConnectionService
+ .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, connectionRequest);
+ assertNotNull("test connection was not set up correctly.", testConnection);
+
+ return testPhone0;
+ }
+
+ private Runnable verifyRunnablePosted() {
+ ArgumentCaptor<Message> runnableCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mMockHandler).sendMessageDelayed(runnableCaptor.capture(), anyLong());
+ assertNotNull("Invalid Message created", runnableCaptor.getValue());
+ Runnable runnable = runnableCaptor.getValue().getCallback();
+ assertNotNull("sendMessageDelayed never occurred.", runnableCaptor);
+ return runnable;
+ }
+
+ private EmergencyNumber setupEmergencyNumber(Uri address) {
+ return new EmergencyNumber(address.getSchemeSpecificPart(), "", "",
+ EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+ Collections.emptyList(),
+ EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+ EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+ }
+
+ private void setupHandleToPhoneMap(PhoneAccountHandle handle, Phone phone) {
+ // use subId 0
+ when(mPhoneUtilsProxy.getSubIdForPhoneAccountHandle(handle)).thenReturn(0);
+ when(mSubscriptionManagerProxy.getPhoneId(0)).thenReturn(0);
+ when(mPhoneFactoryProxy.getPhone(0)).thenReturn(phone);
+ }
+
private AsyncResult getSuppServiceNotification(int notificationType, int code) {
SuppServiceNotification notification = new SuppServiceNotification();
notification.notificationType = notificationType;
@@ -880,6 +1158,7 @@
ServiceState testServiceState = new ServiceState();
testServiceState.setState(serviceState);
testServiceState.setEmergencyOnly(isEmergencyOnly);
+ when(phone.getContext()).thenReturn(mContext);
when(phone.getServiceState()).thenReturn(testServiceState);
when(phone.getPhoneId()).thenReturn(phoneId);
when(phone.getDefaultPhone()).thenReturn(phone);
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
index 6feefec..7d15680 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -5,16 +5,14 @@
import android.os.Bundle;
import android.telecom.Connection;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import androidx.test.runner.AndroidJUnit4;
+
@RunWith(AndroidJUnit4.class)
public class TelephonyConnectionTest {
- @Ignore
@Test
public void testCodecInIms() {
TestTelephonyConnection c = new TestTelephonyConnection();
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index 593494b..5b31c0f 100644
--- a/tests/src/com/android/services/telephony/TestTelephonyConnection.java
+++ b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.telecom.PhoneAccountHandle;
import static org.mockito.ArgumentMatchers.any;
@@ -135,6 +136,28 @@
// Do nothing since the original connection is mock object
}
+ @Override
+ public PersistableBundle getCarrierConfig() {
+ // Depends on PhoneGlobals for context in TelephonyConnection, do not implement during
+ // testing.
+ return new PersistableBundle();
+ }
+
+ @Override
+ public CharSequence getResourceText(int messageId) {
+ return "TEST";
+ }
+
+ @Override
+ public String getResourceString(int id) {
+ return "TEST";
+ }
+
+ @Override
+ void refreshConferenceSupported() {
+ // Requires ImsManager dependencies, do not implement during testing.
+ }
+
public int getNotifyPhoneAccountChangedCount() {
return mNotifyPhoneAccountChangedCount;
}