diff options
Diffstat (limited to 'src')
14 files changed, 525 insertions, 138 deletions
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java index aec3d39862..04cfae5236 100644 --- a/src/com/android/phone/EmergencyDialer.java +++ b/src/com/android/phone/EmergencyDialer.java @@ -261,8 +261,6 @@ public class EmergencyDialer extends Activity implements View.OnClickListener, mEntryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN); Log.d(LOG_TAG, "Launched from " + entryTypeToString(mEntryType)); - // Allow this activity to be displayed in front of the keyguard / lockscreen. - setShowWhenLocked(true); // Allow turning screen on setTurnScreenOn(true); diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java index c92e71dd97..3cea76459b 100644 --- a/src/com/android/phone/NotificationMgr.java +++ b/src/com/android/phone/NotificationMgr.java @@ -18,6 +18,7 @@ package com.android.phone; import static android.Manifest.permission.READ_PHONE_STATE; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.BroadcastOptions; import android.app.Notification; @@ -47,6 +48,7 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.telephony.PhoneNumberUtils; +import android.telephony.RadioAccessFamily; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -59,6 +61,7 @@ import android.widget.Toast; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; +import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.TelephonyCapabilities; import com.android.internal.telephony.util.NotificationChannelController; import com.android.phone.settings.VoicemailSettingsActivity; @@ -907,15 +910,21 @@ public class NotificationMgr { Log.i(LOG_TAG, msg); } - /** - * In case network selection notification shows up repeatedly under - * unstable network condition. The logic is to check whether or not - * the service state keeps in no service condition for at least - * {@link #NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIME_IN_MS}. - * And checking {@link #NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIMES} times. - * To avoid the notification showing up for the momentary state. - */ private void shouldShowNotification(int serviceState, int subId) { + // "Network selection unavailable" notification should only show when network selection is + // visible to the end user. Some CC items e.g. KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL + // can be overridden to hide the network selection to the end user. In this case, the + // notification is not shown to avoid confusion to the end user. + if (!shouldDisplayNetworkSelectOptions(subId)) { + logi("Skipping network selection unavailable notification due to carrier policy."); + return; + } + + // In unstable network condition, the phone may go in and out of service. Add logic here to + // debounce the network selection notification. The notification only shows after phone is + // out of service, AND fulfills one of the two conditions below: + // - Out of service lasts {@link #NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIME_IN_MS} + // - Or has checked {@link #NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIMES} times if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) { if (mPreviousServiceState.get(subId, STATE_UNKNOWN_SERVICE) != ServiceState.STATE_OUT_OF_SERVICE) { @@ -967,4 +976,111 @@ public class NotificationMgr { private static long getTimeStamp() { return SystemClock.elapsedRealtime(); } + + // TODO(b/243010310): merge methods below with Settings#MobileNetworkUtils and optimize them. + // The methods below are copied from com.android.settings.network.telephony.MobileNetworkUtils + // to make sure the network selection unavailable notification should not show when network + // selection menu is not visible to the end user in Settings app. + private boolean shouldDisplayNetworkSelectOptions(int subId) { + final TelephonyManager telephonyManager = mTelephonyManager.createForSubscriptionId(subId); + final CarrierConfigManager carrierConfigManager = mContext.getSystemService( + CarrierConfigManager.class); + final PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId); + + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID + || carrierConfig == null + || !carrierConfig.getBoolean( + CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL) + || carrierConfig.getBoolean( + CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) + || (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL) + && !telephonyManager.isManualNetworkSelectionAllowed())) { + return false; + } + + if (isWorldMode(carrierConfig)) { + final int networkMode = RadioAccessFamily.getNetworkTypeFromRaf( + (int) telephonyManager.getAllowedNetworkTypesForReason( + TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)); + if (networkMode == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO) { + return false; + } + if (shouldSpeciallyUpdateGsmCdma(telephonyManager, carrierConfig)) { + return false; + } + if (networkMode == RILConstants.NETWORK_MODE_LTE_GSM_WCDMA) { + return true; + } + } + + return isGsmBasicOptions(telephonyManager, carrierConfig); + } + + private static boolean isWorldMode(@NonNull PersistableBundle carrierConfig) { + return carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL); + } + + private static boolean shouldSpeciallyUpdateGsmCdma(@NonNull TelephonyManager telephonyManager, + @NonNull PersistableBundle carrierConfig) { + if (!isWorldMode(carrierConfig)) { + return false; + } + + final int networkMode = RadioAccessFamily.getNetworkTypeFromRaf( + (int) telephonyManager.getAllowedNetworkTypesForReason( + TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)); + if (networkMode == RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM + || networkMode == RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA + || networkMode == RILConstants.NETWORK_MODE_LTE_TDSCDMA + || networkMode == RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA + || networkMode + == RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA + || networkMode == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) { + if (!isTdscdmaSupported(telephonyManager, carrierConfig)) { + return true; + } + } + + return false; + } + + private static boolean isTdscdmaSupported(@NonNull TelephonyManager telephonyManager, + @NonNull PersistableBundle carrierConfig) { + if (carrierConfig.getBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL)) { + return true; + } + final String[] numericArray = carrierConfig.getStringArray( + CarrierConfigManager.KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY); + if (numericArray == null) { + return false; + } + final ServiceState serviceState = telephonyManager.getServiceState(); + final String operatorNumeric = + (serviceState != null) ? serviceState.getOperatorNumeric() : null; + if (operatorNumeric == null) { + return false; + } + for (String numeric : numericArray) { + if (operatorNumeric.equals(numeric)) { + return true; + } + } + return false; + } + + private static boolean isGsmBasicOptions(@NonNull TelephonyManager telephonyManager, + @NonNull PersistableBundle carrierConfig) { + if (!carrierConfig.getBoolean( + CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) + && carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) { + return true; + } + + if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { + return true; + } + + return false; + } + // END of TODO:(b/243010310): merge methods above with Settings#MobileNetworkUtils and optimize. } diff --git a/src/com/android/phone/PhoneDisplayMessage.java b/src/com/android/phone/PhoneDisplayMessage.java index be7fc7fd47..c487cba0d9 100644 --- a/src/com/android/phone/PhoneDisplayMessage.java +++ b/src/com/android/phone/PhoneDisplayMessage.java @@ -80,7 +80,8 @@ public class PhoneDisplayMessage { sDisplayMessageDialog.getWindow().addFlags( WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON - | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); sDisplayMessageDialog.show(); } diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java index 45fae1f707..ca4a3aaeea 100644 --- a/src/com/android/phone/PhoneGlobals.java +++ b/src/com/android/phone/PhoneGlobals.java @@ -582,15 +582,15 @@ public class PhoneGlobals extends ContextWrapper { mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null); mTelephonyCallbacks = new PhoneAppCallback[tm.getSupportedModemCount()]; - - for (Phone phone : PhoneFactory.getPhones()) { - int subId = phone.getSubId(); - PhoneAppCallback callback = new PhoneAppCallback(subId); - tm.createForSubscriptionId(subId).registerTelephonyCallback( - TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mHandler::post, callback); - mTelephonyCallbacks[phone.getPhoneId()] = callback; + if (tm.getSupportedModemCount() > 0) { + for (Phone phone : PhoneFactory.getPhones()) { + int subId = phone.getSubId(); + PhoneAppCallback callback = new PhoneAppCallback(subId); + tm.createForSubscriptionId(subId).registerTelephonyCallback( + TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mHandler::post, callback); + mTelephonyCallbacks[phone.getPhoneId()] = callback; + } } - mCarrierVvmPackageInstalledReceiver.register(this); //set the default values for the preferences in the phone. diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java index 19447634da..dc2885b953 100755 --- a/src/com/android/phone/PhoneInterfaceManager.java +++ b/src/com/android/phone/PhoneInterfaceManager.java @@ -50,6 +50,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.LocaleList; import android.os.Looper; import android.os.Message; import android.os.Messenger; @@ -1414,6 +1415,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { request = (MainThreadRequest) ar.userObj; ResultReceiver result = (ResultReceiver) request.argument; int error = 0; + ModemActivityInfo ret = null; if (mLastModemActivityInfo == null) { mLastModemActivitySpecificInfo = new ActivityStatsTechSpecificInfo[1]; mLastModemActivitySpecificInfo[0] = @@ -1432,12 +1434,14 @@ public class PhoneInterfaceManager extends ITelephony.Stub { if (isModemActivityInfoValid(info)) { mergeModemActivityInfo(info); } - mLastModemActivityInfo = - new ModemActivityInfo( - mLastModemActivityInfo.getTimestampMillis(), - mLastModemActivityInfo.getSleepTimeMillis(), - mLastModemActivityInfo.getIdleTimeMillis(), - mLastModemActivitySpecificInfo); + // This is needed to decouple ret from mLastModemActivityInfo + // We don't want to return mLastModemActivityInfo which is updated + // inside mergeModemActivityInfo() + ret = new ModemActivityInfo( + mLastModemActivityInfo.getTimestampMillis(), + mLastModemActivityInfo.getSleepTimeMillis(), + mLastModemActivityInfo.getIdleTimeMillis(), + deepCopyModemActivitySpecificInfo(mLastModemActivitySpecificInfo)); } else { if (ar.result == null) { @@ -1455,10 +1459,10 @@ public class PhoneInterfaceManager extends ITelephony.Stub { } } Bundle bundle = new Bundle(); - if (mLastModemActivityInfo != null) { + if (ret != null) { bundle.putParcelable( TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, - mLastModemActivityInfo); + ret); } else { bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error); } @@ -6337,8 +6341,14 @@ public class PhoneInterfaceManager extends ITelephony.Stub { private SecurityException checkNetworkRequestForSanitizedLocationAccess( NetworkScanRequest request, int subId, String callingPackage) { - boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage) - == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + boolean hasCarrierPriv; + final long identity = Binder.clearCallingIdentity(); + try { + hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage) + == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + } finally { + Binder.restoreCallingIdentity(identity); + } boolean hasNetworkScanPermission = mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN) == PERMISSION_GRANTED; @@ -7717,7 +7727,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { if (!localeFromDefaultSim.getCountry().isEmpty()) { if (DBG) log("Using locale from subId: " + subId + " locale: " + localeFromDefaultSim); - return localeFromDefaultSim.toLanguageTag(); + return matchLocaleFromSupportedLocaleList(localeFromDefaultSim); } else { simLanguage = localeFromDefaultSim.getLanguage(); } @@ -7730,7 +7740,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage); if (mccLocale != null) { if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale); - return mccLocale.toLanguageTag(); + return matchLocaleFromSupportedLocaleList(mccLocale); } if (DBG) log("No locale found - returning null"); @@ -7740,6 +7750,21 @@ public class PhoneInterfaceManager extends ITelephony.Stub { } } + @VisibleForTesting + String matchLocaleFromSupportedLocaleList(@NonNull Locale inputLocale) { + String[] supportedLocale = com.android.internal.app.LocalePicker.getSupportedLocales( + getDefaultPhone().getContext()); + for (String localeTag : supportedLocale) { + if (LocaleList.matchesLanguageAndScript( + inputLocale, Locale.forLanguageTag(localeTag)) + && inputLocale.getCountry().equals( + Locale.forLanguageTag(localeTag).getCountry())) { + return localeTag; + } + } + return inputLocale.toLanguageTag(); + } + private List<SubscriptionInfo> getAllSubscriptionInfoList() { return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(), mApp.getAttributionTag()); @@ -7831,7 +7856,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { */ private void mergeModemActivityInfo(ModemActivityInfo info) { List<ActivityStatsTechSpecificInfo> merged = new ArrayList<>(); - ActivityStatsTechSpecificInfo mDeltaSpecificInfo; + ActivityStatsTechSpecificInfo deltaSpecificInfo; boolean matched; for (int i = 0; i < info.getSpecificInfoLength(); i++) { matched = false; @@ -7856,13 +7881,13 @@ public class PhoneInterfaceManager extends ITelephony.Stub { } if (!matched) { - mDeltaSpecificInfo = + deltaSpecificInfo = new ActivityStatsTechSpecificInfo( rat, freq, info.getTransmitTimeMillis(rat, freq), (int) info.getReceiveTimeMillis(rat, freq)); - merged.addAll(Arrays.asList(mDeltaSpecificInfo)); + merged.addAll(Arrays.asList(deltaSpecificInfo)); } } merged.addAll(Arrays.asList(mLastModemActivitySpecificInfo)); @@ -7877,6 +7902,26 @@ public class PhoneInterfaceManager extends ITelephony.Stub { mLastModemActivityInfo.setIdleTimeMillis( info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis()); + + mLastModemActivityInfo = + new ModemActivityInfo( + mLastModemActivityInfo.getTimestampMillis(), + mLastModemActivityInfo.getSleepTimeMillis(), + mLastModemActivityInfo.getIdleTimeMillis(), + mLastModemActivitySpecificInfo); + } + + private ActivityStatsTechSpecificInfo[] deepCopyModemActivitySpecificInfo( + ActivityStatsTechSpecificInfo[] info) { + int infoSize = info.length; + ActivityStatsTechSpecificInfo[] ret = new ActivityStatsTechSpecificInfo[infoSize]; + for (int i = 0; i < infoSize; i++) { + ret[i] = new ActivityStatsTechSpecificInfo( + info[i].getRat(), info[i].getFrequencyRange(), + info[i].getTransmitTimeMillis(), + (int) info[i].getReceiveTimeMillis()); + } + return ret; } /** @@ -8109,8 +8154,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { } String vvmPackage = componentName.getPackageName(); if (!callingPackage.equals(vvmPackage)) { - throw new SecurityException("Caller not current active visual voicemail package[" - + vvmPackage + "]"); + throw new SecurityException("Caller not current active visual voicemail package"); } } finally { Binder.restoreCallingIdentity(identity); diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java index fec7402ba6..a66f3ee8ff 100644 --- a/src/com/android/phone/PhoneUtils.java +++ b/src/com/android/phone/PhoneUtils.java @@ -504,7 +504,7 @@ public class PhoneUtils { // build the dialog final AlertDialog newDialog = - FrameworksUtils.makeAlertDialogBuilder(contextThemeWrapper) + new AlertDialog.Builder(contextThemeWrapper) .setMessage(text) .setView(dialogView) .setPositiveButton(R.string.send_button, mUSSDDialogListener) diff --git a/src/com/android/phone/settings/AccessibilitySettingsActivity.java b/src/com/android/phone/settings/AccessibilitySettingsActivity.java index 99b14780db..7cc18f6be6 100644 --- a/src/com/android/phone/settings/AccessibilitySettingsActivity.java +++ b/src/com/android/phone/settings/AccessibilitySettingsActivity.java @@ -20,17 +20,21 @@ import android.app.ActionBar; import android.os.Bundle; import android.preference.PreferenceActivity; import android.view.MenuItem; +import android.view.WindowManager; import com.android.phone.R; public class AccessibilitySettingsActivity extends PreferenceActivity { - @Override + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); final ActionBar actionBar = getActionBar(); if (actionBar != null) { - actionBar.setTitle(R.string.accessibility_settings_activity_title); + actionBar.setTitle(R.string.accessibility_settings_activity_title); } getFragmentManager().beginTransaction().replace( android.R.id.content, new AccessibilitySettingsFragment()).commit(); diff --git a/src/com/android/phone/settings/PhoneAccountSettingsActivity.java b/src/com/android/phone/settings/PhoneAccountSettingsActivity.java index 56f5594660..e15be39a2b 100644 --- a/src/com/android/phone/settings/PhoneAccountSettingsActivity.java +++ b/src/com/android/phone/settings/PhoneAccountSettingsActivity.java @@ -20,6 +20,7 @@ import android.app.ActionBar; import android.os.Bundle; import android.preference.PreferenceActivity; import android.view.MenuItem; +import android.view.WindowManager; import com.android.phone.R; @@ -28,6 +29,9 @@ public class PhoneAccountSettingsActivity extends PreferenceActivity { @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); final ActionBar actionBar = getActionBar(); if (actionBar != null) { actionBar.setTitle(R.string.phone_accounts); diff --git a/src/com/android/phone/settings/PickSmsSubscriptionActivity.java b/src/com/android/phone/settings/PickSmsSubscriptionActivity.java index cfbce28a31..97dada00c8 100644 --- a/src/com/android/phone/settings/PickSmsSubscriptionActivity.java +++ b/src/com/android/phone/settings/PickSmsSubscriptionActivity.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.os.Bundle; import android.os.RemoteException; import android.telephony.SubscriptionManager; +import android.view.WindowManager; import android.util.Log; import com.android.internal.telephony.IIntegerConsumer; @@ -91,6 +92,9 @@ public class PickSmsSubscriptionActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); mPreviouslyStopped = false; } diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java index 0b459c9873..61acb17d9e 100755 --- a/src/com/android/phone/settings/RadioInfo.java +++ b/src/com/android/phone/settings/RadioInfo.java @@ -73,6 +73,13 @@ import android.telephony.TelephonyCallback; import android.telephony.TelephonyDisplayInfo; import android.telephony.TelephonyManager; import android.telephony.data.NetworkSlicingConfig; +import android.telephony.ims.ImsException; +import android.telephony.ims.ImsManager; +import android.telephony.ims.ImsMmTelManager; +import android.telephony.ims.ImsRcsManager; +import android.telephony.ims.ProvisioningManager; +import android.telephony.ims.feature.MmTelFeature; +import android.telephony.ims.stub.ImsRegistrationImplBase; import android.text.TextUtils; import android.util.Log; import android.view.Menu; @@ -93,9 +100,6 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog.Builder; import androidx.appcompat.app.AppCompatActivity; -import com.android.ims.ImsConfig; -import com.android.ims.ImsException; -import com.android.ims.ImsManager; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.euicc.EuiccConnector; @@ -182,18 +186,6 @@ public class RadioInfo extends AppCompatActivity { */ private static final int ALWAYS_ON_DSDS_MODE = 1; - private static final int IMS_VOLTE_PROVISIONED_CONFIG_ID = - ImsConfig.ConfigConstants.VLT_SETTING_ENABLED; - - private static final int IMS_VT_PROVISIONED_CONFIG_ID = - ImsConfig.ConfigConstants.LVC_SETTING_ENABLED; - - private static final int IMS_WFC_PROVISIONED_CONFIG_ID = - ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED; - - private static final int EAB_PROVISIONED_CONFIG_ID = - ImsConfig.ConfigConstants.EAB_SETTING_ENABLED; - //Values in must match CELL_INFO_REFRESH_RATES private static final String[] CELL_INFO_REFRESH_RATE_LABELS = { "Disabled", @@ -297,6 +289,7 @@ public class RadioInfo extends AppCompatActivity { private TelephonyManager mTelephonyManager; private ImsManager mImsManager = null; private Phone mPhone = null; + private ProvisioningManager mProvisioningManager = null; private String mPingHostnameResultV4; private String mPingHostnameResultV6; @@ -426,12 +419,23 @@ public class RadioInfo extends AppCompatActivity { unregisterPhoneStateListener(); mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled); + if (phoneIndex == SubscriptionManager.INVALID_PHONE_INDEX) { + log("Invalid phone index " + phoneIndex + ", subscription ID " + subId); + return; + } + // update the subId mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId); // update the phoneId - mImsManager = ImsManager.getInstance(getApplicationContext(), phoneIndex); mPhone = PhoneFactory.getPhone(phoneIndex); + mImsManager = new ImsManager(mPhone.getContext()); + try { + mProvisioningManager = ProvisioningManager.createForSubscriptionId(subId); + } catch (IllegalArgumentException e) { + log("updatePhoneIndex : IllegalArgumentException " + e.getMessage()); + mProvisioningManager = null; + } updateAllFields(); } @@ -487,11 +491,17 @@ public class RadioInfo extends AppCompatActivity { mQueuedWork = new ThreadPoolExecutor(1, 1, RUNNABLE_TIMEOUT_MS, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<Runnable>()); mConnectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = getPhone(SubscriptionManager.getDefaultSubscriptionId()); mTelephonyManager = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)) .createForSubscriptionId(mPhone.getSubId()); - mImsManager = ImsManager.getInstance(getApplicationContext(), mPhone.getPhoneId()); + mImsManager = new ImsManager(mPhone.getContext()); + try { + mProvisioningManager = ProvisioningManager.createForSubscriptionId(mPhone.getSubId()); + } catch (IllegalArgumentException e) { + log("onCreate : IllegalArgumentException " + e.getMessage()); + mProvisioningManager = null; + } sPhoneIndexLabels = getPhoneIndexLabels(mTelephonyManager); @@ -559,7 +569,7 @@ public class RadioInfo extends AppCompatActivity { mImsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch); mEabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch); - if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) { + if (!isImsSupportedOnDevice(mPhone.getContext())) { mImsVolteProvisionedSwitch.setVisibility(View.GONE); mImsVtProvisionedSwitch.setVisibility(View.GONE); mImsWfcProvisionedSwitch.setVisibility(View.GONE); @@ -634,7 +644,7 @@ public class RadioInfo extends AppCompatActivity { mCellInfoRefreshRateIndex = 0; //disabled mPreferredNetworkTypeResult = PREFERRED_NETWORK_LABELS.length - 1; //Unknown - mSelectedPhoneIndex = 0; //phone 0 + mSelectedPhoneIndex = mPhone.getPhoneId(); new Thread(() -> { int networkType = (int) mTelephonyManager.getPreferredNetworkTypeBitmask(); @@ -836,7 +846,7 @@ public class RadioInfo extends AppCompatActivity { R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback); menu.add(1, MENU_ITEM_VIEW_SDN, 0, R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback); - if (ImsManager.isImsSupportedOnDevice(mPhone.getContext())) { + if (isImsSupportedOnDevice(mPhone.getContext())) { menu.add(1, MENU_ITEM_GET_IMS_STATUS, 0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus); } @@ -1563,34 +1573,38 @@ public class RadioInfo extends AppCompatActivity { mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener); } - void setImsVolteProvisionedState(boolean state) { + private void setImsVolteProvisionedState(boolean state) { Log.d(TAG, "setImsVolteProvisioned state: " + ((state) ? "on" : "off")); - setImsConfigProvisionedState(IMS_VOLTE_PROVISIONED_CONFIG_ID, state); + setImsConfigProvisionedState(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE, state); } - void setImsVtProvisionedState(boolean state) { + private void setImsVtProvisionedState(boolean state) { Log.d(TAG, "setImsVtProvisioned() state: " + ((state) ? "on" : "off")); - setImsConfigProvisionedState(IMS_VT_PROVISIONED_CONFIG_ID, state); + setImsConfigProvisionedState(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE, state); } - void setImsWfcProvisionedState(boolean state) { + private void setImsWfcProvisionedState(boolean state) { Log.d(TAG, "setImsWfcProvisioned() state: " + ((state) ? "on" : "off")); - setImsConfigProvisionedState(IMS_WFC_PROVISIONED_CONFIG_ID, state); + setImsConfigProvisionedState(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, state); } - void setEabProvisionedState(boolean state) { + private void setEabProvisionedState(boolean state) { Log.d(TAG, "setEabProvisioned() state: " + ((state) ? "on" : "off")); - setImsConfigProvisionedState(EAB_PROVISIONED_CONFIG_ID, state); + setRcsConfigProvisionedState(ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE, state); } - void setImsConfigProvisionedState(int configItem, boolean state) { - if (mPhone != null && mImsManager != null) { + private void setImsConfigProvisionedState(int capability, int tech, boolean state) { + if (mProvisioningManager != null) { mQueuedWork.execute(new Runnable() { public void run() { try { - mImsManager.getConfigInterface().setProvisionedValue( - configItem, state ? 1 : 0); - } catch (ImsException e) { + mProvisioningManager.setProvisioningStatusForCapability( + capability, tech, state); + } catch (RuntimeException e) { Log.e(TAG, "setImsConfigProvisioned() exception:", e); } } @@ -1598,6 +1612,71 @@ public class RadioInfo extends AppCompatActivity { } } + private void setRcsConfigProvisionedState(int capability, int tech, boolean state) { + if (mProvisioningManager != null) { + mQueuedWork.execute(new Runnable() { + public void run() { + try { + mProvisioningManager.setRcsProvisioningStatusForCapability( + capability, tech, state); + } catch (RuntimeException e) { + Log.e(TAG, "setRcsConfigProvisioned() exception:", e); + } + } + }); + } + } + + private boolean isImsVolteProvisioningRequired() { + return isImsConfigProvisioningRequired( + MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE); + } + + private boolean isImsVtProvisioningRequired() { + return isImsConfigProvisioningRequired( + MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE); + } + + private boolean isImsWfcProvisioningRequired() { + return isImsConfigProvisioningRequired( + MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN); + } + + private boolean isEabProvisioningRequired() { + return isRcsConfigProvisioningRequired( + ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE); + } + + private boolean isImsConfigProvisioningRequired(int capability, int tech) { + if (mProvisioningManager != null) { + try { + return mProvisioningManager.isProvisioningRequiredForCapability( + capability, tech); + } catch (RuntimeException e) { + Log.e(TAG, "isImsConfigProvisioningRequired() exception:", e); + } + } + + return false; + } + + private boolean isRcsConfigProvisioningRequired(int capability, int tech) { + if (mProvisioningManager != null) { + try { + return mProvisioningManager.isRcsProvisioningRequiredForCapability( + capability, tech); + } catch (RuntimeException e) { + Log.e(TAG, "isRcsConfigProvisioningRequired() exception:", e); + } + } + + return false; + } + OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -1617,11 +1696,8 @@ public class RadioInfo extends AppCompatActivity { }; private boolean isImsVolteProvisioned() { - if (mImsManager != null) { - return mImsManager.isVolteEnabledByPlatform() - && mImsManager.isVolteProvisionedOnDevice(); - } - return false; + return getImsConfigProvisionedState(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE); } OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() { @@ -1632,11 +1708,8 @@ public class RadioInfo extends AppCompatActivity { }; private boolean isImsVtProvisioned() { - if (mImsManager != null) { - return mImsManager.isVtEnabledByPlatform() - && mImsManager.isVtProvisionedOnDevice(); - } - return false; + return getImsConfigProvisionedState(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE); } OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() { @@ -1647,11 +1720,8 @@ public class RadioInfo extends AppCompatActivity { }; private boolean isImsWfcProvisioned() { - if (mImsManager != null) { - return mImsManager.isWfcEnabledByPlatform() - && mImsManager.isWfcProvisionedOnDevice(); - } - return false; + return getImsConfigProvisionedState(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN); } OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() { @@ -1662,7 +1732,8 @@ public class RadioInfo extends AppCompatActivity { }; private boolean isEabProvisioned() { - return isFeatureProvisioned(EAB_PROVISIONED_CONFIG_ID, false); + return getRcsConfigProvisionedState(ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE, + ImsRegistrationImplBase.REGISTRATION_TECH_LTE); } OnCheckedChangeListener mEabCheckedChangeListener = new OnCheckedChangeListener() { @@ -1672,23 +1743,30 @@ public class RadioInfo extends AppCompatActivity { } }; - private boolean isFeatureProvisioned(int featureId, boolean defaultValue) { - boolean provisioned = defaultValue; - if (mImsManager != null) { + private boolean getImsConfigProvisionedState(int capability, int tech) { + if (mProvisioningManager != null) { try { - ImsConfig imsConfig = mImsManager.getConfigInterface(); - if (imsConfig != null) { - provisioned = - (imsConfig.getProvisionedValue(featureId) - == ImsConfig.FeatureValueConstants.ON); - } - } catch (ImsException ex) { - Log.e(TAG, "isFeatureProvisioned() exception:", ex); + return mProvisioningManager.getProvisioningStatusForCapability( + capability, tech); + } catch (RuntimeException e) { + Log.e(TAG, "getImsConfigProvisionedState() exception:", e); } } - log("isFeatureProvisioned() featureId=" + featureId + " provisioned=" + provisioned); - return provisioned; + return false; + } + + private boolean getRcsConfigProvisionedState(int capability, int tech) { + if (mProvisioningManager != null) { + try { + return mProvisioningManager.getRcsProvisioningStatusForCapability( + capability, tech); + } catch (RuntimeException e) { + Log.e(TAG, "getRcsConfigProvisionedState() exception:", e); + } + } + + return false; } private boolean isEabEnabledByPlatform() { @@ -1707,35 +1785,56 @@ public class RadioInfo extends AppCompatActivity { } private void updateImsProvisionedState() { - if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) { + if (!isImsSupportedOnDevice(mPhone.getContext())) { return; } - log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned()); - //delightful hack to prevent on-checked-changed calls from - //actually forcing the ims provisioning to its transient/current value. + + updateServiceEnabledByPlatform(); + + updateEabProvisionedSwitch(isEabEnabledByPlatform()); + } + + private void updateVolteProvisionedSwitch(boolean isEnabledByPlatform) { + boolean isProvisioned = isEnabledByPlatform && isImsVolteProvisioned(); + log("updateVolteProvisionedSwitch isProvisioned" + isProvisioned); + mImsVolteProvisionedSwitch.setOnCheckedChangeListener(null); - mImsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned()); + mImsVolteProvisionedSwitch.setChecked(isProvisioned); mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener); mImsVolteProvisionedSwitch.setEnabled(!IS_USER_BUILD - && mImsManager.isVolteEnabledByPlatform()); + && isEnabledByPlatform && isImsVolteProvisioningRequired()); + } + + private void updateVtProvisionedSwitch(boolean isEnabledByPlatform) { + boolean isProvisioned = isEnabledByPlatform && isImsVtProvisioned(); + log("updateVtProvisionedSwitch isProvisioned" + isProvisioned); mImsVtProvisionedSwitch.setOnCheckedChangeListener(null); - mImsVtProvisionedSwitch.setChecked(isImsVtProvisioned()); + mImsVtProvisionedSwitch.setChecked(isProvisioned); mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener); mImsVtProvisionedSwitch.setEnabled(!IS_USER_BUILD - && mImsManager.isVtEnabledByPlatform()); + && isEnabledByPlatform && isImsVtProvisioningRequired()); + } + + private void updateWfcProvisionedSwitch(boolean isEnabledByPlatform) { + boolean isProvisioned = isEnabledByPlatform && isImsWfcProvisioned(); + log("updateWfcProvisionedSwitch isProvisioned" + isProvisioned); mImsWfcProvisionedSwitch.setOnCheckedChangeListener(null); - mImsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned()); + mImsWfcProvisionedSwitch.setChecked(isProvisioned); mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener); mImsWfcProvisionedSwitch.setEnabled(!IS_USER_BUILD - && mImsManager.isWfcEnabledByPlatform()); + && isEnabledByPlatform && isImsWfcProvisioningRequired()); + } + + private void updateEabProvisionedSwitch(boolean isEnabledByPlatform) { + log("updateEabProvisionedSwitch isEabWfcProvisioned()=" + isEabProvisioned()); mEabProvisionedSwitch.setOnCheckedChangeListener(null); mEabProvisionedSwitch.setChecked(isEabProvisioned()); mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener); mEabProvisionedSwitch.setEnabled(!IS_USER_BUILD - && isEabEnabledByPlatform()); + && isEnabledByPlatform && isEabProvisioningRequired()); } OnClickListener mDnsCheckButtonHandler = new OnClickListener() { @@ -1975,4 +2074,45 @@ public class RadioInfo extends AppCompatActivity { intent.putExtra("isDefault", isChecked); sendBroadcast(intent); } + + private boolean isImsSupportedOnDevice(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS); + } + + private void updateServiceEnabledByPlatform() { + int subId = mPhone.getSubId(); + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + log("updateServiceEnabledByPlatform subscription ID is invalid"); + return; + } + + ImsMmTelManager imsMmTelManager = mImsManager.getImsMmTelManager(subId); + try { + imsMmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getMainExecutor(), (result) -> { + updateVolteProvisionedSwitch(result); + }); + imsMmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, + AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getMainExecutor(), (result) -> { + updateVtProvisionedSwitch(result); + }); + imsMmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + AccessNetworkConstants.TRANSPORT_TYPE_WLAN, getMainExecutor(), (result) -> { + updateWfcProvisionedSwitch(result); + }); + } catch (ImsException e) { + e.printStackTrace(); + } + } + + private Phone getPhone(int subId) { + log("getPhone subId = " + subId); + Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId)); + if (phone == null) { + log("return the default phone"); + return PhoneFactory.getDefaultPhone(); + } + + return phone; + } } diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java index 2bd5306a94..02bf4b25d8 100644 --- a/src/com/android/phone/settings/VoicemailSettingsActivity.java +++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java @@ -39,6 +39,7 @@ import android.text.TextDirectionHeuristics; import android.text.TextUtils; import android.util.Log; import android.view.MenuItem; +import android.view.WindowManager; import android.widget.ListAdapter; import android.widget.Toast; @@ -211,6 +212,9 @@ public class VoicemailSettingsActivity extends PreferenceActivity @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); // Make sure we are running as the primary user only UserManager userManager = getApplicationContext().getSystemService(UserManager.class); if (!userManager.isPrimaryUser()) { diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java index 3fa2486460..8c60f2ad7b 100644 --- a/src/com/android/services/telephony/DisconnectCauseUtil.java +++ b/src/com/android/services/telephony/DisconnectCauseUtil.java @@ -25,6 +25,7 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.ims.ImsReasonInfo; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.CallFailCause; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; @@ -113,14 +114,29 @@ public class DisconnectCauseUtil { public static DisconnectCause toTelecomDisconnectCause( int telephonyDisconnectCause, int telephonyPreciseDisconnectCause, String reason, int phoneId, ImsReasonInfo imsReasonInfo) { + return toTelecomDisconnectCause(telephonyDisconnectCause, telephonyPreciseDisconnectCause, + reason, phoneId, imsReasonInfo, getCarrierConfigBundle(phoneId)); + } + + /** + * Final pre-processing method in creating a DisconnectCause. This method should NOT be called + * from another class directly. It only has private-package visibility for testing. + * + * @param carrierConfig + */ + @VisibleForTesting + static DisconnectCause toTelecomDisconnectCause( + int telephonyDisconnectCause, int telephonyPreciseDisconnectCause, String reason, + int phoneId, ImsReasonInfo imsReasonInfo, PersistableBundle carrierConfig) { Context context = PhoneGlobals.getInstance(); + return new DisconnectCause( - toTelecomDisconnectCauseCode(telephonyDisconnectCause), + toTelecomDisconnectCauseCode(telephonyDisconnectCause, carrierConfig), toTelecomDisconnectCauseLabel(context, telephonyDisconnectCause, - telephonyPreciseDisconnectCause), + telephonyPreciseDisconnectCause, carrierConfig), toTelecomDisconnectCauseDescription(context, telephonyDisconnectCause, phoneId), - toTelecomDisconnectReason(context,telephonyDisconnectCause, reason, phoneId), - toTelecomDisconnectCauseTone(telephonyDisconnectCause, phoneId), + toTelecomDisconnectReason(context, telephonyDisconnectCause, reason, phoneId), + toTelecomDisconnectCauseTone(telephonyDisconnectCause, carrierConfig), telephonyDisconnectCause, telephonyPreciseDisconnectCause, imsReasonInfo); @@ -131,7 +147,16 @@ public class DisconnectCauseUtil { * {@link android.telecom.DisconnectCause} disconnect code. * @return The disconnect code as defined in {@link android.telecom.DisconnectCause}. */ - private static int toTelecomDisconnectCauseCode(int telephonyDisconnectCause) { + private static int toTelecomDisconnectCauseCode(int telephonyDisconnectCause, + PersistableBundle carrierConfig) { + + // special case: some carriers determine what disconnect causes play the BUSY tone. + // hence, must adjust the disconnectCause CODE to match the tone. + if (doesCarrierClassifyDisconnectCauseAsBusyCause(telephonyDisconnectCause, + carrierConfig)) { + return DisconnectCause.BUSY; + } + switch (telephonyDisconnectCause) { case android.telephony.DisconnectCause.LOCAL: // The call was still disconnected locally, so this is not an error condition. @@ -293,8 +318,17 @@ public class DisconnectCauseUtil { * Returns a label for to the disconnect cause to be shown to the user. */ private static CharSequence toTelecomDisconnectCauseLabel( - Context context, int telephonyDisconnectCause, int telephonyPreciseDisconnectCause) { + Context context, int telephonyDisconnectCause, int telephonyPreciseDisconnectCause, + PersistableBundle carrierConfig) { CharSequence label; + + // special case: some carriers determine what disconnect causes play the BUSY tone. + // hence, must adjust the disconnectCause LABEL to match the tone. + if (doesCarrierClassifyDisconnectCauseAsBusyCause(telephonyDisconnectCause, + carrierConfig)) { + return context.getResources().getString(R.string.callFailed_userBusy); + } + if (telephonyPreciseDisconnectCause != CallFailCause.NOT_VALID) { label = getLabelFromPreciseDisconnectCause(context, telephonyPreciseDisconnectCause, telephonyDisconnectCause); @@ -780,6 +814,10 @@ public class DisconnectCauseUtil { resourceId = R.string.incall_error_emergency_only; break; + case android.telephony.DisconnectCause.ICC_ERROR: + resourceId = R.string.callFailed_simError; + break; + case android.telephony.DisconnectCause.OUT_OF_SERVICE: // No network connection. if (ImsUtil.shouldPromoteWfc(context, phoneId)) { @@ -1126,21 +1164,15 @@ public class DisconnectCauseUtil { /** * Returns the tone to play for the disconnect cause, or UNKNOWN if none should be played. */ - private static int toTelecomDisconnectCauseTone(int telephonyDisconnectCause, int phoneId) { - Phone phone = PhoneFactory.getPhone(phoneId); - PersistableBundle config; - if (phone != null) { - config = PhoneGlobals.getInstance().getCarrierConfigForSubId(phone.getSubId()); - } else { - config = PhoneGlobals.getInstance().getCarrierConfig(); - } - int[] busyToneArray = config.getIntArray( - CarrierConfigManager.KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY); - for (int busyTone : busyToneArray) { - if (busyTone == telephonyDisconnectCause) { - return ToneGenerator.TONE_SUP_BUSY; - } + private static int toTelecomDisconnectCauseTone(int telephonyDisconnectCause, + PersistableBundle carrierConfig) { + + // special case: some carriers determine what disconnect causes play the BUSY tone. + if (doesCarrierClassifyDisconnectCauseAsBusyCause(telephonyDisconnectCause, + carrierConfig)) { + return ToneGenerator.TONE_SUP_BUSY; } + switch (telephonyDisconnectCause) { case android.telephony.DisconnectCause.CONGESTION: return ToneGenerator.TONE_SUP_CONGESTION; @@ -1179,4 +1211,37 @@ public class DisconnectCauseUtil { return ToneGenerator.TONE_PROP_PROMPT; } } + + /** + * Helper method that examines the carrierConfig KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY + * containing the DisconnectCauses that are classified as DisconnectCause.BUSY + * @param telephonyDisconnectCause + * @param carrierConfig object that holds all the carrier specific settings + * @return whether the cause is in the carrier config busy tone array + */ + private static boolean doesCarrierClassifyDisconnectCauseAsBusyCause( + int telephonyDisconnectCause, PersistableBundle carrierConfig) { + int[] busyToneArray = carrierConfig.getIntArray( + CarrierConfigManager.KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY); + for (int busyTone : busyToneArray) { + if (busyTone == telephonyDisconnectCause) { + return true; + } + } + return false; + } + + private static PersistableBundle getCarrierConfigBundle(int phoneId) { + Phone phone = PhoneFactory.getPhone(phoneId); + PersistableBundle config; + + if (phone != null) { + config = PhoneGlobals.getInstance().getCarrierConfigForSubId(phone.getSubId()); + } else { + config = PhoneGlobals.getInstance().getCarrierConfig(); + } + + return config; + } + } diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java index 056e8cf5bf..bb02f8a64a 100644 --- a/src/com/android/services/telephony/TelecomAccountRegistry.java +++ b/src/com/android/services/telephony/TelecomAccountRegistry.java @@ -158,6 +158,7 @@ public class TelecomAccountRegistry { private boolean mIsUsingSimCallManager; private boolean mIsShowPreciseFailedCause; private final FeatureConnector<ImsManager> mImsManagerConnector; + private int mSubId; AccountEntry(Phone phone, boolean isEmergency, boolean isTest) { mPhone = phone; @@ -165,8 +166,9 @@ public class TelecomAccountRegistry { mIsTestAccount = isTest; mIsAdhocConfCapable = mPhone.isImsRegistered(); mAccount = registerPstnPhoneAccount(isEmergency, isTest); - Log.i(this, "Registered phoneAccount: %s with handle: %s", - mAccount, mAccount.getAccountHandle()); + mSubId = getSubId(); + Log.i(this, "Registered phoneAccount: %s with handle: %s, subId: %d", + mAccount, mAccount.getAccountHandle(), mSubId); mPhoneCapabilitiesNotifier = new PstnPhoneCapabilitiesNotifier((Phone) mPhone, this); mImsManagerConnector = ImsManager.getConnector( @@ -237,8 +239,8 @@ public class TelecomAccountRegistry { mImsManagerConnector.disconnect(); } - private boolean isMatched(SubscriptionInfo subInfo) { - return mPhone.getSubId() == subInfo.getSubscriptionId(); + private boolean isSameSubId(SubscriptionInfo subInfo) { + return mSubId == subInfo.getSubscriptionId(); } private void registerMmTelCapabilityCallback() { @@ -1916,7 +1918,7 @@ public class TelecomAccountRegistry { private boolean isAccountMatched(SubscriptionInfo info) { synchronized (mAccountsLock) { for (AccountEntry entry : mAccounts) { - if (entry.isMatched(info)) { + if (entry.isSameSubId(info)) { return true; } } diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java index 8de5ad0aa5..54a27b94ad 100644 --- a/src/com/android/services/telephony/TelephonyConnectionService.java +++ b/src/com/android/services/telephony/TelephonyConnectionService.java @@ -1444,6 +1444,11 @@ public class TelephonyConnectionService extends ConnectionService { "Invalid phone type", phone.getPhoneId())); } + if (!Objects.equals(request.getAccountHandle(), accountHandle)) { + Log.i(this, "onCreateOutgoingConnection, update phoneAccountHandle, accountHandle = " + + accountHandle); + connection.setPhoneAccountHandle(accountHandle); + } connection.setAddress(handle, PhoneConstants.PRESENTATION_ALLOWED); connection.setTelephonyConnectionInitializing(); connection.setTelephonyVideoState(request.getVideoState()); |