Merge "Revert submission"
diff --git a/Android.bp b/Android.bp
index a81158d..9449334 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,7 +16,7 @@
// for the 'other' dialer.
android_app {
- name: "TeleService",
+ name: "TeleServiceLib",
libs: [
"telephony-common",
@@ -30,9 +30,10 @@
"androidx.preference_preference",
"androidx.recyclerview_recyclerview",
"androidx.legacy_legacy-preference-v14",
- "guava",
"android-support-annotations",
"com.android.phone.common-lib",
+ "guava",
+ "PlatformProperties",
],
srcs: [
@@ -57,8 +58,12 @@
aaptflags: [
"--extra-packages com.android.services.telephony.sip",
+ "--shared-lib",
+ "--extra-packages com.android.phone",
],
+ export_package_resources: true,
+
platform_apis: true,
certificate: "platform",
@@ -68,6 +73,7 @@
proguard_flags_files: [
"proguard.flags",
"sip/proguard.flags",
+ "proguard.proguard",
],
},
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d264bad..fd59ced 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,626 +15,10 @@
-->
<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"
->
+ package="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="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.CONNECTIVITY_INTERNAL" />
- <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">
-
- <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>
- <intent-filter>
- <action android:name="android.intent.action.DIAL_EMERGENCY" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.DIAL_EMERGENCY" />
- <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>
-
- <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>
+ <library android:name="com.android.phone.lib" />
</application>
-</manifest>
+
+</manifest>
\ No newline at end of file
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1321ace..22845e0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -48,3 +48,5 @@
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/com.android.services.telephony.common_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/telephony-common.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/ims-common.jar)
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..e75dcb0
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "presubmit": [
+ {
+ "name": "TeleServiceTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/apex/Android.bp b/apex/Android.bp
new file mode 100644
index 0000000..86ebe3a
--- /dev/null
+++ b/apex/Android.bp
@@ -0,0 +1,28 @@
+apex {
+ name: "com.android.telephony",
+
+ manifest: "apex_manifest.json",
+
+ // optional. if unspecified, a default one is auto-generated
+ androidManifest: "AndroidManifest.xml",
+
+ java_libs: ["telephony-common", "ims-common"],
+ //apps: ["TeleService", "StkLib", "ONSLib"],
+ apps: ["StkLib"],
+
+ key: "com.android.telephony.key",
+ certificate: ":com.android.telephony.certificate",
+}
+
+apex_key {
+ name: "com.android.telephony.key",
+ public_key: "com.android.telephony.avbpubkey",
+ private_key: "com.android.telephony.pem",
+}
+
+android_app_certificate {
+ name: "com.android.telephony.certificate",
+ // This will use com.android.telephony.x509.pem (the cert) and
+ // com.android.telephony.pk8 (the private key)
+ certificate: "com.android.telephony",
+}
diff --git a/apex/AndroidManifest.xml b/apex/AndroidManifest.xml
new file mode 100644
index 0000000..a32ab33
--- /dev/null
+++ b/apex/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.telephony">
+ <!-- APEX does not have classes.dex -->
+ <application android:hasCode="false" />
+ <!-- Setting maxSdk to lock the module to R. minSdk is auto-set by build system -->
+ <uses-sdk
+ android:maxSdkVersion="30"
+ android:targetSdkVersion="30"
+ />
+</manifest>
\ No newline at end of file
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
new file mode 100644
index 0000000..493d6fd
--- /dev/null
+++ b/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.telephony",
+ "version": 1
+}
\ No newline at end of file
diff --git a/apex/com.android.telephony.avbpubkey b/apex/com.android.telephony.avbpubkey
new file mode 100644
index 0000000..cba14427
--- /dev/null
+++ b/apex/com.android.telephony.avbpubkey
Binary files differ
diff --git a/apex/com.android.telephony.pem b/apex/com.android.telephony.pem
new file mode 100644
index 0000000..19d8c05
--- /dev/null
+++ b/apex/com.android.telephony.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAvEOU0eLO65uykCUYoLBXxjsIB7pCIXahtyIMYiGuUl6tnYb2
+gjPxsD9fNrqgdT+WgzHlfMPr4GqkT7prSI4/y9NglnFk2nAKZLQwiwtLOmm54Cnp
+OqqQZ9+g4MvA2rsrmstJ/Pdu4t+9Bv9bZHYLEPCW4LV1v5S2jY7ie/C+SbZm8yFz
+X9RgTX7loH7oSNDqvVMRUeyrlH3gRHxPMQxIMfLMro1NCfkA4q8QnwPpM2+YEBf0
+kktXkvbfJUB0Ywo6BCVAoqxkghNQQTLBuBDFnho13gQSMOLu8C62pzdAyPm/n5Yv
+aqEdmmGkBsy2qiHTiRuiWWl9aGDhd0U6e+hYK4OM3ISDQiTr5OuraIKt8EH7jo8H
+Zb/WqJFygOq5RqXmAvbtq+eBAgLlUNAl5F9RwLU6zPTREsSGG/g1fqUSD4ZS2qHt
+d9aBdSepvL4xDCg9BDTFMt4Xjc83hk+v7nIIPB4cayA9s2kgjXwjZhiMOJuoNMmr
+Wu2GP9zw37WmUF5jXKgICVtoq//qofA3KA+YZ8NcmPRmeBzCEks5fCAZN64AIh5l
+vi8pPv+s8lbhGui/dkgJAGoMWKwukMZZDxTFfgbPU74yIWUpoiXGEv+0WPsOyxKe
+HEC0uXL6h6HtTaxTTyk9OJp1Z12ih2CdHmoK8aHeL1ND+YXxko4rcVyJGvcCAwEA
+AQKCAgAve1gAa5TGhZlOk5yXgoJQw7itwkNFj1cQCi1XXqlJqwlcrppjklhFnGYW
+NpGboLMEWcRIaF2IVz0jwp+mSAI9FQ3KQ8Us9o8YgP2xQ+LwU5QGvmtNWZFcMWGw
+8JKuWACSZO0/OOSlocpaBnN1bfQyjItxFzMgY5B7OWtT2Q8VJkTm0yv3Img7g2LE
+zN0m6FIb9+RpZiiMJgc3HqcWdsOKnXMUHx0sA7o+cereQC1DxMR0YqZTc18d+Nek
+3JG+HOku/HpFzPb4e4iFORj0pH5C9tdZLGuuGr4qo417tQrI5Xx38nf5C7OcqT2m
+XWFAnZFthiO3K0zu02hqHXK3p4z81aerzOAFHQP9Dvw0LrEevhMS7POwnoBMWIYT
+j2oJAKf84AIt+URNxRMcOH4Vs8133ZJxesotYzEdZBN4KBukCC+MzLtkJ3C3vLSu
+PPlwYfS0T/wMLBlQRfGM2pZbuldc4Th+VuE8lvDIvmZKxUXdAh/OkTJRt95SSpFQ
+PZy9NauagIaDyE08z3vgiYUH/498piibXiv4ox9puyfDI30W7VlZA9NBV7UBhkcV
+vxmop3U4KJdI0dcwB/8oQao/eM8Bk8TOI58Ux/gM+7tLM+pzeIPlKsZ3GWjZYyZi
+Fds7JdprR2AljUoKXAGA3G2IejhiB6VSivR8IRLwdWZSAaM9iQKCAQEA512QfnYR
+MDjYzUBYySHANVFi09q3taoYJ1Ovq4w3YnC4Yy6OM1rI1g55mhzGGnrQhC8//Lwy
+v9fxhxEQkx8rY40KJRizfc28l3gIFzF+/mP5DqUQiVZQBiAm0m0y3LA1xTCRxyc/
+yLWCodFOojcg8H3vxDUiL+80wLRX/zXmUHjhGmg+sZVtuWTVpgdFEGR1guVAoXPM
+t6p9+Zpr+yhURRuce7IfjVxIXtjzaZ6fglCYSnakhxvBMWvvhhD2Sx60bl0sBpsT
+oj4VZmd7i01bde1H2BlJ9ca23uGPylvmC+kVFVoqnMv7dZuhHgQY06zg+zts8Grm
+mVcTa5xKtEr2FQKCAQEA0E8t9/XV6tEH5BoiZ6SLIYeh+yk/h8hQKGn+lnzcywon
+L/EEtvqzoeIkbLATOk4ffbiYtI86GxldPUp293ups9rJCJdb7fIahJJd4Pl9d9QF
+dEWkuMC9btyBq0WjvJLIVxKLcBv9NAMnfLYIWk4OfAXQ2Kgv4OrYmxqtLdnzqIT0
+4jgQcHkaDbPIBkOAfAcyy6b6TNsdhiR/ojZ/3s7e0YpUhUkvGqHPeGkg827fznui
+mOSvuIC1eg92Kpsv/NzZkSkhh+Y4yT3mXTPkdRrIoRiwfUsBx9c3CUB1bhMlqYdP
+p9IwfcDYPmPIWqD/5EIm5CIFTh/qFuJuB/RP1xr72wKCAQEAm6BZGGdsqmYilvWI
+g0o7kuG6u0xstDrE4nctPBQmEQZHURe4uRyA6VN1Qk/GhXtFFRT/Uo55CIhFw5eb
+8YpO0jjFsSxLV/zytWQc9RTrGky+87XeSLMRQv2Pf43KX537nTdNZ4ukIOrPAu/a
+l8zDUGE1zWH8LAgYEON+KYHk+Q5GRFAIk8UyuDj2aSaMszkPvktczP0qoASDlkjk
+B14aSR4IhT/Mb3a6i2odWVdEbhCuT7A8fVETA55Z0HFKaj8uGOp9ObhIXaKrHGXR
+OWOAePNxlw9zq2nOCl/pK7HjLPHMp78t2Khw7awQlTMmTAQGlZdkcNdHY6+ptYG8
+0kd1/QKCAQAaosVB+5FK4UedByp3DjcsJmez8eZJundlc4g2PekNnVK9cpgjvZLS
+lFQMAcezoOGt9biw/c90P54IhEkKBCoC8WrbSl9a4aY6ZWzTo5NDizzXTUBuz1Zp
+opCCEfmJ10r+t0RVJX8O84hNDgmrYme/vA6kZX0ZyW3BB3w1bLUXS0j01C5l81Y9
+gkuFYYRAV7tLByLiSPJRgMFBQK7BErqzGHkOQflf8mjRAMBR4E+F25FC85r0gKCz
+5t45PHa6YpL/WL8M3YdNVDjsmgIQZ0hYMQwAOWMU5pQG/tMFLDWYo9CvqNTCf7Im
+6CNqU0PlMABBE4iSIMqR+ooPQlIjMzQZAoIBAQC9JulZdQJzjZSI5tBj+zPScJJQ
+s/+sRfQBy7SalPtc+oLYBP2Js9c1JsR4Dk2vC3V5z7BaL4Lg4YcFVRcz9B4yUVRm
+BL/E34XGLfn5KBI8NeqIvHiivvlAPgoHwHAVsqtE35E2sYjOYbnn1FEaNm6EKiL3
+Dv1auVdLlP3jALJIEwHPzc2ZOc/Sh/LolfajR427j5YlgbMAk5DdXuxz7t9qEcyk
+Nc8HFaoXiBP1jK+L5C4mVvGeI9xghNoJXhNywEmMa2Shab0pmtOMQWuvNMQa3gRC
+OKbaM3A6zjvAl3rjFRBrGORqbu1E/InLOSXWuB8knYVf8LkWEDRjOHqMO3pJ
+-----END RSA PRIVATE KEY-----
diff --git a/apex/com.android.telephony.pk8 b/apex/com.android.telephony.pk8
new file mode 100644
index 0000000..b15a884
--- /dev/null
+++ b/apex/com.android.telephony.pk8
Binary files differ
diff --git a/apex/com.android.telephony.x509.pem b/apex/com.android.telephony.x509.pem
new file mode 100644
index 0000000..8b45823
--- /dev/null
+++ b/apex/com.android.telephony.x509.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGKTCCBBGgAwIBAgIUCmopA1YmjspwjjHHjmtsDPqxBxgwDQYJKoZIhvcNAQEL
+BQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
+b2lkMR4wHAYDVQQDDBVjb20uYW5kcm9pZC50ZWxlcGhvbnkxIjAgBgkqhkiG9w0B
+CQEWE2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMTkxMjA0MDAzNjAxWhgPNDc1NzEw
+MzAwMDM2MDFaMIGiMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
+MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
+CwwHQW5kcm9pZDEeMBwGA1UEAwwVY29tLmFuZHJvaWQudGVsZXBob255MSIwIAYJ
+KoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4qQYe8S6yte4MUDF2/JBUulJLF15CdnALkDJuGYLRom2
+DxRpq2/IqX8gpwVfZCfVjtthKGMhsdLW9gI+oKck0eVB7Q2cU/WO+1Cr9cuKuT6B
+cfJUck125gRGmowWZomDXv1to6ZrGgqBlVGA546w3CNGXW/PoKr8im+xLEgD0TPA
+3jJCbxt2v2IDjMwPChHOF57y9wRkXN5aJHgwIvayReVy3Cko/rJOuPnNo2kLKI5u
+qfM4NovYNAzKbHHPCNzqhySoh2H0iTmHLby5bvXYh32ooGPmxrP6q8PubeNb+Xfc
+yY33tE74ityiqu/2FDuK2iZyL8EZkEWHbX4ddt/JREda1Mcnt95TUudqA28xHgC4
+wRYXLUADvKDVWOYu/ydWBes1iu7ZsEhy8oFdECsZGRQm2BkdmWAsMPUXRWeiaCQ4
+GFfpB38UPczY5GTgYwKAK3mmY5EeBKRu/hFMCfYGJvio2rUujRzIGOd6ovk+G/74
+Eqdbsphrkr6+UOCUrNOYUD0j7kDHVVDiWMoeKL6Qb+dFcewdDO1rRbZv8ZeExf6l
+vacfKKcEE+wls8jqof/y7cu+McGEn4R8+KKiRDcDQqLvZN4Q+CCtNRLiXA2KdrkB
+hKfhnTBBYfDNZA1WOhGrKM+Yb97ObgAgf2HuhZ2F40F3dRZ6w8yaURXAjkdCqycC
+AwEAAaNTMFEwHQYDVR0OBBYEFDCf58Ogbx07WK+hWEylNMxKYrj6MB8GA1UdIwQY
+MBaAFDCf58Ogbx07WK+hWEylNMxKYrj6MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggIBABoGWqoOfPBsXFYzP7aNhywhuCr6ddjAi3ss9vwod6JuVuVg
+Inuw1i/qPb/bO1JFEwYVH3w0JASMwzIl9h5sQv++z0P+cWsLW02AXyszb0jGD3CI
+ni/irO5PO0DdaTSHQWc8DEv0293EcqpKWmQDQ2XWH19rJ5f+Gx1046sFlUi633D2
+sFO5dG94pCtT/TcqwwkeEwA6cV2Re8F1AW8elal3sINBU5MI/OJ3GQDe+pqp9VTg
+xIEQfZ9oP6Ewl6Ect+M2hVG5X4mCk9HQL7aSuPKo2Ej6l3Xq4aQYlpO4wOVZgCJC
+chMbdAn2pjuk8+mDSR39hdIusOgr7zLZscmaGKyoxVz9KVNwd/mmu+9/mftGfYae
+RomF15hVnkhZAw21fSnhKry62+DuKt2WIyu5LqvTvRxFs0Hvoy3wrQY/oruHlgk1
+J1v1rXm3ZTrh2qv1XG8mOdTegurEvjkYQm0E38jdlkhByIHmhDdBARX2Aeb7Lrd8
+9k/7tr9+58+45punZBBMX6iW1xfwaCDF8xfZrrC96azXP6Kv/JZTxbfNm/dqHyKK
+zM2WhELaoJg7uFO9TC5eMsnBQzDoYXsr3Mu7nC7V1Bs/D7jYmFG0dG0LQJwUUGr1
+WqJT4LB0BMnzNrMH1hTQTBVYDlfn7c6fnihNBOWQt72x2GGFQsGAMUWb7pxC
+-----END CERTIFICATE-----
diff --git a/client/Android.bp b/client/Android.bp
new file mode 100644
index 0000000..45c6527
--- /dev/null
+++ b/client/Android.bp
@@ -0,0 +1,41 @@
+// 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
new file mode 100644
index 0000000..db3bb45
--- /dev/null
+++ b/client/AndroidManifest.xml
@@ -0,0 +1,658 @@
+<?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>
+ <intent-filter>
+ <action android:name="android.intent.action.DIAL_EMERGENCY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.DIAL_EMERGENCY" />
+ <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
new file mode 100644
index 0000000..381465e
--- /dev/null
+++ b/client/res/color/settings_text_color_primary.xml
@@ -0,0 +1,23 @@
+<?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
new file mode 100644
index 0000000..7fa4435
--- /dev/null
+++ b/client/res/color/settings_text_color_secondary.xml
@@ -0,0 +1,23 @@
+<?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
new file mode 100644
index 0000000..86cb894
--- /dev/null
+++ b/client/res/drawable-hdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/client/res/drawable-hdpi/ic_overflow_menu.png b/client/res/drawable-hdpi/ic_overflow_menu.png
new file mode 100644
index 0000000..262e9df
--- /dev/null
+++ b/client/res/drawable-hdpi/ic_overflow_menu.png
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
new file mode 100644
index 0000000..dc81cd1
--- /dev/null
+++ b/client/res/drawable-mdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/client/res/drawable-mdpi/ic_overflow_menu.png b/client/res/drawable-mdpi/ic_overflow_menu.png
new file mode 100644
index 0000000..0e720dd
--- /dev/null
+++ b/client/res/drawable-mdpi/ic_overflow_menu.png
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
new file mode 100644
index 0000000..4f4fbaa
--- /dev/null
+++ b/client/res/drawable-xhdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/client/res/drawable-xhdpi/ic_overflow_menu.png b/client/res/drawable-xhdpi/ic_overflow_menu.png
new file mode 100644
index 0000000..9156076
--- /dev/null
+++ b/client/res/drawable-xhdpi/ic_overflow_menu.png
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
new file mode 100644
index 0000000..46e90f7
--- /dev/null
+++ b/client/res/drawable-xxhdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/client/res/drawable-xxhdpi/ic_overflow_menu.png b/client/res/drawable-xxhdpi/ic_overflow_menu.png
new file mode 100644
index 0000000..92526f5
--- /dev/null
+++ b/client/res/drawable-xxhdpi/ic_overflow_menu.png
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
new file mode 100644
index 0000000..3b72636
--- /dev/null
+++ b/client/res/drawable-xxxhdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/client/res/drawable-xxxhdpi/ic_overflow_menu.png b/client/res/drawable-xxxhdpi/ic_overflow_menu.png
new file mode 100644
index 0000000..9028bd4
--- /dev/null
+++ b/client/res/drawable-xxxhdpi/ic_overflow_menu.png
Binary files differ
diff --git a/client/res/drawable/ic_back_arrow.xml b/client/res/drawable/ic_back_arrow.xml
new file mode 100644
index 0000000..72997b0
--- /dev/null
+++ b/client/res/drawable/ic_back_arrow.xml
@@ -0,0 +1,20 @@
+<?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
new file mode 100644
index 0000000..0467d6b
--- /dev/null
+++ b/client/res/drawable/overflow_menu.xml
@@ -0,0 +1,20 @@
+<?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
new file mode 100644
index 0000000..64eff00
--- /dev/null
+++ b/client/res/mipmap-hdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/client/res/mipmap-hdpi/ic_launcher_phone.png b/client/res/mipmap-hdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..15c4142
--- /dev/null
+++ b/client/res/mipmap-hdpi/ic_launcher_phone.png
Binary files differ
diff --git a/client/res/mipmap-mdpi/ic_launcher_contacts.png b/client/res/mipmap-mdpi/ic_launcher_contacts.png
new file mode 100644
index 0000000..b4ee821
--- /dev/null
+++ b/client/res/mipmap-mdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/client/res/mipmap-mdpi/ic_launcher_phone.png b/client/res/mipmap-mdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..3088f75
--- /dev/null
+++ b/client/res/mipmap-mdpi/ic_launcher_phone.png
Binary files differ
diff --git a/client/res/mipmap-xhdpi/ic_launcher_contacts.png b/client/res/mipmap-xhdpi/ic_launcher_contacts.png
new file mode 100644
index 0000000..6feeadf
--- /dev/null
+++ b/client/res/mipmap-xhdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/client/res/mipmap-xhdpi/ic_launcher_phone.png b/client/res/mipmap-xhdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..e87de01
--- /dev/null
+++ b/client/res/mipmap-xhdpi/ic_launcher_phone.png
Binary files differ
diff --git a/client/res/mipmap-xxhdpi/ic_launcher_contacts.png b/client/res/mipmap-xxhdpi/ic_launcher_contacts.png
new file mode 100644
index 0000000..01a3fde
--- /dev/null
+++ b/client/res/mipmap-xxhdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/client/res/mipmap-xxhdpi/ic_launcher_phone.png b/client/res/mipmap-xxhdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..b866b79
--- /dev/null
+++ b/client/res/mipmap-xxhdpi/ic_launcher_phone.png
Binary files differ
diff --git a/client/res/mipmap-xxxhdpi/ic_launcher_contacts.png b/client/res/mipmap-xxxhdpi/ic_launcher_contacts.png
new file mode 100644
index 0000000..328e067
--- /dev/null
+++ b/client/res/mipmap-xxxhdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/client/res/mipmap-xxxhdpi/ic_launcher_phone.png b/client/res/mipmap-xxxhdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..26f51f1
--- /dev/null
+++ b/client/res/mipmap-xxxhdpi/ic_launcher_phone.png
Binary files differ
diff --git a/client/res/values/attrs.xml b/client/res/values/attrs.xml
new file mode 100644
index 0000000..b4ef5d0
--- /dev/null
+++ b/client/res/values/attrs.xml
@@ -0,0 +1,31 @@
+<?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
new file mode 100644
index 0000000..4cf4bd0
--- /dev/null
+++ b/client/res/values/colors.xml
@@ -0,0 +1,44 @@
+<?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
new file mode 100644
index 0000000..c6acbd7
--- /dev/null
+++ b/client/res/values/dimens.xml
@@ -0,0 +1,24 @@
+<?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
new file mode 100644
index 0000000..1d002a2
--- /dev/null
+++ b/client/res/values/strings.xml
@@ -0,0 +1,90 @@
+<?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
new file mode 100644
index 0000000..f8aebd9
--- /dev/null
+++ b/client/res/values/styles.xml
@@ -0,0 +1,145 @@
+<?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/ecc/conversion_toolset_v1/proto/Android.bp b/ecc/conversion_toolset_v1/proto/Android.bp
index f633f90..e1e0643 100644
--- a/ecc/conversion_toolset_v1/proto/Android.bp
+++ b/ecc/conversion_toolset_v1/proto/Android.bp
@@ -22,7 +22,7 @@
],
},
srcs: ["protobuf_ecc_data.proto"],
- sdk_version: "core_platform",
+ sdk_version: "system_current",
jarjar_rules: "jarjar-rules.txt",
java_version: "1.8",
-}
\ No newline at end of file
+}
diff --git a/proguard.proguard b/proguard.proguard
new file mode 100644
index 0000000..2a823d8
--- /dev/null
+++ b/proguard.proguard
@@ -0,0 +1,7 @@
+-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/values-bs/strings.xml b/res/values-bs/strings.xml
index b6b778e..e2e6cfe 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -48,7 +48,7 @@
<string name="no_vm_number_msg" msgid="5165161462411372504">"Broj govorne pošte nije pohranjen na SIM kartici."</string>
<string name="add_vm_number_str" msgid="7368168964435881637">"Dodaj broj"</string>
<string name="voice_number_setting_primary_user_only" msgid="3394706575741912843">"Postavke govorne pošte može promijeniti samo Primarni korisnik."</string>
- <string name="puk_unlocked" msgid="4627340655215746511">"Vaša SIM kartica je odblokirana. Telefon se otključava…"</string>
+ <string name="puk_unlocked" msgid="4627340655215746511">"Vaša SIM kartica je deblokirana. Telefon se otključava…"</string>
<string name="label_ndp" msgid="7617392683877410341">"PIN za otključavanje mreže na SIM kartici"</string>
<string name="sim_ndp_unlock_text" msgid="7737338355451978338">"Otključaj"</string>
<string name="sim_ndp_dismiss_text" msgid="89667342248929777">"Odbaci"</string>
@@ -95,10 +95,10 @@
<string name="sum_loading_settings" msgid="434063780286688775">"Učitavanje postavki…"</string>
<string name="sum_hide_caller_id" msgid="131100328602371933">"Broj je skriven u odlaznim pozivima"</string>
<string name="sum_show_caller_id" msgid="3571854755324664591">"Broj je prikazan u odlaznim pozivima"</string>
- <string name="sum_default_caller_id" msgid="1767070797135682959">"Koristi zadane postavke operatera za prikaz mog broja u odlaznim pozivima"</string>
+ <string name="sum_default_caller_id" msgid="1767070797135682959">"Koristite zadane postavke operatera za prikaz broja u odlaznim pozivima"</string>
<string name="labelCW" msgid="8449327023861428622">"Poziv na čekanju"</string>
- <string name="sum_cw_enabled" msgid="3977308526187139996">"Tokom poziva, obavijesti me o dolaznim pozivima"</string>
- <string name="sum_cw_disabled" msgid="3658094589461768637">"Tokom poziva, obavijesti me o dolaznim pozivima"</string>
+ <string name="sum_cw_enabled" msgid="3977308526187139996">"Obavijesti me o dolaznim pozivima tokom poziva"</string>
+ <string name="sum_cw_disabled" msgid="3658094589461768637">"Obavijesti me o dolaznim pozivima tokom poziva"</string>
<string name="call_forwarding_settings" msgid="8937130467468257671">"Postavke prosljeđivanja poziva"</string>
<string name="call_forwarding_settings_with_label" msgid="2345432813399564272">"Postavke prosljeđivanja poziva (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
<string name="labelCF" msgid="3578719437928476078">"Prosljeđivanje poziva"</string>
@@ -136,7 +136,7 @@
<string name="stk_cc_ss_to_ussd_error" msgid="8330749347425752192">"SS zahtjev je izmijenjen u USSD zahtjev"</string>
<string name="stk_cc_ss_to_ss_error" msgid="8297155544652134278">"Izmijenjeno u novi SS zahtjev"</string>
<string name="stk_cc_ss_to_dial_video_error" msgid="4255261231466032505">"SS zahtjev je izmijenjen u video poziv"</string>
- <string name="fdn_check_failure" msgid="1833769746374185247">"Uključena je postavka brojeva fiksnog biranja u aplikaciji Telefon. Zbog toga ne rade neke funkcije vezane za pozive."</string>
+ <string name="fdn_check_failure" msgid="1833769746374185247">"Uključena je postavka brojeva fiksnog biranja u aplikaciji Telefon. Zbog toga ne rade neke funkcije u vezi s pozivima."</string>
<string name="radio_off_error" msgid="8321564164914232181">"Uključite radio prije prikazivanja ovih postavki."</string>
<string name="close_dialog" msgid="1074977476136119408">"Uredu"</string>
<string name="enable" msgid="2636552299455477603">"Uključi"</string>
@@ -179,7 +179,7 @@
<string name="network_select_title" msgid="4117305053881611988">"Mreža"</string>
<string name="register_automatically" msgid="3907580547590554834">"Automatska registracija…"</string>
<string name="preferred_network_mode_title" msgid="5253395265169539830">"Preferirana vrsta mreže"</string>
- <string name="preferred_network_mode_summary" msgid="3787989000044330064">"Promijeni način rada mreže"</string>
+ <string name="preferred_network_mode_summary" msgid="3787989000044330064">"Promijenite način rada mreže"</string>
<string name="preferred_network_mode_dialogtitle" msgid="2781447433514459696">"Preferirana vrsta mreže"</string>
<string name="forbidden_network" msgid="5081729819561333023">"(zabranjeno)"</string>
<string name="choose_network_title" msgid="5335832663422653082">"Odaberite mrežu"</string>
@@ -242,8 +242,8 @@
<string name="network_operator_category" msgid="4992217193732304680">"Mreža"</string>
<string name="enhanced_4g_lte_mode_title" msgid="4213420368777080540">"Poboljšani 4G LTE način rada"</string>
<!-- no translation found for enhanced_4g_lte_mode_title_variant:0 (7240155150166394308) -->
- <string name="enhanced_4g_lte_mode_summary" msgid="7725708511804143638">"Koristi LTE usluge za poboljšanje glasovne i drugih komunikacija (preporučeno)"</string>
- <string name="enhanced_4g_lte_mode_summary_o2" msgid="2521108446409016542">"Koristi 4G usluge za poboljšanje glasovne i drugih komunikacija (preporučeno)"</string>
+ <string name="enhanced_4g_lte_mode_summary" msgid="7725708511804143638">"Koristite LTE usluge za poboljšanje glasovne i drugih komunikacija (preporučeno)"</string>
+ <string name="enhanced_4g_lte_mode_summary_o2" msgid="2521108446409016542">"Koristite 4G usluge za poboljšanje glasovne i drugih komunikacija (preporučeno)"</string>
<!-- no translation found for enhanced_4g_lte_mode_sumary_variant:0 (2943982616649705147) -->
<!-- no translation found for enhanced_4g_lte_mode_sumary_variant:1 (5262249464504131443) -->
<!-- no translation found for enhanced_4g_lte_mode_sumary_variant:2 (6356974241850241718) -->
@@ -381,7 +381,7 @@
<string name="network_4G" msgid="6800527815504223913">"4G (preporučeno)"</string>
<string name="network_global" msgid="3289646154407617631">"Globalno"</string>
<string name="cdma_system_select_title" msgid="614165233552656431">"Odabir sistema"</string>
- <string name="cdma_system_select_summary" msgid="3840420390242060407">"Promijeni način rada CDMA rominga"</string>
+ <string name="cdma_system_select_summary" msgid="3840420390242060407">"Promijenite način rada CDMA rominga"</string>
<string name="cdma_system_select_dialogtitle" msgid="5524639510676501802">"Odabir sistema"</string>
<string-array name="cdma_system_select_choices">
<item msgid="462340042928284921">"Samo kuća"</item>
@@ -413,15 +413,15 @@
<string name="change_pin2" msgid="3110844547237754871">"Promijeni PIN2"</string>
<string name="enable_fdn_ok" msgid="5080925177369329827">"Onemogući FDN"</string>
<string name="disable_fdn_ok" msgid="3745475926874838676">"Omogući FDN"</string>
- <string name="sum_fdn" msgid="6152246141642323582">"Upravljaj brojevima fiksnog biranja"</string>
+ <string name="sum_fdn" msgid="6152246141642323582">"Upravljajte brojevima fiksnog biranja"</string>
<string name="sum_fdn_change_pin" msgid="3510994280557335727">"Promjena PIN-a za FDN pristup"</string>
<string name="sum_fdn_manage_list" msgid="3311397063233992907">"Upravljanje listom brojeva telefona"</string>
<string name="voice_privacy" msgid="7346935172372181951">"Privatnost glasa"</string>
<string name="voice_privacy_summary" msgid="3556460926168473346">"Omogući poboljšani naćin rada za privatnost"</string>
<string name="tty_mode_option_title" msgid="3843817710032641703">"Način rada TTY"</string>
- <string name="tty_mode_option_summary" msgid="4770510287236494371">"Postavi način rada TTY"</string>
+ <string name="tty_mode_option_summary" msgid="4770510287236494371">"Postavite način rada TTY"</string>
<string name="auto_retry_mode_title" msgid="2985801935424422340">"Automatski ponovni pokušaj"</string>
- <string name="auto_retry_mode_summary" msgid="2863919925349511402">"Omogući način rada za automatski ponovni pokušaj"</string>
+ <string name="auto_retry_mode_summary" msgid="2863919925349511402">"Omogućite način rada za automatski ponovni pokušaj"</string>
<string name="tty_mode_not_allowed_video_call" msgid="6551976083652752815">"Promjena načina rada TTY nije dozvoljena tokom video poziva"</string>
<string name="menu_add" msgid="5616487894975773141">"Dodaj kontakt"</string>
<string name="menu_edit" msgid="3593856941552460706">"Uredi kontakt"</string>
@@ -509,11 +509,11 @@
<string name="incall_error_call_failed" msgid="393508653582682539">"Poziv nije uspio."</string>
<string name="incall_error_cannot_add_call" msgid="5425764862628655443">"Trenutno nije moguće dodati poziv. Možete pokušati poslati poruku."</string>
<string name="incall_error_supp_service_unknown" msgid="8751177117194592623">"Usluga nije podržana"</string>
- <string name="incall_error_supp_service_switch" msgid="5272822448189448479">"Nije moguće prebacivanje poziva."</string>
+ <string name="incall_error_supp_service_switch" msgid="5272822448189448479">"Nije moguće prebacivati pozive."</string>
<string name="incall_error_supp_service_resume" msgid="1276861499306817035">"Nije moguće nastaviti poziv."</string>
<string name="incall_error_supp_service_separate" msgid="8932660028965274353">"Nije moguće odvojiti poziv."</string>
<string name="incall_error_supp_service_transfer" msgid="8211925891867334323">"Prijenos nije moguć."</string>
- <string name="incall_error_supp_service_conference" msgid="27578082433544702">"Nije moguće spajanje poziva."</string>
+ <string name="incall_error_supp_service_conference" msgid="27578082433544702">"Nije moguće spajati pozive."</string>
<string name="incall_error_supp_service_reject" msgid="3044363092441655912">"Nije moguće odbiti poziv."</string>
<string name="incall_error_supp_service_hangup" msgid="836524952243836735">"Nije moguće uputiti poziv(e)."</string>
<string name="incall_error_supp_service_hold" msgid="8535056414643540997">"Nije moguće staviti pozive na čekanje."</string>
@@ -568,7 +568,7 @@
<item msgid="2131559553795606483">"TTY VCO"</item>
</string-array>
<string name="dtmf_tones_title" msgid="7874845461117175236">"DTMF tonovi"</string>
- <string name="dtmf_tones_summary" msgid="2294822239899471201">"Postavi dužinu DTMF tonova"</string>
+ <string name="dtmf_tones_summary" msgid="2294822239899471201">"Postavite dužinu DTMF tonova"</string>
<string-array name="dtmf_tone_entries">
<item msgid="2271798469250155310">"Normalno"</item>
<item msgid="6044210222666533564">"Dugo"</item>
@@ -588,7 +588,7 @@
<string name="ota_listen" msgid="2772252405488894280">"Slijedite govorna uputstva dok ne čujete da je aktivacija završena."</string>
<string name="ota_speaker" msgid="1086766980329820528">"Zvučnik"</string>
<string name="ota_progress" msgid="8837259285255700132">"Programiranje telefona u toku…"</string>
- <string name="ota_failure" msgid="5674217489921481576">"Nije moguće programirati telefon"</string>
+ <string name="ota_failure" msgid="5674217489921481576">"Programiranje telefona nije uspjelo"</string>
<string name="ota_successful" msgid="1106825981548107774">"Vaš telefon je sada aktiviran. Može biti potrebno do 15 minuta za pokretanje usluge."</string>
<string name="ota_unsuccessful" msgid="8531037653803955754">"Telefon se nije aktivirao. \nMožda biste trebali pronaći područje s boljom pokrivenošću (pored prozora ili napolju).\n\nPokušajte ponovo ili pozovite službu za korisnike za više opcija."</string>
<string name="ota_spc_failure" msgid="904092035241370080">"GREŠKE PRETJERANOG SPC-a"</string>
@@ -646,7 +646,7 @@
<string name="message_decode_error" msgid="1061856591500290887">"Došlo je do greške prilikom dekodiranja poruke."</string>
<string name="callFailed_cdma_activation" msgid="5392057031552253550">"SIM kartica je aktivirala vašu uslugu i ažurirala mogućnosti rominga za telefon."</string>
<string name="callFailed_cdma_call_limit" msgid="1074219746093031412">"Previše aktivnih poziva. Prekinite ili spojite postojeće pozive prije upućivanja novog poziva."</string>
- <string name="callFailed_imei_not_accepted" msgid="7257903653685147251">"Povezivanje nije uspjelo, umetnite važeću SIM karticu."</string>
+ <string name="callFailed_imei_not_accepted" msgid="7257903653685147251">"Nije moguće povezati, umetnite važeću SIM karticu."</string>
<string name="callFailed_wifi_lost" msgid="1788036730589163141">"WiFi veza je prekinuta. Poziv je završen."</string>
<string name="dialFailed_low_battery" msgid="6857904237423407056">"Upućivanje video poziva nije moguće zbog istrošenosti baterije."</string>
<string name="callFailed_low_battery" msgid="4056828320214416182">"Video poziv je završen zbog istrošenosti baterije."</string>
@@ -683,54 +683,54 @@
<string name="clh_callFailed_simError_txt" msgid="5128538525762326413">"Nije moguće pristupiti SIM kartici"</string>
<string name="clh_incall_error_out_of_service_txt" msgid="2736010617446749869">"Mobilna mreža nije dostupna"</string>
<string name="clh_callFailed_unassigned_number_txt" msgid="141967660286695682">"Problem s brojem telefona koji pokušavate birati. Kȏd greške 1."</string>
- <string name="clh_callFailed_no_route_to_destination_txt" msgid="4805015149822352308">"Nije moguće završiti poziv. Kôd greške 3."</string>
- <string name="clh_callFailed_channel_unacceptable_txt" msgid="4062754579408613021">"Nije moguće završiti poziv. Kôd greške 6."</string>
- <string name="clh_callFailed_operator_determined_barring_txt" msgid="4202077821465974286">"Nije moguće završiti poziv. Kôd greške 8."</string>
- <string name="clh_callFailed_normal_call_clearing_txt" msgid="5677987959062976462">"Nije moguće završiti poziv. Kôd greške 16."</string>
+ <string name="clh_callFailed_no_route_to_destination_txt" msgid="4805015149822352308">"Završavanje poziva nije uspjelo. Kôd greške 3."</string>
+ <string name="clh_callFailed_channel_unacceptable_txt" msgid="4062754579408613021">"Završavanje poziva nije uspjelo. Kôd greške 6."</string>
+ <string name="clh_callFailed_operator_determined_barring_txt" msgid="4202077821465974286">"Završavanje poziva nije uspjelo. Kôd greške 8."</string>
+ <string name="clh_callFailed_normal_call_clearing_txt" msgid="5677987959062976462">"Završavanje poziva nije uspjelo. Kôd greške 16."</string>
<string name="clh_callFailed_user_busy_txt" msgid="8886432858568086854">"Korisnik je zauzet"</string>
<string name="clh_callFailed_no_user_responding_txt" msgid="341100226919865128">"Korisnik ne odgovara"</string>
- <string name="clh_callFailed_user_alerting_txt" msgid="896082976264427969">"Nije moguće završiti poziv. Kôd greške 19."</string>
+ <string name="clh_callFailed_user_alerting_txt" msgid="896082976264427969">"Završavanje poziva nije uspjelo. Kôd greške 19."</string>
<string name="clh_callFailed_call_rejected_txt" msgid="3439435671153341709">"Poziv je odbijen"</string>
<string name="clh_callFailed_number_changed_txt" msgid="2868476949771441667">"Broj je promijenjen"</string>
- <string name="clh_callFailed_pre_emption_txt" msgid="8887998866342162724">"Nije moguće završiti poziv. Kôd greške 25."</string>
- <string name="clh_callFailed_non_selected_user_clearing_txt" msgid="4804529874810197550">"Nije moguće završiti poziv. Kôd greške 26."</string>
- <string name="clh_callFailed_destination_out_of_order_txt" msgid="1130697076352728824">"Nije moguće završiti poziv. Kôd greške 27."</string>
+ <string name="clh_callFailed_pre_emption_txt" msgid="8887998866342162724">"Završavanje poziva nije uspjelo. Kôd greške 25."</string>
+ <string name="clh_callFailed_non_selected_user_clearing_txt" msgid="4804529874810197550">"Završavanje poziva nije uspjelo. Kôd greške 26."</string>
+ <string name="clh_callFailed_destination_out_of_order_txt" msgid="1130697076352728824">"Završavanje poziva nije uspjelo. Kôd greške 27."</string>
<string name="clh_callFailed_invalid_number_format_txt" msgid="3171016382987224989">"Nevažeći format broja (nepotpun broj)"</string>
- <string name="clh_callFailed_facility_rejected_txt" msgid="1054386430010898993">"Nije moguće završiti poziv. Kôd greške 29."</string>
- <string name="clh_callFailed_response_to_STATUS_ENQUIRY_txt" msgid="2763172551412307536">"Nije moguće završiti poziv. Kôd greške 30."</string>
- <string name="clh_callFailed_normal_unspecified_txt" msgid="978119938935737419">"Nije moguće završiti poziv. Kôd greške 31."</string>
- <string name="clh_callFailed_no_circuit_available_txt" msgid="1519684050419134605">"Nije moguće završiti poziv. Kôd greške 34."</string>
- <string name="clh_callFailed_network_out_of_order_txt" msgid="8689826504394592289">"Nije moguće završiti poziv. Kôd greške 38."</string>
- <string name="clh_callFailed_temporary_failure_txt" msgid="5065091554509067874">"Nije moguće završiti poziv. Kôd greške 41."</string>
- <string name="clh_callFailed_switching_equipment_congestion_txt" msgid="8681599376741988769">"Nije moguće završiti poziv. Kôd greške 42."</string>
- <string name="clh_callFailed_access_information_discarded_txt" msgid="2476199425130545428">"Nije moguće završiti poziv. Kôd greške 43."</string>
- <string name="clh_callFailed_requested_circuit_txt" msgid="7497497808928490219">"Nije moguće završiti poziv. Kôd greške 44."</string>
- <string name="clh_callFailed_resources_unavailable_unspecified_txt" msgid="144010529672928445">"Nije moguće završiti poziv. Kôd greške 47."</string>
- <string name="clh_callFailed_quality_of_service_unavailable_txt" msgid="4650329342288289290">"Nije moguće završiti poziv. Kôd greške 49."</string>
- <string name="clh_callFailed_requested_facility_not_subscribed_txt" msgid="9107977008516882170">"Nije moguće završiti poziv. Kôd greške 50."</string>
- <string name="clh_callFailed_incoming_calls_barred_within_the_CUG_txt" msgid="501037491908315591">"Nije moguće završiti poziv. Kôd greške 55."</string>
- <string name="clh_callFailed_bearer_capability_not_authorized_txt" msgid="4344366517528362620">"Nije moguće završiti poziv. Kôd greške 57."</string>
- <string name="clh_callFailed_bearer_capability_not_presently_available_txt" msgid="1436957294571545381">"Nije moguće završiti poziv. Kôd greške 58."</string>
- <string name="clh_callFailed_service_or_option_not_available_unspecified_txt" msgid="2149878874722675428">"Nije moguće završiti poziv. Kôd greške 63."</string>
- <string name="clh_callFailed_bearer_service_not_implemented_txt" msgid="1074983013965612410">"Nije moguće završiti poziv. Kôd greške 65."</string>
- <string name="clh_callFailed_ACM_equal_to_or_greater_than_ACMmax_txt" msgid="7889034195264205333">"Nije moguće završiti poziv. Kôd greške 68."</string>
- <string name="clh_callFailed_requested_facility_not_implemented_txt" msgid="7996646684699167978">"Nije moguće završiti poziv. Kôd greške 69."</string>
- <string name="clh_callFailed_only_restricted_digital_information_bearer_capability_is_available_txt" msgid="2358958110447385682">"Nije moguće završiti poziv. Kôd greške 70."</string>
- <string name="clh_callFailed_service_or_option_not_implemented_unspecified_txt" msgid="3046428509531159481">"Nije moguće završiti poziv. Kôd greške 79."</string>
- <string name="clh_callFailed_invalid_transaction_identifier_value_txt" msgid="1727401871777396619">"Nije moguće završiti poziv. Kôd greške 81."</string>
- <string name="clh_callFailed_user_not_member_of_CUG_txt" msgid="442282135105229307">"Nije moguće završiti poziv. Kôd greške 87."</string>
- <string name="clh_callFailed_incompatible_destination_txt" msgid="5900394706344969020">"Nije moguće završiti poziv. Kôd greške 88."</string>
- <string name="clh_callFailed_invalid_transit_network_selection_txt" msgid="6274621838349037741">"Nije moguće završiti poziv. Kôd greške 91."</string>
- <string name="clh_callFailed_semantically_incorrect_message_txt" msgid="7000705190197981937">"Nije moguće završiti poziv. Kôd greške 95."</string>
- <string name="clh_callFailed_invalid_mandatory_information_txt" msgid="3609204152671052123">"Nije moguće završiti poziv. Kôd greške 96."</string>
- <string name="clh_callFailed_message_type_non_existent_or_not_implemented_txt" msgid="1552110431052032814">"Nije moguće završiti poziv. Kôd greške 97."</string>
- <string name="clh_callFailed_message_type_not_compatible_with_protocol_state_txt" msgid="7717048934226300032">"Nije moguće završiti poziv. Kôd greške 98."</string>
- <string name="clh_callFailed_information_element_non_existent_or_not_implemented_txt" msgid="8931396541061612169">"Nije moguće završiti poziv. Kôd greške 99."</string>
- <string name="clh_callFailed_conditional_IE_error_txt" msgid="4630685477888727741">"Nije moguće završiti poziv. Kôd greške 100."</string>
- <string name="clh_callFailed_message_not_compatible_with_protocol_state_txt" msgid="3014075977395922947">"Nije moguće završiti poziv. Kôd greške 101."</string>
- <string name="clh_callFailed_recovery_on_timer_expiry_txt" msgid="5637581978978731672">"Nije moguće završiti poziv. Kôd greške 102."</string>
- <string name="clh_callFailed_protocol_Error_unspecified_txt" msgid="9203320572562697755">"Nije moguće završiti poziv. Kôd greške 111."</string>
- <string name="clh_callFailed_interworking_unspecified_txt" msgid="7969686413930847182">"Nije moguće završiti poziv. Kôd greške 127."</string>
+ <string name="clh_callFailed_facility_rejected_txt" msgid="1054386430010898993">"Završavanje poziva nije uspjelo. Kôd greške 29."</string>
+ <string name="clh_callFailed_response_to_STATUS_ENQUIRY_txt" msgid="2763172551412307536">"Završavanje poziva nije uspjelo. Kôd greške 30."</string>
+ <string name="clh_callFailed_normal_unspecified_txt" msgid="978119938935737419">"Završavanje poziva nije uspjelo. Kôd greške 31."</string>
+ <string name="clh_callFailed_no_circuit_available_txt" msgid="1519684050419134605">"Završavanje poziva nije uspjelo. Kôd greške 34."</string>
+ <string name="clh_callFailed_network_out_of_order_txt" msgid="8689826504394592289">"Završavanje poziva nije uspjelo. Kôd greške 38."</string>
+ <string name="clh_callFailed_temporary_failure_txt" msgid="5065091554509067874">"Završavanje poziva nije uspjelo. Kôd greške 41."</string>
+ <string name="clh_callFailed_switching_equipment_congestion_txt" msgid="8681599376741988769">"Završavanje poziva nije uspjelo. Kôd greške 42."</string>
+ <string name="clh_callFailed_access_information_discarded_txt" msgid="2476199425130545428">"Završavanje poziva nije uspjelo. Kôd greške 43."</string>
+ <string name="clh_callFailed_requested_circuit_txt" msgid="7497497808928490219">"Završavanje poziva nije uspjelo. Kôd greške 44."</string>
+ <string name="clh_callFailed_resources_unavailable_unspecified_txt" msgid="144010529672928445">"Završavanje poziva nije uspjelo. Kôd greške 47."</string>
+ <string name="clh_callFailed_quality_of_service_unavailable_txt" msgid="4650329342288289290">"Završavanje poziva nije uspjelo. Kôd greške 49."</string>
+ <string name="clh_callFailed_requested_facility_not_subscribed_txt" msgid="9107977008516882170">"Završavanje poziva nije uspjelo. Kôd greške 50."</string>
+ <string name="clh_callFailed_incoming_calls_barred_within_the_CUG_txt" msgid="501037491908315591">"Završavanje poziva nije uspjelo. Kôd greške 55."</string>
+ <string name="clh_callFailed_bearer_capability_not_authorized_txt" msgid="4344366517528362620">"Završavanje poziva nije uspjelo. Kôd greške 57."</string>
+ <string name="clh_callFailed_bearer_capability_not_presently_available_txt" msgid="1436957294571545381">"Završavanje poziva nije uspjelo. Kôd greške 58."</string>
+ <string name="clh_callFailed_service_or_option_not_available_unspecified_txt" msgid="2149878874722675428">"Završavanje poziva nije uspjelo. Kôd greške 63."</string>
+ <string name="clh_callFailed_bearer_service_not_implemented_txt" msgid="1074983013965612410">"Završavanje poziva nije uspjelo. Kôd greške 65."</string>
+ <string name="clh_callFailed_ACM_equal_to_or_greater_than_ACMmax_txt" msgid="7889034195264205333">"Završavanje poziva nije uspjelo. Kôd greške 68."</string>
+ <string name="clh_callFailed_requested_facility_not_implemented_txt" msgid="7996646684699167978">"Završavanje poziva nije uspjelo. Kôd greške 69."</string>
+ <string name="clh_callFailed_only_restricted_digital_information_bearer_capability_is_available_txt" msgid="2358958110447385682">"Završavanje poziva nije uspjelo. Kôd greške 70."</string>
+ <string name="clh_callFailed_service_or_option_not_implemented_unspecified_txt" msgid="3046428509531159481">"Završavanje poziva nije uspjelo. Kôd greške 79."</string>
+ <string name="clh_callFailed_invalid_transaction_identifier_value_txt" msgid="1727401871777396619">"Završavanje poziva nije uspjelo. Kôd greške 81."</string>
+ <string name="clh_callFailed_user_not_member_of_CUG_txt" msgid="442282135105229307">"Završavanje poziva nije uspjelo. Kôd greške 87."</string>
+ <string name="clh_callFailed_incompatible_destination_txt" msgid="5900394706344969020">"Završavanje poziva nije uspjelo. Kôd greške 88."</string>
+ <string name="clh_callFailed_invalid_transit_network_selection_txt" msgid="6274621838349037741">"Završavanje poziva nije uspjelo. Kôd greške 91."</string>
+ <string name="clh_callFailed_semantically_incorrect_message_txt" msgid="7000705190197981937">"Završavanje poziva nije uspjelo. Kôd greške 95."</string>
+ <string name="clh_callFailed_invalid_mandatory_information_txt" msgid="3609204152671052123">"Završavanje poziva nije uspjelo. Kôd greške 96."</string>
+ <string name="clh_callFailed_message_type_non_existent_or_not_implemented_txt" msgid="1552110431052032814">"Završavanje poziva nije uspjelo. Kôd greške 97."</string>
+ <string name="clh_callFailed_message_type_not_compatible_with_protocol_state_txt" msgid="7717048934226300032">"Završavanje poziva nije uspjelo. Kôd greške 98."</string>
+ <string name="clh_callFailed_information_element_non_existent_or_not_implemented_txt" msgid="8931396541061612169">"Završavanje poziva nije uspjelo. Kôd greške 99."</string>
+ <string name="clh_callFailed_conditional_IE_error_txt" msgid="4630685477888727741">"Završavanje poziva nije uspjelo. Kôd greške 100."</string>
+ <string name="clh_callFailed_message_not_compatible_with_protocol_state_txt" msgid="3014075977395922947">"Završavanje poziva nije uspjelo. Kôd greške 101."</string>
+ <string name="clh_callFailed_recovery_on_timer_expiry_txt" msgid="5637581978978731672">"Završavanje poziva nije uspjelo. Kôd greške 102."</string>
+ <string name="clh_callFailed_protocol_Error_unspecified_txt" msgid="9203320572562697755">"Završavanje poziva nije uspjelo. Kôd greške 111."</string>
+ <string name="clh_callFailed_interworking_unspecified_txt" msgid="7969686413930847182">"Završavanje poziva nije uspjelo. Kôd greške 127."</string>
<string name="labelCallBarring" msgid="4180377113052853173">"Zabrana poziva"</string>
<string name="sum_call_barring_enabled" msgid="5184331188926370824">"Uključeno"</string>
<string name="sum_call_barring_disabled" msgid="5699448000600153096">"Isključeno"</string>
@@ -872,7 +872,7 @@
<string name="radio_info_toggle_dns_check_label" msgid="1394078554927787350">"Uključi/isključi provjeru DNS-a"</string>
<string name="oem_radio_info_label" msgid="2914167475119997456">"OEM-specifične informacije/postavke"</string>
<string name="band_mode_title" msgid="7988822920724576842">"Postavite način radijskog opsega"</string>
- <string name="band_mode_loading" msgid="795923726636735967">"Učitavanje spiska opsega…"</string>
+ <string name="band_mode_loading" msgid="795923726636735967">"Učitavanje liste opsega…"</string>
<string name="band_mode_set" msgid="6657819412803771421">"Postavi"</string>
<string name="band_mode_failed" msgid="1707488541847192924">"Neuspješno"</string>
<string name="band_mode_succeeded" msgid="2230018000534761063">"Uspješno"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index a3bf0d1..708d96a 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -132,10 +132,10 @@
<string name="reverting_settings" msgid="7378668837291012205">"Einstellungen werden zurückgesetzt..."</string>
<string name="response_error" msgid="3904481964024543330">"Unerwartete Antwort von Netzwerk"</string>
<string name="exception_error" msgid="330994460090467">"Netzwerk- oder SIM-Kartenfehler."</string>
- <string name="stk_cc_ss_to_dial_error" msgid="5147693491690618704">"SS-Anfrage wurde in normalen Anruf geändert"</string>
- <string name="stk_cc_ss_to_ussd_error" msgid="8330749347425752192">"SS-Anfrage wurde in USSD-Anfrage geändert"</string>
- <string name="stk_cc_ss_to_ss_error" msgid="8297155544652134278">"In neue SS-Anfrage geändert"</string>
- <string name="stk_cc_ss_to_dial_video_error" msgid="4255261231466032505">"SS-Anfrage wurde in Videoanruf geändert"</string>
+ <string name="stk_cc_ss_to_dial_error" msgid="5147693491690618704">"SS-Anforderung wurde in normalen Anruf geändert"</string>
+ <string name="stk_cc_ss_to_ussd_error" msgid="8330749347425752192">"SS-Anforderung wurde in USSD-Anforderung geändert"</string>
+ <string name="stk_cc_ss_to_ss_error" msgid="8297155544652134278">"In neue SS-Anforderung geändert"</string>
+ <string name="stk_cc_ss_to_dial_video_error" msgid="4255261231466032505">"SS-Anforderung wurde in Videoanruf geändert"</string>
<string name="fdn_check_failure" msgid="1833769746374185247">"Da die Rufnummernbeschränkung in deiner Telefon-App aktiviert ist, funktionieren nicht alle Anruffunktionen."</string>
<string name="radio_off_error" msgid="8321564164914232181">"Aktiviere deine Mobilfunkverbindung, bevor du diese Einstellungen anzeigst."</string>
<string name="close_dialog" msgid="1074977476136119408">"Ok"</string>
@@ -317,11 +317,11 @@
<string name="regional_enable" msgid="7730109417536296079">"Regionalnachrichten aktiviert"</string>
<string name="regional_disable" msgid="3781951818157772545">"Regionalnachrichten deaktiviert"</string>
<string name="enable_disable_national" msgid="6198481711934897632">"National"</string>
- <string name="national_enable" msgid="5159683504138239304">"Nationale Nachrichten aktiviert"</string>
- <string name="national_disable" msgid="8484356368757118987">"Nationale Nachrichten deaktiviert"</string>
+ <string name="national_enable" msgid="5159683504138239304">"Inlandsnachrichten aktiviert"</string>
+ <string name="national_disable" msgid="8484356368757118987">"Inlandsnachrichten deaktiviert"</string>
<string name="enable_disable_international" msgid="4204334217211198792">"International"</string>
- <string name="international_enable" msgid="8943466745792690340">"Internationale Nachrichten aktiviert"</string>
- <string name="international_disable" msgid="4803498658100318265">"Internationale Nachrichten deaktiviert"</string>
+ <string name="international_enable" msgid="8943466745792690340">"Auslandsnachrichten aktiviert"</string>
+ <string name="international_disable" msgid="4803498658100318265">"Auslandsnachrichten deaktiviert"</string>
<string name="list_language_title" msgid="1850167908665485738">"Sprache"</string>
<string name="list_language_summary" msgid="7921756070782277559">"Sprache für Nachrichten auswählen"</string>
<string-array name="list_language_entries">
@@ -575,7 +575,7 @@
<item msgid="2271798469250155310">"Normal"</item>
<item msgid="6044210222666533564">"Lang"</item>
</string-array>
- <string name="network_info_message" msgid="7599413947016532355">"Netzwerknachricht"</string>
+ <string name="network_info_message" msgid="7599413947016532355">"Netznachricht"</string>
<string name="network_error_message" msgid="4271579424089326618">"Fehlermeldung"</string>
<string name="ota_title_activate" msgid="4049645324841263423">"Dein Telefon aktivieren"</string>
<string name="ota_touch_activate" msgid="838764494319694754">"Zur Aktivierung deines Telefondienstes muss ein spezieller Anruf getätigt werden. \n\nWähle \"Aktivieren\" und befolge die Anleitung zur Aktivierung deines Telefons."</string>
@@ -783,7 +783,7 @@
<string name="supp_service_forwarded_call" msgid="6475776013771821457">"Anruf weitergeleitet."</string>
<string name="supp_service_conference_call" msgid="4004193534408317148">"An Telefonkonferenz teilnehmen."</string>
<string name="supp_service_held_call_released" msgid="2847835124639112410">"Gehaltener Anruf wurde beendet."</string>
- <string name="callFailed_otasp_provisioning_in_process" msgid="3345666183602879326">"Der Anruf kann nicht getätigt werden, da das Gerät gerade bereitgestellt wird."</string>
+ <string name="callFailed_otasp_provisioning_in_process" msgid="3345666183602879326">"Der Anruf kann nicht getätigt werden, da das Gerät gerade provisioniert wird."</string>
<string name="callFailed_already_dialing" msgid="7250591188960691086">"Anruf nicht möglich, da bereits ein anderer ausgehender Anruf aufgebaut wird."</string>
<string name="callFailed_already_ringing" msgid="2376603543544289303">"Anruf nicht möglich, da ein nicht angenommener eingehender Anruf vorhanden ist. Nimm den eingehenden Anruf an oder lehne ihn ab, bevor du einen neuen Anruf startest."</string>
<string name="callFailed_calling_disabled" msgid="5010992739401206283">"Anruf nicht möglich, weil Anrufe über die Systemeigenschaft \"ro.telephony.disable-call\" deaktiviert wurden."</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 51b02a1..0bf4e1f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -44,10 +44,10 @@
<string name="pause_prompt_yes" msgid="8184132073048369575">"Sí"</string>
<string name="pause_prompt_no" msgid="2145264674774138579">"No"</string>
<string name="wild_prompt_str" msgid="5858910969703305375">"Reemplazar el carácter comodín con"</string>
- <string name="no_vm_number" msgid="6623853880546176930">"Falta el número de correo de voz"</string>
- <string name="no_vm_number_msg" msgid="5165161462411372504">"No hay un número de correo de voz almacenado en la tarjeta SIM."</string>
+ <string name="no_vm_number" msgid="6623853880546176930">"Falta el número del buzón de voz"</string>
+ <string name="no_vm_number_msg" msgid="5165161462411372504">"No hay un número de buzón de voz almacenado en la tarjeta SIM."</string>
<string name="add_vm_number_str" msgid="7368168964435881637">"Agregar número"</string>
- <string name="voice_number_setting_primary_user_only" msgid="3394706575741912843">"Solo el usuario principal puede cambiar la configuración del correo de voz."</string>
+ <string name="voice_number_setting_primary_user_only" msgid="3394706575741912843">"Solo el usuario principal puede cambiar la configuración del buzón de voz."</string>
<string name="puk_unlocked" msgid="4627340655215746511">"Tu tarjeta SIM ha sido desbloqueada. Tu dispositivo está desbloqueando..."</string>
<string name="label_ndp" msgid="7617392683877410341">"PIN de desbloqueo de red de tarjeta SIM"</string>
<string name="sim_ndp_unlock_text" msgid="7737338355451978338">"Desbloquear"</string>
@@ -76,7 +76,7 @@
<string name="phone_accounts_all_calling_accounts_summary" msgid="2214134955430107240">"Elige las cuentas que pueden realizar llamadas."</string>
<string name="wifi_calling" msgid="3650509202851355742">"Llamada por Wi-Fi"</string>
<string name="connection_service_default_label" msgid="7332739049855715584">"Servicio de conexión integrado"</string>
- <string name="voicemail" msgid="7697769412804195032">"Correo de voz"</string>
+ <string name="voicemail" msgid="7697769412804195032">"Buzón de voz"</string>
<string name="voicemail_settings_with_label" msgid="4228431668214894138">"Buzón de voz (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
<string name="voicemail_abbreviated" msgid="7746778673131551185">"Correo de voz:"</string>
<string name="make_and_receive_calls" msgid="4868913166494621109">"Realiza y recibe llamadas"</string>
@@ -147,7 +147,7 @@
<item msgid="6813323051965618926">"Ocultar número"</item>
<item msgid="9150034130629852635">"Mostrar número"</item>
</string-array>
- <string name="vm_changed" msgid="4739599044379692505">"Número de correo de voz cambiado."</string>
+ <string name="vm_changed" msgid="4739599044379692505">"Número de buzón de voz cambiado."</string>
<string name="vm_change_failed" msgid="7877733929455763566">"No se pudo cambiar el número del buzón de voz.\nSi el problema continua, ponte en contacto con tu proveedor."</string>
<string name="fw_change_failed" msgid="9179241823460192148">"No se pudo cambiar el número de desvío.\nSi el problema continua, ponte en contacto con tu proveedor."</string>
<string name="fw_get_in_vm_failed" msgid="2432678237218183844">"No se pudo recuperar ni guardar la configuración del número actual de reenvío.\n¿Deseas cambiar de proveedor de todos modos?"</string>
@@ -483,7 +483,7 @@
<string name="pin2_unblocked" msgid="4481107908727789303">"El PIN2 ya no está bloqueado."</string>
<string name="pin2_error_exception" msgid="8116103864600823641">"Error en la red o en la tarjeta SIM"</string>
<string name="doneButton" msgid="7371209609238460207">"Finalizado"</string>
- <string name="voicemail_settings_number_label" msgid="1265118640154688162">"Correo de voz"</string>
+ <string name="voicemail_settings_number_label" msgid="1265118640154688162">"Número de buzón de voz"</string>
<string name="card_title_dialing" msgid="8742182654254431781">"Marcando"</string>
<string name="card_title_redialing" msgid="18130232613559964">"Volviendo a marcar"</string>
<string name="card_title_conf_call" msgid="901197309274457427">"Llamada en conferencia"</string>
@@ -492,10 +492,10 @@
<string name="card_title_on_hold" msgid="9028319436626975207">"En espera"</string>
<string name="card_title_hanging_up" msgid="814874106866647871">"Colgando"</string>
<string name="card_title_in_call" msgid="8231896539567594265">"En llamada"</string>
- <string name="notification_voicemail_title" msgid="3932876181831601351">"Correo de voz nuevo"</string>
- <string name="notification_voicemail_title_count" msgid="2806950319222327082">"Correo de voz nuevo (<xliff:g id="COUNT">%d</xliff:g>)"</string>
+ <string name="notification_voicemail_title" msgid="3932876181831601351">"Nuevo mensaje de voz"</string>
+ <string name="notification_voicemail_title_count" msgid="2806950319222327082">"Nuevo mensaje de voz (<xliff:g id="COUNT">%d</xliff:g>)"</string>
<string name="notification_voicemail_text_format" msgid="5720947141702312537">"Marcar <xliff:g id="VOICEMAIL_NUMBER">%s</xliff:g>"</string>
- <string name="notification_voicemail_no_vm_number" msgid="3423686009815186750">"Número de correo de voz desconocido"</string>
+ <string name="notification_voicemail_no_vm_number" msgid="3423686009815186750">"Número de buzón de voz desconocido"</string>
<string name="notification_network_selection_title" msgid="255595526707809121">"Sin servicio"</string>
<string name="notification_network_selection_text" msgid="553288408722427659">"La red seleccionada (<xliff:g id="OPERATOR_NAME">%s</xliff:g>) no está disponible"</string>
<string name="incall_error_power_off" product="watch" msgid="7191184639454113633">"Activa la red móvil y desactiva el modo de avión o el modo de ahorro de batería para realizar una llamada."</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 2f6b920..1805e6b 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -183,8 +183,8 @@
<string name="preferred_network_mode_dialogtitle" msgid="2781447433514459696">"Jenis jaringan yang dipilih"</string>
<string name="forbidden_network" msgid="5081729819561333023">"(terlarang)"</string>
<string name="choose_network_title" msgid="5335832663422653082">"Pilih jaringan"</string>
- <string name="network_disconnected" msgid="8844141106841160825">"Tidak tersambung"</string>
- <string name="network_connected" msgid="2760235679963580224">"Tersambung"</string>
+ <string name="network_disconnected" msgid="8844141106841160825">"Terputus"</string>
+ <string name="network_connected" msgid="2760235679963580224">"Terhubung"</string>
<string name="network_connecting" msgid="160901383582774987">"Menyambungkan..."</string>
<string name="network_could_not_connect" msgid="6547460848093727998">"Tidak dapat tersambung"</string>
<string-array name="preferred_network_mode_choices">
@@ -823,7 +823,7 @@
<string name="radioInfo_phone_idle" msgid="2191653783170757819">"Tidak ada aktivitas"</string>
<string name="radioInfo_phone_ringing" msgid="8100354169567413370">"Berdering"</string>
<string name="radioInfo_phone_offhook" msgid="7564601639749936170">"Panggilan sedang Berlangsung"</string>
- <string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Sambungan terputus"</string>
+ <string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Terputus"</string>
<string name="radioInfo_data_connecting" msgid="925092271092152472">"Menghubungkan"</string>
<string name="radioInfo_data_connected" msgid="7637335645634239508">"Terhubung"</string>
<string name="radioInfo_data_suspended" msgid="8695262782642002785">"Ditangguhkan"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index ed69389..192038d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -107,21 +107,21 @@
<string name="sum_cfu_enabled_indicator" msgid="9030139213402432776">"Deviazione di tutte le chiamate"</string>
<string name="sum_cfu_enabled" msgid="5806923046528144526">"Deviazione di tutte le chiamate al numero <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
<string name="sum_cfu_enabled_no_number" msgid="7287752761743377930">"Numero non disponibile"</string>
- <string name="sum_cfu_disabled" msgid="5010617134210809853">"Off"</string>
+ <string name="sum_cfu_disabled" msgid="5010617134210809853">"OFF"</string>
<string name="labelCFB" msgid="615265213360512768">"Se occupato"</string>
<string name="messageCFB" msgid="1958017270393563388">"Numero se occupato"</string>
<string name="sum_cfb_enabled" msgid="332037613072049492">"Deviazione al numero <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfb_disabled" msgid="3589913334164866035">"Off"</string>
+ <string name="sum_cfb_disabled" msgid="3589913334164866035">"OFF"</string>
<string name="disable_cfb_forbidden" msgid="4831494744351633961">"Il tuo operatore non supporta la disattivazione dell\'inoltro chiamate quando il telefono è occupato."</string>
<string name="labelCFNRy" msgid="3403533792248457946">"Se non si risponde"</string>
<string name="messageCFNRy" msgid="7644434155765359009">"Numero se non si risponde"</string>
<string name="sum_cfnry_enabled" msgid="3000500837493854799">"Deviazione al numero <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfnry_disabled" msgid="1990563512406017880">"Off"</string>
+ <string name="sum_cfnry_disabled" msgid="1990563512406017880">"OFF"</string>
<string name="disable_cfnry_forbidden" msgid="3174731413216550689">"Il tuo operatore non supporta la disattivazione dell\'inoltro chiamate quando il telefono non risponde."</string>
<string name="labelCFNRc" msgid="4163399350778066013">"Se non raggiungibile"</string>
<string name="messageCFNRc" msgid="6980340731313007250">"Numero se non raggiungibile"</string>
<string name="sum_cfnrc_enabled" msgid="1799069234006073477">"Deviazione al numero <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfnrc_disabled" msgid="739289696796917683">"Off"</string>
+ <string name="sum_cfnrc_disabled" msgid="739289696796917683">"OFF"</string>
<string name="disable_cfnrc_forbidden" msgid="775348748084726890">"Il tuo operatore non supporta la disattivazione dell\'inoltro chiamate quando il telefono non è raggiungibile."</string>
<string name="updating_title" msgid="6130548922615719689">"Impostazioni chiamate"</string>
<string name="call_settings_admin_user_only" msgid="7238947387649986286">"Le impostazioni delle chiamate possono essere modificate solo dall\'utente amministratore."</string>
@@ -255,7 +255,7 @@
<string name="roaming_disable" msgid="8856224638624592681">"Connessione a servizi di dati in roaming"</string>
<string name="roaming_reenable_message" msgid="1951802463885727915">"Disattivazione del roaming dati in corso. Tocca per attivarlo."</string>
<string name="roaming_enabled_message" msgid="9022249120750897">"Potrebbero essere addebitati costi per il roaming. Tocca per modificare."</string>
- <string name="roaming_notification_title" msgid="3590348480688047320">"Connessione dati mobile interrotta"</string>
+ <string name="roaming_notification_title" msgid="3590348480688047320">"Connessione dati mobili interrotta"</string>
<string name="roaming_on_notification_title" msgid="7451473196411559173">"Roaming dei dati attivo"</string>
<string name="roaming_warning" msgid="7855681468067171971">"I costi potrebbero essere elevati."</string>
<string name="roaming_check_price_warning" msgid="8212484083990570215">"Verifica i costi con il tuo fornitore di rete."</string>
@@ -291,7 +291,7 @@
<string name="throttle_data_rate_reduced_subtext" msgid="8369839346277847725">"<xliff:g id="USED_0">%1$s</xliff:g> max superato\nVelocità dati ridotta a <xliff:g id="USED_1">%2$d</xliff:g> Kb/s"</string>
<string name="throttle_time_frame_subtext" msgid="6462089615392402127">"<xliff:g id="USED_0">%1$d</xliff:g>٪ del ciclo trascorso\nIl periodo succ. inizia tra <xliff:g id="USED_1">%2$d</xliff:g> gg (<xliff:g id="USED_2">%3$s</xliff:g>)"</string>
<string name="throttle_rate_subtext" msgid="7221971817325779535">"Velocità dati ridotta a <xliff:g id="USED">%1$d</xliff:g> Kb/s se limite utilizzo dati superato"</string>
- <string name="throttle_help_subtext" msgid="2817114897095534807">"Informazioni sulla norme di utilizzo dati della rete cellulare del gestore"</string>
+ <string name="throttle_help_subtext" msgid="2817114897095534807">"Informazioni sulle norme di utilizzo dati della rete cellulare del gestore"</string>
<string name="cell_broadcast_sms" msgid="4053449797289031063">"SMS cell broadcast"</string>
<string name="enable_disable_cell_bc_sms" msgid="4759958924031721350">"SMS cell broadcast"</string>
<string name="cell_bc_sms_enable" msgid="2019708772024632073">"SMS cell broadcast attivato"</string>
@@ -468,7 +468,7 @@
<string name="pin_changed" msgid="7291153750090452808">"PIN aggiornato"</string>
<string name="puk_requested" msgid="2061337960609806851">"Password errata. PIN bloccato. Codice PUK richiesto."</string>
<string name="enter_pin2_text" msgid="7266379426804295979">"PIN2"</string>
- <string name="oldPin2Label" msgid="4648543187859997203">"PIN2 attuale"</string>
+ <string name="oldPin2Label" msgid="4648543187859997203">"PIN2 precedente"</string>
<string name="newPin2Label" msgid="1840905981784453939">"Nuovo PIN2"</string>
<string name="confirmPin2Label" msgid="4336025914667593762">"Conferma nuovo PIN2"</string>
<string name="badPuk2" msgid="6438182906645832235">"PUK2 errato. Riprova."</string>
@@ -561,7 +561,7 @@
<string name="hac_mode_summary" msgid="7774989500136009881">"Attiva la compatibilità con apparecchi acustici"</string>
<string name="rtt_mode_title" msgid="3075948111362818043">"Chiamate con Real-time text (RTT)"</string>
<string name="rtt_mode_summary" msgid="8631541375609989562">"Consenti l\'utilizzo di messaggi durante le chiamate vocali"</string>
- <string name="rtt_mode_more_information" msgid="587500128658756318">"RTT aiuta i chiamanti con disabilità uditive o del linguaggio e le persone che hanno bisogno di un supporto scritto oltre alla voce.<br> <a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>>Ulteriori informazioni</a>\n <br><br> - Le chiamate RTT vengono salvare come una trascrizione in messaggi\n <br> - RTT non è disponibile per le videochiamate"</string>
+ <string name="rtt_mode_more_information" msgid="587500128658756318">"RTT aiuta i chiamanti con disabilità uditive o del linguaggio e le persone che hanno bisogno di un supporto scritto oltre alla voce.<br> <a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>>Ulteriori informazioni</a>\n <br><br> - Le chiamate RTT vengono salvate come una trascrizione in messaggi\n <br> - RTT non è disponibile per le videochiamate"</string>
<string name="no_rtt_when_roaming" msgid="5268008247378355389">"Nota: la funzionalità RTT non è disponibile in roaming"</string>
<string-array name="tty_mode_entries">
<item msgid="3238070884803849303">"TTY disattivato"</item>
@@ -751,7 +751,7 @@
<string name="call_barring_baicr_disabled" msgid="3488129262744027262">"Bloccare il roaming internazionale in arrivo?"</string>
<string name="call_barring_deactivate_all" msgid="7837931580047157328">"Disattiva tutto"</string>
<string name="call_barring_deactivate_all_description" msgid="4474119585042121604">"Disattiva tutte le impostazioni di blocco chiamate"</string>
- <string name="call_barring_deactivate_success" msgid="3545644320298275337">"Bocco chiamate disattivato"</string>
+ <string name="call_barring_deactivate_success" msgid="3545644320298275337">"Blocco chiamate disattivato"</string>
<string name="call_barring_change_pwd" msgid="1730691950940338387">"Modifica password"</string>
<string name="call_barring_change_pwd_description" msgid="1274245130382054227">"Modifica la password di blocco chiamate"</string>
<string name="call_barring_change_pwd_description_disabled" msgid="2911647051915343920">"Impossibile modificare la password di blocco chiamate"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 697919b..c9aa805 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -274,7 +274,7 @@
<string name="data_usage_disable_mobile" msgid="5669109209055988308">"Mobil internet uzilsinmi?"</string>
<string name="sim_selection_required_pref" msgid="6985901872978341314">"SIM kartani tanlang"</string>
<string name="sim_change_data_title" msgid="9142726786345906606">"SIM karta o‘zgartirilsinmi?"</string>
- <string name="sim_change_data_message" msgid="3567358694255933280">"Mobil internet uchun <xliff:g id="OLD_SIM">%2$s</xliff:g> o‘rniga <xliff:g id="NEW_SIM">%1$s</xliff:g> SIM kartasidan foydalanilsinmi?"</string>
+ <string name="sim_change_data_message" msgid="3567358694255933280">"Mobil internet uchun <xliff:g id="OLD_SIM">%2$s</xliff:g> emas, <xliff:g id="NEW_SIM">%1$s</xliff:g> ishlatilsinmi?"</string>
<string name="wifi_calling_settings_title" msgid="5800018845662016507">"Wi-Fi chaqiruv"</string>
<string name="video_calling_settings_title" msgid="342829454913266078">"Operator tarmog‘i orqali video suhbatlar"</string>
<string name="gsm_umts_options" msgid="4968446771519376808">"GSM/UMTS sozlamalari"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index fca8acf..8d84baf 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -15,6 +15,21 @@
-->
<resources>
+ <!-- Base attributes available to CheckBoxPreference. Copied from frameworks/base/core/res. -->
+ <declare-styleable name="CheckBoxPreference">
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ CheckBoxPreference is checked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="android:summaryOn" />
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ CheckBoxPreference is unchecked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="android:summaryOff" />
+ <!-- The state (true for on, or false for off) that causes dependents to be disabled. By default,
+ dependents will be disabled when this is unchecked, so the value of this preference is false. -->
+ <attr name="android:disableDependentsState" />
+ </declare-styleable>
+
<declare-styleable name="EditPhoneNumberPreference">
<!-- The enable button text. -->
<attr name="enableButtonText" format="string" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dfec1d8..bc69a56 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -16,22 +16,10 @@
<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 -->
@@ -620,9 +608,6 @@
<!-- 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 -->
@@ -992,8 +977,6 @@
<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>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index df409c7..e95142b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -211,15 +211,6 @@
<item name="android:textColor">?android:attr/textColorPrimaryInverseDisableOnly</item>
</style>
- <style name="NetworkOperatorsSettingsTheme" parent="@android:style/Theme.DeviceDefault.Settings">
- <item name="android:forceDarkAllowed">true</item>
- <item name="android:switchPreferenceStyle">@style/SettingsSwitchPreference</item>
- <item name="android:preferenceCategoryStyle">@style/SettingsPreferenceCategory</item>
- <item name="android:preferenceStyle">@style/SettingsPreference</item>
- <item name="android:dialogPreferenceStyle">@style/SettingsDialogPreference</item>
- <item name="android:preferenceScreenStyle">@style/SettingsPreferenceScreen</item>
- </style>
-
<style name="TrimmedHorizontalProgressBar" parent="android:Widget.Material.ProgressBar.Horizontal">
<item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material_trimmed</item>
<item name="android:minHeight">3dip</item>
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index ceea4a6..fef4f72 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -29,10 +29,6 @@
<item name="android:singleLineTitle">false</item>
</style>
- <style name="SettingsPreferenceCategory" parent="@*android:style/Preference.DeviceDefault.Category">
- <item name="android:layout">@layout/preference_category_material_settings_with_divider</item>
- </style>
-
<style name="SettingsDialogPreference" parent="@*android:style/Preference.DeviceDefault.DialogPreference">
<item name="android:singleLineTitle">false</item>
<item name="android:iconSpaceReserved">true</item>
diff --git a/res/xml/callbarring_options.xml b/res/xml/callbarring_options.xml
index 6f2c48a..6506031 100644
--- a/res/xml/callbarring_options.xml
+++ b/res/xml/callbarring_options.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
+ xmlns:phone="http://schemas.android.com/apk/res-auto"
android:title="@string/call_barring_settings">
<!-- Note for all com.android.phone.EditPinPreference objects
diff --git a/res/xml/callforward_options.xml b/res/xml/callforward_options.xml
index 0ff1e90..775151e 100644
--- a/res/xml/callforward_options.xml
+++ b/res/xml/callforward_options.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
+ xmlns:phone="http://schemas.android.com/apk/res-auto"
android:title="@string/call_forwarding_settings">
diff --git a/res/xml/voicemail_settings.xml b/res/xml/voicemail_settings.xml
index 021a764..cbe1cf4 100644
--- a/res/xml/voicemail_settings.xml
+++ b/res/xml/voicemail_settings.xml
@@ -15,7 +15,7 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
+ xmlns:phone="http://schemas.android.com/apk/res-auto"
android:title="@string/voicemail">
<com.android.phone.settings.VoicemailProviderListPreference
diff --git a/sip/res/values-bs/strings.xml b/sip/res/values-bs/strings.xml
index a02d893..69aa5a8 100644
--- a/sip/res/values-bs/strings.xml
+++ b/sip/res/values-bs/strings.xml
@@ -42,11 +42,11 @@
<string name="registration_status_not_receiving" msgid="3873074208531938401">"Ne prima pozive."</string>
<string name="registration_status_no_data" msgid="2987064560116584121">"Registracija računa je zaustavljena jer niste povezani na internet."</string>
<string name="registration_status_no_wifi_data" msgid="685470618241482948">"Registracija računa je zaustavljena jer nema WiFi veze."</string>
- <string name="registration_status_not_running" msgid="6236403137652262659">"Registracija računa neuspješna."</string>
+ <string name="registration_status_not_running" msgid="6236403137652262659">"Registracija računa nije uspjela."</string>
<string name="registration_status_done" msgid="6787397199273357721">"Primanje poziva."</string>
- <string name="registration_status_failed_try_later" msgid="7855389184910312091">"Registracija računa neuspješna: (<xliff:g id="REGISTRATION_ERROR_MESSAGE">%s</xliff:g>); pokušat ćemo kasnije"</string>
- <string name="registration_status_invalid_credentials" msgid="8896714049938660777">"Registracija računa neuspješna: netačno korisničko ime ili lozinka."</string>
- <string name="registration_status_server_unreachable" msgid="3832339558868965604">"Registracija računa neuspješna: provjerite naziv servera."</string>
+ <string name="registration_status_failed_try_later" msgid="7855389184910312091">"Registracija računa nije uspjela: (<xliff:g id="REGISTRATION_ERROR_MESSAGE">%s</xliff:g>); pokušat ćemo kasnije"</string>
+ <string name="registration_status_invalid_credentials" msgid="8896714049938660777">"Registracija računa nije uspjela: netačno korisničko ime ili lozinka."</string>
+ <string name="registration_status_server_unreachable" msgid="3832339558868965604">"Registracija računa nije uspjela: provjerite naziv servera."</string>
<string name="third_party_account_summary" msgid="5918779106950859167">"Ovaj račun trenutno koristi aplikacija <xliff:g id="ACCOUNT_OWNER">%s</xliff:g>."</string>
<string name="sip_edit_title" msgid="7438891546610820307">"Detalji o SIP računima"</string>
<string name="sip_edit_new_title" msgid="8394790068979636381">"Detalji o SIP računima"</string>
diff --git a/sip/res/values-gl/strings.xml b/sip/res/values-gl/strings.xml
index 797d35d..1a40bf3 100644
--- a/sip/res/values-gl/strings.xml
+++ b/sip/res/values-gl/strings.xml
@@ -53,7 +53,7 @@
<string name="domain_address_title" msgid="8238078615181248579">"Servidor"</string>
<string name="username_title" msgid="298416796886107970">"Nome de usuario"</string>
<string name="password_title" msgid="8035579335591959021">"Contrasinal"</string>
- <string name="display_name_title" msgid="3730105783656830160">"Nome de visualización"</string>
+ <string name="display_name_title" msgid="3730105783656830160">"Nome visible"</string>
<string name="proxy_address_title" msgid="4120361943254795287">"Enderezo proxy saínte"</string>
<string name="port_title" msgid="1703586046264385110">"Número de porto"</string>
<string name="transport_title" msgid="1661659138226029178">"Tipo de transporte"</string>
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 3858595..3f57cae 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -19,13 +19,16 @@
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;
+import android.content.res.Resources;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.UserManager;
@@ -109,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) {
@@ -181,9 +228,9 @@
startActivity(intent);
}
};
- builder.setMessage(getResources().getString(
+ builder.setMessage(getResourcesForSubId().getString(
R.string.enable_video_calling_dialog_msg))
- .setNeutralButton(getResources().getString(
+ .setNeutralButton(getResourcesForSubId().getString(
R.string.enable_video_calling_dialog_settings),
networkSettingsClickListener)
.setPositiveButton(android.R.string.ok, null)
@@ -211,9 +258,9 @@
}
mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
- mSubscriptionInfoHelper.setActionBarTitle(
- getActionBar(), getResources(), R.string.call_settings_with_label);
mPhone = mSubscriptionInfoHelper.getPhone();
+ mSubscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResourcesForSubId(), R.string.call_settings_with_label);
mTelecomManager = getSystemService(TelecomManager.class);
}
@@ -265,6 +312,7 @@
protected void onPause() {
super.onPause();
listenPhoneState(false);
+ unregisterReceiver(mReceiver);
// Remove callback for provisioning changes.
try {
@@ -315,7 +363,7 @@
mButtonAutoRetry = (SwitchPreference) findPreference(BUTTON_RETRY_KEY);
mEnableVideoCalling = (SwitchPreference) findPreference(ENABLE_VIDEO_CALLING_KEY);
- mButtonWifiCalling = findPreference(getResources().getString(
+ mButtonWifiCalling = findPreference(getResourcesForSubId().getString(
R.string.wifi_calling_settings_key));
PersistableBundle carrierConfig =
@@ -377,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() {
@@ -424,8 +476,7 @@
} else if (!mImsMgr.isWfcEnabledByPlatform() || !mImsMgr.isWfcProvisionedOnDevice()) {
prefSet.removePreference(mButtonWifiCalling);
} else {
- String title = SubscriptionManager.getResourcesForSubId(mPhone.getContext(),
- mPhone.getSubId()).getString(R.string.wifi_calling);
+ String title = getResourcesForSubId().getString(R.string.wifi_calling);
mButtonWifiCalling.setTitle(title);
int resId = com.android.internal.R.string.wifi_calling_off_summary;
@@ -447,7 +498,7 @@
if (DBG) log("Unexpected WFC mode value: " + wfcMode);
}
}
- mButtonWifiCalling.setSummary(resId);
+ mButtonWifiCalling.setSummary(getResourcesForSubId().getString(resId));
Intent intent = mButtonWifiCalling.getIntent();
if (intent != null) {
intent.putExtra(Settings.EXTRA_SUB_ID, mPhone.getSubId());
@@ -509,9 +560,9 @@
setIntent(newIntent);
mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
- mSubscriptionInfoHelper.setActionBarTitle(
- getActionBar(), getResources(), R.string.call_settings_with_label);
mPhone = mSubscriptionInfoHelper.getPhone();
+ mSubscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResourcesForSubId(), R.string.call_settings_with_label);
}
private static void log(String msg) {
@@ -540,4 +591,12 @@
activity.startActivity(intent);
activity.finish();
}
+
+ private Resources getResourcesForSubId() {
+ if (mPhone != null) {
+ return SubscriptionManager.getResourcesForSubId(mPhone.getContext(), mPhone.getSubId());
+ } else {
+ return getResources();
+ }
+ }
}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index dab04f0..9e7bb39 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -558,7 +558,8 @@
public void updatePhoneStateListeners(boolean isRefresh, int updateType, int subIdToUpdate) {
List<SubscriptionInfo> subInfos = SubscriptionController.getInstance()
- .getActiveSubscriptionInfoList(mApplication.getOpPackageName());
+ .getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
+ mApplication.getFeatureId());
// Sort sub id list based on slot id, so that CFI/MWI notifications will be updated for
// slot 0 first then slot 1. This is needed to ensure that when CFI or MWI is enabled for
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 1d074bc..13dcaa7 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -20,6 +20,7 @@
import static android.service.carrier.CarrierService.ICarrierServiceWrapper.RESULT_ERROR;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -55,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;
@@ -94,6 +95,8 @@
private PersistableBundle[] mConfigFromDefaultApp;
// Carrier configs from privileged carrier config app, indexed by phoneID.
private PersistableBundle[] mConfigFromCarrierApp;
+ // Persistent Carrier configs that are provided via the override test API, indexed by phone ID.
+ private PersistableBundle[] mPersistentOverrideConfigs;
// Carrier configs that are provided via the override test API, indexed by phone ID.
private PersistableBundle[] mOverrideConfigs;
// Service connection for binding to config app.
@@ -151,6 +154,8 @@
private static final String TAG_VERSION = "package_version";
private static final String TAG_BUNDLE = "bundle_data";
+ private static final String OVERRIDE_PACKAGE_ADDITION = "-override";
+
// SharedPreferences key for last known build fingerprint.
private static final String KEY_FINGERPRINT = "build_fingerprint";
@@ -220,8 +225,17 @@
case EVENT_DO_FETCH_DEFAULT:
{
- final PersistableBundle config =
- restoreConfigFromXml(mPlatformCarrierConfigPackage, phoneId);
+ // Restore persistent override values.
+ PersistableBundle config = restoreConfigFromXml(
+ mPlatformCarrierConfigPackage, OVERRIDE_PACKAGE_ADDITION, phoneId);
+ if (config != null) {
+ log("Loaded persistent override config from XML. package="
+ + mPlatformCarrierConfigPackage
+ + " phoneId=" + phoneId);
+ mPersistentOverrideConfigs[phoneId] = config;
+ }
+
+ config = restoreConfigFromXml(mPlatformCarrierConfigPackage, "", phoneId);
if (config != null) {
log(
"Loaded config from XML. package="
@@ -283,7 +297,7 @@
}
PersistableBundle config =
resultData.getParcelable(KEY_CONFIG_BUNDLE);
- saveConfigToXml(mPlatformCarrierConfigPackage, phoneId,
+ saveConfigToXml(mPlatformCarrierConfigPackage, "", phoneId,
carrierId, config);
mConfigFromDefaultApp[phoneId] = config;
sendMessage(
@@ -351,7 +365,7 @@
{
final String carrierPackageName = getCarrierPackageForPhoneId(phoneId);
final PersistableBundle config =
- restoreConfigFromXml(carrierPackageName, phoneId);
+ restoreConfigFromXml(carrierPackageName, "", phoneId);
if (config != null) {
log(
"Loaded config from XML. package="
@@ -414,8 +428,8 @@
}
PersistableBundle config =
resultData.getParcelable(KEY_CONFIG_BUNDLE);
- saveConfigToXml(getCarrierPackageForPhoneId(phoneId), phoneId,
- carrierId, config);
+ saveConfigToXml(getCarrierPackageForPhoneId(phoneId), "",
+ phoneId, carrierId, config);
mConfigFromCarrierApp[phoneId] = config;
sendMessage(
obtainMessage(
@@ -528,6 +542,7 @@
int numPhones = TelephonyManager.from(context).getSupportedModemCount();
mConfigFromDefaultApp = new PersistableBundle[numPhones];
mConfigFromCarrierApp = new PersistableBundle[numPhones];
+ mPersistentOverrideConfigs = new PersistableBundle[numPhones];
mOverrideConfigs = new PersistableBundle[numPhones];
mServiceConnection = new CarrierServiceConnection[numPhones];
mHasSentConfigChange = new boolean[numPhones];
@@ -737,12 +752,13 @@
* In case of errors or invalid input, no file will be written.
*
* @param packageName the name of the package from which we fetched this bundle.
+ * @param extraString An extra string to be used in the XML file name.
* @param phoneId the phone ID.
* @param carrierId contains all carrier-identifying information.
* @param config the bundle to be written. Null will be treated as an empty bundle.
*/
- private void saveConfigToXml(String packageName, int phoneId, CarrierIdentifier carrierId,
- PersistableBundle config) {
+ private void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
+ CarrierIdentifier carrierId, PersistableBundle config) {
if (SubscriptionManager.getSimStateForSlotIndex(phoneId)
!= TelephonyManager.SIM_STATE_LOADED) {
loge("Skip save config because SIM records are not loaded.");
@@ -776,7 +792,7 @@
try {
outFile = new FileOutputStream(
new File(mContext.getFilesDir(),
- getFilenameForConfig(packageName, iccid, cid)));
+ getFilenameForConfig(packageName, extraString, iccid, cid)));
FastXmlSerializer out = new FastXmlSerializer();
out.setOutput(outFile, "utf-8");
out.startDocument("utf-8", true);
@@ -810,11 +826,13 @@
* current version, then null will be returned.
*
* @param packageName the name of the package from which we fetched this bundle.
+ * @param extraString An extra string to be used in the XML file name.
* @param phoneId the phone ID.
* @return the bundle from the XML file. Returns null if there is no saved config, the saved
* version does not match, or reading config fails.
*/
- private PersistableBundle restoreConfigFromXml(String packageName, int phoneId) {
+ private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString,
+ int phoneId) {
final String version = getPackageVersion(packageName);
if (version == null) {
loge("Failed to get package version for: " + packageName);
@@ -834,11 +852,12 @@
}
PersistableBundle restoredBundle = null;
+ File file = null;
FileInputStream inFile = null;
try {
- inFile = new FileInputStream(
- new File(mContext.getFilesDir(),
- getFilenameForConfig(packageName, iccid, cid)));
+ file = new File(mContext.getFilesDir(),
+ getFilenameForConfig(packageName, extraString, iccid, cid));
+ inFile = new FileInputStream(file);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(inFile, "utf-8");
@@ -860,7 +879,9 @@
inFile.close();
}
catch (FileNotFoundException e) {
- loge(e.toString());
+ // Missing file is normal occurrence that might occur with a new sim or when restoring
+ // an override file during boot and should not be treated as an error.
+ if (file != null) log("File not found: " + file.getPath());
}
catch (XmlPullParserException e) {
loge(e.toString());
@@ -901,13 +922,13 @@
}
/** Builds a canonical file name for a config file. */
- private String getFilenameForConfig(@NonNull String packageName, @NonNull String iccid,
- int cid) {
+ private String getFilenameForConfig(@NonNull String packageName, @NonNull String extraString,
+ @NonNull String iccid, int cid) {
// the same carrier should have a single copy of XML file named after carrier id.
// However, it's still possible that platform doesn't recognize the current sim carrier,
// we will use iccid + carrierid as the canonical file name. carrierid can also handle the
// cases SIM OTA resolves to different carrier while iccid remains the same.
- return "carrierconfig-" + packageName + "-" + iccid + "-" + cid + ".xml";
+ return "carrierconfig-" + packageName + extraString + "-" + iccid + "-" + cid + ".xml";
}
/** Return the current version code of a package, or null if the name is not found. */
@@ -946,8 +967,14 @@
@Override
public @NonNull PersistableBundle getConfigForSubId(int subId, String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mContext, subId, callingPackage, "getCarrierConfig")) {
+ return getConfigForSubIdWithFeature(subId, callingPackage, null);
+ }
+
+ @Override
+ public @NonNull PersistableBundle getConfigForSubIdWithFeature(int subId, String callingPackage,
+ String callingFeatureId) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+ callingFeatureId, "getCarrierConfig")) {
return new PersistableBundle();
}
@@ -967,6 +994,11 @@
retConfig.putAll(config);
retConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
}
+ config = mPersistentOverrideConfigs[phoneId];
+ if (config != null) {
+ retConfig.putAll(config);
+ retConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ }
config = mOverrideConfigs[phoneId];
if (config != null) {
retConfig.putAll(config);
@@ -976,7 +1008,8 @@
}
@Override
- public void overrideConfig(int subscriptionId, PersistableBundle overrides) {
+ public void overrideConfig(int subscriptionId, @Nullable PersistableBundle overrides,
+ boolean persistent) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE, null);
//TODO: Also check for SHELL UID to restrict this method to testing only (b/131326259)
@@ -985,18 +1018,38 @@
log("Ignore invalid phoneId: " + phoneId + " for subId: " + subscriptionId);
return;
}
+ overrideConfig(mOverrideConfigs, phoneId, overrides);
- if (overrides == null) {
- mOverrideConfigs[phoneId] = new PersistableBundle();
- } else if (mOverrideConfigs[phoneId] == null) {
- mOverrideConfigs[phoneId] = overrides;
- } else {
- mOverrideConfigs[phoneId].putAll(overrides);
+ if (persistent) {
+ overrideConfig(mPersistentOverrideConfigs, phoneId, overrides);
+
+ if (overrides != null) {
+ final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
+ saveConfigToXml(mPlatformCarrierConfigPackage, OVERRIDE_PACKAGE_ADDITION, phoneId,
+ carrierId, mPersistentOverrideConfigs[phoneId]);
+ } else {
+ final String iccid = getIccIdForPhoneId(phoneId);
+ final int cid = getSpecificCarrierIdForPhoneId(phoneId);
+ String fileName = getFilenameForConfig(mPlatformCarrierConfigPackage,
+ OVERRIDE_PACKAGE_ADDITION, iccid, cid);
+ File fileToDelete = new File(mContext.getFilesDir(), fileName);
+ fileToDelete.delete();
+ }
}
-
notifySubscriptionInfoUpdater(phoneId);
}
+ private void overrideConfig(@NonNull PersistableBundle[] currentOverrides, int phoneId,
+ @Nullable PersistableBundle overrides) {
+ if (overrides == null) {
+ currentOverrides[phoneId] = new PersistableBundle();
+ } else if (currentOverrides[phoneId] == null) {
+ currentOverrides[phoneId] = overrides;
+ } else {
+ currentOverrides[phoneId].putAll(overrides);
+ }
+ }
+
@Override
public void notifyConfigChangedForSubId(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
@@ -1068,6 +1121,8 @@
// display ConfigFromCarrierApp
printConfig(mConfigFromCarrierApp[i], pw, "mConfigFromCarrierApp");
pw.println("");
+ printConfig(mPersistentOverrideConfigs[i], pw, "mPersistentOverrideConfigs");
+ pw.println("");
printConfig(mOverrideConfigs[i], pw, "mOverrideConfigs");
}
diff --git a/src/com/android/phone/EditPhoneNumberPreference.java b/src/com/android/phone/EditPhoneNumberPreference.java
index 74b8a45..35af20d 100644
--- a/src/com/android/phone/EditPhoneNumberPreference.java
+++ b/src/com/android/phone/EditPhoneNumberPreference.java
@@ -136,9 +136,9 @@
a.recycle();
//get the summary settings, use CheckBoxPreference as the standard.
- a = context.obtainStyledAttributes(attrs, android.R.styleable.CheckBoxPreference, 0, 0);
- mSummaryOn = a.getString(android.R.styleable.CheckBoxPreference_summaryOn);
- mSummaryOff = a.getString(android.R.styleable.CheckBoxPreference_summaryOff);
+ a = context.obtainStyledAttributes(attrs, R.styleable.CheckBoxPreference, 0, 0);
+ mSummaryOn = a.getString(R.styleable.CheckBoxPreference_summaryOn);
+ mSummaryOff = a.getString(R.styleable.CheckBoxPreference_summaryOff);
a.recycle();
}
diff --git a/src/com/android/phone/EmergencyActionGroup.java b/src/com/android/phone/EmergencyActionGroup.java
index c090af7..53ec1eb 100644
--- a/src/com/android/phone/EmergencyActionGroup.java
+++ b/src/com/android/phone/EmergencyActionGroup.java
@@ -157,24 +157,19 @@
public void onClick(View v) {
Intent intent = (Intent) v.getTag(R.id.tag_intent);
- switch (v.getId()) {
- case R.id.action1:
- case R.id.action2:
- case R.id.action3:
- AccessibilityManager accessibilityMgr =
- (AccessibilityManager) mContext.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- if (accessibilityMgr.isTouchExplorationEnabled()) {
- getContext().startActivity(intent);
- } else {
- revealTheButton(v);
- }
- break;
- case R.id.selected_container:
- if (!mHiding) {
- getContext().startActivity(intent);
- }
- break;
+ if (v.getId() == R.id.action1 || v.getId() == R.id.action2 || v.getId() == R.id.action3) {
+ AccessibilityManager accessibilityMgr =
+ (AccessibilityManager) mContext.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityMgr.isTouchExplorationEnabled()) {
+ getContext().startActivity(intent);
+ } else {
+ revealTheButton(v);
+ }
+ } else if (v.getId() == R.id.selected_container) {
+ if (!mHiding) {
+ getContext().startActivity(intent);
+ }
}
}
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index c20281a..7531aca 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -461,16 +461,15 @@
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
- switch (view.getId()) {
- case R.id.digits:
- // Happen when "Done" button of the IME is pressed. This can happen when this
- // Activity is forced into landscape mode due to a desk dock.
- if (keyCode == KeyEvent.KEYCODE_ENTER
- && event.getAction() == KeyEvent.ACTION_UP) {
- placeCall();
- return true;
- }
- break;
+ if (view.getId()
+ == R.id.digits) { // Happen when "Done" button of the IME is pressed. This can
+ // happen when this
+ // Activity is forced into landscape mode due to a desk dock.
+ if (keyCode == KeyEvent.KEYCODE_ENTER
+ && event.getAction() == KeyEvent.ACTION_UP) {
+ placeCall();
+ return true;
+ }
}
return false;
}
@@ -510,27 +509,22 @@
@Override
public void onClick(View view) {
- switch (view.getId()) {
- case R.id.deleteButton: {
- keyPressed(KeyEvent.KEYCODE_DEL);
- return;
+ if (view.getId() == R.id.deleteButton) {
+ keyPressed(KeyEvent.KEYCODE_DEL);
+ return;
+ } else if (view.getId() == R.id.floating_action_button) {
+ view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+ placeCall();
+ return;
+ } else if (view.getId() == R.id.digits) {
+ if (mDigits.length() != 0) {
+ mDigits.setCursorVisible(true);
}
- case R.id.floating_action_button: {
- view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
- placeCall();
- return;
- }
- case R.id.digits: {
- if (mDigits.length() != 0) {
- mDigits.setCursorVisible(true);
- }
- return;
- }
- case R.id.floating_action_button_dialpad: {
- mDigits.getText().clear();
- switchView(mDialpadView, mEmergencyShortcutView, true);
- return;
- }
+ return;
+ } else if (view.getId() == R.id.floating_action_button_dialpad) {
+ mDigits.getText().clear();
+ switchView(mDialpadView, mEmergencyShortcutView, true);
+ return;
}
}
@@ -539,67 +533,54 @@
if (!pressed) {
return;
}
- switch (view.getId()) {
- case R.id.one: {
- playTone(ToneGenerator.TONE_DTMF_1);
- keyPressed(KeyEvent.KEYCODE_1);
- return;
- }
- case R.id.two: {
- playTone(ToneGenerator.TONE_DTMF_2);
- keyPressed(KeyEvent.KEYCODE_2);
- return;
- }
- case R.id.three: {
- playTone(ToneGenerator.TONE_DTMF_3);
- keyPressed(KeyEvent.KEYCODE_3);
- return;
- }
- case R.id.four: {
- playTone(ToneGenerator.TONE_DTMF_4);
- keyPressed(KeyEvent.KEYCODE_4);
- return;
- }
- case R.id.five: {
- playTone(ToneGenerator.TONE_DTMF_5);
- keyPressed(KeyEvent.KEYCODE_5);
- return;
- }
- case R.id.six: {
- playTone(ToneGenerator.TONE_DTMF_6);
- keyPressed(KeyEvent.KEYCODE_6);
- return;
- }
- case R.id.seven: {
- playTone(ToneGenerator.TONE_DTMF_7);
- keyPressed(KeyEvent.KEYCODE_7);
- return;
- }
- case R.id.eight: {
- playTone(ToneGenerator.TONE_DTMF_8);
- keyPressed(KeyEvent.KEYCODE_8);
- return;
- }
- case R.id.nine: {
- playTone(ToneGenerator.TONE_DTMF_9);
- keyPressed(KeyEvent.KEYCODE_9);
- return;
- }
- case R.id.zero: {
- playTone(ToneGenerator.TONE_DTMF_0);
- keyPressed(KeyEvent.KEYCODE_0);
- return;
- }
- case R.id.pound: {
- playTone(ToneGenerator.TONE_DTMF_P);
- keyPressed(KeyEvent.KEYCODE_POUND);
- return;
- }
- case R.id.star: {
- playTone(ToneGenerator.TONE_DTMF_S);
- keyPressed(KeyEvent.KEYCODE_STAR);
- return;
- }
+ if (view.getId() == R.id.one) {
+ playTone(ToneGenerator.TONE_DTMF_1);
+ keyPressed(KeyEvent.KEYCODE_1);
+ return;
+ } else if (view.getId() == R.id.two) {
+ playTone(ToneGenerator.TONE_DTMF_2);
+ keyPressed(KeyEvent.KEYCODE_2);
+ return;
+ } else if (view.getId() == R.id.three) {
+ playTone(ToneGenerator.TONE_DTMF_3);
+ keyPressed(KeyEvent.KEYCODE_3);
+ return;
+ } else if (view.getId() == R.id.four) {
+ playTone(ToneGenerator.TONE_DTMF_4);
+ keyPressed(KeyEvent.KEYCODE_4);
+ return;
+ } else if (view.getId() == R.id.five) {
+ playTone(ToneGenerator.TONE_DTMF_5);
+ keyPressed(KeyEvent.KEYCODE_5);
+ return;
+ } else if (view.getId() == R.id.six) {
+ playTone(ToneGenerator.TONE_DTMF_6);
+ keyPressed(KeyEvent.KEYCODE_6);
+ return;
+ } else if (view.getId() == R.id.seven) {
+ playTone(ToneGenerator.TONE_DTMF_7);
+ keyPressed(KeyEvent.KEYCODE_7);
+ return;
+ } else if (view.getId() == R.id.eight) {
+ playTone(ToneGenerator.TONE_DTMF_8);
+ keyPressed(KeyEvent.KEYCODE_8);
+ return;
+ } else if (view.getId() == R.id.nine) {
+ playTone(ToneGenerator.TONE_DTMF_9);
+ keyPressed(KeyEvent.KEYCODE_9);
+ return;
+ } else if (view.getId() == R.id.zero) {
+ playTone(ToneGenerator.TONE_DTMF_0);
+ keyPressed(KeyEvent.KEYCODE_0);
+ return;
+ } else if (view.getId() == R.id.pound) {
+ playTone(ToneGenerator.TONE_DTMF_P);
+ keyPressed(KeyEvent.KEYCODE_POUND);
+ return;
+ } else if (view.getId() == R.id.star) {
+ playTone(ToneGenerator.TONE_DTMF_S);
+ keyPressed(KeyEvent.KEYCODE_STAR);
+ return;
}
}
@@ -609,16 +590,13 @@
@Override
public boolean onLongClick(View view) {
int id = view.getId();
- switch (id) {
- case R.id.deleteButton: {
- mDigits.getText().clear();
- return true;
- }
- case R.id.zero: {
- removePreviousDigitIfPossible();
- keyPressed(KeyEvent.KEYCODE_PLUS);
- return true;
- }
+ if (id == R.id.deleteButton) {
+ mDigits.getText().clear();
+ return true;
+ } else if (id == R.id.zero) {
+ removePreviousDigitIfPossible();
+ keyPressed(KeyEvent.KEYCODE_PLUS);
+ return true;
}
return false;
}
diff --git a/src/com/android/phone/EmergencyInfoGroup.java b/src/com/android/phone/EmergencyInfoGroup.java
index 186de03..f5aca7f 100644
--- a/src/com/android/phone/EmergencyInfoGroup.java
+++ b/src/com/android/phone/EmergencyInfoGroup.java
@@ -207,26 +207,21 @@
@Override
public void onClick(View view) {
- switch (view.getId()) {
- case R.id.emergency_info_view:
- AccessibilityManager accessibilityMgr =
- (AccessibilityManager) mContext.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- if (accessibilityMgr.isTouchExplorationEnabled()) {
- if (mOnConfirmClickListener != null) {
- mOnConfirmClickListener.onConfirmClick(this);
- }
- } else {
- revealSelectedButton();
- }
- break;
- case R.id.emergency_info_confirm_view:
+ if (view.getId() == R.id.emergency_info_view) {
+ AccessibilityManager accessibilityMgr =
+ (AccessibilityManager) mContext.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityMgr.isTouchExplorationEnabled()) {
if (mOnConfirmClickListener != null) {
mOnConfirmClickListener.onConfirmClick(this);
}
- break;
- default:
- break;
+ } else {
+ revealSelectedButton();
+ }
+ } else if (view.getId() == R.id.emergency_info_confirm_view) {
+ if (mOnConfirmClickListener != null) {
+ mOnConfirmClickListener.onConfirmClick(this);
+ }
}
}
diff --git a/src/com/android/phone/EmergencyShortcutButton.java b/src/com/android/phone/EmergencyShortcutButton.java
index 9e51e82..d147ce4 100644
--- a/src/com/android/phone/EmergencyShortcutButton.java
+++ b/src/com/android/phone/EmergencyShortcutButton.java
@@ -182,26 +182,23 @@
@Override
public void onClick(View view) {
- switch (view.getId()) {
- case R.id.emergency_call_number_info_view:
- AccessibilityManager accessibilityMgr =
- (AccessibilityManager) mContext.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- if (accessibilityMgr.isTouchExplorationEnabled()) {
- // TalkBack itself includes a prompt to confirm click action implicitly,
- // so we don't need an additional confirmation with second tap on button.
- if (mOnConfirmClickListener != null) {
- mOnConfirmClickListener.onConfirmClick(this);
- }
- } else {
- revealSelectedButton();
- }
- break;
- case R.id.emergency_call_confirm_view:
+ if (view.getId() == R.id.emergency_call_number_info_view) {
+ AccessibilityManager accessibilityMgr =
+ (AccessibilityManager) mContext.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityMgr.isTouchExplorationEnabled()) {
+ // TalkBack itself includes a prompt to confirm click action implicitly,
+ // so we don't need an additional confirmation with second tap on button.
if (mOnConfirmClickListener != null) {
mOnConfirmClickListener.onConfirmClick(this);
}
- break;
+ } else {
+ revealSelectedButton();
+ }
+ } else if (view.getId() == R.id.emergency_call_confirm_view) {
+ if (mOnConfirmClickListener != null) {
+ mOnConfirmClickListener.onConfirmClick(this);
+ }
}
}
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/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 410965b..66017e4 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -29,7 +29,6 @@
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Handler;
@@ -564,16 +563,15 @@
builder.build(),
UserHandle.ALL);
} else {
- List<UserInfo> users = mUserManager.getUsers(true);
- for (UserInfo user : users) {
- if (mUserManager.isManagedProfile(user.getUserHandle().getIdentifier())) {
+ List<UserHandle> users = getUsersExcludeDying();
+ for (UserHandle user : users) {
+ if (mUserManager.isManagedProfile(user.getIdentifier())) {
continue;
}
- UserHandle userHandle = user.getUserHandle();
cancelAsUser(
Integer.toString(subId) /* tag */,
CALL_FORWARD_NOTIFICATION,
- userHandle);
+ user);
}
}
}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 90f408b..812fabc 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -369,6 +369,10 @@
// register for MMI/USSD
mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
+ // Initialize cell status using current airplane mode.
+ handleAirplaneModeChange(this, Settings.Global.getInt(getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, AIRPLANE_OFF));
+
// Register for misc other intent broadcasts.
IntentFilter intentFilter =
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -443,7 +447,7 @@
}
public PersistableBundle getCarrierConfigForSubId(int subId) {
- return configLoader.getConfigForSubId(subId, getOpPackageName());
+ return configLoader.getConfigForSubIdWithFeature(subId, getOpPackageName(), getFeatureId());
}
private void registerSettingsObserver() {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 919c964..880aa57 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -56,6 +56,7 @@
import android.os.UserManager;
import android.os.WorkSource;
import android.preference.PreferenceManager;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Telephony;
import android.sysprop.TelephonyProperties;
@@ -262,6 +263,8 @@
private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
+ private static final int CMD_ERASE_MODEM_CONFIG = 74;
+ private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
// Parameters of select command.
private static final int SELECT_COMMAND = 0xA4;
@@ -298,6 +301,12 @@
private static final int MANUFACTURER_CODE_LENGTH = 8;
/**
+ * Experiment flag to enable erase modem config on reset network, default value is false
+ */
+ public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
+ "reset_network_erase_modem_config_enabled";
+
+ /**
* A request object to use for transmitting data to an ICC.
*/
private static final class IccAPDUArgument {
@@ -868,7 +877,7 @@
}
// Result cannot be null. Return ModemActivityInfo with all fields set to 0.
if (request.result == null) {
- request.result = new ModemActivityInfo(0, 0, 0, null, 0);
+ request.result = new ModemActivityInfo(0, 0, 0, new int[0], 0);
}
notifyRequester(request);
break;
@@ -1210,6 +1219,13 @@
((SIMRecords) uiccApp.getIccRecords())
.setForbiddenPlmns(onCompleted, fplmns);
}
+ case CMD_ERASE_MODEM_CONFIG:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
+ defaultPhone.eraseModemConfig(onCompleted);
+ break;
+ case EVENT_ERASE_MODEM_CONFIG_DONE:
+ handleNullReturnEvent(msg, "eraseModemConfig");
break;
default:
Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
@@ -1419,6 +1435,20 @@
return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
}
+ private void sendEraseModemConfig(Phone phone) {
+ if (phone != null) {
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+ mApp, phone.getSubId(), "eraseModemConfig");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
+ if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+
public void dial(String number) {
dialForSubscriber(getPreferredVoiceSubscription(), number);
}
@@ -1668,15 +1698,30 @@
}
}
+ @Deprecated
@Override
public boolean isRadioOn(String callingPackage) {
- return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
+ return isRadioOnWithFeature(callingPackage, null);
+ }
+
+
+ @Override
+ public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
+ return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
+ callingFeatureId);
+ }
+
+ @Deprecated
+ @Override
+ public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
+ return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
}
@Override
- public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
+ public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
return false;
}
@@ -1998,11 +2043,12 @@
}
@Override
- public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage) {
+ public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage,
+ String callingFeatureId) {
if (!TextUtils.isEmpty(callingPackage)) {
final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getNetworkCountryIsoForPhone")) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
+ callingFeatureId, "getNetworkCountryIsoForPhone")) {
return "";
}
}
@@ -2019,7 +2065,8 @@
// Todo: fix this when we can get the actual cellular network info when the device
// is on IWLAN.
if (TelephonyManager.NETWORK_TYPE_IWLAN
- == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
+ == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName(),
+ mApp.getFeatureId())) {
return "";
}
Phone phone = PhoneFactory.getPhone(phoneId);
@@ -2250,14 +2297,14 @@
}
@Override
- public String getImeiForSlot(int slotIndex, String callingPackage) {
+ public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Phone phone = PhoneFactory.getPhone(slotIndex);
if (phone == null) {
return null;
}
int subId = phone.getSubId();
if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
- callingPackage, "getImeiForSlot")) {
+ callingPackage, callingFeatureId, "getImeiForSlot")) {
return null;
}
@@ -2281,7 +2328,7 @@
}
@Override
- public String getMeidForSlot(int slotIndex, String callingPackage) {
+ public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Phone phone = PhoneFactory.getPhone(slotIndex);
if (phone == null) {
return null;
@@ -2289,7 +2336,7 @@
int subId = phone.getSubId();
if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
- callingPackage, "getMeidForSlot")) {
+ callingPackage, callingFeatureId, "getMeidForSlot")) {
return null;
}
@@ -2313,14 +2360,16 @@
}
@Override
- public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
+ public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
+ String callingFeatureId) {
Phone phone = PhoneFactory.getPhone(slotIndex);
if (phone == null) {
return null;
}
int subId = phone.getSubId();
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getDeviceSoftwareVersionForSlot")) {
return null;
}
@@ -2407,6 +2456,11 @@
mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
}
+ private void enforceActiveEmergencySessionPermission() {
+ mApp.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
+ }
+
/**
* Make sure the caller has the CALL_PHONE permission.
*
@@ -2416,9 +2470,8 @@
mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
}
- private void enforceConnectivityInternalPermission() {
- mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
- "ConnectivityService");
+ private void enforceSettingsPermission() {
+ mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
}
private String createTelUrl(String number) {
@@ -2465,14 +2518,17 @@
* Returns the CDMA ERI icon index to display
*/
@Override
- public int getCdmaEriIconIndex(String callingPackage) {
- return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
+ public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
+ return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
+ callingFeatureId);
}
@Override
- public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
+ public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getCdmaEriIconIndexForSubscriber")) {
return -1;
}
@@ -2495,14 +2551,17 @@
* 1 - FLASHING
*/
@Override
- public int getCdmaEriIconMode(String callingPackage) {
- return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
+ public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
+ return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
+ callingFeatureId);
}
@Override
- public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
+ public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getCdmaEriIconModeForSubscriber")) {
return -1;
}
@@ -2523,14 +2582,17 @@
* Returns the CDMA ERI text,
*/
@Override
- public String getCdmaEriText(String callingPackage) {
- return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
+ public String getCdmaEriText(String callingPackage, String callingFeatureId) {
+ return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
+ callingFeatureId);
}
@Override
- public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
+ public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getCdmaEriIconTextForSubscriber")) {
return null;
}
@@ -2665,10 +2727,12 @@
}
@Override
- public String getVisualVoicemailPackageName(String callingPackage, int subId) {
+ public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
+ int subId) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getVisualVoicemailPackageName")) {
return null;
}
@@ -2831,9 +2895,11 @@
* Returns the unread count of voicemails for a subId
*/
@Override
- public int getVoiceMessageCountForSubscriber(int subId, String callingPackage) {
+ public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getVoiceMessageCountForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getVoiceMessageCountForSubscriber")) {
return 0;
}
final long identity = Binder.clearCallingIdentity();
@@ -3743,13 +3809,15 @@
* Returns the data network type for a subId; does not throw SecurityException.
*/
@Override
- public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
+ public int getNetworkTypeForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
final int targetSdk = getTargetSdk(callingPackage);
if (targetSdk > android.os.Build.VERSION_CODES.Q) {
- return getDataNetworkTypeForSubscriber(subId, callingPackage);
+ return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
} else if (targetSdk == android.os.Build.VERSION_CODES.Q
&& !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
- mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getNetworkTypeForSubscriber")) {
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -3770,17 +3838,20 @@
* Returns the data network type
*/
@Override
- public int getDataNetworkType(String callingPackage) {
- return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
+ public int getDataNetworkType(String callingPackage, String callingFeatureId) {
+ return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
+ callingFeatureId);
}
/**
* Returns the data network type for a subId
*/
@Override
- public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
+ public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getDataNetworkTypeForSubscriber")) {
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -3801,9 +3872,11 @@
* Returns the Voice network type for a subId
*/
@Override
- public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
+ public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getDataNetworkTypeForSubscriber")) {
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -3857,14 +3930,17 @@
* or {@link Phone#LTE_ON_CDMA_TRUE}
*/
@Override
- public int getLteOnCdmaMode(String callingPackage) {
- return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
+ public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
+ return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
+ callingFeatureId);
}
@Override
- public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
+ public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getLteOnCdmaModeForSubscriber")) {
return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
}
@@ -4188,9 +4264,10 @@
* Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
* on a particular subscription
*/
- public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
+ public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getForbiddenPlmns")) {
+ mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
return null;
}
@@ -4222,12 +4299,13 @@
* @param appType the uicc app type, must be USIM or SIM.
* @param fplmns the Forbiden plmns list that needed to be written to the SIM.
* @param callingPackage the op Package name.
+ * @param callingFeatureId the feature in the package.
* @return number of fplmns that is successfully written to the SIM.
*/
- public int setForbiddenPlmns(
- int subId, int appType, List<String> fplmns, String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "setForbiddenPlmns")) {
+ public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
+ String callingFeatureId) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
+ callingFeatureId, "setForbiddenPlmns")) {
if (DBG) logv("no permissions for setForbiddenplmns");
throw new IllegalStateException("No Permissions for setForbiddenPlmns");
}
@@ -4403,10 +4481,11 @@
return false;
}
- public String[] getPcscfAddress(String apnType, String callingPackage) {
+ public String[] getPcscfAddress(String apnType, String callingPackage,
+ String callingFeatureId) {
final Phone defaultPhone = getDefaultPhone();
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, defaultPhone.getSubId(), callingPackage, "getPcscfAddress")) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
+ callingPackage, callingFeatureId, "getPcscfAddress")) {
return new String[0];
}
@@ -4594,7 +4673,9 @@
// may happen if the device does not support IMS.
return "";
}
- return resolver.getImsServiceConfiguration(slotId, isCarrierImsService);
+ // TODO: change API to query RCS separately.
+ return resolver.getImsServiceConfiguration(slotId, isCarrierImsService,
+ ImsFeature.FEATURE_MMTEL);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4836,10 +4917,10 @@
* @return the preferred network type, defined in RILConstants.java.
*/
@Override
- public int getCalculatedPreferredNetworkType(String callingPackage) {
+ public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
final Phone defaultPhone = getDefaultPhone();
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
- callingPackage, "getCalculatedPreferredNetworkType")) {
+ callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
return RILConstants.PREFERRED_NETWORK_MODE;
}
@@ -4912,7 +4993,7 @@
* @hide
*/
@Override
- public boolean isTetherApnRequiredForSubscriber(int subId) {
+ public boolean isTetheringApnRequiredForSubscriber(int subId) {
enforceModifyPermission();
final long identity = Binder.clearCallingIdentity();
final Phone phone = getPhone(subId);
@@ -5213,9 +5294,17 @@
@Override
public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
+ enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
+
+ final long identity = Binder.clearCallingIdentity();
+
List<String> privilegedPackages = new ArrayList<>();
- for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
- privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
+ try {
+ for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
+ privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
return privilegedPackages;
}
@@ -5288,10 +5377,11 @@
}
@Override
- public String getLine1NumberForDisplay(int subId, String callingPackage) {
+ public String getLine1NumberForDisplay(int subId, String callingPackage,
+ String callingFeatureId) {
// This is open to apps with WRITE_SMS.
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
- mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
+ mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
return null;
}
@@ -5315,9 +5405,10 @@
}
@Override
- public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
+ public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
+ mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
return null;
}
@@ -5335,12 +5426,13 @@
}
@Override
- public String[] getMergedSubscriberIds(int subId, String callingPackage) {
+ public String[] getMergedSubscriberIds(int subId, String callingPackage,
+ String callingFeatureId) {
// This API isn't public, so no need to provide a valid subscription ID - we're not worried
// about carrier-privileged callers not having access.
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
- "getMergedSubscriberIds")) {
+ callingFeatureId, "getMergedSubscriberIds")) {
return null;
}
@@ -5445,7 +5537,8 @@
// Get all subscriberIds from the group.
final List<String> mergedSubscriberIds = new ArrayList<>();
final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
- .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName());
+ .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
+ mApp.getFeatureId());
for (SubscriptionInfo subInfo : groupInfos) {
subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
if (subscriberId != null) {
@@ -5569,10 +5662,10 @@
}
@Override
- public boolean isVideoCallingEnabled(String callingPackage) {
+ public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
final Phone defaultPhone = getDefaultPhone();
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, defaultPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
+ callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
return false;
}
@@ -5593,9 +5686,11 @@
}
@Override
- public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
+ public boolean canChangeDtmfToneLength(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "isVideoCallingEnabled")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "isVideoCallingEnabled")) {
return false;
}
@@ -5611,9 +5706,9 @@
}
@Override
- public boolean isWorldPhone(int subId, String callingPackage) {
+ public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "isVideoCallingEnabled")) {
+ mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
return false;
}
@@ -5688,6 +5783,12 @@
}
}
+ @Deprecated
+ @Override
+ public String getDeviceId(String callingPackage) {
+ return getDeviceIdWithFeature(callingPackage, null);
+ }
+
/**
* Returns the unique device ID of phone, for example, the IMEI for
* GSM and the MEID for CDMA phones. Return null if device ID is not available.
@@ -5696,14 +5797,14 @@
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
@Override
- public String getDeviceId(String callingPackage) {
+ public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
final Phone phone = PhoneFactory.getPhone(0);
if (phone == null) {
return null;
}
int subId = phone.getSubId();
if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
- callingPackage, "getDeviceId")) {
+ callingPackage, callingFeatureId, "getDeviceId")) {
return null;
}
@@ -5742,9 +5843,9 @@
@Override
public int getSubIdForPhoneAccountHandle(
- PhoneAccountHandle phoneAccountHandle, String callingPackage) {
+ PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
- callingPackage, "getSubIdForPhoneAccountHandle")) {
+ callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
throw new SecurityException("Requires READ_PHONE_STATE permission.");
}
final long identity = Binder.clearCallingIdentity();
@@ -5823,7 +5924,7 @@
@Override
public void factoryReset(int subId) {
- enforceConnectivityInternalPermission();
+ enforceSettingsPermission();
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
return;
}
@@ -5849,6 +5950,13 @@
if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
ImsManager.getInstance(mApp, slotId).factoryReset();
}
+
+ // Erase modem config if erase modem on network setting is enabled.
+ String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
+ if (configValue != null && Boolean.parseBoolean(configValue)) {
+ sendEraseModemConfig(getDefaultPhone());
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -5871,7 +5979,7 @@
final long identity = Binder.clearCallingIdentity();
try {
final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
- phone.getContext().getOpPackageName());
+ phone.getContext().getOpPackageName(), phone.getContext().getFeatureId());
if (info == null) {
log("getSimLocaleForSubscriber, inactive subId: " + subId);
return null;
@@ -5909,14 +6017,16 @@
}
private List<SubscriptionInfo> getAllSubscriptionInfoList() {
- return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName());
+ return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
+ mApp.getFeatureId());
}
/**
* NOTE: this method assumes permission checks are done and caller identity has been cleared.
*/
private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
- return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName());
+ return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
+ mApp.getFeatureId());
}
private final ModemActivityInfo mLastModemActivityInfo =
@@ -6002,7 +6112,7 @@
public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
+ mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
return null;
}
@@ -6552,9 +6662,10 @@
* @hide
*/
@Override
- public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
+ public List<ClientRequestStats> getClientRequestStats(String callingPackage,
+ String callingFeatureId, int subId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getClientRequestStats")) {
+ mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
return null;
}
Phone phone = getPhone(subId);
@@ -6665,14 +6776,15 @@
* Get the current modem radio state for the given slot.
* @param slotIndex slot index.
* @param callingPackage the name of the package making the call.
+ * @param callingFeatureId The feature in the package.
* @return the current radio power state from the modem
*/
@Override
- public int getRadioPowerState(int slotIndex, String callingPackage) {
+ public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Phone phone = PhoneFactory.getPhone(slotIndex);
if (phone != null) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
+ callingPackage, callingFeatureId, "getRadioPowerState")) {
return TelephonyManager.RADIO_POWER_UNAVAILABLE;
}
@@ -7021,9 +7133,11 @@
}
@Override
- public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
+ public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "getNumberOfModemsWithSimultaneousDataConnections")) {
return -1;
}
@@ -7076,9 +7190,10 @@
@Override
public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
- String callingPackage) {
+ String callingPackage, String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, getDefaultSubscription(), callingPackage, "getEmergencyNumberList")) {
+ mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
+ "getEmergencyNumberList")) {
throw new SecurityException("Requires READ_PHONE_STATE permission.");
}
final long identity = Binder.clearCallingIdentity();
@@ -7170,6 +7285,57 @@
}
@Override
+ public int getEmergencyNumberDbVersion(int subId) {
+ enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final Phone phone = getPhone(subId);
+ if (phone == null) {
+ loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
+ return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
+ }
+ return phone.getEmergencyNumberDbVersion();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void notifyOtaEmergencyNumberDbInstalled() {
+ enforceModifyPermission();
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ for (Phone phone: PhoneFactory.getPhones()) {
+ EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+ if (tracker != null) {
+ tracker.updateOtaEmergencyNumberDatabase();
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void updateTestOtaEmergencyNumberDbFilePath(String otaFilePath) {
+ enforceActiveEmergencySessionPermission();
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ for (Phone phone: PhoneFactory.getPhones()) {
+ EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+ if (tracker != null) {
+ tracker.updateTestOtaEmergencyNumberDbFilePath(otaFilePath);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
Phone phone = getPhone(subId);
@@ -7213,12 +7379,14 @@
* Whether a modem stack is enabled or not.
*/
@Override
- public boolean isModemEnabledForSlot(int slotIndex, String callingPackage) {
+ public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
+ String callingFeatureId) {
Phone phone = PhoneFactory.getPhone(slotIndex);
if (phone == null) return false;
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, phone.getSubId(), callingPackage, "isModemEnabledForSlot")) {
+ mApp, phone.getSubId(), callingPackage, callingFeatureId,
+ "isModemEnabledForSlot")) {
throw new SecurityException("Requires READ_PHONE_STATE permission.");
}
@@ -7250,9 +7418,10 @@
@Override
@TelephonyManager.IsMultiSimSupportedResult
- public int isMultiSimSupported(String callingPackage) {
+ public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
- getDefaultPhone().getSubId(), callingPackage, "isMultiSimSupported")) {
+ getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
+ "isMultiSimSupported")) {
return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
}
@@ -7353,9 +7522,11 @@
* Return value defaults to true.
*/
@Override
- public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage) {
+ public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
+ String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, subId, callingPackage, "doesSwitchMultiSimConfigTriggerReboot")) {
+ mApp, subId, callingPackage, callingFeatureId,
+ "doesSwitchMultiSimConfigTriggerReboot")) {
return false;
}
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 428c006..672a27f 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.os.Binder;
-import android.os.Build;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
@@ -31,6 +30,7 @@
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.util.TelephonyUtils;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -83,6 +83,11 @@
STRING_ARRAY, UNKNOWN
}
+ private class CcOptionParseResult {
+ public int mSubId;
+ public boolean mPersistent;
+ }
+
// Maps carrier config keys to type. It is possible to infer the type for most carrier config
// keys by looking at the end of the string which usually tells the type.
// For instance: "xxxx_string", "xxxx_string_array", etc.
@@ -226,11 +231,12 @@
pw.println(" is specified, it will choose the default voice SIM slot.");
pw.println(" KEY: The key to the carrier config value to print. All values are printed");
pw.println(" if KEY is not specified.");
- pw.println(" cc set-value [-s SLOT_ID] KEY [NEW_VALUE]");
+ pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
pw.println(" Set carrier config KEY to NEW_VALUE.");
pw.println(" Options are:");
pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
pw.println(" is specified, it will choose the default voice SIM slot.");
+ pw.println(" -p: Value will be stored persistent");
pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
@@ -568,32 +574,47 @@
return slotId;
}
- // Get the subId from argument SLOT_ID if it was provided. Otherwise use the default
- // subscription.
- private int getSubIdFromArgumentSlotId(String tag) {
+ // Parse options related to Carrier Config Commands.
+ private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
PrintWriter errPw = getErrPrintWriter();
- int subId = SubscriptionManager.getDefaultSubscriptionId();
- String opt;
+ CcOptionParseResult result = new CcOptionParseResult();
+ result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
+ result.mPersistent = false;
+ String opt;
while ((opt = getNextOption()) != null) {
switch (opt) {
case "-s": {
try {
- subId = slotStringToSubId(tag, getNextArgRequired());
+ result.mSubId = slotStringToSubId(tag, getNextArgRequired());
+ if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
+ errPw.println(tag + "No valid subscription found.");
+ return null;
+ }
+
} catch (IllegalArgumentException e) {
// Missing slot id
errPw.println(tag + "SLOT_ID expected after -s.");
- return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ return null;
+ }
+ break;
+ }
+ case "-p": {
+ if (allowOptionPersistent) {
+ result.mPersistent = true;
+ } else {
+ errPw.println(tag + "Unexpected option " + opt);
+ return null;
}
break;
}
default: {
errPw.println(tag + "Unknown option " + opt);
- return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ return null;
}
}
}
- return subId;
+ return result;
}
private int slotStringToSubId(String tag, String slotString) {
@@ -623,7 +644,7 @@
private int handleCcCommand() {
// Verify that the user is allowed to run the command. Only allowed in rooted device in a
// non user build.
- if (Binder.getCallingUid() != Process.ROOT_UID || Build.IS_USER) {
+ if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
getErrPrintWriter().println("cc: Permission denied.");
return -1;
}
@@ -657,17 +678,16 @@
String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
String key = null;
- // Get the subId from the SLOT_ID-argument.
- int subId = getSubIdFromArgumentSlotId(tag);
- if (!SubscriptionManager.isValidSubscriptionId(subId)) {
- errPw.println(tag + "No valid subscription found.");
+ // Parse all options
+ CcOptionParseResult options = parseCcOptions(tag, false);
+ if (options == null) {
return -1;
}
// Get bundle containing all carrier configuration values.
- PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(subId);
+ PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
if (bundle == null) {
- errPw.println(tag + "No carrier config values found for subId " + subId + ".");
+ errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
return -1;
}
@@ -698,17 +718,16 @@
PrintWriter errPw = getErrPrintWriter();
String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
- // Get the subId from the SLOT_ID-argument.
- int subId = getSubIdFromArgumentSlotId(tag);
- if (!SubscriptionManager.isValidSubscriptionId(subId)) {
- errPw.println(tag + "No valid subscription found.");
+ // Parse all options
+ CcOptionParseResult options = parseCcOptions(tag, true);
+ if (options == null) {
return -1;
}
// Get bundle containing all current carrier configuration values.
- PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(subId);
+ PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
if (originalValues == null) {
- errPw.println(tag + "No carrier config values found for subId " + subId + ".");
+ errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
return -1;
}
@@ -745,12 +764,12 @@
}
// Override the value
- mCarrierConfigManager.overrideConfig(subId, overrideBundle);
+ mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
// Find bundle containing all new carrier configuration values after the override.
- PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(subId);
+ PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
if (newValues == null) {
- errPw.println(tag + "No carrier config values found for subId " + subId + ".");
+ errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
return -1;
}
@@ -768,15 +787,14 @@
PrintWriter errPw = getErrPrintWriter();
String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
- // Get the subId from the SLOT_ID-argument.
- int subId = getSubIdFromArgumentSlotId(tag);
- if (!SubscriptionManager.isValidSubscriptionId(subId)) {
- errPw.println(tag + "No valid subscription found.");
+ // Parse all options
+ CcOptionParseResult options = parseCcOptions(tag, false);
+ if (options == null) {
return -1;
}
// Clear all values that has previously been set.
- mCarrierConfigManager.overrideConfig(subId, null);
+ mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
getOutPrintWriter()
.println("All previously set carrier config override values has been cleared");
return 0;
diff --git a/src/com/android/phone/euicc/EuiccPublicActionUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccPublicActionUiDispatcherActivity.java
new file mode 100644
index 0000000..64a40b9
--- /dev/null
+++ b/src/com/android/phone/euicc/EuiccPublicActionUiDispatcherActivity.java
@@ -0,0 +1,52 @@
+/*
+ * 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.euicc;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.service.euicc.EuiccService;
+import android.telephony.euicc.EuiccManager;
+import android.util.Log;
+
+/**
+ * Trampoline activity to forward public eUICC intents to the active UI implementation.
+ *
+ * <p>Unlike {@link EuiccUiDispatcherActivity}, this activity does not require any permissions to
+ * start.
+ */
+public class EuiccPublicActionUiDispatcherActivity extends EuiccUiDispatcherActivity {
+ private static final String TAG = "EuiccPublicActionUiDispatcherActivity";
+
+ @Override
+ @Nullable
+ protected Intent getEuiccUiIntent() {
+ String action = getIntent().getAction();
+
+ Intent intent = new Intent();
+ // Propagate the extras from the original Intent.
+ intent.putExtras(getIntent());
+ switch (action) {
+ case EuiccManager.ACTION_START_EUICC_ACTIVATION:
+ intent.setAction(EuiccService.ACTION_START_EUICC_ACTIVATION);
+ break;
+ default:
+ Log.w(TAG, "Unsupported action: " + action);
+ return null;
+ }
+
+ return intent;
+ }
+}
diff --git a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
index fbe3b86..c27a82b 100644
--- a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
+++ b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
-import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -26,9 +25,8 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.UserHandle;
-import android.permission.IPermissionManager;
+import android.permission.PermissionManager;
import android.service.euicc.EuiccService;
import android.telephony.euicc.EuiccManager;
import android.util.Log;
@@ -39,21 +37,45 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
/** Trampoline activity to forward eUICC intents from apps to the active UI implementation. */
public class EuiccUiDispatcherActivity extends Activity {
private static final String TAG = "EuiccUiDispatcher";
+ private static final long CHANGE_PERMISSION_TIMEOUT_MS = 15 * 1000; // 15 seconds
/** Flags to use when querying PackageManager for Euicc component implementations. */
private static final int EUICC_QUERY_FLAGS =
PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
| PackageManager.GET_RESOLVED_FILTER;
- private final IPermissionManager mPermissionManager = AppGlobals.getPermissionManager();
+ private PermissionManager mPermissionManager;
+ private boolean mGrantPermissionDone = false;
+ private ThreadPoolExecutor mExecutor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mPermissionManager = (PermissionManager) getSystemService(Context.PERMISSION_SERVICE);
+ mExecutor = new ThreadPoolExecutor(
+ 1 /* corePoolSize */,
+ 1 /* maxPoolSize */,
+ 15, TimeUnit.SECONDS, /* keepAliveTime */
+ new LinkedBlockingQueue<>(), /* workQueue */
+ new ThreadFactory() {
+ private final AtomicInteger mCount = new AtomicInteger(1);
+
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "EuiccService #" + mCount.getAndIncrement());
+ }
+ }
+ );
try {
Intent euiccUiIntent = resolveEuiccUiIntent();
if (euiccUiIntent == null) {
@@ -93,7 +115,7 @@
return null;
}
- grantDefaultPermissionsToActiveLuiApp(activityInfo);
+ grantDefaultPermissionsToLuiApp(activityInfo);
euiccUiIntent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));
return euiccUiIntent;
@@ -128,6 +150,12 @@
return intent;
}
+ @Override
+ protected void onDestroy() {
+ mExecutor.shutdownNow();
+ super.onDestroy();
+ }
+
@VisibleForTesting
@Nullable
ActivityInfo findBestActivity(Intent euiccUiIntent) {
@@ -136,11 +164,20 @@
/** Grants default permissions to the active LUI app. */
@VisibleForTesting
- protected void grantDefaultPermissionsToActiveLuiApp(ActivityInfo activityInfo) {
+ protected void grantDefaultPermissionsToLuiApp(ActivityInfo activityInfo) {
+ CountDownLatch latch = new CountDownLatch(1);
try {
- mPermissionManager.grantDefaultPermissionsToActiveLuiApp(
- activityInfo.packageName, UserHandle.myUserId());
- } catch (RemoteException e) {
+ mPermissionManager.grantDefaultPermissionsToLuiApp(
+ activityInfo.packageName, UserHandle.of(UserHandle.myUserId()), mExecutor,
+ isSuccess -> {
+ if (isSuccess) {
+ latch.countDown();
+ } else {
+ Log.e(TAG, "Failed to revoke LUI app permissions.");
+ }
+ });
+ waitUntilReady(latch);
+ } catch (RuntimeException e) {
Log.e(TAG, "Failed to grant permissions to active LUI app.", e);
}
}
@@ -148,14 +185,22 @@
/** Cleans up all the packages that shouldn't have permission. */
@VisibleForTesting
protected void revokePermissionFromLuiApps(Intent intent) {
+ CountDownLatch latch = new CountDownLatch(1);
try {
Set<String> luiApps = getAllLuiAppPackageNames(intent);
String[] luiAppsArray = luiApps.toArray(new String[luiApps.size()]);
mPermissionManager.revokeDefaultPermissionsFromLuiApps(luiAppsArray,
- UserHandle.myUserId());
- } catch (RemoteException e) {
+ UserHandle.of(UserHandle.myUserId()), mExecutor, isSuccess -> {
+ if (isSuccess) {
+ latch.countDown();
+ } else {
+ Log.e(TAG, "Failed to revoke LUI app permissions.");
+ }
+ });
+ waitUntilReady(latch);
+ } catch (RuntimeException e) {
Log.e(TAG, "Failed to revoke LUI app permissions.");
- throw new RuntimeException(e);
+ throw e;
}
}
@@ -170,4 +215,11 @@
}
return packageNames;
}
+
+ private void waitUntilReady(CountDownLatch latch) {
+ try {
+ latch.await(CHANGE_PERMISSION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+ }
}
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index 04045f1..ce5b839 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -192,6 +192,7 @@
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;
@@ -345,12 +346,6 @@
updateImsProvisionedState();
}
- @Override
- public void onPhysicalChannelConfigurationChanged(
- List<PhysicalChannelConfig> configs) {
- updatePhysicalChannelConfiguration(configs);
- }
-
}
private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
@@ -428,6 +423,13 @@
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;
@@ -644,6 +646,8 @@
unregisterPhoneStateListener();
registerPhoneStateListener();
+ mPhone.registerForPhysicalChannelConfig(mHandler,
+ EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, null);
mConnectivityManager.registerNetworkCallback(
mDefaultNetworkRequest, mNetworkCallback, mHandler);
@@ -759,6 +763,7 @@
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("");
@@ -794,8 +799,7 @@
| PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
| PhoneStateListener.LISTEN_CELL_INFO
| PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
- | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
private void updateDnsCheckState() {
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/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 4a5fb4a..9e32f00 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -117,6 +117,8 @@
private static int toTelecomDisconnectCauseCode(int telephonyDisconnectCause) {
switch (telephonyDisconnectCause) {
case android.telephony.DisconnectCause.LOCAL:
+ // The call was still disconnected locally, so this is not an error condition.
+ case android.telephony.DisconnectCause.OUTGOING_EMERGENCY_CALL_PLACED:
return DisconnectCause.LOCAL;
case android.telephony.DisconnectCause.NORMAL:
@@ -797,6 +799,8 @@
break;
case android.telephony.DisconnectCause.IMS_ACCESS_BLOCKED:
return DisconnectCause.REASON_IMS_ACCESS_BLOCKED;
+ case android.telephony.DisconnectCause.OUTGOING_EMERGENCY_CALL_PLACED:
+ return DisconnectCause.REASON_EMERGENCY_CALL_PLACED;
}
// If no specific code-mapping found, then fall back to using the reason.
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index b47adb2..4c3f9c9 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -1030,9 +1030,9 @@
// call log.
connection.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
connection.destroy();
- handleConnectionDestruction(connection);
}
mConferenceParticipantConnections.clear();
+ updateManageConference();
}
}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 730bee5..5a1e6a6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -287,7 +287,7 @@
mIsRttCapable = false;
}
- mIsVideoCapable = mPhone.isVideoEnabled() && !mIsRttCapable;
+ mIsVideoCapable = mPhone.isVideoEnabled();
boolean isVideoEnabledByPlatform = ImsManager.getInstance(mPhone.getContext(),
mPhone.getPhoneId()).isVtEnabledByPlatform();
diff --git a/src/com/android/services/telephony/TelephonyConferenceBase.java b/src/com/android/services/telephony/TelephonyConferenceBase.java
index a8bbf64..5e7ecf6 100644
--- a/src/com/android/services/telephony/TelephonyConferenceBase.java
+++ b/src/com/android/services/telephony/TelephonyConferenceBase.java
@@ -17,6 +17,7 @@
package com.android.services.telephony;
import android.annotation.NonNull;
+import android.os.Bundle;
import android.telecom.Conference;
import android.telecom.Connection;
import android.telecom.PhoneAccountHandle;
@@ -134,9 +135,11 @@
final Connection primaryConnection = getPrimaryConnection();
if (primaryConnection != null && primaryConnection instanceof TelephonyConnection) {
TelephonyConnection telephonyConnection = (TelephonyConnection) primaryConnection;
- putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+ Bundle newExtras = new Bundle();
+ newExtras.putInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
ServiceState.rilRadioTechnologyToNetworkType(
telephonyConnection.getCallRadioTech()));
+ putExtras(newExtras);
} else {
Log.w(TAG, "No primary connection found while updateCallRadioTechAfterCreation");
}
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 87941b0..5a9fbcf 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.AsyncResult;
@@ -42,13 +43,16 @@
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsStreamMediaProfile;
import android.text.TextUtils;
import android.util.Pair;
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;
@@ -137,7 +141,7 @@
if (connection != null &&
((connection.getAddress() != null &&
mOriginalConnection.getAddress() != null &&
- mOriginalConnection.getAddress().contains(connection.getAddress())) ||
+ mOriginalConnection.getAddress().equals(connection.getAddress())) ||
connection.getState() == mOriginalConnection.getStateBeforeHandover())) {
Log.d(TelephonyConnection.this,
"SettingOriginalConnection " + mOriginalConnection.toString()
@@ -405,12 +409,26 @@
}
}
if (messageId != -1 && getPhone() != null && getPhone().getContext() != null) {
- return getPhone().getContext().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.
*/
@@ -646,6 +664,7 @@
@Override
public void onRttTerminated() {
updateConnectionProperties();
+ refreshConferenceSupported();
sendRttSessionRemotelyTerminated();
}
@@ -763,6 +782,11 @@
private boolean mShowPreciseFailedCause;
/**
+ * Provides a DisconnectCause associated with a hang up request.
+ */
+ private int mHangupDisconnectCause = DisconnectCause.NOT_VALID;
+
+ /**
* Listeners to our TelephonyConnection specific callbacks
*/
private final Set<TelephonyConnectionListener> mTelephonyListeners = Collections.newSetFromMap(
@@ -1334,6 +1358,75 @@
}
}
+ private void refreshCodecType() {
+ Bundle newExtras = getExtras();
+ if (newExtras == null) {
+ newExtras = new Bundle();
+ }
+ int newCodecType;
+ if (isImsConnection()) {
+ newCodecType = transformCodec(getOriginalConnection().getAudioCodec());
+ } else {
+ // For SRVCC, report AUDIO_CODEC_NONE.
+ newCodecType = Connection.AUDIO_CODEC_NONE;
+ }
+ int oldCodecType = newExtras.getInt(Connection.EXTRA_AUDIO_CODEC,
+ Connection.AUDIO_CODEC_NONE);
+ if (newCodecType != oldCodecType) {
+ newExtras.putInt(Connection.EXTRA_AUDIO_CODEC, newCodecType);
+ putTelephonyExtras(newExtras);
+ }
+ }
+
+ private int transformCodec(int codec) {
+ switch (codec) {
+ case ImsStreamMediaProfile.AUDIO_QUALITY_NONE:
+ return Connection.AUDIO_CODEC_NONE;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_AMR:
+ return Connection.AUDIO_CODEC_AMR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB:
+ return Connection.AUDIO_CODEC_AMR_WB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_QCELP13K:
+ return Connection.AUDIO_CODEC_QCELP13K;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC:
+ return Connection.AUDIO_CODEC_EVRC;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_B:
+ return Connection.AUDIO_CODEC_EVRC_B;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_WB:
+ return Connection.AUDIO_CODEC_EVRC_WB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_NW:
+ return Connection.AUDIO_CODEC_EVRC_NW;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_GSM_EFR:
+ return Connection.AUDIO_CODEC_GSM_EFR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_GSM_FR:
+ return Connection.AUDIO_CODEC_GSM_FR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_GSM_HR:
+ return Connection.AUDIO_CODEC_GSM_HR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G711U:
+ return Connection.AUDIO_CODEC_G711U;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G723:
+ return Connection.AUDIO_CODEC_G723;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G711A:
+ return Connection.AUDIO_CODEC_G711A;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G722:
+ return Connection.AUDIO_CODEC_G722;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G711AB:
+ return Connection.AUDIO_CODEC_G711AB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G729:
+ return Connection.AUDIO_CODEC_G729;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_NB:
+ return Connection.AUDIO_CODEC_EVS_NB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_WB:
+ return Connection.AUDIO_CODEC_EVS_WB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB:
+ return Connection.AUDIO_CODEC_EVS_SWB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_FB:
+ return Connection.AUDIO_CODEC_EVS_FB;
+ default:
+ return Connection.AUDIO_CODEC_NONE;
+ }
+ }
+
private boolean shouldSetDisableAddCallExtra() {
if (mOriginalConnection == null) {
return false;
@@ -1412,7 +1505,8 @@
b.getBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL);
}
- private PersistableBundle getCarrierConfig() {
+ @VisibleForTesting
+ public PersistableBundle getCarrierConfig() {
Phone phone = getPhone();
if (phone == null) {
return null;
@@ -1481,6 +1575,7 @@
protected void hangup(int telephonyDisconnectCode) {
if (mOriginalConnection != null) {
+ mHangupDisconnectCause = telephonyDisconnectCode;
try {
// Hanging up a ringing call requires that we invoke call.hangup() as opposed to
// connection.hangup(). Without this change, the party originating the call
@@ -1733,9 +1828,16 @@
preciseDisconnectCause =
mOriginalConnection.getPreciseDisconnectCause();
}
+ int disconnectCause = mOriginalConnection.getDisconnectCause();
+ if ((mHangupDisconnectCause != DisconnectCause.NOT_VALID)
+ && (mHangupDisconnectCause != disconnectCause)) {
+ Log.i(LOG_TAG, "setDisconnected: override cause: " + disconnectCause
+ + " -> " + mHangupDisconnectCause);
+ disconnectCause = mHangupDisconnectCause;
+ }
setTelephonyConnectionDisconnected(
DisconnectCauseUtil.toTelecomDisconnectCause(
- mOriginalConnection.getDisconnectCause(),
+ disconnectCause,
preciseDisconnectCause,
mOriginalConnection.getVendorDisconnectCause(),
getPhone().getPhoneId()));
@@ -1760,6 +1862,7 @@
updateAddress();
updateMultiparty();
refreshDisableAddCall();
+ refreshCodecType();
}
/**
@@ -1835,6 +1938,10 @@
Log.v(this, "close");
clearOriginalConnection();
destroy();
+ if (mTelephonyConnectionService != null) {
+ removeTelephonyConnectionListener(
+ mTelephonyConnectionService.getTelephonyConnectionListener());
+ }
notifyDestroyed();
}
@@ -2187,7 +2294,7 @@
Context context = getPhone().getContext();
setTelephonyStatusHints(new StatusHints(
- context.getString(labelId),
+ getResourceString(labelId),
Icon.createWithResource(
context, R.drawable.ic_signal_wifi_4_bar_24dp),
null /* extras */));
@@ -2270,7 +2377,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) {
@@ -2580,8 +2688,11 @@
// For IMS PS call conference call, it can be updated via its host connection
// {@link #Listener.onExtrasChanged} event.
if (getConference() != null) {
- getConference().putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+ Bundle newExtras = new Bundle();
+ newExtras.putInt(
+ TelecomManager.EXTRA_CALL_NETWORK_TYPE,
ServiceState.rilRadioTechnologyToNetworkType(vrat));
+ getConference().putExtras(newExtras);
}
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 2d96c6b..40c90ec 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.
@@ -182,6 +177,8 @@
public boolean isLocked = false;
// Is the emergency number associated with the slot
public boolean hasDialedEmergencyNumber = false;
+ //SimState
+ public int simState;
public SlotStatus(int slotId, int capabilities) {
this.slotId = slotId;
@@ -189,7 +186,10 @@
}
}
- // SubscriptionManager Proxy interface for testing
+ /**
+ * SubscriptionManager dependencies for testing.
+ */
+ @VisibleForTesting
public interface SubscriptionManagerProxy {
int getDefaultVoicePhoneId();
int getSimStateForSlotIdx(int slotId);
@@ -213,7 +213,9 @@
}
};
- // TelephonyManager Proxy interface for testing
+ /**
+ * TelephonyManager dependencies for testing.
+ */
@VisibleForTesting
public interface TelephonyManagerProxy {
int getPhoneCount();
@@ -253,7 +255,9 @@
}
}
- //PhoneFactory proxy interface for testing
+ /**
+ * PhoneFactory Dependencies for testing.
+ */
@VisibleForTesting
public interface PhoneFactoryProxy {
Phone getPhone(int index);
@@ -278,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 =
@@ -320,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
@@ -354,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"));
}
@@ -369,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"));
}
@@ -377,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()));
@@ -389,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"));
}
@@ -398,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"));
}
@@ -419,7 +591,7 @@
if (disableActivation) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause
.CDMA_ALREADY_ACTIVATED,
"Tried to dial *228",
@@ -443,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;
@@ -454,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();
@@ -464,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) {
@@ -581,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());
}
@@ -625,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."));
}
@@ -648,13 +816,14 @@
// TODO: Switch out the underlying connection instead of creating a new
// one and causing UI Jank.
boolean noActiveSimCard = SubscriptionController.getInstance()
- .getActiveSubInfoCount(phone.getContext().getOpPackageName()) == 0;
+ .getActiveSubInfoCount(phone.getContext().getOpPackageName(),
+ phone.getContext().getFeatureId()) == 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()));
@@ -683,7 +852,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();
@@ -708,7 +877,7 @@
}
}
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE,
"SIM_STATE_PIN_REQUIRED"));
}
@@ -716,7 +885,7 @@
Log.d(this, "onCreateOutgoingConnection, phone is null");
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE, "Phone is null"));
}
@@ -744,7 +913,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()));
@@ -762,7 +931,7 @@
break;
} else {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE,
"ServiceState.STATE_OUT_OF_SERVICE",
phone.getPhoneId()));
@@ -773,25 +942,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()));
}
@@ -805,7 +973,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()));
@@ -814,10 +982,10 @@
final TelephonyConnection connection =
createConnectionFor(phone, null, true /* isOutgoing */, request.getAccountHandle(),
- request.getTelecomCallId(), request.getAddress(), request.getVideoState());
+ request.getTelecomCallId());
if (connection == null) {
return Connection.createFailedConnection(
- DisconnectCauseUtil.toTelecomDisconnectCause(
+ mDisconnectCauseFactory.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_FAILURE,
"Invalid phone type",
phone.getPhoneId()));
@@ -850,7 +1018,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"));
}
@@ -859,7 +1027,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()));
@@ -873,19 +1041,14 @@
return Connection.createCanceledConnection();
}
- // We should rely on the originalConnection to get the video state. The request coming
- // from Telecom does not know the video state of the incoming call.
- int videoState = originalConnection != null ? originalConnection.getVideoState() :
- VideoProfile.STATE_AUDIO_ONLY;
-
TelephonyConnection connection =
createConnectionFor(phone, originalConnection, false /* isOutgoing */,
- request.getAccountHandle(), request.getTelecomCallId(),
- request.getAddress(), videoState);
+ request.getAccountHandle(), request.getTelecomCallId());
handleIncomingRtt(request, originalConnection);
if (connection == null) {
return Connection.createCanceledConnection();
} else {
+ connection.setTtyEnabled(mDeviceState.isTtyModeEnabled(getApplicationContext()));
return connection;
}
}
@@ -938,6 +1101,61 @@
}
@Override
+ public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request) {
+ Log.i(this, "onCreateIncomingConnectionFailed, request: " + request);
+ // If there is an incoming emergency CDMA Call (while the phone is in ECBM w/ No SIM),
+ // make sure the PhoneAccount lookup retrieves the default Emergency Phone.
+ PhoneAccountHandle accountHandle = request.getAccountHandle();
+ boolean isEmergency = false;
+ if (accountHandle != null && PhoneUtils.EMERGENCY_ACCOUNT_HANDLE_ID.equals(
+ accountHandle.getId())) {
+ Log.w(this, "onCreateIncomingConnectionFailed:Emergency call failed... ");
+ isEmergency = true;
+ }
+ Phone phone = getPhoneForAccount(accountHandle, isEmergency,
+ /* Note: when not an emergency, handle can be null for unknown callers */
+ request.getAddress() == null ? null : request.getAddress().getSchemeSpecificPart());
+ if (phone == null) {
+ Log.w(this, "onCreateIncomingConnectionFailed: can not find corresponding phone.");
+ return;
+ }
+
+ Call call = phone.getRingingCall();
+ if (!call.getState().isRinging()) {
+ Log.w(this, "onCreateIncomingConnectionFailed, no ringing call found for failed call");
+ return;
+ }
+
+ com.android.internal.telephony.Connection originalConnection =
+ call.getState() == Call.State.WAITING
+ ? call.getLatestConnection() : call.getEarliestConnection();
+ TelephonyConnection knownConnection =
+ getConnectionForOriginalConnection(originalConnection);
+ if (knownConnection != null) {
+ Log.w(this, "onCreateIncomingConnectionFailed, original connection already registered."
+ + " Hanging it up.");
+ knownConnection.onAbort();
+ return;
+ }
+
+ TelephonyConnection connection =
+ createConnectionFor(phone, originalConnection, false /* isOutgoing */,
+ request.getAccountHandle(), request.getTelecomCallId());
+ if (connection == null) {
+ Log.w(this, "onCreateIncomingConnectionFailed, TelephonyConnection created as null, "
+ + "ignoring.");
+ return;
+ }
+
+ // We have to do all of this work because in some cases, hanging up the call maps to
+ // different underlying signaling (CDMA), which is already encapsulated in
+ // TelephonyConnection.
+ connection.onReject();
+ connection.close();
+ }
+
+ @Override
public void triggerConferenceRecalculate() {
if (mTelephonyConferenceController.shouldRecalculate()) {
mTelephonyConferenceController.recalculate();
@@ -963,7 +1181,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"));
}
@@ -1036,8 +1254,8 @@
TelephonyConnection connection =
createConnectionFor(phone, unknownConnection,
!unknownConnection.isIncoming() /* isOutgoing */,
- request.getAccountHandle(), request.getTelecomCallId(),
- request.getAddress(), videoState);
+ request.getAccountHandle(), request.getTelecomCallId()
+ );
if (connection == null) {
return Connection.createCanceledConnection();
@@ -1216,7 +1434,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.
@@ -1240,6 +1458,19 @@
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);
+ }
+ }
+ }
}
originalConnection = phone.dial(number, new ImsPhone.ImsDialArgs.Builder()
.setVideoState(videoState)
@@ -1274,7 +1505,7 @@
break;
}
connection.setTelephonyConnectionDisconnected(
- DisconnectCauseUtil.toTelecomDisconnectCause(cause, e.getMessage(),
+ mDisconnectCauseFactory.toTelecomDisconnectCause(cause, e.getMessage(),
phone.getPhoneId()));
connection.close();
return;
@@ -1298,7 +1529,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 {
@@ -1306,14 +1537,24 @@
}
}
+ private boolean shouldHoldForEmergencyCall(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, "shouldHoldForEmergencyCall: couldn't get CarrierConfigManager");
+ return true;
+ }
+ return cfgManager.getConfigForSubId(phone.getSubId()).getBoolean(
+ CarrierConfigManager.KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL, true);
+ }
+
private TelephonyConnection createConnectionFor(
Phone phone,
com.android.internal.telephony.Connection originalConnection,
boolean isOutgoing,
PhoneAccountHandle phoneAccountHandle,
- String telecomCallId,
- Uri address,
- int videoState) {
+ String telecomCallId) {
TelephonyConnection returnConnection = null;
int phoneType = phone.getPhoneType();
if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
@@ -1342,15 +1583,20 @@
private boolean isOriginalConnectionKnown(
com.android.internal.telephony.Connection originalConnection) {
+ return (getConnectionForOriginalConnection(originalConnection) != null);
+ }
+
+ private TelephonyConnection getConnectionForOriginalConnection(
+ com.android.internal.telephony.Connection originalConnection) {
for (Connection connection : getAllConnections()) {
if (connection instanceof TelephonyConnection) {
TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
if (telephonyConnection.getOriginalConnection() == originalConnection) {
- return true;
+ return telephonyConnection;
}
}
}
- return false;
+ return null;
}
/**
@@ -1365,7 +1611,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);
@@ -1395,7 +1641,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;
}
@@ -1415,13 +1661,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) {
@@ -1430,34 +1684,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);
}
@@ -1465,7 +1726,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.
@@ -1474,12 +1735,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;
}
@@ -1586,6 +1848,8 @@
// 4)
// Report Slot's PIN/PUK lock status for sorting later.
int simState = mSubscriptionManagerProxy.getSimStateForSlotIdx(i);
+ // Record SimState.
+ status.simState = simState;
if (simState == TelephonyManager.SIM_STATE_PIN_REQUIRED ||
simState == TelephonyManager.SIM_STATE_PUK_REQUIRED) {
status.isLocked = true;
@@ -1631,6 +1895,15 @@
if (o1.hasDialedEmergencyNumber && !o2.hasDialedEmergencyNumber) {
return 1;
}
+ // Sort by non-absent SIM.
+ if (o1.simState == TelephonyManager.SIM_STATE_ABSENT
+ && o2.simState != TelephonyManager.SIM_STATE_ABSENT) {
+ return -1;
+ }
+ if (o2.simState == TelephonyManager.SIM_STATE_ABSENT
+ && o1.simState != TelephonyManager.SIM_STATE_ABSENT) {
+ return 1;
+ }
// First start by seeing if either of the phone slots are locked. If they
// are, then sort by non-locked SIM first. If they are both locked, sort
// by capability instead.
@@ -1708,13 +1981,8 @@
return true;
}
- @Override
- public void removeConnection(Connection connection) {
- super.removeConnection(connection);
- if (connection instanceof TelephonyConnection) {
- TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
- telephonyConnection.removeTelephonyConnectionListener(mTelephonyConnectionListener);
- }
+ TelephonyConnection.TelephonyConnectionListener getTelephonyConnectionListener() {
+ return mTelephonyConnectionListener;
}
/**
@@ -1789,13 +2057,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
new file mode 100644
index 0000000..de44863
--- /dev/null
+++ b/tests/Android.bp
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2009 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.
+//
+
+android_test {
+ name: "TeleServiceTests",
+
+ srcs: ["src/**/*.java"],
+
+ libs: [
+ "android.test.mock",
+ "android.test.runner",
+ "telephony-common",
+ "android.test.base",
+ "ims-common",
+ ],
+ platform_apis: true,
+ certificate: "platform",
+
+ instrumentation_for: "TeleServiceLib",
+
+ static_libs: [
+ "androidx.test.rules",
+ "mockito-target-minus-junit4",
+ "androidx.test.espresso.core",
+ "truth-prebuilt",
+ ],
+
+ test_suites: [
+ "device-tests",
+ "mts",
+ ],
+
+}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index a8bd204..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_PACKAGE_NAME := TeleServiceTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JAVA_LIBRARIES := telephony-common android.test.base ims-common
-
-LOCAL_INSTRUMENTATION_FOR := TeleService
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.rules \
- mockito-target-minus-junit4 \
- androidx.test.espresso.core \
- truth-prebuilt
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index d434650..17f4a8f 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"
+ android:targetPackage="com.android.phone.lib"
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..f4ce494
--- /dev/null
+++ b/tests/src/com/android/TestContext.java
@@ -0,0 +1,127 @@
+/*
+ * 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 String getFeatureId() {
+ return "";
+ }
+
+ @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/CallFeaturesSettingTest.java b/tests/src/com/android/phone/CallFeaturesSettingTest.java
index 15d48ba..7c7d6f8 100644
--- a/tests/src/com/android/phone/CallFeaturesSettingTest.java
+++ b/tests/src/com/android/phone/CallFeaturesSettingTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
+import android.app.KeyguardManager;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
@@ -35,6 +36,7 @@
import com.android.internal.telephony.PhoneConstants;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
@@ -49,17 +51,19 @@
IccCard mMockIccCard;
@Rule
public ActivityTestRule<CallFeaturesSetting> mRule =
- new ActivityTestRule<>(CallFeaturesSetting.class);
+ new ActivityTestRule<>(CallFeaturesSetting.class, false, true);
private CallFeaturesSetting mActivity;
@Before
- public void setUp() {
+ public void setUp() throws Throwable {
MockitoAnnotations.initMocks(this);
mActivity = mRule.getActivity();
Context targetContext = InstrumentationRegistry.getTargetContext();
doReturn(targetContext).when(mMockPhone).getContext();
+ keepScreenOn(mRule, mActivity);
}
+ @Ignore
@FlakyTest
@Test
public void onResume_fdnIsAvailable_shouldShowFdnMenu() throws NoSuchFieldException,
@@ -69,12 +73,13 @@
when(mMockIccCard.getIccFdnAvailable()).thenReturn(true);
getField("mPhone").set(mActivity, mMockPhone);
- mActivity.onResume();
+ mActivity.runOnUiThread(() -> mActivity.onResume());
// Check the FDN menu is displayed.
onView(withText(R.string.fdn)).check(matches(isDisplayed()));
}
+ @Ignore
@FlakyTest
@Test
public void onResume_iccCardIsNull_shouldNotShowFdnMenu() throws NoSuchFieldException,
@@ -83,12 +88,13 @@
when(mMockPhone.getIccCard()).thenReturn(null);
getField("mPhone").set(mActivity, mMockPhone);
- mActivity.onResume();
+ mActivity.runOnUiThread(() -> mActivity.onResume());
// Check the FDN menu is not displayed.
onView(withText(R.string.fdn)).check(doesNotExist());
}
+ @Ignore
@FlakyTest
@Test
public void onResume_fdnIsNotAvailable_shouldNotShowFdnMenu() throws NoSuchFieldException,
@@ -98,7 +104,7 @@
when(mMockIccCard.getIccFdnAvailable()).thenReturn(false);
getField("mPhone").set(mActivity, mMockPhone);
- mActivity.onResume();
+ mActivity.runOnUiThread(() -> mActivity.onResume());
// Check the FDN menu is not displayed.
onView(withText(R.string.fdn)).check(doesNotExist());
@@ -109,4 +115,19 @@
field.setAccessible(true);
return field;
}
+
+ /**
+ * Automatically wake up device to perform tests.
+ */
+ private static void keepScreenOn(ActivityTestRule activityTestRule,
+ final CallFeaturesSetting activity) throws Throwable {
+ activityTestRule.runOnUiThread(() -> {
+ activity.setTurnScreenOn(true);
+ activity.setShowWhenLocked(true);
+ KeyguardManager keyguardManager =
+ activity.getSystemService(KeyguardManager.class);
+ keyguardManager.requestDismissKeyguard(activity, null);
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
}
diff --git a/tests/src/com/android/phone/LocationAccessPolicyTest.java b/tests/src/com/android/phone/LocationAccessPolicyTest.java
index 6939108..f2bc8d2 100644
--- a/tests/src/com/android/phone/LocationAccessPolicyTest.java
+++ b/tests/src/com/android/phone/LocationAccessPolicyTest.java
@@ -35,6 +35,7 @@
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 +172,7 @@
mScenario = scenario;
}
-
+ @Ignore
@Test
public void test() {
setupScenario(mScenario);
@@ -188,10 +189,10 @@
anyInt(), anyInt())).thenReturn(s.appHasCoarseManifest
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
- when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_FINE_LOCATION),
+ when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OPSTR_FINE_LOCATION),
anyInt(), anyString(), nullable(String.class), nullable(String.class)))
.thenReturn(s.fineAppOp);
- when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_COARSE_LOCATION),
+ when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OPSTR_COARSE_LOCATION),
anyInt(), anyString(), nullable(String.class), nullable(String.class)))
.thenReturn(s.coarseAppOp);
diff --git a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
index b8f2ec1..85dba51 100644
--- a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
+++ b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
@@ -121,7 +121,7 @@
}
@Override
- protected void grantDefaultPermissionsToActiveLuiApp(ActivityInfo activityInfo) {}
+ protected void grantDefaultPermissionsToLuiApp(ActivityInfo activityInfo) {}
@Override
protected void revokePermissionFromLuiApps(Intent intent) {}
diff --git a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
index edfc34f..19e802b 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
@@ -30,6 +30,7 @@
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;
@@ -109,6 +110,7 @@
* 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 7251402..d294604 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -38,6 +38,7 @@
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;
@@ -65,6 +66,7 @@
.thenReturn(null);
}
+ @Ignore
@Test
@SmallTest
public void testSinglePartyEmulation() {
@@ -112,6 +114,7 @@
/**
* Tests CEPs with disconnected participants present with disconnected state.
*/
+ @Ignore
@Test
@SmallTest
public void testDisconnectParticipantViaDisconnectState() {
@@ -175,6 +178,7 @@
/**
* Tests CEPs with removed participants.
*/
+ @Ignore
@Test
@SmallTest
public void testDisconnectParticipantViaRemoval() {
@@ -232,6 +236,7 @@
*
* This test verifies that we can still enter single party emulation in this case.
*/
+ @Ignore
@Test
@SmallTest
public void testSinglePartyEmulationEnterOnDisconnectParticipant() {
@@ -290,6 +295,7 @@
* 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() {
@@ -346,6 +352,7 @@
* Verify that the single party emulate correctly when the conference start with only
* one participant.
*/
+ @Ignore
@Test
@SmallTest
public void testSinglePartyEmulationWithOneParticipantAtBeginning() {
@@ -370,6 +377,7 @@
/**
* Verify that we do not use single party emulation when a sim call manager is in use.
*/
+ @Ignore
@Test
@SmallTest
public void testNoSinglePartyEmulationWithSimCallManager() {
@@ -408,6 +416,7 @@
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 ab4c067..cd7a580 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -17,35 +17,47 @@
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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
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.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;
@@ -57,6 +69,8 @@
import org.mockito.Mock;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
/**
@@ -70,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
@@ -280,6 +346,37 @@
/**
* Prerequisites:
+ * - MSIM Device, only slot 1 inserted and PUK locked
+ * - slot 1 has higher capabilities
+ *
+ * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one
+ * with a SIM inserted (even if it is PUK locked)
+ */
+ @Test
+ @SmallTest
+ public void testSlot1PinLockedAndSlot0Absent() {
+ Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
+ false /*isEmergencyOnly*/);
+ Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
+ false /*isEmergencyOnly*/);
+ setDefaultPhone(slot0Phone);
+ setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID);
+ setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT);
+ setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_PIN_REQUIRED);
+ // Slot 1 has more capabilities
+ setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM);
+ setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE);
+ // Slot 1 has SIM inserted.
+ setSlotHasIccCard(SLOT_0_PHONE_ID, false /*isInserted*/);
+ setSlotHasIccCard(SLOT_1_PHONE_ID, true /*isInserted*/);
+
+ Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall();
+
+ assertEquals(slot1Phone, resultPhone);
+ }
+
+ /**
+ * Prerequisites:
* - MSIM Device, two slots with SIMs inserted
* - Slot 1 is LTE capable, Slot 0 is GSM capable
*
@@ -524,7 +621,6 @@
* called.
*/
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialTempFailOneSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -533,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*/);
@@ -555,8 +651,8 @@
* Verify that the connection is set to disconnected with an error disconnect cause and dial is
* not called.
*/
+
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialPermFailOneSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -565,7 +661,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*/);
@@ -590,7 +686,6 @@
* PhoneAccount.
*/
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialTempFailTwoSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -599,11 +694,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*/);
@@ -628,7 +727,6 @@
* PhoneAccount.
*/
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialPermFailTwoSlot() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -637,11 +735,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*/);
@@ -666,7 +768,6 @@
* notified of this twice.
*/
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialTempFailTwoSlot_twoFailure() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -675,11 +776,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*/);
@@ -718,7 +823,6 @@
* notified of the change to slot 1.
*/
@Test
- @FlakyTest
@SmallTest
public void testRetryOutgoingOriginalConnection_redialPermFailTwoSlot_twoFailure() {
TestTelephonyConnection c = new TestTelephonyConnection();
@@ -727,11 +831,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*/);
@@ -769,6 +877,7 @@
// registration to occur.
Phone phone = c.getPhone();
c.setOriginalConnection(c.getOriginalConnection());
+ 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.
@@ -805,6 +914,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;
@@ -817,6 +1159,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
new file mode 100644
index 0000000..cfc0ccc
--- /dev/null
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -0,0 +1,25 @@
+package com.android.services.telephony;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.os.Bundle;
+import android.telecom.Connection;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class TelephonyConnectionTest {
+
+ @Test
+ public void testCodecInIms() {
+ TestTelephonyConnection c = new TestTelephonyConnection();
+ c.updateState();
+ Bundle extras = c.getExtras();
+ int codec = extras.getInt(Connection.EXTRA_AUDIO_CODEC, Connection.AUDIO_CODEC_NONE);
+ assertEquals(codec, Connection.AUDIO_CODEC_AMR);
+ }
+
+}
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index f77fd30..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;
@@ -80,6 +81,9 @@
mOriginalConnection = mock(Connection.class);
// Set up mMockRadioConnection and mMockPhone to contain an active call
when(mMockRadioConnection.getState()).thenReturn(Call.State.ACTIVE);
+ when(mOriginalConnection.getState()).thenReturn(Call.State.ACTIVE);
+ when(mMockRadioConnection.getAudioCodec()).thenReturn(
+ android.telecom.Connection.AUDIO_CODEC_AMR);
when(mMockRadioConnection.getCall()).thenReturn(mMockCall);
when(mMockRadioConnection.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
doNothing().when(mMockRadioConnection).addListener(any(Connection.Listener.class));
@@ -132,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;
}