Merge "Fix the issue that ims emergency call redial fails"
diff --git a/OWNERS b/OWNERS
index f190411..1d3173f 100644
--- a/OWNERS
+++ b/OWNERS
@@ -9,3 +9,4 @@
mpq@google.com
jminjie@google.com
shuoq@google.com
+paulye@google.com
diff --git a/res/drawable-hdpi/ic_fire_white_24.png b/res/drawable-hdpi/ic_fire_white_24.png
new file mode 100644
index 0000000..0c0c6ed
--- /dev/null
+++ b/res/drawable-hdpi/ic_fire_white_24.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_shield_white_24.png b/res/drawable-hdpi/ic_shield_white_24.png
new file mode 100644
index 0000000..bf23794
--- /dev/null
+++ b/res/drawable-hdpi/ic_shield_white_24.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_fire_white_24.png b/res/drawable-mdpi/ic_fire_white_24.png
new file mode 100644
index 0000000..de8fda9
--- /dev/null
+++ b/res/drawable-mdpi/ic_fire_white_24.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_shield_white_24.png b/res/drawable-mdpi/ic_shield_white_24.png
new file mode 100644
index 0000000..9a5d958
--- /dev/null
+++ b/res/drawable-mdpi/ic_shield_white_24.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_fire_white_24.png b/res/drawable-xhdpi/ic_fire_white_24.png
new file mode 100644
index 0000000..750072e
--- /dev/null
+++ b/res/drawable-xhdpi/ic_fire_white_24.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_shield_white_24.png b/res/drawable-xhdpi/ic_shield_white_24.png
new file mode 100644
index 0000000..e886233
--- /dev/null
+++ b/res/drawable-xhdpi/ic_shield_white_24.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_fire_white_24.png b/res/drawable-xxhdpi/ic_fire_white_24.png
new file mode 100644
index 0000000..37c6ecd
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_fire_white_24.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_shield_white_24.png b/res/drawable-xxhdpi/ic_shield_white_24.png
new file mode 100644
index 0000000..1621836
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_shield_white_24.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_fire_white_24.png b/res/drawable-xxxhdpi/ic_fire_white_24.png
new file mode 100644
index 0000000..fb1d630
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_fire_white_24.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_shield_white_24.png b/res/drawable-xxxhdpi/ic_shield_white_24.png
new file mode 100644
index 0000000..8b9f129
--- /dev/null
+++ b/res/drawable-xxxhdpi/ic_shield_white_24.png
Binary files differ
diff --git a/res/layout/emergency_dialer.xml b/res/layout/emergency_dialer.xml
index cdb9530..7f99664 100644
--- a/res/layout/emergency_dialer.xml
+++ b/res/layout/emergency_dialer.xml
@@ -22,6 +22,7 @@
<!-- Emergency dialer shortcuts layout-->
<FrameLayout
android:id="@+id/emergency_dialer_shortcuts"
+ android:accessibilityPaneTitle="@string/emergencyDialerIconLabel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
@@ -52,6 +53,7 @@
<!--Emergency Dialer Layout-->
<FrameLayout
android:id="@+id/emergency_dialer"
+ android:accessibilityPaneTitle="@string/pane_title_emergency_dialpad"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="36dp"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b60d85f..7773af6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1152,6 +1152,19 @@
emergency calling is not currently available. -->
<string name="dial_emergency_calling_not_available">Emergency calling not available</string>
+ <!-- Text for description of police calling type -->
+ <string name="police_type_description">Police</string>
+ <!-- Text for description of ambulance calling type -->
+ <string name="ambulance_type_description">Ambulance</string>
+ <!-- Text for description of fire calling type -->
+ <string name="fire_type_description">Fire</string>
+
+ <!-- Format for concatenating multiple emergency type descriptions. The separator may differ in
+ different locales, for example arabic comma "،" is used in some countries. Some languages
+ may use full-width separator without leading or trailing spaces, eg. Ideographic comma "、"
+ in Chinese and Japanese. -->
+ <string name="description_concat_format">%1$s, %2$s</string>
+
<!-- Displayed in the text entry box in the dialer when in landscape mode to guide the user
to dial using the physical keyboard -->
<string name="dialerKeyboardHintText">Use keyboard to dial</string>
@@ -1386,6 +1399,13 @@
-->
<string name="description_dialpad_button">show dialpad</string>
+ <!-- Pane title of the Emergency Dialpad
+
+ Used by AccessibilityService to announce the purpose of the pane of emergency dialpad.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="pane_title_emergency_dialpad">Emergency Dialpad</string>
+
<!-- Visual voicemail on/off title [CHAR LIMIT=40] -->
<string name="voicemail_visual_voicemail_switch_title">Visual Voicemail</string>
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index bfeee7a..bdffb26 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -76,6 +76,11 @@
mReplaceInvalidCFNumber = replaceInvalidCFNumber;
}
+ void restoreCallForwardInfo(CallForwardInfo cf) {
+ handleCallForwardResult(cf);
+ updateSummaryText();
+ }
+
@Override
protected void onBindDialogView(View view) {
// default the button clicked to be the cancel button.
@@ -100,7 +105,15 @@
int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ?
CommandsInterface.CF_ACTION_REGISTRATION :
CommandsInterface.CF_ACTION_DISABLE;
- int time = (reason != CommandsInterface.CF_REASON_NO_REPLY) ? 0 : 20;
+ int time = 0;
+ if (reason == CommandsInterface.CF_REASON_NO_REPLY) {
+ PersistableBundle carrierConfig = PhoneGlobals.getInstance()
+ .getCarrierConfigForSubId(mPhone.getSubId());
+ if (carrierConfig.getBoolean(
+ CarrierConfigManager.KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true)) {
+ time = 20;
+ }
+ }
final String number = getPhoneNumber();
Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo);
@@ -137,7 +150,7 @@
}
}
- void handleCallForwardResult(CallForwardInfo cf) {
+ private void handleCallForwardResult(CallForwardInfo cf) {
callForwardInfo = cf;
Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo);
// In some cases, the network can send call forwarding URIs for voicemail that violate the
diff --git a/src/com/android/phone/CdmaOptions.java b/src/com/android/phone/CdmaOptions.java
index 7f7d58c..70744e5 100644
--- a/src/com/android/phone/CdmaOptions.java
+++ b/src/com/android/phone/CdmaOptions.java
@@ -24,12 +24,12 @@
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.settingslib.RestrictedLockUtils;
@@ -53,15 +53,9 @@
private PreferenceFragment mPrefFragment;
private PreferenceScreen mPrefScreen;
- private Phone mPhone;
+ private int mSubId;
- // Constructor for CdmaOptionsTest, since PreferenceScreen is final and cannot be mocked
- @VisibleForTesting
- public CdmaOptions(Phone phone) {
- mPhone = phone;
- }
-
- public CdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen, Phone phone) {
+ public CdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen, int subId) {
mPrefFragment = prefFragment;
mPrefScreen = prefScreen;
mPrefFragment.addPreferencesFromResource(R.xml.cdma_options);
@@ -75,19 +69,18 @@
mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
- update(phone);
+ updateSubscriptionId(subId);
}
- // Unlike mPrefFragment or mPrefScreen, mPhone may change during lifecycle of CdmaOptions.
- // For example, a new sim card is inserted. When that happens, we update CdmaOptions with new
- // phone.
- protected void update(Phone phone) {
- mPhone = phone;
+ protected void updateSubscriptionId(int subId) {
+ mSubId = subId;
+ int phoneType = TelephonyManager.from(mPrefFragment.getContext())
+ .createForSubscriptionId(mSubId).getPhoneType();
PersistableBundle carrierConfig =
- PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
// Some CDMA carriers want the APN settings.
- boolean addAPNExpand = shouldAddApnExpandPreference(carrierConfig);
+ boolean addAPNExpand = shouldAddApnExpandPreference(phoneType, carrierConfig);
boolean addCdmaSubscription =
deviceSupportsNvAndRuim();
// Read platform settings for carrier settings
@@ -118,7 +111,7 @@
final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
// This will setup the Home and Search affordance
intent.putExtra(":settings:show_fragment_as_subsetting", true);
- intent.putExtra("sub_id", mPhone.getSubId());
+ intent.putExtra("sub_id", mSubId);
mPrefFragment.startActivity(intent);
return true;
}
@@ -149,12 +142,9 @@
* carrier config
*/
@VisibleForTesting
- public boolean shouldAddApnExpandPreference(PersistableBundle config) {
- if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
- && config.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL)) {
- return true;
- }
- return false;
+ public static boolean shouldAddApnExpandPreference(int phoneType, PersistableBundle config) {
+ return phoneType == PhoneConstants.PHONE_TYPE_CDMA
+ && config.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL);
}
private boolean deviceSupportsNvAndRuim() {
diff --git a/src/com/android/phone/CdmaSubscriptionListPreference.java b/src/com/android/phone/CdmaSubscriptionListPreference.java
index 4a32dc4..cd0c681 100644
--- a/src/com/android/phone/CdmaSubscriptionListPreference.java
+++ b/src/com/android/phone/CdmaSubscriptionListPreference.java
@@ -17,17 +17,15 @@
package com.android.phone;
import android.content.Context;
-import android.os.AsyncResult;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.preference.ListPreference;
import android.provider.Settings;
+import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.settingslib.utils.ThreadUtils;
public class CdmaSubscriptionListPreference extends ListPreference {
@@ -41,19 +39,17 @@
// 1 - NV
static final int preferredSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
- private Phone mPhone;
- private CdmaSubscriptionButtonHandler mHandler;
+ private TelephonyManager mTelephonyManager;
public CdmaSubscriptionListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- mPhone = PhoneFactory.getDefaultPhone();
- mHandler = new CdmaSubscriptionButtonHandler();
+ mTelephonyManager = TelephonyManager.from(context);
setCurrentCdmaSubscriptionModeValue();
}
private void setCurrentCdmaSubscriptionModeValue() {
- int cdmaSubscriptionMode = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
+ int cdmaSubscriptionMode = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode);
setValue(Integer.toString(cdmaSubscriptionMode));
}
@@ -62,6 +58,15 @@
this(context, null);
}
+ /**
+ * Sets the subscription id associated with this preference.
+ *
+ * @param subId the subscription id.
+ */
+ public void setSubscriptionId(int subId) {
+ mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
+ }
+
@Override
protected void showDialog(Bundle state) {
setCurrentCdmaSubscriptionModeValue();
@@ -92,40 +97,23 @@
statusCdmaSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
}
- // Set the CDMA subscription mode, when mode has been successfully changed
- // handleSetCdmaSubscriptionMode will be invoked and the value saved.
- mPhone.setCdmaSubscription(statusCdmaSubscriptionMode, mHandler
- .obtainMessage(CdmaSubscriptionButtonHandler.MESSAGE_SET_CDMA_SUBSCRIPTION,
- getValue()));
+ // Set the CDMA subscription mode, when mode has been successfully changed, update the
+ // mode to the global setting.
+ ThreadUtils.postOnBackgroundThread(() -> {
+ // The subscription mode selected by user.
+ int cdmaSubscriptionMode = Integer.parseInt(getValue());
- }
+ boolean isSuccessed = mTelephonyManager.setCdmaSubscriptionMode(
+ statusCdmaSubscriptionMode);
- private class CdmaSubscriptionButtonHandler extends Handler {
-
- static final int MESSAGE_SET_CDMA_SUBSCRIPTION = 0;
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_SET_CDMA_SUBSCRIPTION:
- handleSetCdmaSubscriptionMode(msg);
- break;
- }
- }
-
- private void handleSetCdmaSubscriptionMode(Message msg) {
- mPhone = PhoneFactory.getDefaultPhone();
- AsyncResult ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- // Get the original string entered by the user
- int cdmaSubscriptionMode = Integer.parseInt((String) ar.userObj);
- Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+ // Update the global settings if successed.
+ if (isSuccessed) {
+ Settings.Global.putInt(getContext().getContentResolver(),
Settings.Global.CDMA_SUBSCRIPTION_MODE,
- cdmaSubscriptionMode );
+ cdmaSubscriptionMode);
} else {
Log.e(LOG_TAG, "Setting Cdma subscription source failed");
}
- }
+ });
}
}
diff --git a/src/com/android/phone/CdmaSystemSelectListPreference.java b/src/com/android/phone/CdmaSystemSelectListPreference.java
index 9c24aa7..0044a8b 100644
--- a/src/com/android/phone/CdmaSystemSelectListPreference.java
+++ b/src/com/android/phone/CdmaSystemSelectListPreference.java
@@ -17,43 +17,49 @@
package com.android.phone;
import android.content.Context;
-import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.ListPreference;
import android.provider.Settings;
+import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
-import com.android.internal.telephony.Phone;
+import com.android.settingslib.utils.ThreadUtils;
public class CdmaSystemSelectListPreference extends ListPreference {
private static final String LOG_TAG = "CdmaRoamingListPreference";
private static final boolean DBG = false;
- private Phone mPhone;
+ private TelephonyManager mTelephonyManager;
private MyHandler mHandler = new MyHandler();
public CdmaSystemSelectListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- mPhone = PhoneGlobals.getPhone();
mHandler = new MyHandler();
- mPhone.queryCdmaRoamingPreference(
- mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE));
+ mTelephonyManager = TelephonyManager.from(context);
}
public CdmaSystemSelectListPreference(Context context) {
this(context, null);
}
+ /**
+ * Sets the subscription id associated with this preference.
+ *
+ * @param subId the subscription id.
+ */
+ public void setSubscriptionId(int subId) {
+ mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
+ queryCdmaRoamingMode();
+ }
+
@Override
protected void showDialog(Bundle state) {
- if (mPhone.isInEcm()) {
- // In ECM mode do not show selection options
- } else {
+ if (!mTelephonyManager.getEmergencyCallbackMode()) {
super.showDialog(state);
}
}
@@ -64,26 +70,22 @@
if (positiveResult && (getValue() != null)) {
int buttonCdmaRoamingMode = Integer.parseInt(getValue());
- int settingsCdmaRoamingMode =
- Settings.Global.getInt(mPhone.getContext().getContentResolver(),
- Settings.Global.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
+ int settingsCdmaRoamingMode = Settings.Global.getInt(
+ getContext().getContentResolver(),
+ Settings.Global.CDMA_ROAMING_MODE,
+ TelephonyManager.CDMA_ROAMING_MODE_HOME);
if (buttonCdmaRoamingMode != settingsCdmaRoamingMode) {
- int statusCdmaRoamingMode;
- switch(buttonCdmaRoamingMode) {
- case Phone.CDMA_RM_ANY:
- statusCdmaRoamingMode = Phone.CDMA_RM_ANY;
- break;
- case Phone.CDMA_RM_HOME:
- default:
- statusCdmaRoamingMode = Phone.CDMA_RM_HOME;
+ int cdmaRoamingMode = TelephonyManager.CDMA_ROAMING_MODE_ANY;
+ if (buttonCdmaRoamingMode != TelephonyManager.CDMA_ROAMING_MODE_ANY) {
+ cdmaRoamingMode = TelephonyManager.CDMA_ROAMING_MODE_HOME;
}
//Set the Settings.Secure network mode
- Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+ Settings.Global.putInt(
+ getContext().getContentResolver(),
Settings.Global.CDMA_ROAMING_MODE,
- buttonCdmaRoamingMode );
+ buttonCdmaRoamingMode);
//Set the roaming preference mode
- mPhone.setCdmaRoamingPreference(statusCdmaRoamingMode, mHandler
- .obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE));
+ setCdmaRoamingMode(cdmaRoamingMode);
}
} else {
Log.d(LOG_TAG, String.format("onDialogClosed: positiveResult=%b value=%s -- do nothing",
@@ -110,27 +112,28 @@
}
private void handleQueryCdmaRoamingPreference(Message msg) {
- AsyncResult ar = (AsyncResult) msg.obj;
+ int cdmaRoamingMode = msg.arg1;
- if (ar.exception == null) {
- int statusCdmaRoamingMode = ((int[])ar.result)[0];
+ if (cdmaRoamingMode != TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT) {
int settingsRoamingMode = Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
- Settings.Global.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
+ getContext().getContentResolver(),
+ Settings.Global.CDMA_ROAMING_MODE,
+ TelephonyManager.CDMA_ROAMING_MODE_HOME);
+
//check that statusCdmaRoamingMode is from an accepted value
- if (statusCdmaRoamingMode == Phone.CDMA_RM_HOME ||
- statusCdmaRoamingMode == Phone.CDMA_RM_ANY ) {
+ if (cdmaRoamingMode == TelephonyManager.CDMA_ROAMING_MODE_HOME
+ || cdmaRoamingMode == TelephonyManager.CDMA_ROAMING_MODE_ANY) {
//check changes in statusCdmaRoamingMode and updates settingsRoamingMode
- if (statusCdmaRoamingMode != settingsRoamingMode) {
- settingsRoamingMode = statusCdmaRoamingMode;
+ if (cdmaRoamingMode != settingsRoamingMode) {
+ settingsRoamingMode = cdmaRoamingMode;
//changes the Settings.Secure accordingly to statusCdmaRoamingMode
Settings.Global.putInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
Settings.Global.CDMA_ROAMING_MODE,
- settingsRoamingMode );
+ settingsRoamingMode);
}
//changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
- setValue(Integer.toString(statusCdmaRoamingMode));
+ setValue(Integer.toString(cdmaRoamingMode));
}
else {
if(DBG) Log.i(LOG_TAG, "reset cdma roaming mode to default" );
@@ -140,29 +143,45 @@
}
private void handleSetCdmaRoamingPreference(Message msg) {
- AsyncResult ar = (AsyncResult) msg.obj;
+ boolean isSuccessed = (boolean) msg.obj;
- if ((ar.exception == null) && (getValue() != null)) {
+ if (isSuccessed && (getValue() != null)) {
int cdmaRoamingMode = Integer.parseInt(getValue());
- Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+ Settings.Global.putInt(
+ getContext().getContentResolver(),
Settings.Global.CDMA_ROAMING_MODE,
cdmaRoamingMode );
} else {
- mPhone.queryCdmaRoamingPreference(obtainMessage(MESSAGE_GET_ROAMING_PREFERENCE));
+ queryCdmaRoamingMode();
}
}
private void resetCdmaRoamingModeToDefault() {
//set the mButtonCdmaRoam
- setValue(Integer.toString(Phone.CDMA_RM_ANY));
+ setValue(Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_ANY));
//set the Settings.System
- Settings.Global.putInt(mPhone.getContext().getContentResolver(),
- Settings.Global.CDMA_ROAMING_MODE,
- Phone.CDMA_RM_ANY );
+ Settings.Global.putInt(
+ getContext().getContentResolver(),
+ Settings.Global.CDMA_ROAMING_MODE,
+ TelephonyManager.CDMA_ROAMING_MODE_ANY);
//Set the Status
- mPhone.setCdmaRoamingPreference(Phone.CDMA_RM_ANY,
- obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE));
+ setCdmaRoamingMode(TelephonyManager.CDMA_ROAMING_MODE_ANY);
}
}
+ private void queryCdmaRoamingMode() {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ Message msg = mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE);
+ msg.arg1 = mTelephonyManager.getCdmaRoamingMode();
+ msg.sendToTarget();
+ });
+ }
+
+ private void setCdmaRoamingMode(int mode) {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ Message msg = mHandler.obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE);
+ msg.obj = mTelephonyManager.setCdmaRoamingMode(mode);
+ msg.sendToTarget();
+ });
+ }
}
diff --git a/src/com/android/phone/CellInfoUtil.java b/src/com/android/phone/CellInfoUtil.java
index 2c5f2a8..462cafe 100644
--- a/src/com/android/phone/CellInfoUtil.java
+++ b/src/com/android/phone/CellInfoUtil.java
@@ -26,7 +26,6 @@
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
-import android.telephony.TelephonyManager;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
@@ -47,47 +46,6 @@
}
/**
- * Get the network type from a CellInfo. Network types include
- * {@link TelephonyManager#NETWORK_TYPE_LTE}, {@link TelephonyManager#NETWORK_TYPE_UMTS},
- * {@link TelephonyManager#NETWORK_TYPE_GSM}, {@link TelephonyManager#NETWORK_TYPE_CDMA} and
- * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}
- * @return network types
- */
- public static int getNetworkType(CellInfo cellInfo) {
- if (cellInfo instanceof CellInfoLte) {
- return TelephonyManager.NETWORK_TYPE_LTE;
- } else if (cellInfo instanceof CellInfoWcdma) {
- return TelephonyManager.NETWORK_TYPE_UMTS;
- } else if (cellInfo instanceof CellInfoGsm) {
- return TelephonyManager.NETWORK_TYPE_GSM;
- } else if (cellInfo instanceof CellInfoCdma) {
- return TelephonyManager.NETWORK_TYPE_CDMA;
- } else {
- Log.e(TAG, "Invalid CellInfo type");
- return TelephonyManager.NETWORK_TYPE_UNKNOWN;
- }
- }
-
- /**
- * Get signal level as an int from 0..4.
- * @return Signal strength level
- */
- public static int getLevel(CellInfo cellInfo) {
- if (cellInfo instanceof CellInfoLte) {
- return ((CellInfoLte) cellInfo).getCellSignalStrength().getLevel();
- } else if (cellInfo instanceof CellInfoWcdma) {
- return ((CellInfoWcdma) cellInfo).getCellSignalStrength().getLevel();
- } else if (cellInfo instanceof CellInfoGsm) {
- return ((CellInfoGsm) cellInfo).getCellSignalStrength().getLevel();
- } else if (cellInfo instanceof CellInfoCdma) {
- return ((CellInfoCdma) cellInfo).getCellSignalStrength().getLevel();
- } else {
- Log.e(TAG, "Invalid CellInfo type");
- return 0;
- }
- }
-
- /**
* Wrap a CellIdentity into a CellInfo.
*/
public static CellInfo wrapCellInfoWithCellIdentity(CellIdentity cellIdentity) {
diff --git a/src/com/android/phone/EccShortcutAdapter.java b/src/com/android/phone/EccShortcutAdapter.java
new file mode 100644
index 0000000..deeb82f
--- /dev/null
+++ b/src/com/android/phone/EccShortcutAdapter.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2018 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;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.phone.ecc.CountryEccInfo;
+import com.android.phone.ecc.EccInfo;
+
+import com.google.common.collect.LinkedListMultimap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An abstract adapter between ECC data and the view contains ECC shortcuts.
+ * This adapter will convert given {@link CountryEccInfo} to number string, description string and
+ * icon resource id for each {@link EccInfo}.
+ * The subclass should implements {@link #inflateView} to provide the view for an ECC data, when the
+ * view container calls {@link #getView}.
+ */
+public abstract class EccShortcutAdapter extends BaseAdapter {
+ // GSM default emergency number, used when country's fallback ECC(112 or 911) not available.
+ private static final String FALLBACK_EMERGENCY_NUMBER = "112";
+
+ private List<EccDisplayMaterial> mEccDisplayMaterialList;
+
+ private CharSequence mPoliceDescription;
+ private CharSequence mAmbulanceDescription;
+ private CharSequence mFireDescription;
+
+ private static class EccDisplayMaterial {
+ public CharSequence number = null;
+ public int iconRes = 0;
+ public CharSequence description = null;
+ }
+
+ public EccShortcutAdapter(@NonNull Context context) {
+ mPoliceDescription = context.getText(R.string.police_type_description);
+ mAmbulanceDescription = context.getText(R.string.ambulance_type_description);
+ mFireDescription = context.getText(R.string.fire_type_description);
+
+ mEccDisplayMaterialList = new ArrayList<>();
+ }
+
+ @Override
+ public int getCount() {
+ return mEccDisplayMaterialList.size();
+ }
+
+ @Override
+ public EccDisplayMaterial getItem(int position) {
+ return mEccDisplayMaterialList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ EccDisplayMaterial material = getItem(position);
+ return inflateView(convertView, parent, material.number, material.description,
+ material.iconRes);
+ }
+
+ /**
+ * Get a View that display the given ECC data: number, description and iconRes.
+ *
+ * @param convertView The old view to reuse, if possible. Note: You should check that this view
+ * is non-null and of an appropriate type before using. If it is not possible
+ * to convert this view to display the correct data, this method can create a
+ * new view. Heterogeneous lists can specify their number of view types, so
+ * that this View is always of the right type (see {@link
+ * BaseAdapter#getViewTypeCount()} and {@link
+ * BaseAdapter#getItemViewType(int)}).
+ * @param parent The parent that this view will eventually be attached to.
+ * @param number The number of the ECC shortcut to display in the view.
+ * @param description The description of the ECC shortcut to display in the view.
+ * @param iconRes The icon resource ID represent for the ECC shortcut.
+ * @return A View corresponding to the data at the specified position.
+ */
+ public abstract View inflateView(View convertView, ViewGroup parent, CharSequence number,
+ CharSequence description, int iconRes);
+
+ /**
+ * Update country ECC info. This method converts given country ECC info to ECC data that could
+ * be display by the short container View.
+ *
+ * @param context The context used to access resources.
+ * @param countryEccInfo Updated country ECC info.
+ */
+ public void updateCountryEccInfo(@NonNull Context context, CountryEccInfo countryEccInfo) {
+ List<EccDisplayMaterial> displayMaterials = new ArrayList<>();
+
+ final EccInfo.Type[] orderedMustHaveTypes =
+ { EccInfo.Type.POLICE, EccInfo.Type.AMBULANCE, EccInfo.Type.FIRE };
+
+ String fallback = null;
+ EccInfo[] eccInfoList = null;
+ if (countryEccInfo != null) {
+ fallback = countryEccInfo.getFallbackEcc();
+ eccInfoList = countryEccInfo.getEccInfoList();
+ }
+ if (TextUtils.isEmpty(fallback)) {
+ fallback = FALLBACK_EMERGENCY_NUMBER;
+ }
+
+ // Finding matched ECC for each must have types.
+ // Using LinkedListMultimap to prevent duplicated keys.
+ // LinkedListMultimap also preserve the insertion order of keys (ECC number) and values
+ // (matched types of the ECC number), which follows the order in orderedMustHaveTypes.
+ LinkedListMultimap<String, EccInfo.Type> eccList = LinkedListMultimap.create();
+ for (EccInfo.Type type : orderedMustHaveTypes) {
+ String number = null;
+ if (eccInfoList != null) {
+ number = pickEccNumberForType(type, eccInfoList);
+ }
+ if (number == null) {
+ number = fallback;
+ }
+ // append type for exist number, otherwise insert a new entry.
+ eccList.put(number, type);
+ }
+
+ // prepare display material for picked ECC
+ for (String number : eccList.keySet()) {
+ EccDisplayMaterial material = prepareDisplayMaterialForEccInfo(context,
+ new EccInfo(number, eccList.asMap().get(number)));
+ if (material != null) {
+ displayMaterials.add(material);
+ }
+ }
+
+ mEccDisplayMaterialList = displayMaterials;
+ notifyDataSetChanged();
+ }
+
+ private @Nullable String pickEccNumberForType(@NonNull EccInfo.Type targetType,
+ @NonNull EccInfo[] eccInfoList) {
+ EccInfo pickedEccInfo = null;
+ for (EccInfo eccInfo : eccInfoList) {
+ if (eccInfo.containsType(targetType)) {
+ // An ECC is more suitable for a type if the ECC has fewer other types.
+ if (pickedEccInfo == null
+ || eccInfo.getTypesCount() < pickedEccInfo.getTypesCount()) {
+ pickedEccInfo = eccInfo;
+ }
+ }
+ }
+ if (pickedEccInfo != null) {
+ return pickedEccInfo.getNumber();
+ }
+ return null;
+ }
+
+ private @Nullable EccDisplayMaterial prepareDisplayMaterialForEccInfo(@NonNull Context context,
+ @NonNull EccInfo eccInfo) {
+ EccDisplayMaterial material = new EccDisplayMaterial();
+ material.number = eccInfo.getNumber();
+ EccInfo.Type[] types = eccInfo.getTypes();
+ for (EccInfo.Type type : types) {
+ CharSequence description;
+ switch (type) {
+ case POLICE:
+ description = mPoliceDescription;
+ material.iconRes = R.drawable.ic_shield_white_24;
+ break;
+ case AMBULANCE:
+ description = mAmbulanceDescription;
+ material.iconRes = R.drawable.ic_emergency_number_24;
+ break;
+ case FIRE:
+ description = mFireDescription;
+ material.iconRes = R.drawable.ic_fire_white_24;
+ break;
+ default:
+ // ignore unknown types
+ continue;
+ }
+ if (TextUtils.isEmpty(material.description)) {
+ material.description = description;
+ } else {
+ // concatenate multiple types
+ material.iconRes = R.drawable.ic_emergency_number_24;
+ material.description = context.getString(R.string.description_concat_format,
+ material.description, description);
+ }
+ }
+ if (TextUtils.isEmpty(material.description) || material.iconRes == 0) {
+ return null;
+ }
+ return material;
+ }
+
+}
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index fc4ef6a..66701d5 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -23,20 +23,29 @@
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.KeyguardManager;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.DataSetObserver;
import android.graphics.Color;
import android.graphics.Point;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.ToneGenerator;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PersistableBundle;
+import android.os.SystemClock;
import android.provider.Settings;
+import android.telecom.ParcelableCallAnalytics;
import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
@@ -53,6 +62,7 @@
import android.text.TextWatcher;
import android.text.method.DialerKeyListener;
import android.text.style.TtsSpan;
+import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
@@ -60,19 +70,27 @@
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.phone.common.dialpad.DialpadKeyButton;
import com.android.phone.common.util.ViewUtil;
import com.android.phone.common.widget.ResizingTextEditText;
+import com.android.phone.ecc.CountryEccInfo;
+import com.android.phone.ecc.EccInfoHelper;
+import com.android.phone.ecc.IsoToEccProtobufRepository;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
/**
* EmergencyDialer is a special dialer that is used ONLY for dialing emergency calls.
@@ -100,13 +118,81 @@
public class EmergencyDialer extends Activity implements View.OnClickListener,
View.OnLongClickListener, View.OnKeyListener, TextWatcher,
DialpadKeyButton.OnPressedListener, ColorExtractor.OnColorsChangedListener,
- EmergencyShortcutButton.OnConfirmClickListener {
+ EmergencyShortcutButton.OnConfirmClickListener, SensorEventListener {
+
+ private class MetricsWriter {
+ // Metrics constants indicating the entry type that user opened emergency dialer.
+ // This info is sent from system UI with EXTRA_ENTRY_TYPE. Please make them being
+ // in sync with those in com.android.systemui.util.EmergencyDialerConstants.
+ public static final int ENTRY_TYPE_UNKNOWN = 0;
+ public static final int ENTRY_TYPE_LOCKSCREEN_BUTTON = 1;
+ public static final int ENTRY_TYPE_POWER_MENU = 2;
+
+ // Metrics constants indicating the UI that user made phone call.
+ public static final int CALL_SOURCE_DIALPAD = 0;
+ public static final int CALL_SOURCE_SHORTCUT = 1;
+
+ // Metrics constants indicating the phone number type of a call user made.
+ public static final int PHONE_NUMBER_TYPE_GENERAL = 0;
+ public static final int PHONE_NUMBER_TYPE_EMERGENCY = 1;
+
+ // Metrics constants indicating the actions performed by user.
+ public static final int USER_ACTION_NONE = 0x0;
+ public static final int USER_ACTION_OPEN_DIALPAD = 0x1;
+ public static final int USER_ACTION_OPEN_EMERGENCY_INFO = 0x2;
+ public static final int USER_ACTION_MAKE_CALL_VIA_DIALPAD = 0x4;
+ public static final int USER_ACTION_MAKE_CALL_VIA_SHORTCUT = 0x8;
+
+ private MetricsLogger mMetricsLogger = new MetricsLogger();
+
+ public void writeMetricsForEnter() {
+ int entryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN);
+ KeyguardManager keyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+ mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER)
+ .setType(MetricsEvent.TYPE_OPEN)
+ .setSubtype(entryType)
+ .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_IS_SCREEN_LOCKED,
+ keyguard.isKeyguardLocked() ? 1 : 0));
+ }
+
+ public void writeMetricsForExit() {
+ int entryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN);
+ long userStayDuration = SystemClock.elapsedRealtime() - mUserEnterTimeMillis;
+ mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER)
+ .setType(MetricsEvent.TYPE_CLOSE)
+ .setSubtype(entryType)
+ .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_USER_ACTIONS, mUserActions)
+ .addTaggedData(
+ MetricsEvent.FIELD_EMERGENCY_DIALER_DURATION_MS, userStayDuration));
+ }
+
+ public void writeMetricsForMakingCall(int callSource, int phoneNumberType,
+ boolean hasShortcut) {
+ mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER_MAKE_CALL)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setSubtype(callSource)
+ .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_PHONE_NUMBER_TYPE,
+ phoneNumberType)
+ .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_PHONE_NUMBER_HAS_SHORTCUT,
+ hasShortcut ? 1 : 0)
+ .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_IN_POCKET,
+ mIsProximityNear ? 1 : 0));
+ }
+ }
+
// Keys used with onSaveInstanceState().
private static final String LAST_NUMBER = "lastNumber";
// Intent action for this activity.
public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
+ /**
+ * Extra included in {@link #ACTION_DIAL} to indicate the entry type that user starts
+ * the emergency dialer.
+ */
+ public static final String EXTRA_ENTRY_TYPE =
+ "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE";
+
// List of dialer button IDs.
private static final int[] DIALER_KEYS = new int[] {
R.id.one, R.id.two, R.id.three,
@@ -135,13 +221,20 @@
/** 85% opacity for black background **/
private static final int BLACK_BACKGROUND_GRADIENT_ALPHA = 217;
+ /** Size limit of emergency shortcut buttons container. **/
+ private static final int SHORTCUT_SIZE_LIMIT = 3;
+
ResizingTextEditText mDigits;
private View mDialButton;
private View mDelete;
private View mEmergencyShortcutView;
private View mDialpadView;
+ private EccInfoHelper mEccInfoHelper;
+
private List<EmergencyShortcutButton> mEmergencyShortcutButtonList;
+ private EccShortcutAdapter mShortcutAdapter;
+ private DataSetObserver mShortcutDataSetObserver = null;
private ToneGenerator mToneGenerator;
private Object mToneGeneratorLock = new Object();
@@ -161,6 +254,30 @@
}
};
+ /**
+ * Customize accessibility methods in View.
+ */
+ private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
+
+ /**
+ * Stop AccessiblityService from reading the title of a hidden View.
+ *
+ * <p>The crossfade animation will set the visibility of fade out view to {@link View.GONE}
+ * in the animation end. The view with an accessibility pane title would call the
+ * {@link AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED} event, which would trigger the
+ * accessibility service to read the pane title of fade out view instead of pane title of
+ * fade in view. So it need to filter out the event called by vanished pane.
+ */
+ @Override
+ public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+ if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+ && host.getVisibility() == View.GONE) {
+ return;
+ }
+ super.onPopulateAccessibilityEvent(host, event);
+ }
+ };
+
private String mLastNumber; // last number we tried to dial. Used to restore error dialog.
// Background gradient
@@ -173,6 +290,22 @@
private boolean mAreEmergencyDialerShortcutsEnabled;
+ private MetricsWriter mMetricsWriter;
+ private SensorManager mSensorManager;
+ private Sensor mProximitySensor;
+ private boolean mIsProximityNear = false;
+
+ /**
+ * The time, in millis, since boot when user opened emergency dialer.
+ * This is used when calculating the user stay duration for metrics data.
+ */
+ private long mUserEnterTimeMillis = 0;
+
+ /**
+ * Bit flag indicating the actions performed by user. This is used for metrics data.
+ */
+ private int mUserActions = MetricsWriter.USER_ACTION_NONE;
+
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Do nothing
@@ -207,13 +340,21 @@
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ mMetricsWriter = new MetricsWriter();
+ mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+ if (mSensorManager != null) {
+ mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+ }
+
// Allow this activity to be displayed in front of the keyguard / lockscreen.
setShowWhenLocked(true);
// Allow turning screen on
setTurnScreenOn(true);
- mAreEmergencyDialerShortcutsEnabled = Settings.Global.getInt(getContentResolver(),
- Settings.Global.FASTER_EMERGENCY_PHONE_CALL_ENABLED, 0) != 0;
+ mAreEmergencyDialerShortcutsEnabled = FeatureFlagUtils
+ .isEnabled(this, FeatureFlagUtils.EMERGENCY_DIAL_SHORTCUTS);
+ Log.d(LOG_TAG, "Enable emergency dialer shortcut: "
+ + mAreEmergencyDialerShortcutsEnabled);
mColorExtractor = new ColorExtractor(this);
@@ -311,6 +452,7 @@
mEmergencyActionGroup = (EmergencyActionGroup) findViewById(R.id.emergency_action_group);
if (mAreEmergencyDialerShortcutsEnabled) {
+ mEccInfoHelper = new EccInfoHelper(new IsoToEccProtobufRepository());
setupEmergencyShortcutsView();
}
}
@@ -325,6 +467,10 @@
}
}
unregisterReceiver(mBroadcastReceiver);
+ if (mShortcutAdapter != null && mShortcutDataSetObserver != null) {
+ mShortcutAdapter.unregisterDataSetObserver(mShortcutDataSetObserver);
+ mShortcutDataSetObserver = null;
+ }
}
@Override
@@ -438,12 +584,22 @@
public void onConfirmClick(EmergencyShortcutButton button) {
if (button == null) return;
+ mUserActions |= MetricsWriter.USER_ACTION_MAKE_CALL_VIA_SHORTCUT;
+
+ // We interest on the context when user has intention to make phone call,
+ // so write metrics here for shortcut number even the call may not be created.
+ mMetricsWriter.writeMetricsForMakingCall(MetricsWriter.CALL_SOURCE_SHORTCUT,
+ MetricsWriter.PHONE_NUMBER_TYPE_EMERGENCY, true);
+
String phoneNumber = button.getPhoneNumber();
if (!TextUtils.isEmpty(phoneNumber)) {
if (DBG) Log.d(LOG_TAG, "dial emergency number: " + Rlog.pii(LOG_TAG, phoneNumber));
+ Bundle extras = new Bundle();
+ extras.putInt(TelecomManager.EXTRA_CALL_SOURCE,
+ ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_SHORTCUT);
TelecomManager tm = (TelecomManager) getSystemService(TELECOM_SERVICE);
- tm.placeCall(Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null), null);
+ tm.placeCall(Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null), extras);
} else {
Log.d(LOG_TAG, "emergency number is empty");
}
@@ -468,11 +624,13 @@
return;
}
case R.id.floating_action_button_dialpad: {
+ mUserActions |= MetricsWriter.USER_ACTION_OPEN_DIALPAD;
mDigits.getText().clear();
switchView(mDialpadView, mEmergencyShortcutView, true);
return;
}
case R.id.emergency_info_button: {
+ mUserActions |= MetricsWriter.USER_ACTION_OPEN_EMERGENCY_INFO;
Intent intent = (Intent) view.getTag(R.id.tag_intent);
if (intent != null) {
startActivity(intent);
@@ -574,6 +732,11 @@
@Override
protected void onStart() {
super.onStart();
+
+ mUserEnterTimeMillis = SystemClock.elapsedRealtime();
+ mUserActions = MetricsWriter.USER_ACTION_NONE;
+ mMetricsWriter.writeMetricsForEnter();
+
// It does not support dark text theme, when emergency dialer shortcuts are enabled.
// And set background color to black.
if (mAreEmergencyDialerShortcutsEnabled) {
@@ -587,12 +750,43 @@
mBackgroundGradient.setColors(lockScreenColors, false);
updateTheme(lockScreenColors.supportsDarkText());
}
+
+ if (mAreEmergencyDialerShortcutsEnabled && mEccInfoHelper != null) {
+ final Context context = this;
+ mEccInfoHelper.getCountryEccInfoAsync(context,
+ new EccInfoHelper.CountryEccInfoResultCallback() {
+ @Override
+ public void onSuccess(String iso, CountryEccInfo countryEccInfo) {
+ Log.d(LOG_TAG, "Retrieve ECC info success, country ISO: "
+ + Rlog.pii(LOG_TAG, iso));
+ updateLocationAndEccInfo(iso, countryEccInfo);
+ }
+
+ @Override
+ public void onDetectCountryFailed() {
+ Log.w(LOG_TAG, "Cannot detect current country.");
+ updateLocationAndEccInfo(null, null);
+ }
+
+ @Override
+ public void onRetrieveCountryEccInfoFailed(String iso) {
+ Log.w(LOG_TAG, "Retrieve ECC info failed, country ISO: "
+ + Rlog.pii(LOG_TAG, iso));
+ updateLocationAndEccInfo(iso, null);
+ }
+ });
+ }
}
@Override
protected void onResume() {
super.onResume();
+ if (mProximitySensor != null) {
+ mSensorManager.registerListener(
+ this, mProximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
// retrieve the DTMF tone play back setting.
mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
@@ -617,11 +811,15 @@
@Override
public void onPause() {
super.onPause();
+ if (mProximitySensor != null) {
+ mSensorManager.unregisterListener(this, mProximitySensor);
+ }
}
@Override
protected void onStop() {
super.onStop();
+ mMetricsWriter.writeMetricsForExit();
mColorExtractor.removeOnColorsChangedListener(this);
}
@@ -659,6 +857,7 @@
* place the call, but check to make sure it is a viable number.
*/
private void placeCall() {
+ mUserActions |= MetricsWriter.USER_ACTION_MAKE_CALL_VIA_DIALPAD;
mLastNumber = mDigits.getText().toString();
// Convert into emergency number according to emergency conversion map.
@@ -675,11 +874,23 @@
playTone(ToneGenerator.TONE_PROP_NACK);
return;
}
+
+ mMetricsWriter.writeMetricsForMakingCall(MetricsWriter.CALL_SOURCE_DIALPAD,
+ MetricsWriter.PHONE_NUMBER_TYPE_EMERGENCY, isShortcutNumber(mLastNumber));
+
+ Bundle extras = new Bundle();
+ extras.putInt(TelecomManager.EXTRA_CALL_SOURCE,
+ ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_DIALPAD);
TelecomManager tm = (TelecomManager) getSystemService(TELECOM_SERVICE);
- tm.placeCall(Uri.fromParts(PhoneAccount.SCHEME_TEL, mLastNumber, null), null);
+ tm.placeCall(Uri.fromParts(PhoneAccount.SCHEME_TEL, mLastNumber, null), extras);
} else {
if (DBG) Log.d(LOG_TAG, "rejecting bad requested number " + mLastNumber);
+ // We interest on the context when user has intention to make phone call,
+ // so write metrics here for non-emergency numbers even these numbers are rejected.
+ mMetricsWriter.writeMetricsForMakingCall(MetricsWriter.CALL_SOURCE_DIALPAD,
+ MetricsWriter.PHONE_NUMBER_TYPE_GENERAL, false);
+
showDialog(BAD_EMERGENCY_NUMBER_DIALOG);
}
mDigits.getText().delete(0, mDigits.getText().length());
@@ -882,6 +1093,9 @@
mEmergencyShortcutView = findViewById(R.id.emergency_dialer_shortcuts);
mDialpadView = findViewById(R.id.emergency_dialer);
+ mEmergencyShortcutView.setAccessibilityDelegate(mAccessibilityDelegate);
+ mDialpadView.setAccessibilityDelegate(mAccessibilityDelegate);
+
final View dialpadButton = findViewById(R.id.floating_action_button_dialpad);
dialpadButton.setOnClickListener(this);
@@ -895,53 +1109,94 @@
final View emergencyDialpadTitle = findViewById(R.id.emergency_dialpad_title_container);
emergencyDialpadTitle.setVisibility(View.VISIBLE);
- // TODO: Integrating emergency phone number table will get location information.
- // Using null to present no location status.
- setLocationInfo(null);
-
mEmergencyShortcutButtonList = new ArrayList<>();
setupEmergencyCallShortcutButton();
+ updateLocationAndEccInfo(null, null);
+
switchView(mEmergencyShortcutView, mDialpadView, false);
}
- private void setLocationInfo(String country) {
+ private void setLocationInfo(String countryIso) {
final View locationInfo = findViewById(R.id.location_info);
- if (TextUtils.isEmpty(country)) {
+ String countryName = null;
+ if (!TextUtils.isEmpty(countryIso)) {
+ Locale locale = Locale.getDefault();
+ countryName = new Locale(locale.getLanguage(), countryIso, locale.getVariant())
+ .getDisplayCountry();
+ }
+ if (TextUtils.isEmpty(countryName)) {
locationInfo.setVisibility(View.INVISIBLE);
} else {
final TextView location = (TextView) locationInfo.findViewById(R.id.location_text);
- location.setText(country);
+ location.setText(countryName);
locationInfo.setVisibility(View.VISIBLE);
}
}
- // TODO: Integrate emergency phone number table.
- // Using default layout(no location, phone number is 112, description is Emergency,
- // and icon is cross shape) until integrating emergency phone number table.
private void setupEmergencyCallShortcutButton() {
final ViewGroup shortcutButtonContainer = findViewById(
R.id.emergency_shortcut_buttons_container);
shortcutButtonContainer.setClipToOutline(true);
+ final TextView emergencyNumberTitle = findViewById(R.id.emergency_number_title);
- final EmergencyShortcutButton button =
- (EmergencyShortcutButton) getLayoutInflater().inflate(
- R.layout.emergency_shortcut_button,
- shortcutButtonContainer, false);
+ mShortcutAdapter = new EccShortcutAdapter(this) {
+ @Override
+ public View inflateView(View convertView, ViewGroup parent, CharSequence number,
+ CharSequence description, int iconRes) {
+ EmergencyShortcutButton button = (EmergencyShortcutButton) getLayoutInflater()
+ .inflate(R.layout.emergency_shortcut_button, parent, false);
+ button.setPhoneNumber(number);
+ button.setPhoneDescription(description);
+ button.setPhoneTypeIcon(iconRes);
+ button.setOnConfirmClickListener(EmergencyDialer.this);
+ return button;
+ }
+ };
+ mShortcutDataSetObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ updateLayout();
+ }
- button.setPhoneNumber("112");
- button.setPhoneDescription("Emergency");
- button.setPhoneTypeIcon(R.drawable.ic_emergency_number_24);
- button.setOnConfirmClickListener(this);
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ updateLayout();
+ }
- shortcutButtonContainer.addView(button);
- mEmergencyShortcutButtonList.add(button);
+ private void updateLayout() {
+ // clear previous added buttons
+ shortcutButtonContainer.removeAllViews();
+ mEmergencyShortcutButtonList.clear();
- //Set emergency number title for numerous buttons.
- if (shortcutButtonContainer.getChildCount() > 1) {
- final TextView emergencyNumberTitle = findViewById(R.id.emergency_number_title);
- emergencyNumberTitle.setText(getString(R.string.numerous_emergency_numbers_title));
+ for (int i = 0; i < mShortcutAdapter.getCount() && i < SHORTCUT_SIZE_LIMIT; ++i) {
+ EmergencyShortcutButton button = (EmergencyShortcutButton)
+ mShortcutAdapter.getView(i, null, shortcutButtonContainer);
+ mEmergencyShortcutButtonList.add(button);
+ shortcutButtonContainer.addView(button);
+ }
+
+ // update emergency numbers title for numerous buttons.
+ if (mEmergencyShortcutButtonList.size() > 1) {
+ emergencyNumberTitle.setText(getString(
+ R.string.numerous_emergency_numbers_title));
+ } else {
+ emergencyNumberTitle.setText(getText(R.string.single_emergency_number_title));
+ }
+ }
+ };
+ mShortcutAdapter.registerDataSetObserver(mShortcutDataSetObserver);
+ }
+
+ private void updateLocationAndEccInfo(String iso, CountryEccInfo countryEccInfo) {
+ if (!isFinishing() && !isDestroyed()) {
+ setLocationInfo(iso);
+ if (mShortcutAdapter != null) {
+ mShortcutAdapter.updateCountryEccInfo(this, countryEccInfo);
+ }
}
}
@@ -1023,4 +1278,30 @@
}
});
}
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ float distance = event.values[0];
+ mIsProximityNear = (distance < mProximitySensor.getMaximumRange());
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ // Not used.
+ }
+
+ private boolean isShortcutNumber(String number) {
+ if (TextUtils.isEmpty(number) || mEmergencyShortcutButtonList == null) {
+ return false;
+ }
+
+ boolean isShortcut = false;
+ for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
+ if (button != null && number.equals(button.getPhoneNumber())) {
+ isShortcut = true;
+ break;
+ }
+ }
+ return isShortcut;
+ }
}
diff --git a/src/com/android/phone/EmergencyShortcutButton.java b/src/com/android/phone/EmergencyShortcutButton.java
index 92877c7..59b3794 100644
--- a/src/com/android/phone/EmergencyShortcutButton.java
+++ b/src/com/android/phone/EmergencyShortcutButton.java
@@ -19,6 +19,8 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
+import android.metrics.LogMaker;
+import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -30,6 +32,9 @@
import androidx.annotation.NonNull;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
/**
* Emergency shortcut button displays a local emergency phone number information(including phone
* number, and phone type). To decrease false clicking, it need to click twice to confirm to place
@@ -61,6 +66,12 @@
private boolean mConfirmViewHiding;
+ /**
+ * The time, in millis, since boot when user taps on shortcut button to reveal confirm view.
+ * This is used for metrics when calculating the interval between reveal tap and confirm tap.
+ */
+ private long mTimeOfRevealTapInMillis = 0;
+
public EmergencyShortcutButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -103,14 +114,14 @@
/**
* Set emergency phone number description.
*/
- public void setPhoneDescription(@NonNull String description) {
+ public void setPhoneDescription(@NonNull CharSequence description) {
mPhoneTypeDescription.setText(description);
}
/**
* Set emergency phone number.
*/
- public void setPhoneNumber(@NonNull String number) {
+ public void setPhoneNumber(@NonNull CharSequence number) {
mPhoneNumber.setText(number);
mPhoneCallHint.setText(
getContext().getString(R.string.emergency_call_shortcut_hint, number));
@@ -118,7 +129,7 @@
// Set content description for phone number.
if (number.length() > 1) {
StringBuilder stringBuilder = new StringBuilder();
- for (char c : number.toCharArray()) {
+ for (char c : number.toString().toCharArray()) {
stringBuilder.append(c).append(" ");
}
mPhoneNumber.setContentDescription(stringBuilder.toString().trim());
@@ -185,6 +196,8 @@
switch (view.getId()) {
case R.id.emergency_call_number_info_view:
if (AccessibilityManager.getInstance(mContext).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);
}
@@ -193,6 +206,15 @@
}
break;
case R.id.emergency_call_confirm_view:
+ if (mTimeOfRevealTapInMillis != 0) {
+ long timeBetweenTwoTaps =
+ SystemClock.elapsedRealtime() - mTimeOfRevealTapInMillis;
+ // Reset reveal time to zero for next reveal-confirm taps pair.
+ mTimeOfRevealTapInMillis = 0;
+
+ writeMetricsForConfirmTap(timeBetweenTwoTaps);
+ }
+
if (mOnConfirmClickListener != null) {
mOnConfirmClickListener.onConfirmClick(this);
}
@@ -204,6 +226,7 @@
mConfirmViewHiding = false;
mConfirmView.setVisibility(View.VISIBLE);
+ mTimeOfRevealTapInMillis = SystemClock.elapsedRealtime();
int centerX = mCallNumberInfoView.getLeft() + mCallNumberInfoView.getWidth() / 2;
int centerY = mCallNumberInfoView.getTop() + mCallNumberInfoView.getHeight() / 2;
Animator reveal = ViewAnimationUtils.createCircularReveal(
@@ -240,6 +263,8 @@
@Override
public void onAnimationEnd(Animator animation) {
mConfirmView.setVisibility(INVISIBLE);
+ // Reset reveal time to zero for next reveal-confirm taps pair.
+ mTimeOfRevealTapInMillis = 0;
}
});
reveal.start();
@@ -254,4 +279,12 @@
hideSelectedButton();
}
};
+
+ private void writeMetricsForConfirmTap(long timeBetweenTwoTaps) {
+ LogMaker logContent = new LogMaker(MetricsEvent.EMERGENCY_DIALER_SHORTCUT_CONFIRM_TAP)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_SHORTCUT_TAPS_INTERVAL,
+ timeBetweenTwoTaps);
+ MetricsLogger.action(logContent);
+ }
}
diff --git a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
index 082eaa9..b79cdd8 100644
--- a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
+++ b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
@@ -2,8 +2,10 @@
import android.app.ActionBar;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
+import android.telephony.CarrierConfigManager;
import android.util.Log;
import android.view.MenuItem;
@@ -26,6 +28,9 @@
private Phone mPhone;
private SubscriptionInfoHelper mSubscriptionInfoHelper;
+ private boolean mShowCLIRButton;
+ private boolean mShowCWButton;
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -41,24 +46,60 @@
mCLIRButton = (CLIRListPreference) prefSet.findPreference(BUTTON_CLIR_KEY);
mCWButton = (CallWaitingSwitchPreference) prefSet.findPreference(BUTTON_CW_KEY);
- mPreferences.add(mCLIRButton);
- mPreferences.add(mCWButton);
-
- if (icicle == null) {
- if (DBG) Log.d(LOG_TAG, "start to init ");
- mCLIRButton.init(this, false, mPhone);
+ PersistableBundle b = null;
+ if (mSubscriptionInfoHelper.hasSubId()) {
+ b = PhoneGlobals.getInstance().getCarrierConfigForSubId(
+ mSubscriptionInfoHelper.getSubId());
} else {
- if (DBG) Log.d(LOG_TAG, "restore stored states");
- mInitIndex = mPreferences.size();
- mCLIRButton.init(this, true, mPhone);
- mCWButton.init(this, true, mPhone);
- int[] clirArray = icicle.getIntArray(mCLIRButton.getKey());
- if (clirArray != null) {
- if (DBG) Log.d(LOG_TAG, "onCreate: clirArray[0]="
- + clirArray[0] + ", clirArray[1]=" + clirArray[1]);
- mCLIRButton.handleGetCLIRResult(clirArray);
+ b = PhoneGlobals.getInstance().getCarrierConfig();
+ }
+
+ if (b != null) {
+ mShowCLIRButton = b.getBoolean(
+ CarrierConfigManager.KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL);
+ mShowCWButton = b.getBoolean(
+ CarrierConfigManager.KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL);
+ }
+
+ if (mCLIRButton != null) {
+ if (mShowCLIRButton) {
+ mPreferences.add(mCLIRButton);
} else {
- mCLIRButton.init(this, false, mPhone);
+ prefSet.removePreference(mCLIRButton);
+ }
+ }
+
+ if (mCWButton != null) {
+ if (mShowCWButton) {
+ mPreferences.add(mCWButton);
+ } else {
+ prefSet.removePreference(mCWButton);
+ }
+ }
+
+ if (mPreferences.size() != 0) {
+ if (icicle == null) {
+ if (DBG) Log.d(LOG_TAG, "start to init ");
+ doPreferenceInit(mInitIndex);
+ } else {
+ if (DBG) Log.d(LOG_TAG, "restore stored states");
+ mInitIndex = mPreferences.size();
+ if (mShowCWButton) {
+ mCWButton.init(this, true, mPhone);
+ }
+ if (mShowCLIRButton) {
+ mCLIRButton.init(this, true, mPhone);
+ int[] clirArray = icicle.getIntArray(mCLIRButton.getKey());
+ if (clirArray != null) {
+ if (DBG) {
+ Log.d(LOG_TAG, "onCreate: clirArray[0]="
+ + clirArray[0] + ", clirArray[1]=" + clirArray[1]);
+ }
+ mCLIRButton.handleGetCLIRResult(clirArray);
+ } else {
+ mCLIRButton.init(this, false, mPhone);
+ }
+ }
}
}
@@ -73,7 +114,7 @@
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- if (mCLIRButton.clirArray != null) {
+ if (mShowCLIRButton && mCLIRButton.clirArray != null) {
outState.putIntArray(mCLIRButton.getKey(), mCLIRButton.clirArray);
}
}
@@ -82,10 +123,7 @@
public void onFinished(Preference preference, boolean reading) {
if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
mInitIndex++;
- Preference pref = mPreferences.get(mInitIndex);
- if (pref instanceof CallWaitingSwitchPreference) {
- ((CallWaitingSwitchPreference) pref).init(this, false, mPhone);
- }
+ doPreferenceInit(mInitIndex);
}
super.onFinished(preference, reading);
}
@@ -99,4 +137,15 @@
}
return super.onOptionsItemSelected(item);
}
+
+ private void doPreferenceInit(int index) {
+ if (mPreferences.size() != 0) {
+ Preference pref = mPreferences.get(index);
+ if (pref instanceof CallWaitingSwitchPreference) {
+ ((CallWaitingSwitchPreference) pref).init(this, false, mPhone);
+ } else if (pref instanceof CLIRListPreference) {
+ ((CLIRListPreference) pref).init(this, false, mPhone);
+ }
+ }
+ }
}
diff --git a/src/com/android/phone/GsmUmtsCallBarringOptions.java b/src/com/android/phone/GsmUmtsCallBarringOptions.java
index 4b875ee..a6f9844 100644
--- a/src/com/android/phone/GsmUmtsCallBarringOptions.java
+++ b/src/com/android/phone/GsmUmtsCallBarringOptions.java
@@ -18,12 +18,15 @@
import android.app.ActionBar;
import android.app.Dialog;
+import android.content.Context;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.PersistableBundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
+import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -360,6 +363,25 @@
Log.d(LOG_TAG, "onCreate, reading callbarring_options.xml file finished!");
}
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ PersistableBundle carrierConfig;
+ if (mSubscriptionInfoHelper.hasSubId()) {
+ carrierConfig = configManager.getConfigForSubId(mSubscriptionInfoHelper.getSubId());
+ } else {
+ carrierConfig = configManager.getConfig();
+ }
+ boolean isPwChangeButtonVisible = true;
+ boolean isDisableAllButtonVisible = true;
+ if (carrierConfig != null) {
+ isPwChangeButtonVisible = carrierConfig.getBoolean(
+ CarrierConfigManager.KEY_CALL_BARRING_SUPPORTS_PASSWORD_CHANGE_BOOL, true);
+ isDisableAllButtonVisible = carrierConfig.getBoolean(
+ CarrierConfigManager.KEY_CALL_BARRING_SUPPORTS_DEACTIVATE_ALL_BOOL, true);
+ } else {
+ Log.w(LOG_TAG, "Couldn't access CarrierConfig bundle");
+ }
+
// Get UI object references
PreferenceScreen prefSet = getPreferenceScreen();
mButtonBAOC = (CallBarringEditPreference) prefSet.findPreference(BUTTON_BAOC_KEY);
@@ -371,6 +393,15 @@
prefSet.findPreference(BUTTON_BA_ALL_KEY);
mButtonChangePW = (EditPinPreference) prefSet.findPreference(BUTTON_BA_CHANGE_PW_KEY);
+ // Some carriers do not use PW change and disable all buttons. Hide them if this is the
+ // case.
+ if (!isDisableAllButtonVisible) {
+ prefSet.removePreference(mButtonDisableAll);
+ }
+ if (!isPwChangeButtonVisible) {
+ prefSet.removePreference(mButtonChangePW);
+ }
+
// Assign click listener and update state
mButtonBAOC.setOnPinEnteredListener(this);
mButtonBAOIC.setOnPinEnteredListener(this);
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
index e562e46..6d80621 100644
--- a/src/com/android/phone/GsmUmtsCallForwardOptions.java
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -31,6 +31,7 @@
private static final String KEY_TOGGLE = "toggle";
private static final String KEY_STATUS = "status";
private static final String KEY_NUMBER = "number";
+ private static final String KEY_ENABLE = "enable";
private CallForwardEditPreference mButtonCFU;
private CallForwardEditPreference mButtonCFB;
@@ -112,11 +113,12 @@
for (CallForwardEditPreference pref : mPreferences) {
Bundle bundle = mIcicle.getParcelable(pref.getKey());
pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
+ pref.setEnabled(bundle.getBoolean(KEY_ENABLE));
CallForwardInfo cf = new CallForwardInfo();
cf.number = bundle.getString(KEY_NUMBER);
cf.status = bundle.getInt(KEY_STATUS);
pref.init(this, mPhone, mReplaceInvalidCFNumbers);
- pref.handleCallForwardResult(cf);
+ pref.restoreCallForwardInfo(cf);
}
}
mFirstResume = false;
@@ -131,6 +133,7 @@
for (CallForwardEditPreference pref : mPreferences) {
Bundle bundle = new Bundle();
bundle.putBoolean(KEY_TOGGLE, pref.isToggled());
+ bundle.putBoolean(KEY_ENABLE, pref.isEnabled());
if (pref.callForwardInfo != null) {
bundle.putString(KEY_NUMBER, pref.callForwardInfo.number);
bundle.putInt(KEY_STATUS, pref.callForwardInfo.status);
diff --git a/src/com/android/phone/GsmUmtsCallOptions.java b/src/com/android/phone/GsmUmtsCallOptions.java
index 5358db9..ab44b54 100644
--- a/src/com/android/phone/GsmUmtsCallOptions.java
+++ b/src/com/android/phone/GsmUmtsCallOptions.java
@@ -62,25 +62,45 @@
}
public static void init(PreferenceScreen prefScreen, SubscriptionInfoHelper subInfoHelper) {
- Preference callForwardingPref = prefScreen.findPreference(CALL_FORWARDING_KEY);
- callForwardingPref.setIntent(subInfoHelper.getIntent(GsmUmtsCallForwardOptions.class));
-
- Preference additionalGsmSettingsPref =
- prefScreen.findPreference(ADDITIONAL_GSM_SETTINGS_KEY);
- additionalGsmSettingsPref.setIntent(
- subInfoHelper.getIntent(GsmUmtsAdditionalCallOptions.class));
-
- Preference callBarringPref = prefScreen.findPreference(CALL_BARRING_KEY);
PersistableBundle b = null;
if (subInfoHelper.hasSubId()) {
b = PhoneGlobals.getInstance().getCarrierConfigForSubId(subInfoHelper.getSubId());
} else {
b = PhoneGlobals.getInstance().getCarrierConfig();
}
- if (b != null && b.getBoolean(CarrierConfigManager.KEY_CALL_BARRING_VISIBILITY_BOOL)) {
- callBarringPref.setIntent(subInfoHelper.getIntent(GsmUmtsCallBarringOptions.class));
- } else {
- prefScreen.removePreference(callBarringPref);
+
+ 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));
+ } else {
+ prefScreen.removePreference(callForwardingPref);
+ }
+ }
+
+ Preference additionalGsmSettingsPref =
+ prefScreen.findPreference(ADDITIONAL_GSM_SETTINGS_KEY);
+ if (additionalGsmSettingsPref != null) {
+ if (b != null && (b.getBoolean(
+ CarrierConfigManager.KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL)
+ || b.getBoolean(
+ CarrierConfigManager.KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL))) {
+ additionalGsmSettingsPref.setIntent(
+ subInfoHelper.getIntent(GsmUmtsAdditionalCallOptions.class));
+ } else {
+ prefScreen.removePreference(additionalGsmSettingsPref);
+ }
+ }
+
+ Preference callBarringPref = prefScreen.findPreference(CALL_BARRING_KEY);
+ if (callBarringPref != null) {
+ if (b != null && b.getBoolean(CarrierConfigManager.KEY_CALL_BARRING_VISIBILITY_BOOL)) {
+ callBarringPref.setIntent(subInfoHelper.getIntent(GsmUmtsCallBarringOptions.class));
+ } else {
+ prefScreen.removePreference(callBarringPref);
+ }
}
}
}
diff --git a/src/com/android/phone/MobileDataPreference.java b/src/com/android/phone/MobileDataPreference.java
index 38d700e..4e82f20 100644
--- a/src/com/android/phone/MobileDataPreference.java
+++ b/src/com/android/phone/MobileDataPreference.java
@@ -52,6 +52,9 @@
public int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
public boolean mChecked;
+ // Whether to show the dialog to ask switching default data subscription.
+ // Should be true only when a multi-sim phone only supports data connection on a single phone,
+ // and user is enabling data on the non-default phone.
public boolean mMultiSimDialog;
private TelephonyManager mTelephonyManager;
private SubscriptionManager mSubscriptionManager;
@@ -123,47 +126,46 @@
final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(
mSubId);
final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
- boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
+ final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
+ final boolean isMultipleDataOnCapable =
+ (mTelephonyManager.getNumberOfModemsWithSimultaneousDataConnections() > 1);
+ final boolean isDefaultDataSubscription = (nextSir != null && currentSir != null
+ && currentSir.getSubscriptionId() == nextSir.getSubscriptionId());
if (mChecked) {
- // If the device is single SIM or is enabling data on the active data SIM then forgo
- // the pop-up.
- if (isMultiSim || (nextSir != null && currentSir != null
- && currentSir.getSubscriptionId() == nextSir.getSubscriptionId())) {
- setMobileDataEnabled(false);
- if (nextSir != null && currentSir != null
- && currentSir.getSubscriptionId() == nextSir.getSubscriptionId()) {
- disableDataForOtherSubscriptions(mSubId);
- }
- return;
- }
- // disabling data; show confirmation dialog which eventually
- // calls setMobileDataEnabled() once user confirms.
- mMultiSimDialog = false;
- super.performClick(preferenceScreen);
- } else {
- // If we are showing the Sim Card tile then we are a Multi-Sim device.
- if (isMultiSim) {
- mMultiSimDialog = true;
- if (nextSir != null && currentSir != null
- && currentSir.getSubscriptionId() == nextSir.getSubscriptionId()) {
- setMobileDataEnabled(true);
- disableDataForOtherSubscriptions(mSubId);
- return;
- }
+ if (!isMultiSim) {
+ // disabling data; show confirmation dialog which eventually
+ // calls setMobileDataEnabled() once user confirms.
+ mMultiSimDialog = false;
super.performClick(preferenceScreen);
} else {
- setMobileDataEnabled(true);
+ // Don't show any dialog.
+ setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
+ }
+ } else {
+ if (isMultiSim && !isMultipleDataOnCapable && !isDefaultDataSubscription) {
+ // enabling data and setting to default; show confirmation dialog which eventually
+ // calls setMobileDataEnabled() once user confirms.
+ mMultiSimDialog = true;
+ super.performClick(preferenceScreen);
+ } else {
+ // Don't show any dialog.
+ setMobileDataEnabled(true /* enabled */, false /* disableOtherSubscriptions */);
}
}
}
- private void setMobileDataEnabled(boolean enabled) {
+ private void setMobileDataEnabled(boolean enabled, boolean disableOtherSubscriptions) {
if (DBG) Log.d(TAG, "setMobileDataEnabled(" + enabled + "," + mSubId + ")");
MetricsLogger.action(getContext(), MetricsEvent.ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE,
enabled);
mTelephonyManager.setDataEnabled(mSubId, enabled);
+
+ if (disableOtherSubscriptions) {
+ disableDataForOtherSubscriptions(mSubId);
+ }
+
setChecked(enabled);
}
@@ -232,11 +234,10 @@
}
if (mMultiSimDialog) {
mSubscriptionManager.setDefaultDataSubId(mSubId);
- setMobileDataEnabled(true);
- disableDataForOtherSubscriptions(mSubId);
+ setMobileDataEnabled(true /* enabled */, true /* disableOtherSubscriptions */);
} else {
// TODO: extend to modify policy enabled flag.
- setMobileDataEnabled(false);
+ setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
}
}
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index c48f5cb..7a795ed 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -35,7 +35,7 @@
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
-import android.os.AsyncResult;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -76,7 +76,6 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyIntents;
import com.android.phone.settings.PhoneAccountSettingsFragment;
import com.android.settingslib.RestrictedLockUtils;
@@ -149,6 +148,45 @@
return super.onOptionsItemSelected(item);
}
+
+ /**
+ * Returns true if Wifi calling is enabled for at least one phone.
+ */
+ public static boolean isWifiCallingEnabled(Context context) {
+ int phoneCount = TelephonyManager.from(context).getPhoneCount();
+ for (int i = 0; i < phoneCount; i++) {
+ if (isWifiCallingEnabled(context, i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if Wifi calling is enabled for the specific phone with id {@code phoneId}.
+ */
+ public static boolean isWifiCallingEnabled(Context context, int phoneId) {
+ final PhoneAccountHandle simCallManager =
+ TelecomManager.from(context).getSimCallManager();
+
+ boolean isWifiCallingEnabled;
+ if (simCallManager != null) {
+ Intent intent = PhoneAccountSettingsFragment
+ .buildPhoneAccountConfigureIntent(context, simCallManager);
+ PackageManager pm = context.getPackageManager();
+ isWifiCallingEnabled = intent != null
+ && !pm.queryIntentActivities(intent, 0 /* flags */).isEmpty();
+ } else {
+ ImsManager imsMgr = ImsManager.getInstance(context, phoneId);
+ isWifiCallingEnabled = imsMgr != null
+ && imsMgr.isWfcEnabledByPlatform()
+ && imsMgr.isWfcProvisionedOnDevice()
+ && isImsServiceStateReady(imsMgr);
+ }
+
+ return isWifiCallingEnabled;
+ }
+
/**
* Whether to show the entry point to eUICC settings.
*
@@ -236,6 +274,22 @@
}
}
+ private static boolean isImsServiceStateReady(ImsManager imsMgr) {
+ boolean isImsServiceStateReady = false;
+
+ try {
+ if (imsMgr != null && imsMgr.getImsServiceState() == ImsFeature.STATE_READY) {
+ isImsServiceStateReady = true;
+ }
+ } catch (ImsException ex) {
+ Log.e(MobileNetworkFragment.LOG_TAG,
+ "Exception when trying to get ImsServiceStatus: " + ex);
+ }
+
+ Log.d(MobileNetworkFragment.LOG_TAG, "isImsServiceStateReady=" + isImsServiceStateReady);
+ return isImsServiceStateReady;
+ }
+
public static class MobileNetworkFragment extends PreferenceFragment implements
Preference.OnPreferenceChangeListener, RoamingDialogFragment.RoamingDialogListener {
@@ -293,6 +347,7 @@
private SubscriptionManager mSubscriptionManager;
private TelephonyManager mTelephonyManager;
+ private int mSubId;
//UI objects
private AdvancedOptionsPreference mAdvancedOptions;
@@ -313,7 +368,6 @@
private List<SubscriptionInfo> mActiveSubInfos;
private UserManager mUm;
- private Phone mPhone;
private ImsManager mImsMgr;
private MyHandler mHandler;
private boolean mOkClicked;
@@ -347,20 +401,20 @@
updateVideoCallState();
}
- /*
- * Listen to different subId if mPhone is updated.
+ /**
+ * Listen to different subId if it's changed.
*/
- protected void updatePhone() {
- int newSubId = (mPhone != null
- && SubscriptionManager.isValidSubscriptionId(mPhone.getSubId()))
- ? mPhone.getSubId()
- : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ protected void updateSubscriptionId(Integer subId) {
+ if (subId.equals(PhoneCallStateListener.this.mSubId)) {
+ return;
+ }
- // Now, listen to new subId if it's valid.
+ PhoneCallStateListener.this.mSubId = subId;
+
mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
- mSubId = newSubId;
- if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+ // Now, listen to new subId if it's valid.
+ if (SubscriptionManager.isValidSubscriptionId(subId)) {
mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
}
}
@@ -417,7 +471,7 @@
@Override
public void onPositiveButtonClick(DialogFragment dialog) {
- mPhone.setDataRoamingEnabled(true);
+ mTelephonyManager.setDataRoamingEnabled(true);
mButtonDataRoam.setChecked(true);
MetricsLogger.action(getContext(),
getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
@@ -448,7 +502,6 @@
sendMetricsEventPreferenceClicked(preferenceScreen, preference);
/** TODO: Refactor and get rid of the if's using subclasses */
- final int phoneSubId = mPhone.getSubId();
if (preference.getKey().equals(BUTTON_4G_LTE_KEY)) {
return true;
} else if (mGsmUmtsOptions != null &&
@@ -456,7 +509,7 @@
return true;
} else if (mCdmaOptions != null &&
mCdmaOptions.preferenceTreeClick(preference) == true) {
- if (mPhone.isInEcm()) {
+ if (mTelephonyManager.getEmergencyCallbackMode()) {
mClickedPreference = preference;
@@ -469,8 +522,8 @@
} else if (preference == mButtonPreferredNetworkMode) {
//displays the value taken from the Settings.System
int settingsNetworkMode = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
- android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+ getContext().getContentResolver(),
+ android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
preferredNetworkMode);
mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
return true;
@@ -493,8 +546,8 @@
return true;
} else if (preference == mButtonEnabledNetworks) {
int settingsNetworkMode = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
- android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+ getContext().getContentResolver(),
+ android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
preferredNetworkMode);
mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
return true;
@@ -669,27 +722,26 @@
private void updatePhone(int slotId) {
final SubscriptionInfo sir = mSubscriptionManager
.getActiveSubscriptionInfoForSimSlotIndex(slotId);
+
if (sir != null) {
- int phoneId = SubscriptionManager.getPhoneId(sir.getSubscriptionId());
- if (SubscriptionManager.isValidPhoneId(phoneId)) {
- mPhone = PhoneFactory.getPhone(phoneId);
+ mSubId = sir.getSubscriptionId();
+
+ Log.i(LOG_TAG, "updatePhone:- slotId=" + slotId + " sir=" + sir);
+
+ mImsMgr = ImsManager.getInstance(getContext(),
+ SubscriptionManager.getPhoneId(mSubId));
+ mTelephonyManager = new TelephonyManager(getContext(), mSubId);
+ if (mImsMgr == null) {
+ log("updatePhone :: Could not get ImsManager instance!");
+ } else if (DBG) {
+ log("updatePhone :: mImsMgr=" + mImsMgr);
}
- }
- if (mPhone == null) {
- // Do the best we can
- mPhone = PhoneGlobals.getPhone();
- }
- Log.i(LOG_TAG, "updatePhone:- slotId=" + slotId + " sir=" + sir);
-
- mImsMgr = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
- mTelephonyManager = new TelephonyManager(mPhone.getContext(), mPhone.getSubId());
- if (mImsMgr == null) {
- log("updatePhone :: Could not get ImsManager instance!");
- } else if (DBG) {
- log("updatePhone :: mImsMgr=" + mImsMgr);
+ } else {
+ // There is no active subscription in the given slot.
+ mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
- mPhoneStateListener.updatePhone();
+ mPhoneStateListener.updateSubscriptionId(mSubId);
}
private TabHost.TabContentFactory mEmptyTabContent = new TabHost.TabContentFactory() {
@@ -788,6 +840,11 @@
int max = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
mActiveSubInfos = new ArrayList<SubscriptionInfo>(max);
+ int currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
+ updatePhone(currentTab);
+ if (hasActiveSubscriptions()) {
+ updateEnabledNetworksEntries();
+ }
Log.i(LOG_TAG, "onCreate:-");
}
@@ -863,7 +920,7 @@
// Set UI state in onResume because a user could go home, launch some
// app to change this setting's backend, and re-launch this settings app
// and the UI state would be inconsistent with actual state
- mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
+ mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null
|| getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null) {
@@ -909,24 +966,26 @@
prefSet.addPreference(mButtonDataRoam);
prefSet.addPreference(mDataUsagePref);
- // Customized preferences needs to be initialized with subId.
- mMobileDataPref.initialize(phoneSubId);
- mDataUsagePref.initialize(phoneSubId);
-
mMobileDataPref.setEnabled(hasActiveSubscriptions);
mButtonDataRoam.setEnabled(hasActiveSubscriptions);
mDataUsagePref.setEnabled(hasActiveSubscriptions);
- // Initialize states of mButtonDataRoam.
- mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
- mButtonDataRoam.setDisabledByAdmin(false);
- if (mButtonDataRoam.isEnabled()) {
- if (RestrictedLockUtils.hasBaseUserRestriction(context,
- UserManager.DISALLOW_DATA_ROAMING, UserHandle.myUserId())) {
- mButtonDataRoam.setEnabled(false);
- } else {
- mButtonDataRoam.checkRestrictionAndSetDisabled(
- UserManager.DISALLOW_DATA_ROAMING);
+ if (hasActiveSubscriptions) {
+ // Customized preferences needs to be initialized with subId.
+ mMobileDataPref.initialize(phoneSubId);
+ mDataUsagePref.initialize(phoneSubId);
+
+ // Initialize states of mButtonDataRoam.
+ mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
+ mButtonDataRoam.setDisabledByAdmin(false);
+ if (mButtonDataRoam.isEnabled()) {
+ if (RestrictedLockUtils.hasBaseUserRestriction(context,
+ UserManager.DISALLOW_DATA_ROAMING, UserHandle.myUserId())) {
+ mButtonDataRoam.setEnabled(false);
+ } else {
+ mButtonDataRoam.checkRestrictionAndSetDisabled(
+ UserManager.DISALLOW_DATA_ROAMING);
+ }
}
}
}
@@ -934,7 +993,6 @@
private void updateBody() {
final Activity activity = getActivity();
final PreferenceScreen prefSet = getPreferenceScreen();
- final int phoneSubId = mPhone.getSubId();
final boolean hasActiveSubscriptions = hasActiveSubscriptions();
if (activity == null || activity.isDestroyed()) {
@@ -949,18 +1007,27 @@
prefSet.removeAll();
- updateBodyBasicFields(activity, prefSet, phoneSubId, hasActiveSubscriptions);
+ updateBodyBasicFields(activity, prefSet, mSubId, hasActiveSubscriptions);
- if (mExpandAdvancedFields) {
- updateBodyAdvancedFields(activity, prefSet, phoneSubId, hasActiveSubscriptions);
+ if (hasActiveSubscriptions) {
+ if (mExpandAdvancedFields) {
+ updateBodyAdvancedFields(activity, prefSet, mSubId, hasActiveSubscriptions);
+ } else {
+ prefSet.addPreference(mAdvancedOptions);
+ }
} else {
- prefSet.addPreference(mAdvancedOptions);
+ // Shows the "Carrier" preference that allows user to add a e-sim profile.
+ if (showEuiccSettings(getContext())) {
+ mEuiccSettingsPref.setSummary(null /* summary */);
+ prefSet.addPreference(mEuiccSettingsPref);
+ }
}
}
private void updateBodyAdvancedFields(Activity activity, PreferenceScreen prefSet,
int phoneSubId, boolean hasActiveSubscriptions) {
- boolean isLteOnCdma = mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
+ boolean isLteOnCdma = mTelephonyManager.getLteOnCdmaMode()
+ == PhoneConstants.LTE_ON_CDMA_TRUE;
if (DBG) {
log("updateBody: isLteOnCdma=" + isLteOnCdma + " phoneSubId=" + phoneSubId);
@@ -981,12 +1048,12 @@
}
int settingsNetworkMode = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
preferredNetworkMode);
PersistableBundle carrierConfig =
- PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
mIsGlobalCdma = isLteOnCdma
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
if (carrierConfig.getBoolean(
@@ -996,15 +1063,15 @@
prefSet.removePreference(mLteDataServicePref);
} else if (carrierConfig.getBoolean(CarrierConfigManager
.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)
- && !mPhone.getServiceState().getRoaming()
- && mPhone.getServiceState().getDataRegState()
+ && !mTelephonyManager.getServiceState().getRoaming()
+ && mTelephonyManager.getServiceState().getDataRegState()
== ServiceState.STATE_IN_SERVICE) {
prefSet.removePreference(mButtonPreferredNetworkMode);
prefSet.removePreference(mButtonEnabledNetworks);
- final int phoneType = mPhone.getPhoneType();
+ final int phoneType = mTelephonyManager.getPhoneType();
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- updateCdmaOptions(this, prefSet, mPhone);
+ updateCdmaOptions(this, prefSet, mSubId);
} else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
} else {
@@ -1021,99 +1088,11 @@
// change Preferred Network Mode.
mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
- updateCdmaOptions(this, prefSet, mPhone);
+ updateCdmaOptions(this, prefSet, mSubId);
updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
} else {
prefSet.removePreference(mButtonPreferredNetworkMode);
- final int phoneType = mPhone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- int lteForced = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
- android.provider.Settings.Global.LTE_SERVICE_FORCED + mPhone.getSubId(),
- 0);
-
- if (isLteOnCdma) {
- if (lteForced == 0) {
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_cdma_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_cdma_values);
- } else {
- switch (settingsNetworkMode) {
- case Phone.NT_MODE_CDMA:
- case Phone.NT_MODE_CDMA_NO_EVDO:
- case Phone.NT_MODE_EVDO_NO_CDMA:
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_cdma_no_lte_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_cdma_no_lte_values);
- break;
- case Phone.NT_MODE_GLOBAL:
- case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
- case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
- case Phone.NT_MODE_LTE_ONLY:
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_cdma_only_lte_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_cdma_only_lte_values);
- break;
- default:
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_cdma_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_cdma_values);
- break;
- }
- }
- }
- updateCdmaOptions(this, prefSet, mPhone);
-
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- if (isSupportTdscdma()) {
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_tdscdma_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_tdscdma_values);
- } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
- && !getResources().getBoolean(R.bool.config_enabled_lte)) {
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_except_gsm_lte_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_except_gsm_lte_values);
- } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
- int select = (mShow4GForLTE == true) ?
- R.array.enabled_networks_except_gsm_4g_choices
- : R.array.enabled_networks_except_gsm_choices;
- mButtonEnabledNetworks.setEntries(select);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_except_gsm_values);
- } else if (!getResources().getBoolean(R.bool.config_enabled_lte)) {
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_except_lte_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_except_lte_values);
- } else if (mIsGlobalCdma) {
- mButtonEnabledNetworks.setEntries(
- R.array.enabled_networks_cdma_choices);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_cdma_values);
- } else {
- int select = (mShow4GForLTE == true) ? R.array.enabled_networks_4g_choices
- : R.array.enabled_networks_choices;
- mButtonEnabledNetworks.setEntries(select);
- mButtonEnabledNetworks.setEntryValues(
- R.array.enabled_networks_values);
- }
- updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- if (isWorldMode()) {
- mButtonEnabledNetworks.setEntries(
- R.array.preferred_network_mode_choices_world_mode);
- mButtonEnabledNetworks.setEntryValues(
- R.array.preferred_network_mode_values_world_mode);
- }
+ updateEnabledNetworksEntries();
mButtonEnabledNetworks.setOnPreferenceChangeListener(this);
if (DBG) log("settingsNetworkMode: " + settingsNetworkMode);
}
@@ -1161,8 +1140,12 @@
UpdatePreferredNetworkModeSummary(settingsNetworkMode);
UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
// Display preferred network type based on what modem returns b/18676277
- mPhone.setPreferredNetworkType(settingsNetworkMode, mHandler
- .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+ new SetPreferredNetworkAsyncTask(
+ mTelephonyManager,
+ mSubId,
+ settingsNetworkMode,
+ mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
/**
* Enable/disable depending upon if there are any active subscriptions.
@@ -1214,6 +1197,107 @@
}
}
+ // Requires that mSubId is up to date
+ void updateEnabledNetworksEntries() {
+ final int phoneType = mTelephonyManager.getPhoneType();
+ final PersistableBundle carrierConfig =
+ PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+ if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+ final int lteForced = android.provider.Settings.Global.getInt(
+ getContext().getContentResolver(),
+ android.provider.Settings.Global.LTE_SERVICE_FORCED + mSubId,
+ 0);
+ final boolean isLteOnCdma = mTelephonyManager.getLteOnCdmaMode()
+ == PhoneConstants.LTE_ON_CDMA_TRUE;
+ final int settingsNetworkMode = android.provider.Settings.Global.getInt(
+ getContext().getContentResolver(),
+ android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
+ preferredNetworkMode);
+ if (isLteOnCdma) {
+ if (lteForced == 0) {
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_cdma_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_cdma_values);
+ } else {
+ switch (settingsNetworkMode) {
+ case Phone.NT_MODE_CDMA:
+ case Phone.NT_MODE_CDMA_NO_EVDO:
+ case Phone.NT_MODE_EVDO_NO_CDMA:
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_cdma_no_lte_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_cdma_no_lte_values);
+ break;
+ case Phone.NT_MODE_GLOBAL:
+ case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+ case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+ case Phone.NT_MODE_LTE_ONLY:
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_cdma_only_lte_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_cdma_only_lte_values);
+ break;
+ default:
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_cdma_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_cdma_values);
+ break;
+ }
+ }
+ }
+ updateCdmaOptions(this, getPreferenceScreen(), mSubId);
+
+ } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+ if (isSupportTdscdma()) {
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_tdscdma_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_tdscdma_values);
+ } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
+ && !getResources().getBoolean(R.bool.config_enabled_lte)) {
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_except_gsm_lte_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_except_gsm_lte_values);
+ } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
+ int select = mShow4GForLTE
+ ? R.array.enabled_networks_except_gsm_4g_choices
+ : R.array.enabled_networks_except_gsm_choices;
+ mButtonEnabledNetworks.setEntries(select);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_except_gsm_values);
+ } else if (!getResources().getBoolean(R.bool.config_enabled_lte)) {
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_except_lte_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_except_lte_values);
+ } else if (mIsGlobalCdma) {
+ mButtonEnabledNetworks.setEntries(
+ R.array.enabled_networks_cdma_choices);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_cdma_values);
+ } else {
+ int select = mShow4GForLTE ? R.array.enabled_networks_4g_choices
+ : R.array.enabled_networks_choices;
+ mButtonEnabledNetworks.setEntries(select);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.enabled_networks_values);
+ }
+ updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId,
+ mNetworkQueryService);
+ } else {
+ throw new IllegalStateException("Unexpected phone type: " + phoneType);
+ }
+ if (isWorldMode()) {
+ mButtonEnabledNetworks.setEntries(
+ R.array.preferred_network_mode_choices_world_mode);
+ mButtonEnabledNetworks.setEntryValues(
+ R.array.preferred_network_mode_values_world_mode);
+ }
+ }
+
@Override
public void onPause() {
super.onPause();
@@ -1241,7 +1325,7 @@
public boolean onPreferenceChange(Preference preference, Object objValue) {
sendMetricsEventPreferenceChanged(getPreferenceScreen(), preference, objValue);
- final int phoneSubId = mPhone.getSubId();
+ final int phoneSubId = mSubId;
if (preference == mButtonPreferredNetworkMode) {
//NOTE onPreferenceChange seems to be called even if there is no change
//Check if the button value is changed from the System.Setting
@@ -1249,7 +1333,7 @@
int buttonNetworkMode;
buttonNetworkMode = Integer.parseInt((String) objValue);
int settingsNetworkMode = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
preferredNetworkMode);
if (buttonNetworkMode != settingsNetworkMode) {
@@ -1288,12 +1372,16 @@
}
android.provider.Settings.Global.putInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
buttonNetworkMode );
//Set the modem network mode
- mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
- .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+ new SetPreferredNetworkAsyncTask(
+ mTelephonyManager,
+ mSubId,
+ modemNetworkMode,
+ mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
} else if (preference == mButtonEnabledNetworks) {
mButtonEnabledNetworks.setValue((String) objValue);
@@ -1301,7 +1389,7 @@
buttonNetworkMode = Integer.parseInt((String) objValue);
if (DBG) log("buttonNetworkMode: " + buttonNetworkMode);
int settingsNetworkMode = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
preferredNetworkMode);
if (buttonNetworkMode != settingsNetworkMode) {
@@ -1336,12 +1424,16 @@
UpdateEnabledNetworksValueAndSummary(buttonNetworkMode);
android.provider.Settings.Global.putInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
buttonNetworkMode );
//Set the modem network mode
- mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
- .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+ new SetPreferredNetworkAsyncTask(
+ mTelephonyManager,
+ mSubId,
+ modemNetworkMode,
+ mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
} else if (preference == mButton4glte) {
boolean enhanced4gMode = !mButton4glte.isChecked();
@@ -1353,10 +1445,10 @@
//normally called on the toggle click
if (!mButtonDataRoam.isChecked()) {
PersistableBundle carrierConfig =
- PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
if (carrierConfig != null && carrierConfig.getBoolean(
CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL)) {
- mPhone.setDataRoamingEnabled(true);
+ mTelephonyManager.setDataRoamingEnabled(true);
MetricsLogger.action(getContext(),
getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
true);
@@ -1367,13 +1459,15 @@
// First confirm with a warning dialog about charges
mOkClicked = false;
RoamingDialogFragment fragment = new RoamingDialogFragment();
- fragment.setPhone(mPhone);
+ Bundle b = new Bundle();
+ b.putInt(RoamingDialogFragment.SUB_ID_KEY, mSubId);
+ fragment.setArguments(b);
fragment.show(getFragmentManager(), ROAMING_TAG);
// Don't update the toggle unless the confirm button is actually pressed.
return false;
}
} else {
- mPhone.setDataRoamingEnabled(false);
+ mTelephonyManager.setDataRoamingEnabled(false);
MetricsLogger.action(getContext(),
getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
false);
@@ -1403,7 +1497,7 @@
}
private boolean is4gLtePrefEnabled(PersistableBundle carrierConfig) {
- return (mTelephonyManager.getCallState(mPhone.getSubId())
+ return (mTelephonyManager.getCallState(mSubId)
== TelephonyManager.CALL_STATE_IDLE)
&& mImsMgr != null
&& mImsMgr.isNonTtyOrTtyOnVolteEnabled()
@@ -1432,26 +1526,25 @@
return;
}
- AsyncResult ar = (AsyncResult) msg.obj;
- final int phoneSubId = mPhone.getSubId();
+ boolean success = (boolean) msg.obj;
- if (ar.exception == null) {
+ if (success) {
int networkMode;
if (getPreferenceScreen().findPreference(
BUTTON_PREFERED_NETWORK_MODE) != null) {
networkMode = Integer.parseInt(mButtonPreferredNetworkMode.getValue());
android.provider.Settings.Global.putInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE
- + phoneSubId,
+ + mSubId,
networkMode );
}
if (getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null) {
networkMode = Integer.parseInt(mButtonEnabledNetworks.getValue());
android.provider.Settings.Global.putInt(
- mPhone.getContext().getContentResolver(),
+ getContext().getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE
- + phoneSubId,
+ + mSubId,
networkMode );
}
} else {
@@ -1463,11 +1556,9 @@
}
private void updatePreferredNetworkUIFromDb() {
- final int phoneSubId = mPhone.getSubId();
-
int settingsNetworkMode = android.provider.Settings.Global.getInt(
- mPhone.getContext().getContentResolver(),
- android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+ getContext().getContentResolver(),
+ android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
preferredNetworkMode);
if (DBG) {
@@ -1512,7 +1603,7 @@
R.string.preferred_network_mode_gsm_wcdma_summary);
break;
case Phone.NT_MODE_CDMA:
- switch (mPhone.getLteOnCdmaMode()) {
+ switch (mTelephonyManager.getLteOnCdmaMode()) {
case PhoneConstants.LTE_ON_CDMA_TRUE:
mButtonPreferredNetworkMode.setSummary(
R.string.preferred_network_mode_cdma_summary);
@@ -1565,9 +1656,9 @@
R.string.preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary);
break;
case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
- if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ||
- mIsGlobalCdma ||
- isWorldMode()) {
+ if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+ || mIsGlobalCdma
+ || isWorldMode()) {
mButtonPreferredNetworkMode.setSummary(
R.string.preferred_network_mode_global_summary);
} else {
@@ -1702,9 +1793,9 @@
}
mButtonEnabledNetworks.setValue(
Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
- if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ||
- mIsGlobalCdma ||
- isWorldMode()) {
+ if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+ || mIsGlobalCdma
+ || isWorldMode()) {
mButtonEnabledNetworks.setSummary(R.string.network_global);
} else {
mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
@@ -1743,31 +1834,23 @@
return;
}
- boolean removePref = false;
+ // Removes the preference if the wifi calling is disabled.
+ if (!isWifiCallingEnabled(getContext(), SubscriptionManager.getPhoneId(mSubId))) {
+ mCallingCategory.removePreference(mWiFiCallingPref);
+ return;
+ }
+
final PhoneAccountHandle simCallManager =
TelecomManager.from(getContext()).getSimCallManager();
if (simCallManager != null) {
Intent intent = PhoneAccountSettingsFragment.buildPhoneAccountConfigureIntent(
getContext(), simCallManager);
- if (intent != null) {
- PackageManager pm = mPhone.getContext().getPackageManager();
- List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
- if (!resolutions.isEmpty()) {
- mWiFiCallingPref.setTitle(resolutions.get(0).loadLabel(pm));
- mWiFiCallingPref.setSummary(null);
- mWiFiCallingPref.setIntent(intent);
- } else {
- removePref = true;
- }
- } else {
- removePref = true;
- }
- } else if (mImsMgr == null
- || !mImsMgr.isWfcEnabledByPlatform()
- || !mImsMgr.isWfcProvisionedOnDevice()
- || !isImsServiceStateReady()) {
- removePref = true;
+ PackageManager pm = getContext().getPackageManager();
+ List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
+ mWiFiCallingPref.setTitle(resolutions.get(0).loadLabel(pm));
+ mWiFiCallingPref.setSummary(null);
+ mWiFiCallingPref.setIntent(intent);
} else {
int resId = com.android.internal.R.string.wifi_calling_off_summary;
if (mImsMgr.isWfcEnabledByUser()) {
@@ -1792,13 +1875,9 @@
mWiFiCallingPref.setSummary(resId);
}
- if (removePref) {
- mCallingCategory.removePreference(mWiFiCallingPref);
- } else {
- mCallingCategory.addPreference(mWiFiCallingPref);
- mWiFiCallingPref.setEnabled(mTelephonyManager.getCallState(mPhone.getSubId())
- == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
- }
+ mCallingCategory.addPreference(mWiFiCallingPref);
+ mWiFiCallingPref.setEnabled(mTelephonyManager.getCallState(mSubId)
+ == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
}
private void updateEnhanced4gLteState() {
@@ -1807,12 +1886,12 @@
}
PersistableBundle carrierConfig = PhoneGlobals.getInstance()
- .getCarrierConfigForSubId(mPhone.getSubId());
+ .getCarrierConfigForSubId(mSubId);
if ((mImsMgr == null
|| !mImsMgr.isVolteEnabledByPlatform()
|| !mImsMgr.isVolteProvisionedOnDevice()
- || !isImsServiceStateReady()
+ || !isImsServiceStateReady(mImsMgr)
|| carrierConfig.getBoolean(
CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL))) {
getPreferenceScreen().removePreference(mButton4glte);
@@ -1831,21 +1910,21 @@
}
PersistableBundle carrierConfig = PhoneGlobals.getInstance()
- .getCarrierConfigForSubId(mPhone.getSubId());
+ .getCarrierConfigForSubId(mSubId);
if (mImsMgr != null
&& mImsMgr.isVtEnabledByPlatform()
&& mImsMgr.isVtProvisionedOnDevice()
- && isImsServiceStateReady()
+ && isImsServiceStateReady(mImsMgr)
&& (carrierConfig.getBoolean(
CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
- || mPhone.mDcTracker.isDataEnabled())) {
+ || mTelephonyManager.isDataEnabled())) {
mCallingCategory.addPreference(mVideoCallingPref);
if (!mButton4glte.isChecked()) {
mVideoCallingPref.setEnabled(false);
mVideoCallingPref.setChecked(false);
} else {
- mVideoCallingPref.setEnabled(mTelephonyManager.getCallState(mPhone.getSubId())
+ mVideoCallingPref.setEnabled(mTelephonyManager.getCallState(mSubId)
== TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
mVideoCallingPref.setChecked(mImsMgr.isVtEnabledByUser());
mVideoCallingPref.setOnPreferenceChangeListener(this);
@@ -1931,7 +2010,7 @@
return;
}
- updateGsmUmtsOptions(this, prefSet, mPhone.getSubId(), mNetworkQueryService);
+ updateGsmUmtsOptions(this, prefSet, mSubId, mNetworkQueryService);
PreferenceCategory networkOperatorCategory =
(PreferenceCategory) prefSet.findPreference(
@@ -1954,10 +2033,11 @@
if (prefSet == null) {
return;
}
- updateCdmaOptions(this, prefSet, mPhone);
+ updateCdmaOptions(this, prefSet, mSubId);
CdmaSystemSelectListPreference systemSelect =
(CdmaSystemSelectListPreference)prefSet.findPreference
(BUTTON_CDMA_SYSTEM_SELECT_KEY);
+ systemSelect.setSubscriptionId(mSubId);
if (systemSelect != null) {
systemSelect.setEnabled(enable);
}
@@ -1968,7 +2048,7 @@
return true;
}
- String operatorNumeric = mPhone.getServiceState().getOperatorNumeric();
+ String operatorNumeric = mTelephonyManager.getServiceState().getOperatorNumeric();
String[] numericArray = getResources().getStringArray(
R.array.config_support_tdscdma_roaming_on_networks);
if (numericArray.length == 0 || operatorNumeric == null) {
@@ -2095,31 +2175,42 @@
}
private void updateCdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
- Phone phone) {
+ int subId) {
// We don't want to re-create CdmaOptions if already exists. Otherwise, the preferences
// inside it will also be re-created which causes unexpected behavior. For example,
// the open dialog gets dismissed or detached after pause / resume.
if (mCdmaOptions == null) {
- mCdmaOptions = new CdmaOptions(prefFragment, prefScreen, phone);
+ mCdmaOptions = new CdmaOptions(prefFragment, prefScreen, subId);
} else {
- mCdmaOptions.update(phone);
+ mCdmaOptions.updateSubscriptionId(subId);
}
}
+ }
- private boolean isImsServiceStateReady() {
- boolean isImsServiceStateReady = false;
+ private static final class SetPreferredNetworkAsyncTask extends AsyncTask<Void, Void, Boolean> {
- try {
- if (mImsMgr != null && mImsMgr.getImsServiceState() == ImsFeature.STATE_READY) {
- isImsServiceStateReady = true;
- }
- } catch (ImsException ex) {
- loge("Exception when trying to get ImsServiceStatus: " + ex);
- }
+ private final TelephonyManager mTelephonyManager;
+ private final int mSubId;
+ private final int mNetworkType;
+ private final Message mCallback;
- log("isImsServiceStateReady=" + isImsServiceStateReady);
- return isImsServiceStateReady;
+ SetPreferredNetworkAsyncTask(
+ TelephonyManager tm, int subId, int networkType, Message callback) {
+ mTelephonyManager = tm;
+ mSubId = subId;
+ mNetworkType = networkType;
+ mCallback = callback;
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... voids) {
+ return mTelephonyManager.setPreferredNetworkType(mSubId, mNetworkType);
+ }
+
+ @Override
+ protected void onPostExecute(Boolean isSuccessed) {
+ mCallback.obj = isSuccessed;
+ mCallback.sendToTarget();
}
}
}
-
diff --git a/src/com/android/phone/NetworkOperatorPreference.java b/src/com/android/phone/NetworkOperatorPreference.java
index 85adf16..e582924 100644
--- a/src/com/android/phone/NetworkOperatorPreference.java
+++ b/src/com/android/phone/NetworkOperatorPreference.java
@@ -24,7 +24,6 @@
import android.preference.Preference;
import android.telephony.CellInfo;
import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Gravity;
@@ -71,7 +70,7 @@
networkTitle += " " + getContext().getResources().getString(R.string.forbidden_network);
}
setTitle(networkTitle);
- int level = CellInfoUtil.getLevel(mCellInfo);
+ int level = mCellInfo.getCellSignalStrength().getLevel();
if (DBG) Log.d(TAG, "refresh level: " + String.valueOf(level));
if (mLevel != level) {
mLevel = level;
@@ -86,17 +85,15 @@
updateIcon(level);
}
- private int getIconId(int networkType) {
- if (networkType == TelephonyManager.NETWORK_TYPE_CDMA) {
- return R.drawable.signal_strength_1x;
- } else if (networkType == TelephonyManager.NETWORK_TYPE_LTE) {
- return R.drawable.signal_strength_lte;
- } else if (networkType == TelephonyManager.NETWORK_TYPE_UMTS) {
- return R.drawable.signal_strength_3g;
- } else if (networkType == TelephonyManager.NETWORK_TYPE_GSM) {
- return R.drawable.signal_strength_g;
- } else {
- return 0;
+ private static int getIconIdForCell(CellInfo ci) {
+ final int type = ci.getCellIdentity().getType();
+ switch (type) {
+ case CellInfo.TYPE_GSM: return R.drawable.signal_strength_g;
+ case CellInfo.TYPE_WCDMA: // fall through
+ case CellInfo.TYPE_TDSCDMA: return R.drawable.signal_strength_3g;
+ case CellInfo.TYPE_LTE: return R.drawable.signal_strength_lte;
+ case CellInfo.TYPE_CDMA: return R.drawable.signal_strength_1x;
+ default: return 0;
}
}
@@ -113,7 +110,7 @@
signalDrawable.setDarkIntensity(0);
// Make the network type drawable
- int iconType = getIconId(CellInfoUtil.getNetworkType(mCellInfo));
+ int iconType = getIconIdForCell(mCellInfo);
Drawable networkDrawable =
iconType == NO_CELL_DATA_CONNECTED_ICON
? EMPTY_DRAWABLE
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
index 316d11a..6d8b30f 100644
--- a/src/com/android/phone/NetworkOperators.java
+++ b/src/com/android/phone/NetworkOperators.java
@@ -19,7 +19,6 @@
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
-import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.preference.Preference;
@@ -33,9 +32,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.settingslib.utils.ThreadUtils;
/**
* "Networks" settings UI for the Phone app.
@@ -55,16 +52,14 @@
public static final String BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key";
public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
- int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
- private static final int ALREADY_IN_AUTO_SELECTION = 1;
-
//preference objects
private NetworkSelectListPreference mNetworkSelect;
private TwoStatePreference mAutoSelect;
private Preference mChooseNetwork;
+ private ProgressDialog mProgressDialog;
private int mSubId;
- private ProgressDialog mProgressDialog;
+ private TelephonyManager mTelephonyManager;
// There's two sets of Auto-Select UI in this class.
// If {@code com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI} set as true
@@ -94,6 +89,7 @@
removePreference(mChooseNetwork);
}
mProgressDialog = new ProgressDialog(getContext());
+ mTelephonyManager = TelephonyManager.from(getContext());
}
/**
@@ -104,7 +100,7 @@
*/
protected void update(final int subId, INetworkQueryService queryService) {
mSubId = subId;
- mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+ mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
if (mAutoSelect != null) {
mAutoSelect.setOnPreferenceChangeListener(this);
@@ -112,11 +108,9 @@
if (mEnableNewManualSelectNetworkUI) {
if (mChooseNetwork != null) {
- TelephonyManager telephonyManager = (TelephonyManager)
- getContext().getSystemService(Context.TELEPHONY_SERVICE);
- if (DBG) logd("data connection status " + telephonyManager.getDataState());
- if (telephonyManager.getDataState() == telephonyManager.DATA_CONNECTED) {
- mChooseNetwork.setSummary(telephonyManager.getNetworkOperatorName());
+ ServiceState ss = mTelephonyManager.getServiceState();
+ if (ss != null && ss.getState() == ServiceState.STATE_IN_SERVICE) {
+ mChooseNetwork.setSummary(mTelephonyManager.getNetworkOperatorName());
} else {
mChooseNetwork.setSummary(R.string.network_disconnected);
}
@@ -152,48 +146,44 @@
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- AsyncResult ar;
switch (msg.what) {
case EVENT_AUTO_SELECT_DONE:
mAutoSelect.setEnabled(true);
dismissProgressBar();
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- if (DBG) logd("automatic network selection: failed!");
- displayNetworkSelectionFailed(ar.exception);
- } else {
+ boolean isSuccessed = (boolean) msg.obj;
+
+ if (isSuccessed) {
if (DBG) logd("automatic network selection: succeeded!");
- displayNetworkSelectionSucceeded(msg.arg1);
+ displayNetworkSelectionSucceeded();
+ } else {
+ if (DBG) logd("automatic network selection: failed!");
+ displayNetworkSelectionFailed();
}
break;
case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
+ int networkSelectionMode = msg.arg1;
+ if (networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN) {
if (DBG) logd("get network selection mode: failed!");
- } else if (ar.result != null) {
- try {
- int[] modes = (int[]) ar.result;
- boolean autoSelect = (modes[0] == 0);
- if (DBG) {
- logd("get network selection mode: "
- + (autoSelect ? "auto" : "manual") + " selection");
+ } else {
+ boolean autoSelect = networkSelectionMode
+ == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+ if (DBG) {
+ logd("get network selection mode: "
+ + (autoSelect ? "auto" : "manual") + " selection");
+ }
+ if (mAutoSelect != null) {
+ mAutoSelect.setChecked(autoSelect);
+ }
+ if (mEnableNewManualSelectNetworkUI) {
+ if (mChooseNetwork != null) {
+ mChooseNetwork.setEnabled(!autoSelect);
}
- if (mAutoSelect != null) {
- mAutoSelect.setChecked(autoSelect);
+ } else {
+ if (mNetworkSelect != null) {
+ mNetworkSelect.setEnabled(!autoSelect);
}
- if (mEnableNewManualSelectNetworkUI) {
- if (mChooseNetwork != null) {
- mChooseNetwork.setEnabled(!autoSelect);
- }
- } else {
- if (mNetworkSelect != null) {
- mNetworkSelect.setEnabled(!autoSelect);
- }
- }
- } catch (Exception e) {
- if (DBG) loge("get network selection mode: unable to parse result.");
}
}
}
@@ -202,38 +192,22 @@
};
// Used by both mAutoSelect and mNetworkSelect buttons.
- protected void displayNetworkSelectionFailed(Throwable ex) {
- String status;
- if ((ex != null && ex instanceof CommandException)
- && ((CommandException) ex).getCommandError()
- == CommandException.Error.ILLEGAL_SIM_OR_ME) {
- status = getContext().getResources().getString(R.string.not_allowed);
- } else {
- status = getContext().getResources().getString(R.string.connect_later);
- }
+ protected void displayNetworkSelectionFailed() {
+ String status = getContext().getResources().getString(R.string.connect_later);
final PhoneGlobals app = PhoneGlobals.getInstance();
app.notificationMgr.postTransientNotification(
NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
- TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
- Phone phone = PhoneFactory.getPhone(mPhoneId);
- if (phone != null) {
- ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId());
- if (ss != null) {
- app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
- }
+ ServiceState ss = mTelephonyManager.getServiceStateForSubscriber(mSubId);
+ if (ss != null) {
+ app.notificationMgr.updateNetworkSelection(ss.getState(), mSubId);
}
}
// Used by both mAutoSelect and mNetworkSelect buttons.
- protected void displayNetworkSelectionSucceeded(int msgArg1) {
- String status = null;
- if (msgArg1 == ALREADY_IN_AUTO_SELECTION) {
- status = getContext().getResources().getString(R.string.already_auto);
- } else {
- status = getContext().getResources().getString(R.string.registration_done);
- }
+ protected void displayNetworkSelectionSucceeded() {
+ String status = getContext().getResources().getString(R.string.registration_done);
final PhoneGlobals app = PhoneGlobals.getInstance();
app.notificationMgr.postTransientNotification(
@@ -256,10 +230,17 @@
if (DBG) logd("select network automatically...");
showAutoSelectProgressBar();
mAutoSelect.setEnabled(false);
- Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
- Phone phone = PhoneFactory.getPhone(mPhoneId);
- if (phone != null) {
- phone.setNetworkSelectionModeAutomatic(msg);
+ if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ mTelephonyManager.setNetworkSelectionModeAutomatic();
+ // Because TelephonyManager#setNetworkSelectionModeAutomatic doesn't have a
+ // return value, we query the current network selection mode to tell if the
+ // TelephonyManager#setNetworkSelectionModeAutomatic is successed.
+ int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
+ Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
+ msg.obj = networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+ msg.sendToTarget();
+ });
}
} else {
if (mEnableNewManualSelectNetworkUI) {
@@ -277,11 +258,12 @@
protected void getNetworkSelectionMode() {
if (DBG) logd("getting network selection mode...");
- Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
- Phone phone = PhoneFactory.getPhone(mPhoneId);
- if (phone != null) {
- phone.getNetworkSelectionMode(msg);
- }
+ ThreadUtils.postOnBackgroundThread(() -> {
+ int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
+ Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
+ msg.arg1 = networkSelectionMode;
+ msg.sendToTarget();
+ });
}
private void dismissProgressBar() {
@@ -300,10 +282,10 @@
}
/**
- * Open the Choose netwotk page via {@alink NetworkSelectSettingActivity}
+ * Open the Choose network page via {@alink NetworkSelectSettingActivity}
*/
public void openChooseNetworkPage() {
- Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mPhoneId);
+ Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mSubId);
getContext().startActivity(intent);
}
diff --git a/src/com/android/phone/NetworkQueryService.java b/src/com/android/phone/NetworkQueryService.java
index 22b5509..e67582f 100644
--- a/src/com/android/phone/NetworkQueryService.java
+++ b/src/com/android/phone/NetworkQueryService.java
@@ -19,7 +19,6 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.os.AsyncResult;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -33,13 +32,14 @@
import android.telephony.NetworkScan;
import android.telephony.NetworkScanRequest;
import android.telephony.RadioAccessSpecifier;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyScanManager;
import android.util.Log;
+import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.List;
@@ -185,7 +185,7 @@
* completion.
*/
public void startNetworkQuery(
- INetworkQueryServiceCallback cb, int phoneId, boolean isIncrementalResult) {
+ INetworkQueryServiceCallback cb, int subId, boolean isIncrementalResult) {
if (cb != null) {
// register the callback to the list of callbacks.
synchronized (mCallbacks) {
@@ -233,16 +233,23 @@
networkScanCallback);
mState = QUERY_IS_RUNNING;
} else {
- Phone phone = PhoneFactory.getPhone(phoneId);
- if (phone != null) {
- phone.getAvailableNetworks(
- mHandler.obtainMessage(
- EVENT_NETWORK_SCAN_VIA_PHONE_COMPLETED));
+ if (SubscriptionManager.isValidSubscriptionId(subId)) {
mState = QUERY_IS_RUNNING;
- if (DBG) log("start network scan via Phone");
+ ThreadUtils.postOnBackgroundThread(() -> {
+ if (DBG) log("start network scan via Phone xxx");
+ TelephonyManager telephonyManager =
+ TelephonyManager.from(getApplicationContext())
+ .createForSubscriptionId(subId);
+ CellNetworkScanResult result =
+ telephonyManager.getAvailableNetworks();
+ Message msg = mHandler.obtainMessage(
+ EVENT_NETWORK_SCAN_VIA_PHONE_COMPLETED);
+ msg.obj = result;
+ msg.sendToTarget();
+ });
} else {
if (DBG) {
- log("phone is null");
+ log("SubscriptionId is invalid");
}
}
}
@@ -316,8 +323,7 @@
}
/**
- * Broadcast the results from the query to all registered callback
- * objects.
+ * Broadcast the results from the query to all registered callback objects.
*/
private void broadcastQueryResults(Message msg) {
// reset the state.
@@ -331,11 +337,11 @@
try {
switch (msg.what) {
case EVENT_NETWORK_SCAN_VIA_PHONE_COMPLETED:
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar != null) {
- cb.onResults(getCellInfoList((List<OperatorInfo>) ar.result));
+ CellNetworkScanResult result = (CellNetworkScanResult) msg.obj;
+ if (result.getOperators() != null) {
+ cb.onResults(getCellInfoList(result.getOperators()));
} else {
- if (DBG) log("AsyncResult is null.");
+ if (DBG) log("Operators list is null.");
}
// Send the onComplete() callback to indicate the one-time network
// scan has completed.
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
index 51a678d..cec914a 100644
--- a/src/com/android/phone/NetworkSelectListPreference.java
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -19,7 +19,6 @@
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
-import android.os.AsyncResult;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
@@ -44,8 +43,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -64,7 +62,7 @@
private static final String LOG_TAG = "networkSelect";
private static final boolean DBG = true;
- private static final int EVENT_NETWORK_SELECTION_DONE = 1;
+ private static final int EVENT_MANUALLY_NETWORK_SELECTION_DONE = 1;
private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
private static final int EVENT_NETWORK_SCAN_COMPLETED = 3;
@@ -72,13 +70,12 @@
private static final int DIALOG_NETWORK_SELECTION = 100;
private static final int DIALOG_NETWORK_LIST_LOAD = 200;
- private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
private List<CellInfo> mCellInfoList;
private CellInfo mCellInfo;
private int mSubId;
+ private TelephonyManager mTelephonyManager;
private NetworkOperators mNetworkOperators;
- private boolean mNeedScanAgain;
private List<String> mForbiddenPlmns;
private ProgressDialog mProgressDialog;
@@ -113,9 +110,8 @@
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- AsyncResult ar;
switch (msg.what) {
- case EVENT_NETWORK_SELECTION_DONE:
+ case EVENT_MANUALLY_NETWORK_SELECTION_DONE:
if (DBG) logd("hideProgressPanel");
try {
dismissProgressBar();
@@ -123,16 +119,16 @@
}
setEnabled(true);
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- if (DBG) logd("manual network selection: failed!");
- mNetworkOperators.displayNetworkSelectionFailed(ar.exception);
- } else {
+ boolean isSuccessed = (boolean) msg.obj;
+ if (isSuccessed) {
if (DBG) {
logd("manual network selection: succeeded! "
+ getNetworkTitle(mCellInfo));
}
- mNetworkOperators.displayNetworkSelectionSucceeded(msg.arg1);
+ mNetworkOperators.displayNetworkSelectionSucceeded();
+ } else {
+ if (DBG) logd("manual network selection: failed!");
+ mNetworkOperators.displayNetworkSelectionFailed();
}
mNetworkOperators.getNetworkSelectionMode();
break;
@@ -235,14 +231,9 @@
// This preference should share the same progressDialog with networkOperators category.
mProgressDialog = progressDialog;
- if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
- mPhoneId = SubscriptionManager.getPhoneId(mSubId);
- }
+ mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
- TelephonyManager telephonyManager = (TelephonyManager)
- getContext().getSystemService(Context.TELEPHONY_SERVICE);
-
- setSummary(telephonyManager.getNetworkOperatorName(mSubId));
+ setSummary(mTelephonyManager.getNetworkOperatorName());
setOnPreferenceChangeListener(this);
}
@@ -300,7 +291,8 @@
if (DBG) logd("load networks list...");
try {
if (mNetworkQueryService != null) {
- mNetworkQueryService.startNetworkQuery(mCallback, mPhoneId, false);
+ mNetworkQueryService.startNetworkQuery(
+ mCallback, mSubId, false /* isIncrementalResult */);
} else {
displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
}
@@ -406,16 +398,21 @@
MetricsLogger.action(getContext(),
MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK);
- Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
- Phone phone = PhoneFactory.getPhone(mPhoneId);
- if (phone != null) {
- OperatorInfo operatorInfo = getOperatorInfoFromCellInfo(mCellInfo);
- if (DBG) logd("manually selected network: " + operatorInfo.toString());
- phone.selectNetworkManually(operatorInfo, true, msg);
- displayNetworkSelectionInProgress();
+ if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ final OperatorInfo operatorInfo = getOperatorInfoFromCellInfo(mCellInfo);
+ if (DBG) logd("manually selected network: " + operatorInfo.toString());
+ boolean isSuccessed = mTelephonyManager.setNetworkSelectionModeManual(
+ operatorInfo.getOperatorNumeric(), true /* persistSelection */);
+ int mode = mTelephonyManager.getNetworkSelectionMode();
+ Message msg = mHandler.obtainMessage(EVENT_MANUALLY_NETWORK_SELECTION_DONE);
+ msg.obj = isSuccessed;
+ msg.sendToTarget();
+ });
} else {
- loge("Error selecting network. phone is null.");
+ loge("Error selecting network, subscription Id is invalid " + mSubId);
}
+
return true;
}
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
index 96e4a26..56f0187 100644
--- a/src/com/android/phone/NetworkSelectSetting.java
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.os.AsyncResult;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@@ -47,8 +46,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -64,7 +62,7 @@
private static final String TAG = "NetworkSelectSetting";
private static final boolean DBG = true;
- private static final int EVENT_NETWORK_SELECTION_DONE = 1;
+ private static final int EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE = 1;
private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
private static final int EVENT_NETWORK_SCAN_ERROR = 3;
private static final int EVENT_NETWORK_SCAN_COMPLETED = 4;
@@ -81,11 +79,10 @@
private View mProgressHeader;
private Preference mStatusMessagePreference;
private List<CellInfo> mCellInfoList;
- private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+ private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private ViewGroup mFrameLayout;
private NetworkOperatorPreference mSelectedNetworkOperatorPreference;
private TelephonyManager mTelephonyManager;
- private NetworkOperators mNetworkOperators;
private List<String> mForbiddenPlmns;
private final Runnable mUpdateNetworkOperatorsRunnable = () -> {
@@ -95,9 +92,9 @@
/**
* Create a new instance of this fragment.
*/
- public static NetworkSelectSetting newInstance(int phoneId) {
+ public static NetworkSelectSetting newInstance(int subId) {
Bundle args = new Bundle();
- args.putInt(NetworkSelectSettingActivity.KEY_PHONE_ID, phoneId);
+ args.putInt(NetworkSelectSettingActivity.KEY_SUBSCRIPTION_ID, subId);
NetworkSelectSetting fragment = new NetworkSelectSetting();
fragment.setArguments(args);
@@ -109,7 +106,7 @@
if (DBG) logd("onCreate");
super.onCreate(icicle);
- mPhoneId = getArguments().getInt(NetworkSelectSettingActivity.KEY_PHONE_ID);
+ mSubId = getArguments().getInt(NetworkSelectSettingActivity.KEY_SUBSCRIPTION_ID);
addPreferencesFromResource(R.xml.choose_network);
mConnectedNetworkOperatorsPreference =
@@ -118,9 +115,7 @@
(PreferenceCategory) findPreference(PREF_KEY_NETWORK_OPERATORS);
mStatusMessagePreference = new Preference(getContext());
mSelectedNetworkOperatorPreference = null;
- mTelephonyManager = (TelephonyManager)
- getContext().getSystemService(Context.TELEPHONY_SERVICE);
- mNetworkOperators = new NetworkOperators(getContext());
+ mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
setRetainInstance(true);
}
@@ -199,9 +194,7 @@
MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK);
// Connect to the network
- Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
- Phone phone = PhoneFactory.getPhone(mPhoneId);
- if (phone != null) {
+ if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
if (DBG) {
logd("Connect to the network: " + CellInfoUtil.getNetworkTitle(cellInfo));
}
@@ -218,14 +211,20 @@
}
}
- // Select network manually via Phone
OperatorInfo operatorInfo = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo);
if (DBG) logd("manually selected network operator: " + operatorInfo.toString());
- phone.selectNetworkManually(operatorInfo, true, msg);
+
+ ThreadUtils.postOnBackgroundThread(() -> {
+ Message msg = mHandler.obtainMessage(EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE);
+ msg.obj = mTelephonyManager.setNetworkSelectionModeManual(
+ operatorInfo.getOperatorNumeric(), true /* persistSelection */);
+ msg.sendToTarget();
+ });
+
setProgressBarVisible(true);
return true;
} else {
- loge("Error selecting network. phone is null.");
+ loge("Error selecting network. Subscription Id is invalid.");
mSelectedNetworkOperatorPreference = null;
return false;
}
@@ -257,23 +256,22 @@
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- AsyncResult ar;
switch (msg.what) {
- case EVENT_NETWORK_SELECTION_DONE:
+ case EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE:
if (DBG) logd("network selection done: hide the progress header");
setProgressBarVisible(false);
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
+ boolean isSuccessed = (boolean) msg.obj;
+ if (isSuccessed) {
+ if (DBG) logd("manual network selection: succeeded! ");
+ // Set summary as "Connected" to the selected network.
+ mSelectedNetworkOperatorPreference.setSummary(R.string.network_connected);
+ } else {
if (DBG) logd("manual network selection: failed! ");
updateNetworkSelection();
// Set summary as "Couldn't connect" to the selected network.
mSelectedNetworkOperatorPreference.setSummary(
R.string.network_could_not_connect);
- } else {
- if (DBG) logd("manual network selection: succeeded! ");
- // Set summary as "Connected" to the selected network.
- mSelectedNetworkOperatorPreference.setSummary(R.string.network_connected);
}
break;
@@ -316,7 +314,7 @@
if (mNetworkQueryService != null) {
if (DBG) logd("start network query");
mNetworkQueryService
- .startNetworkQuery(mCallback, mPhoneId, true /* is incremental result */);
+ .startNetworkQuery(mCallback, mSubId, true /* is incremental result */);
} else {
if (DBG) logd("unable to start network query, mNetworkQueryService is null");
addMessagePreference(R.string.network_query_error);
@@ -420,7 +418,7 @@
if (DBG) logd("Force config ConnectedNetworkOperatorsPreferenceCategory");
if (mTelephonyManager.getDataState() == mTelephonyManager.DATA_CONNECTED) {
// Try to get the network registration states
- ServiceState ss = mTelephonyManager.getServiceStateForSubscriber(mPhoneId);
+ ServiceState ss = mTelephonyManager.getServiceState();
List<NetworkRegistrationState> networkList =
ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN);
if (networkList == null || networkList.size() == 0) {
@@ -560,8 +558,8 @@
map.put(plmn, cellInfo);
} else {
if (map.get(plmn).isRegistered()
- || CellInfoUtil.getLevel(map.get(plmn))
- > CellInfoUtil.getLevel(cellInfo)) {
+ || map.get(plmn).getCellSignalStrength().getLevel()
+ > cellInfo.getCellSignalStrength().getLevel()) {
// Skip if the stored cellInfo is registered or has higher signal strength level
continue;
}
@@ -626,11 +624,10 @@
private void updateNetworkSelection() {
if (DBG) logd("Update notification about no service of user selected operator");
final PhoneGlobals app = PhoneGlobals.getInstance();
- Phone phone = PhoneFactory.getPhone(mPhoneId);
- if (phone != null) {
- ServiceState ss = mTelephonyManager.getServiceStateForSubscriber(phone.getSubId());
+ if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+ ServiceState ss = mTelephonyManager.getServiceState();
if (ss != null) {
- app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
+ app.notificationMgr.updateNetworkSelection(ss.getState(), mSubId);
}
}
}
diff --git a/src/com/android/phone/NetworkSelectSettingActivity.java b/src/com/android/phone/NetworkSelectSettingActivity.java
index a151c81..5b29b281 100644
--- a/src/com/android/phone/NetworkSelectSettingActivity.java
+++ b/src/com/android/phone/NetworkSelectSettingActivity.java
@@ -31,14 +31,14 @@
*/
public class NetworkSelectSettingActivity extends Activity {
private static final String TAG = "NetworkSelectSettingActivity";
- public static final String KEY_PHONE_ID = "phone_id";
+ public static final String KEY_SUBSCRIPTION_ID = "subscription_id";
/**
* Returns the Android Intent that led to this Activity being created.
*/
- public static Intent getIntent(Context context, int phoneId) {
+ public static Intent getIntent(Context context, int subId) {
Intent intent = new Intent(context, NetworkSelectSettingActivity.class);
- intent.putExtra(KEY_PHONE_ID, phoneId);
+ intent.putExtra(KEY_SUBSCRIPTION_ID, subId);
return intent;
}
@@ -46,7 +46,7 @@
public void onCreate(Bundle savedState) {
Log.d(TAG, "onCreate()");
super.onCreate(savedState);
- int phoneId = getIntent().getExtras().getInt(KEY_PHONE_ID);
+ int subId = getIntent().getExtras().getInt(KEY_SUBSCRIPTION_ID);
setContentView(R.layout.choose_network);
FragmentManager fragmentManager = getFragmentManager();
@@ -54,7 +54,7 @@
if (fragment == null) {
fragmentManager.beginTransaction()
.add(R.id.choose_network_content,
- NetworkSelectSetting.newInstance(phoneId), TAG)
+ NetworkSelectSetting.newInstance(subId), TAG)
.commit();
}
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 444eae0..2e4684e 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -57,6 +57,7 @@
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoWcdma;
+import android.telephony.CellLocation;
import android.telephony.ClientRequestStats;
import android.telephony.IccOpenLogicalChannelResponse;
import android.telephony.LocationAccessPolicy;
@@ -75,6 +76,8 @@
import android.telephony.UiccSlotInfo;
import android.telephony.UssdResponse;
import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.telephony.cdma.CdmaCellLocation;
+import android.telephony.gsm.GsmCellLocation;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsMmTelFeature;
import android.telephony.ims.aidl.IImsRcsFeature;
@@ -82,7 +85,6 @@
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.ArraySet;
-import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -148,8 +150,6 @@
// Message codes used with mMainThreadHandler
private static final int CMD_HANDLE_PIN_MMI = 1;
- private static final int CMD_ANSWER_RINGING_CALL = 4;
- private static final int CMD_END_CALL = 5; // not used yet
private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
private static final int CMD_OPEN_CHANNEL = 9;
@@ -195,6 +195,18 @@
private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
private static final int CMD_SWITCH_SLOTS = 50;
private static final int EVENT_SWITCH_SLOTS_DONE = 51;
+ private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
+ private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
+ private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
+ private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
+ private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
+ private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
+ private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
+ private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
+ private static final int CMD_GET_ALL_CELL_INFO = 60;
+ private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
+ private static final int CMD_GET_CELL_LOCATION = 62;
+ private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
// Parameters of select command.
private static final int SELECT_COMMAND = 0xA4;
@@ -276,15 +288,18 @@
// SubscriptionManager.INVALID_SUBSCRIPTION_ID
public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ public WorkSource workSource;
+
public MainThreadRequest(Object argument) {
this.argument = argument;
}
- public MainThreadRequest(Object argument, Integer subId) {
+ MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
this.argument = argument;
if (subId != null) {
this.subId = subId;
}
+ this.workSource = workSource;
}
}
@@ -323,40 +338,35 @@
IccAPDUArgument iccArgument;
switch (msg.what) {
- case CMD_HANDLE_USSD_REQUEST: {
- request = (MainThreadRequest) msg.obj;
- final Phone phone = getPhoneFromRequest(request);
- Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
- String ussdRequest = ussdObject.first;
- ResultReceiver wrappedCallback = ussdObject.second;
+ case CMD_HANDLE_USSD_REQUEST: {
+ request = (MainThreadRequest) msg.obj;
+ final Phone phone = getPhoneFromRequest(request);
+ Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
+ String ussdRequest = ussdObject.first;
+ ResultReceiver wrappedCallback = ussdObject.second;
- if (!isUssdApiAllowed(request.subId)) {
- // Carrier does not support use of this API, return failure.
- Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
- UssdResponse response = new UssdResponse(ussdRequest, null);
- Bundle returnData = new Bundle();
- returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
- wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
+ if (!isUssdApiAllowed(request.subId)) {
+ // Carrier does not support use of this API, return failure.
+ Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
+ UssdResponse response = new UssdResponse(ussdRequest, null);
+ Bundle returnData = new Bundle();
+ returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
+ wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
- request.result = true;
- synchronized (request) {
- request.notifyAll();
- }
- return;
- }
+ request.result = true;
+ notifyRequester(request);
+ return;
+ }
- try {
- request.result = phone != null ?
- phone.handleUssdRequest(ussdRequest, wrappedCallback)
- : false;
- } catch (CallStateException cse) {
- request.result = false;
- }
- // Wake up the requesting thread
- synchronized (request) {
- request.notifyAll();
- }
- break;
+ try {
+ request.result = phone != null
+ ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
+ } catch (CallStateException cse) {
+ request.result = false;
+ }
+ // Wake up the requesting thread
+ notifyRequester(request);
+ break;
}
case CMD_HANDLE_PIN_MMI: {
@@ -366,51 +376,10 @@
getPhoneFromRequest(request).handlePinMmi((String) request.argument)
: false;
// Wake up the requesting thread
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
}
- case CMD_ANSWER_RINGING_CALL:
- request = (MainThreadRequest) msg.obj;
- int answer_subId = request.subId;
- answerRingingCallInternal(answer_subId);
- request.result = ""; // dummy result for notifying the waiting thread
- // Wake up the requesting thread
- synchronized (request) {
- request.notifyAll();
- }
- break;
-
- case CMD_END_CALL:
- request = (MainThreadRequest) msg.obj;
- int end_subId = request.subId;
- final boolean hungUp;
- Phone phone = getPhone(end_subId);
- if (phone == null) {
- if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId);
- break;
- }
- int phoneType = phone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // CDMA: If the user presses the Power button we treat it as
- // ending the complete call session
- hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId));
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- // GSM: End the call as per the Phone state
- hungUp = PhoneUtils.hangup(mCM);
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up"));
- request.result = hungUp;
- // Wake up the requesting thread
- synchronized (request) {
- request.notifyAll();
- }
- break;
-
case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
request = (MainThreadRequest) msg.obj;
iccArgument = (IccAPDUArgument) request.argument;
@@ -418,9 +387,7 @@
if (uiccCard == null) {
loge("iccTransmitApduLogicalChannel: No UICC");
request.result = new IccIoResult(0x6F, 0, (byte[])null);
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
} else {
onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
request);
@@ -447,9 +414,7 @@
loge("iccTransmitApduLogicalChannel: Unknown exception");
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
@@ -459,9 +424,7 @@
if (uiccCard == null) {
loge("iccTransmitApduBasicChannel: No UICC");
request.result = new IccIoResult(0x6F, 0, (byte[])null);
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
} else {
onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
request);
@@ -487,9 +450,7 @@
loge("iccTransmitApduBasicChannel: Unknown exception");
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_EXCHANGE_SIM_IO:
@@ -499,9 +460,7 @@
if (uiccCard == null) {
loge("iccExchangeSimIO: No UICC");
request.result = new IccIoResult(0x6F, 0, (byte[])null);
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
} else {
onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
request);
@@ -519,9 +478,7 @@
} else {
request.result = new IccIoResult(0x6f, 0, (byte[])null);
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_SEND_ENVELOPE:
@@ -530,9 +487,7 @@
if (uiccCard == null) {
loge("sendEnvelopeWithStatus: No UICC");
request.result = new IccIoResult(0x6F, 0, (byte[])null);
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
} else {
onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
@@ -555,9 +510,7 @@
loge("sendEnvelopeWithStatus: exception:" + ar.exception);
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_OPEN_CHANNEL:
@@ -568,9 +521,7 @@
loge("iccOpenLogicalChannel: No UICC");
request.result = new IccOpenLogicalChannelResponse(-1,
IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
} else {
onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
@@ -616,9 +567,7 @@
IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
}
request.result = openChannelResp;
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_CLOSE_CHANNEL:
@@ -627,9 +576,7 @@
if (uiccCard == null) {
loge("iccCloseLogicalChannel: No UICC");
request.result = false;
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
} else {
onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
@@ -643,7 +590,7 @@
case CMD_NV_READ_ITEM:
request = (MainThreadRequest) msg.obj;
onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
- mPhone.nvReadItem((Integer) request.argument, onCompleted);
+ mPhone.nvReadItem((Integer) request.argument, onCompleted, request.workSource);
break;
case EVENT_NV_READ_ITEM_DONE:
@@ -662,16 +609,15 @@
loge("nvReadItem: Unknown exception");
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_NV_WRITE_ITEM:
request = (MainThreadRequest) msg.obj;
onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
- mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted);
+ mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
+ request.workSource);
break;
case EVENT_NV_WRITE_ITEM_DONE:
@@ -720,9 +666,7 @@
loge("getPreferredNetworkType: Unknown exception");
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_SET_PREFERRED_NETWORK_TYPE:
@@ -739,16 +683,14 @@
case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
request = (MainThreadRequest)msg.obj;
onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
- mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted);
+ mPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
break;
case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
ar = (AsyncResult)msg.obj;
request = (MainThreadRequest)ar.userObj;
request.result = ar;
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_SET_VOICEMAIL_NUMBER:
@@ -808,9 +750,7 @@
cellScanResult = new CellNetworkScanResult(errorCode, null);
}
request.result = cellScanResult;
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
@@ -830,7 +770,7 @@
case CMD_GET_MODEM_ACTIVITY_INFO:
request = (MainThreadRequest) msg.obj;
onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
- mPhone.getModemActivityInfo(onCompleted);
+ mPhone.getModemActivityInfo(onCompleted, request.workSource);
break;
case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
@@ -852,9 +792,7 @@
if (request.result == null) {
request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_SET_ALLOWED_CARRIERS:
@@ -862,7 +800,7 @@
onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
mPhone.setAllowedCarriers(
(List<CarrierIdentifier>) request.argument,
- onCompleted);
+ onCompleted, request.workSource);
break;
case EVENT_SET_ALLOWED_CARRIERS_DONE:
@@ -884,15 +822,13 @@
if (request.result == null) {
request.result = new int[]{-1};
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_GET_ALLOWED_CARRIERS:
request = (MainThreadRequest) msg.obj;
onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
- mPhone.getAllowedCarriers(onCompleted);
+ mPhone.getAllowedCarriers(onCompleted, request.workSource);
break;
case EVENT_GET_ALLOWED_CARRIERS_DONE:
@@ -914,9 +850,7 @@
if (request.result == null) {
request.result = new ArrayList<CarrierIdentifier>(0);
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case EVENT_GET_FORBIDDEN_PLMNS_DONE:
@@ -933,9 +867,7 @@
loge("getForbiddenPlmns: Unknown exception");
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
case CMD_GET_FORBIDDEN_PLMNS:
@@ -945,9 +877,7 @@
loge("getForbiddenPlmns() UiccCard is null");
request.result = new IllegalArgumentException(
"getForbiddenPlmns() UiccCard is null");
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
}
Integer appType = (Integer) request.argument;
@@ -956,9 +886,7 @@
loge("getForbiddenPlmns() no app with specified type -- "
+ appType);
request.result = new IllegalArgumentException("Failed to get UICC App");
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
break;
} else {
if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
@@ -980,17 +908,122 @@
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
request.result = (ar.exception == null);
+ notifyRequester(request);
+ break;
+ case CMD_GET_NETWORK_SELECTION_MODE:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
+ getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
+ break;
+
+ case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ if (ar.exception != null) {
+ request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
+ } else {
+ int mode = ((int[]) ar.result)[0];
+ if (mode == 0) {
+ request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+ } else {
+ request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
+ }
+ }
+ notifyRequester(request);
+ break;
+ case CMD_GET_CDMA_ROAMING_MODE:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
+ getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
+ break;
+ case EVENT_GET_CDMA_ROAMING_MODE_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ if (ar.exception != null) {
+ request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
+ } else {
+ request.result = ((int[]) ar.result)[0];
+ }
+ notifyRequester(request);
+ break;
+ case CMD_SET_CDMA_ROAMING_MODE:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
+ int mode = (int) request.argument;
+ getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
+ break;
+ case EVENT_SET_CDMA_ROAMING_MODE_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ request.result = ar.exception == null;
+ notifyRequester(request);
+ break;
+ case CMD_SET_CDMA_SUBSCRIPTION_MODE:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
+ int subscriptionMode = (int) request.argument;
+ getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
+ break;
+ case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ request.result = ar.exception == null;
+ notifyRequester(request);
+ break;
+
+ case CMD_GET_ALL_CELL_INFO:
+ request = (MainThreadRequest) msg.obj;
+ Pair<Phone, WorkSource> args = (Pair<Phone, WorkSource>) request.argument;
+ onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
+ ((Phone) args.first).getAllCellInfo(args.second, onCompleted);
+ break;
+
+ case EVENT_GET_ALL_CELL_INFO_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ request.result = (ar.exception == null) ? ar.result : new ArrayList<CellInfo>();
synchronized (request) {
request.notifyAll();
}
break;
+ case CMD_GET_CELL_LOCATION: {
+ request = (MainThreadRequest) msg.obj;
+ WorkSource ws = (WorkSource) request.argument;
+ Phone phone = getPhoneFromRequest(request);
+ phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
+ break;
+ }
+
+ case EVENT_GET_CELL_LOCATION_DONE: {
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ if (ar.exception == null) {
+ request.result = ar.result;
+ } else {
+ Phone phone = getPhoneFromRequest(request);
+ request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
+ ? new CdmaCellLocation() : new GsmCellLocation();
+ }
+
+ synchronized (request) {
+ request.notifyAll();
+ }
+ break;
+ }
+
default:
Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
break;
}
}
+ private void notifyRequester(MainThreadRequest request) {
+ synchronized (request) {
+ request.notifyAll();
+ }
+ }
+
private void handleNullReturnEvent(Message msg, String command) {
AsyncResult ar = (AsyncResult) msg.obj;
MainThreadRequest request = (MainThreadRequest) ar.userObj;
@@ -1004,9 +1037,7 @@
loge(command + ": Unknown exception");
}
}
- synchronized (request) {
- request.notifyAll();
- }
+ notifyRequester(request);
}
}
@@ -1016,7 +1047,17 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument) {
- return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null);
+ }
+
+ /**
+ * Posts the specified command to be executed on the main thread,
+ * waits for the request to complete, and returns the result.
+ * @see #sendRequestAsync
+ */
+ private Object sendRequest(int command, Object argument, WorkSource workSource) {
+ return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+ workSource);
}
/**
@@ -1025,11 +1066,20 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument, Integer subId) {
+ return sendRequest(command, argument, subId, null);
+ }
+
+ /**
+ * Posts the specified command to be executed on the main thread,
+ * waits for the request to complete, and returns the result.
+ * @see #sendRequestAsync
+ */
+ private Object sendRequest(int command, Object argument, Integer subId, WorkSource workSource) {
if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
throw new RuntimeException("This method will deadlock if called from the main thread.");
}
- MainThreadRequest request = new MainThreadRequest(argument, subId);
+ MainThreadRequest request = new MainThreadRequest(argument, subId, workSource);
Message msg = mMainThreadHandler.obtainMessage(command, request);
msg.sendToTarget();
@@ -1204,7 +1254,7 @@
* @return true is a call was ended
*/
public boolean endCall() {
- return endCallForSubscriber(getDefaultSubscription());
+ return false;
}
/**
@@ -1212,75 +1262,15 @@
* @return true is a call was ended
*/
public boolean endCallForSubscriber(int subId) {
- if (mApp.checkCallingOrSelfPermission(permission.MODIFY_PHONE_STATE)
- != PackageManager.PERMISSION_GRANTED) {
- Log.i(LOG_TAG, "endCall: called without modify phone state.");
- EventLog.writeEvent(0x534e4554, "67862398", -1, "");
- throw new SecurityException("MODIFY_PHONE_STATE permission required.");
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId));
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ return false;
}
public void answerRingingCall() {
- answerRingingCallForSubscriber(getDefaultSubscription());
+ // Deprecated.
}
public void answerRingingCallForSubscriber(int subId) {
- if (DBG) log("answerRingingCall...");
- // TODO: there should eventually be a separate "ANSWER_PHONE" permission,
- // but that can probably wait till the big TelephonyManager API overhaul.
- // For now, protect this call with the MODIFY_PHONE_STATE permission.
- enforceModifyPermission();
-
- final long identity = Binder.clearCallingIdentity();
- try {
- sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId));
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- /**
- * Make the actual telephony calls to implement answerRingingCall().
- * This should only be called from the main thread of the Phone app.
- * @see #answerRingingCall
- *
- * TODO: it would be nice to return true if we answered the call, or
- * false if there wasn't actually a ringing incoming call, or some
- * other error occurred. (In other words, pass back the return value
- * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().)
- * But that would require calling this method via sendRequest() rather
- * than sendRequestAsync(), and right now we don't actually *need* that
- * return value, so let's just return void for now.
- */
- private void answerRingingCallInternal(int subId) {
- final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle();
- if (hasRingingCall) {
- final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle();
- final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle();
- if (hasActiveCall && hasHoldingCall) {
- // Both lines are in use!
- // TODO: provide a flag to let the caller specify what
- // policy to use if both lines are in use. (The current
- // behavior is hardwired to "answer incoming, end ongoing",
- // which is how the CALL button is specced to behave.)
- PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall());
- return;
- } else {
- // answerCall() will automatically hold the current active
- // call, if there is one.
- PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
- return;
- }
- } else {
- // No call was ringing.
- return;
- }
+ // Deprecated
}
/**
@@ -1835,12 +1825,9 @@
try {
if (DBG_LOC) log("getCellLocation: is active user");
Bundle data = new Bundle();
- Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
- if (phone == null) {
- return null;
- }
-
- phone.getCellLocation(workSource).fillInNotifierBundle(data);
+ int subId = mSubscriptionController.getDefaultDataSubId();
+ CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
+ cl.fillInNotifierBundle(data);
return data;
} finally {
Binder.restoreCallingIdentity(identity);
@@ -1922,7 +1909,10 @@
@SuppressWarnings("unchecked")
public List<NeighboringCellInfo>
getNeighboringCellInfo(String callingPackage, int targetSdk) {
- if (targetSdk > android.os.Build.VERSION_CODES.P) return null;
+ if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
+ throw new SecurityException(
+ "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
+ }
if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
callingPackage) != AppOpsManager.MODE_ALLOWED) {
@@ -1961,7 +1951,9 @@
try {
List<CellInfo> cellInfos = new ArrayList<CellInfo>();
for (Phone phone : PhoneFactory.getPhones()) {
- final List<CellInfo> info = phone.getAllCellInfo(workSource);
+ final List<CellInfo> info = (List<CellInfo>) sendRequest(
+ CMD_GET_ALL_CELL_INFO,
+ new Pair<Phone, WorkSource>(phone, workSource));
if (info != null) cellInfos.addAll(info);
}
return cellInfos;
@@ -2590,6 +2582,11 @@
}
}
+ @Override
+ public int getNetworkSelectionMode(int subId) {
+ return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
+ }
+
/**
* Returns the network type for a subId
*/
@@ -3009,13 +3006,14 @@
*/
@Override
public String nvReadItem(int itemID) {
+ WorkSource workSource = getWorkSource(Binder.getCallingUid());
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, getDefaultSubscription(), "nvReadItem");
final long identity = Binder.clearCallingIdentity();
try {
if (DBG) log("nvReadItem: item " + itemID);
- String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID);
+ String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
return value;
} finally {
@@ -3033,6 +3031,7 @@
*/
@Override
public boolean nvWriteItem(int itemID, String itemValue) {
+ WorkSource workSource = getWorkSource(Binder.getCallingUid());
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, getDefaultSubscription(), "nvWriteItem");
@@ -3040,7 +3039,7 @@
try {
if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
- new Pair<Integer, String>(itemID, itemValue));
+ new Pair<Integer, String>(itemID, itemValue), workSource);
if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
return success;
} finally {
@@ -3295,24 +3294,30 @@
}
}
- /**
- * Set the network selection mode to manual with the selected carrier.
+ /**
+ * Ask the radio to connect to the input network and change selection mode to manual.
+ *
+ * @param subId the id of the subscription.
+ * @param operatorInfo the operator information, included the PLMN, long name and short name of
+ * the operator to attach to.
+ * @param persistSelection whether the selection will persist until reboot. If true, only allows
+ * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
+ * normal network selection next time.
+ * @return {@code true} on success; {@code true} on any failure.
*/
@Override
- public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
- boolean persistSelection) {
+ public boolean setNetworkSelectionModeManual(
+ int subId, OperatorInfo operatorInfo, boolean persistSelection) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setNetworkSelectionModeManual");
-
final long identity = Binder.clearCallingIdentity();
try {
- OperatorInfo operator = new OperatorInfo(
- /* operatorAlphaLong */ "",
- /* operatorAlphaShort */ "",
- operatorNumeric);
- if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
- ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
+ ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
persistSelection);
+ if (DBG) {
+ log("setNetworkSelectionModeManual: subId: " + subId
+ + " operator: " + operatorInfo);
+ }
return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
} finally {
Binder.restoreCallingIdentity(identity);
@@ -3327,12 +3332,11 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "getCellNetworkScanResults");
- final long identity = Binder.clearCallingIdentity();
+ long identity = Binder.clearCallingIdentity();
try {
if (DBG) log("getCellNetworkScanResults: subId " + subId);
- CellNetworkScanResult result = (CellNetworkScanResult) sendRequest(
+ return (CellNetworkScanResult) sendRequest(
CMD_PERFORM_NETWORK_SCAN, null, subId);
- return result;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -3948,7 +3952,7 @@
int returnValue = 0;
try {
- AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
+ AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
if(result.exception == null) {
if (result.result != null) {
byte[] responseData = (byte[])(result.result);
@@ -4353,13 +4357,15 @@
public void requestModemActivityInfo(ResultReceiver result) {
enforceModifyPermission();
ModemActivityInfo ret = null;
+ WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLastModemActivityInfo) {
- ModemActivityInfo info = (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO,
- null);
- if (info != null) {
+ ModemActivityInfo info = (ModemActivityInfo) sendRequest(
+ CMD_GET_MODEM_ACTIVITY_INFO,
+ null, workSource);
+ if (isModemActivityInfoValid(info)) {
int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
for (int i = 0; i < mergedTxTimeMs.length; i++) {
mergedTxTimeMs[i] =
@@ -4391,6 +4397,25 @@
}
}
+ // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
+ // less than total activity duration.
+ private boolean isModemActivityInfoValid(ModemActivityInfo info) {
+ if (info == null) {
+ return false;
+ }
+ int activityDurationMs =
+ (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
+ int totalTxTimeMs = 0;
+ for (int i = 0; i < info.getTxTimeMillis().length; i++) {
+ totalTxTimeMs += info.getTxTimeMillis()[i];
+ }
+ return (info.isValid()
+ && (info.getSleepTimeMillis() <= activityDurationMs)
+ && (info.getIdleTimeMillis() <= activityDurationMs)
+ && (info.getRxTimeMillis() <= activityDurationMs)
+ && (totalTxTimeMs <= activityDurationMs));
+ }
+
/**
* {@hide}
* Returns the service state information on specified subscription.
@@ -4686,6 +4711,7 @@
@Override
public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
enforceModifyPermission();
+ WorkSource workSource = getWorkSource(Binder.getCallingUid());
if (carriers == null) {
throw new NullPointerException("carriers cannot be null");
@@ -4694,7 +4720,8 @@
final long identity = Binder.clearCallingIdentity();
try {
int subId = SubscriptionManager.getSubId(slotIndex)[0];
- int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId);
+ int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId,
+ workSource);
return retVal[0];
} finally {
Binder.restoreCallingIdentity(identity);
@@ -4712,11 +4739,13 @@
@Override
public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
enforceReadPrivilegedPermission();
+ WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
try {
int subId = SubscriptionManager.getSubId(slotIndex)[0];
- return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId);
+ return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId,
+ workSource);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4918,10 +4947,12 @@
enforceModifyPermission();
Phone phone = PhoneFactory.getPhone(slotIndex);
+ WorkSource workSource = getWorkSource(Binder.getCallingUid());
+
final long identity = Binder.clearCallingIdentity();
try {
if (phone != null) {
- phone.setSimPowerState(state);
+ phone.setSimPowerState(state, workSource);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -4987,6 +5018,63 @@
}
}
+ /**
+ * Checks if data roaming is enabled on the subscription with id {@code subId}.
+ *
+ * <p>Requires one of the following permissions:
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
+ * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
+ * privileges.
+ *
+ * @param subId subscription id
+ * @return {@code true} if data roaming is enabled on this subscription, otherwise return
+ * {@code false}.
+ */
+ @Override
+ public boolean isDataRoamingEnabled(int subId) {
+ boolean isEnabled = false;
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
+ null /* message */);
+ Phone phone = getPhone(subId);
+ isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
+ } catch (Exception e) {
+ TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isDataRoamingEnabled");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return isEnabled;
+ }
+
+
+ /**
+ * Enables/Disables the data roaming on the subscription with id {@code subId}.
+ *
+ * <p> Requires permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
+ * privileges.
+ *
+ * @param subId subscription id
+ * @param isEnabled {@code true} means enable, {@code false} means disable.
+ */
+ @Override
+ public void setDataRoamingEnabled(int subId, boolean isEnabled) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+ mApp, subId, "setDataRoamingEnabled");
+
+ Phone phone = getPhone(subId);
+ if (phone != null) {
+ phone.setDataRoamingEnabled(isEnabled);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
@Override
public UiccSlotInfo[] getUiccSlotsInfo() {
enforceReadPrivilegedPermission();
@@ -5191,4 +5279,43 @@
Binder.restoreCallingIdentity(identity);
}
}
+
+ @Override
+ public int getCdmaRoamingMode(int subId) {
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+ mApp, subId, "getCdmaRoamingMode");
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public boolean setCdmaRoamingMode(int subId, int mode) {
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+ mApp, subId, "setCdmaRoamingMode");
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public boolean setCdmaSubscriptionMode(int subId, int mode) {
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+ mApp, subId, "setCdmaSubscriptionMode");
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
}
diff --git a/src/com/android/phone/PhoneSearchIndexablesProvider.java b/src/com/android/phone/PhoneSearchIndexablesProvider.java
index 57a5b8a..339602d 100644
--- a/src/com/android/phone/PhoneSearchIndexablesProvider.java
+++ b/src/com/android/phone/PhoneSearchIndexablesProvider.java
@@ -42,6 +42,11 @@
public class PhoneSearchIndexablesProvider extends SearchIndexablesProvider {
private static final String TAG = "PhoneSearchIndexablesProvider";
+
+ private static final String ESIM_LIST_PROFILE_KEY = "esim_list_profile";
+ private static final String ENHANCED_4G_LTE_KEY = "enhanced_4g_lte";
+ private static final String WIFI_CALLING_KEY = "wifi_calling_key";
+
private UserManager mUserManager;
private static SearchIndexableResource[] INDEXABLE_RES = new SearchIndexableResource[] {
@@ -113,10 +118,15 @@
}
} else {
if (isEuiccSettingsHidden()) {
- cursor.addRow(createNonIndexableRow("esim_list_profile" /* key */));
+ cursor.addRow(createNonIndexableRow(ESIM_LIST_PROFILE_KEY));
}
+
if (isEnhanced4gLteHidden()) {
- cursor.addRow(createNonIndexableRow("enhanced_4g_lte" /* key */));
+ cursor.addRow(createNonIndexableRow(ENHANCED_4G_LTE_KEY));
+ }
+
+ if (isWifiCallingHidden()) {
+ cursor.addRow(createNonIndexableRow(WIFI_CALLING_KEY));
}
}
@@ -141,6 +151,10 @@
return MobileNetworkSettings.hideEnhanced4gLteSettings(getContext());
}
+ boolean isWifiCallingHidden() {
+ return !MobileNetworkSettings.isWifiCallingEnabled(getContext());
+ }
+
private Object[] createNonIndexableRow(String key) {
final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = key;
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 712b8cb..c5625e9 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -19,7 +19,6 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
-import android.bluetooth.IBluetoothHeadsetPhone;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@@ -30,7 +29,6 @@
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.VideoProfile;
@@ -106,9 +104,6 @@
/** Phone state changed event*/
private static final int PHONE_STATE_CHANGED = -1;
- /** check status then decide whether answerCall */
- private static final int MSG_CHECK_STATUS_ANSWERCALL = 100;
-
/** poll phone DISCONNECTING status interval */
private static final int DISCONNECTING_POLLING_INTERVAL_MS = 200;
@@ -125,15 +120,6 @@
*/
private static final int THEME = com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert;
- private static class FgRingCalls {
- private Call fgCall;
- private Call ringing;
- public FgRingCalls(Call fg, Call ring) {
- fgCall = fg;
- ringing = ring;
- }
- }
-
/** USSD information used to aggregate all USSD messages */
private static AlertDialog sUssdDialog = null;
private static StringBuilder sUssdMsg = new StringBuilder();
@@ -147,34 +133,6 @@
* Mute settings for each connection as needed.
*/
private static class ConnectionHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_CHECK_STATUS_ANSWERCALL:
- FgRingCalls frC = (FgRingCalls) msg.obj;
- // wait for finishing disconnecting
- // before check the ringing call state
- if ((frC.fgCall != null) &&
- (frC.fgCall.getState() == Call.State.DISCONNECTING) &&
- (msg.arg1 < DISCONNECTING_POLLING_TIMES_LIMIT)) {
- Message retryMsg =
- mConnectionHandler.obtainMessage(MSG_CHECK_STATUS_ANSWERCALL);
- retryMsg.arg1 = 1 + msg.arg1;
- retryMsg.obj = msg.obj;
- mConnectionHandler.sendMessageDelayed(retryMsg,
- DISCONNECTING_POLLING_INTERVAL_MS);
- // since hangupActiveCall() also accepts the ringing call
- // check if the ringing call was already answered or not
- // only answer it when the call still is ringing
- } else if (frC.ringing.isRinging()) {
- if (msg.arg1 == DISCONNECTING_POLLING_TIMES_LIMIT) {
- Log.e(LOG_TAG, "DISCONNECTING time out");
- }
- answerCall(frC.ringing);
- }
- break;
- }
- }
}
/**
@@ -195,294 +153,6 @@
}
/**
- * Answer the currently-ringing call.
- *
- * @return true if we answered the call, or false if there wasn't
- * actually a ringing incoming call, or some other error occurred.
- *
- * @see #answerAndEndHolding(CallManager, Call)
- * @see #answerAndEndActive(CallManager, Call)
- */
- /* package */ static boolean answerCall(Call ringingCall) {
- log("answerCall(" + ringingCall + ")...");
- final PhoneGlobals app = PhoneGlobals.getInstance();
- final CallNotifier notifier = app.notifier;
-
- final Phone phone = ringingCall.getPhone();
- final boolean phoneIsCdma = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
- boolean answered = false;
- IBluetoothHeadsetPhone btPhone = null;
-
- if (phoneIsCdma) {
- // Stop any signalInfo tone being played when a Call waiting gets answered
- if (ringingCall.getState() == Call.State.WAITING) {
- notifier.stopSignalInfoTone();
- }
- }
-
- if (ringingCall != null && ringingCall.isRinging()) {
- if (DBG) log("answerCall: call state = " + ringingCall.getState());
- try {
- if (phoneIsCdma) {
- if (app.cdmaPhoneCallState.getCurrentCallState()
- == CdmaPhoneCallState.PhoneCallState.IDLE) {
- // This is the FIRST incoming call being answered.
- // Set the Phone Call State to SINGLE_ACTIVE
- app.cdmaPhoneCallState.setCurrentCallState(
- CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE);
- } else {
- // This is the CALL WAITING call being answered.
- // Set the Phone Call State to CONF_CALL
- app.cdmaPhoneCallState.setCurrentCallState(
- CdmaPhoneCallState.PhoneCallState.CONF_CALL);
- // Enable "Add Call" option after answering a Call Waiting as the user
- // should be allowed to add another call in case one of the parties
- // drops off
- app.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
- }
- }
-
- final boolean isRealIncomingCall = isRealIncomingCall(ringingCall.getState());
-
- //if (DBG) log("sPhone.acceptCall");
- app.mCM.acceptCall(ringingCall);
- answered = true;
-
- setAudioMode();
- } catch (CallStateException ex) {
- Log.w(LOG_TAG, "answerCall: caught " + ex, ex);
-
- if (phoneIsCdma) {
- // restore the cdmaPhoneCallState and btPhone.cdmaSetSecondCallState:
- app.cdmaPhoneCallState.setCurrentCallState(
- app.cdmaPhoneCallState.getPreviousCallState());
- if (btPhone != null) {
- try {
- btPhone.cdmaSetSecondCallState(false);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
- }
- }
- }
- }
- }
- return answered;
- }
-
- /**
- * Hangs up all active calls.
- */
- static void hangupAllCalls(CallManager cm) {
- final Call ringing = cm.getFirstActiveRingingCall();
- final Call fg = cm.getActiveFgCall();
- final Call bg = cm.getFirstActiveBgCall();
-
- // We go in reverse order, BG->FG->RINGING because hanging up a ringing call or an active
- // call can move a bg call to a fg call which would force us to loop over each call
- // several times. This ordering works best to ensure we dont have any more calls.
- if (bg != null && !bg.isIdle()) {
- hangup(bg);
- }
- if (fg != null && !fg.isIdle()) {
- hangup(fg);
- }
- if (ringing != null && !ringing.isIdle()) {
- hangupRingingCall(fg);
- }
- }
-
- /**
- * Smart "hang up" helper method which hangs up exactly one connection,
- * based on the current Phone state, as follows:
- * <ul>
- * <li>If there's a ringing call, hang that up.
- * <li>Else if there's a foreground call, hang that up.
- * <li>Else if there's a background call, hang that up.
- * <li>Otherwise do nothing.
- * </ul>
- * @return true if we successfully hung up, or false
- * if there were no active calls at all.
- */
- static boolean hangup(CallManager cm) {
- boolean hungup = false;
- Call ringing = cm.getFirstActiveRingingCall();
- Call fg = cm.getActiveFgCall();
- Call bg = cm.getFirstActiveBgCall();
-
- if (!ringing.isIdle()) {
- log("hangup(): hanging up ringing call");
- hungup = hangupRingingCall(ringing);
- } else if (!fg.isIdle()) {
- log("hangup(): hanging up foreground call");
- hungup = hangup(fg);
- } else if (!bg.isIdle()) {
- log("hangup(): hanging up background call");
- hungup = hangup(bg);
- } else {
- // No call to hang up! This is unlikely in normal usage,
- // since the UI shouldn't be providing an "End call" button in
- // the first place. (But it *can* happen, rarely, if an
- // active call happens to disconnect on its own right when the
- // user is trying to hang up..)
- log("hangup(): no active call to hang up");
- }
- if (DBG) log("==> hungup = " + hungup);
-
- return hungup;
- }
-
- static boolean hangupRingingCall(Call ringing) {
- if (DBG) log("hangup ringing call");
- int phoneType = ringing.getPhone().getPhoneType();
- Call.State state = ringing.getState();
-
- if (state == Call.State.INCOMING) {
- // Regular incoming call (with no other active calls)
- log("hangupRingingCall(): regular incoming call: hangup()");
- return hangup(ringing);
- } else {
- // Unexpected state: the ringing call isn't INCOMING or
- // WAITING, so there's no reason to have called
- // hangupRingingCall() in the first place.
- // (Presumably the incoming call went away at the exact moment
- // we got here, so just do nothing.)
- Log.w(LOG_TAG, "hangupRingingCall: no INCOMING or WAITING call");
- return false;
- }
- }
-
- static boolean hangupActiveCall(Call foreground) {
- if (DBG) log("hangup active call");
- return hangup(foreground);
- }
-
- static boolean hangupHoldingCall(Call background) {
- if (DBG) log("hangup holding call");
- return hangup(background);
- }
-
- /**
- * Used in CDMA phones to end the complete Call session
- * @param phone the Phone object.
- * @return true if *any* call was successfully hung up
- */
- static boolean hangupRingingAndActive(Phone phone) {
- boolean hungUpRingingCall = false;
- boolean hungUpFgCall = false;
- Call ringingCall = phone.getRingingCall();
- Call fgCall = phone.getForegroundCall();
-
- // Hang up any Ringing Call
- if (!ringingCall.isIdle()) {
- log("hangupRingingAndActive: Hang up Ringing Call");
- hungUpRingingCall = hangupRingingCall(ringingCall);
- }
-
- // Hang up any Active Call
- if (!fgCall.isIdle()) {
- log("hangupRingingAndActive: Hang up Foreground Call");
- hungUpFgCall = hangupActiveCall(fgCall);
- }
-
- return hungUpRingingCall || hungUpFgCall;
- }
-
- /**
- * Trivial wrapper around Call.hangup(), except that we return a
- * boolean success code rather than throwing CallStateException on
- * failure.
- *
- * @return true if the call was successfully hung up, or false
- * if the call wasn't actually active.
- */
- static boolean hangup(Call call) {
- try {
- CallManager cm = PhoneGlobals.getInstance().mCM;
-
- if (call.getState() == Call.State.ACTIVE && cm.hasActiveBgCall()) {
- // handle foreground call hangup while there is background call
- log("- hangup(Call): hangupForegroundResumeBackground...");
- cm.hangupForegroundResumeBackground(cm.getFirstActiveBgCall());
- } else {
- log("- hangup(Call): regular hangup()...");
- call.hangup();
- }
- return true;
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "Call hangup: caught " + ex, ex);
- }
-
- return false;
- }
-
- /**
- * Trivial wrapper around Connection.hangup(), except that we silently
- * do nothing (rather than throwing CallStateException) if the
- * connection wasn't actually active.
- */
- static void hangup(Connection c) {
- try {
- if (c != null) {
- c.hangup();
- }
- } catch (CallStateException ex) {
- Log.w(LOG_TAG, "Connection hangup: caught " + ex, ex);
- }
- }
-
- static boolean answerAndEndHolding(CallManager cm, Call ringing) {
- if (DBG) log("end holding & answer waiting: 1");
- if (!hangupHoldingCall(cm.getFirstActiveBgCall())) {
- Log.e(LOG_TAG, "end holding failed!");
- return false;
- }
-
- if (DBG) log("end holding & answer waiting: 2");
- return answerCall(ringing);
-
- }
-
- /**
- * Answers the incoming call specified by "ringing", and ends the currently active phone call.
- *
- * This method is useful when's there's an incoming call which we cannot manage with the
- * current call. e.g. when you are having a phone call with CDMA network and has received
- * a SIP call, then we won't expect our telephony can manage those phone calls simultaneously.
- * Note that some types of network may allow multiple phone calls at once; GSM allows to hold
- * an ongoing phone call, so we don't need to end the active call. The caller of this method
- * needs to check if the network allows multiple phone calls or not.
- *
- * @see #answerCall(Call)
- * @see InCallScreen#internalAnswerCall()
- */
- /* package */ static boolean answerAndEndActive(CallManager cm, Call ringing) {
- if (DBG) log("answerAndEndActive()...");
-
- // Unlike the answerCall() method, we *don't* need to stop the
- // ringer or change audio modes here since the user is already
- // in-call, which means that the audio mode is already set
- // correctly, and that we wouldn't have started the ringer in the
- // first place.
-
- // hanging up the active call also accepts the waiting call
- // while active call and waiting call are from the same phone
- // i.e. both from GSM phone
- Call fgCall = cm.getActiveFgCall();
- if (!hangupActiveCall(fgCall)) {
- Log.w(LOG_TAG, "end active call failed!");
- return false;
- }
-
- mConnectionHandler.removeMessages(MSG_CHECK_STATUS_ANSWERCALL);
- Message msg = mConnectionHandler.obtainMessage(MSG_CHECK_STATUS_ANSWERCALL);
- msg.arg1 = 1;
- msg.obj = new FgRingCalls(fgCall, ringing);
- mConnectionHandler.sendMessage(msg);
-
- return true;
- }
-
- /**
* For a CDMA phone, advance the call state upon making a new
* outgoing call.
*
@@ -676,87 +346,6 @@
return builder.toString();
}
- /**
- * Wrapper function to control when to send an empty Flash command to the network.
- * Mainly needed for CDMA networks, such as scenarios when we need to send a blank flash
- * to the network prior to placing a 3-way call for it to be successful.
- */
- static void sendEmptyFlash(Phone phone) {
- if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- Call fgCall = phone.getForegroundCall();
- if (fgCall.getState() == Call.State.ACTIVE) {
- // Send the empty flash
- if (DBG) Log.d(LOG_TAG, "onReceive: (CDMA) sending empty flash to network");
- switchHoldingAndActive(phone.getBackgroundCall());
- }
- }
- }
-
- static void swap() {
- final PhoneGlobals mApp = PhoneGlobals.getInstance();
- if (!okToSwapCalls(mApp.mCM)) {
- // TODO: throw an error instead?
- return;
- }
-
- // Swap the fg and bg calls.
- // In the future we may provide some way for user to choose among
- // multiple background calls, for now, always act on the first background call.
- PhoneUtils.switchHoldingAndActive(mApp.mCM.getFirstActiveBgCall());
- }
-
- /**
- * @param heldCall is the background call want to be swapped
- */
- static void switchHoldingAndActive(Call heldCall) {
- log("switchHoldingAndActive()...");
- try {
- CallManager cm = PhoneGlobals.getInstance().mCM;
- if (heldCall.isIdle()) {
- // no heldCall, so it is to hold active call
- cm.switchHoldingAndActive(cm.getFgPhone().getBackgroundCall());
- } else {
- // has particular heldCall, so to switch
- cm.switchHoldingAndActive(heldCall);
- }
- setAudioMode(cm);
- } catch (CallStateException ex) {
- Log.w(LOG_TAG, "switchHoldingAndActive: caught " + ex, ex);
- }
- }
-
- static void mergeCalls() {
- mergeCalls(PhoneGlobals.getInstance().mCM);
- }
-
- static void mergeCalls(CallManager cm) {
- int phoneType = cm.getFgPhone().getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- log("mergeCalls(): CDMA...");
- PhoneGlobals app = PhoneGlobals.getInstance();
- if (app.cdmaPhoneCallState.getCurrentCallState()
- == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
- // Set the Phone Call State to conference
- app.cdmaPhoneCallState.setCurrentCallState(
- CdmaPhoneCallState.PhoneCallState.CONF_CALL);
-
- // Send flash cmd
- // TODO: Need to change the call from switchHoldingAndActive to
- // something meaningful as we are not actually trying to swap calls but
- // instead are merging two calls by sending a Flash command.
- log("- sending flash...");
- switchHoldingAndActive(cm.getFirstActiveBgCall());
- }
- } else {
- try {
- log("mergeCalls(): calling cm.conference()...");
- cm.conference(cm.getFirstActiveBgCall());
- } catch (CallStateException ex) {
- Log.w(LOG_TAG, "mergeCalls: caught " + ex, ex);
- }
- }
- }
-
static void separateCall(Connection c) {
try {
if (DBG) log("separateCall: " + toLogSafePhoneNumber(c.getAddress()));
diff --git a/src/com/android/phone/RoamingDialogFragment.java b/src/com/android/phone/RoamingDialogFragment.java
index 4d3bd47..d24967b 100644
--- a/src/com/android/phone/RoamingDialogFragment.java
+++ b/src/com/android/phone/RoamingDialogFragment.java
@@ -27,14 +27,16 @@
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
-import com.android.internal.telephony.Phone;
-
/**
* A dialog fragment that asks the user if they are sure they want to turn on data roaming
* to avoid accidental charges.
*/
public class RoamingDialogFragment extends DialogFragment implements OnClickListener {
+ public static final String SUB_ID_KEY = "sub_id_key";
+
+ private int mSubId;
+
/**
* The interface we expect a host activity to implement.
*/
@@ -45,15 +47,12 @@
// the host activity which implements the listening interface
private RoamingDialogListener mListener;
- private Phone mPhone;
-
- public void setPhone(Phone phone) {
- mPhone = phone;
- }
-
@Override
public void onAttach(Context context) {
super.onAttach(context);
+ Bundle args = getArguments();
+ mSubId = args.getInt(SUB_ID_KEY);
+
// Verify host activity implemented callback interface
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.network_setting_content);
@@ -69,13 +68,11 @@
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
int title = R.string.roaming_alert_title;
- if (mPhone != null) {
- PersistableBundle carrierConfig =
- PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- if (carrierConfig != null && carrierConfig.getBoolean(
- CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
- title = R.string.roaming_check_price_warning;
- }
+ PersistableBundle carrierConfig =
+ PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+ if (carrierConfig != null && carrierConfig.getBoolean(
+ CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
+ title = R.string.roaming_check_price_warning;
}
builder.setMessage(getResources().getString(R.string.roaming_warning))
.setTitle(title)
diff --git a/src/com/android/phone/ecc/CountryEccInfo.java b/src/com/android/phone/ecc/CountryEccInfo.java
index 6bef8d3..969901d 100644
--- a/src/com/android/phone/ecc/CountryEccInfo.java
+++ b/src/com/android/phone/ecc/CountryEccInfo.java
@@ -19,7 +19,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import java.util.List;
+import java.util.Collection;
/**
* ECC info of a country.
@@ -28,7 +28,7 @@
private final String mFallbackEcc;
private final EccInfo[] mEccInfoList;
- public CountryEccInfo(String eccFallback, @NonNull List<EccInfo> eccInfoList) {
+ public CountryEccInfo(String eccFallback, @NonNull Collection<EccInfo> eccInfoList) {
mFallbackEcc = eccFallback;
mEccInfoList = eccInfoList.toArray(new EccInfo[eccInfoList.size()]);
}
diff --git a/src/com/android/phone/ecc/EccInfo.java b/src/com/android/phone/ecc/EccInfo.java
index d047b9b..fb41370 100644
--- a/src/com/android/phone/ecc/EccInfo.java
+++ b/src/com/android/phone/ecc/EccInfo.java
@@ -18,7 +18,7 @@
import androidx.annotation.NonNull;
-import java.util.List;
+import java.util.Collection;
/**
* Emergency call code info.
@@ -41,7 +41,7 @@
mTypes = new Type[]{ type };
}
- public EccInfo(@NonNull String number, @NonNull List<Type> types) {
+ public EccInfo(@NonNull String number, @NonNull Collection<Type> types) {
mNumber = number;
mTypes = types.toArray(new Type[types.size()]);
}
diff --git a/src/com/android/phone/ecc/EccInfoHelper.java b/src/com/android/phone/ecc/EccInfoHelper.java
index 514f388..cd47dde 100644
--- a/src/com/android/phone/ecc/EccInfoHelper.java
+++ b/src/com/android/phone/ecc/EccInfoHelper.java
@@ -27,6 +27,7 @@
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -45,6 +46,8 @@
* Helper for retrieve ECC info for current country.
*/
public class EccInfoHelper {
+ // Debug constants.
+ private static final boolean DBG = false;
private static final String LOG_TAG = "EccInfoHelper";
// country ISO to ECC list data source
@@ -164,14 +167,17 @@
TelephonyManager tm = (TelephonyManager) context.getSystemService(
Context.TELEPHONY_SERVICE);
String iso = tm.getNetworkCountryIso();
- Log.d(LOG_TAG, "Current country ISO is " + iso);
+ if (DBG) Log.d(LOG_TAG, "Current country ISO is " + Rlog.pii(LOG_TAG, iso));
if (TextUtils.isEmpty(iso)) {
// XXX: according to ServiceStateTracker's implementation, retrieve cell info in a
// thread other than TelephonyManager's main thread.
String mcc = getCurrentMccFromCellInfo(context);
iso = MccTable.countryCodeForMcc(mcc);
- Log.d(LOG_TAG, "Current mcc is " + mcc + ", mapping to ISO: " + iso);
+ if (DBG) {
+ Log.d(LOG_TAG, "Current mcc is " + Rlog.pii(LOG_TAG, mcc) + ", mapping to ISO: "
+ + Rlog.pii(LOG_TAG, iso));
+ }
}
return iso;
}
@@ -204,7 +210,7 @@
break;
}
}
- Log.d(LOG_TAG, "Retrieve MCC from cell info list: " + mcc);
+ if (DBG) Log.d(LOG_TAG, "Retrieve MCC from cell info list: " + Rlog.pii(LOG_TAG, mcc));
} else {
Log.w(LOG_TAG, "Cannot get cell info list.");
}
diff --git a/src/com/android/phone/ecc/IsoToEccProtobufRepository.java b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
new file mode 100644
index 0000000..817ff1d
--- /dev/null
+++ b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 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.ecc;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * Provides a mapping table from country ISO to ECC info. The data is stored in Protocol Buffers
+ * binary format, compressed with GZIP.
+ */
+public class IsoToEccProtobufRepository implements IsoToEccRepository {
+ private static final String LOG_TAG = "EccRepository";
+
+ private Map<String, CountryEccInfo> mEccTable = null;
+
+ @Override
+ @Nullable
+ public CountryEccInfo getCountryEccInfo(@NonNull Context context, String iso)
+ throws IOException {
+ if (TextUtils.isEmpty(iso)) {
+ return null;
+ }
+
+ if (mEccTable == null) {
+ mEccTable = initMappingTable(context);
+ }
+ return mEccTable.get(iso.toUpperCase());
+ }
+
+ private Map<String, CountryEccInfo> initMappingTable(@NonNull Context context)
+ throws IOException {
+ ProtobufEccData.AllInfo allEccData = null;
+
+ long startTime = SystemClock.uptimeMillis();
+ allEccData = parseEccData(new BufferedInputStream(
+ context.getAssets().open("eccdata")));
+ long endTime = SystemClock.uptimeMillis();
+
+ if (allEccData == null) {
+ // Returns an empty table.
+ return new HashMap<>();
+ }
+
+ if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+ Log.d(LOG_TAG, "Loading time = " + (endTime - startTime) + "ms"
+ + ", Country Count = " + allEccData.getCountriesCount()
+ + ", initialized = " + allEccData.isInitialized());
+ }
+
+ // Converts to run-time data from Protobuf data.
+ Map<String, CountryEccInfo> table = new HashMap<>();
+ for (ProtobufEccData.CountryInfo countryData : allEccData.getCountriesList()) {
+ if (countryData.hasIsoCode()) {
+ CountryEccInfo countryInfo = loadCountryEccInfo(countryData);
+ if (countryInfo != null) {
+ table.put(countryData.getIsoCode().toUpperCase(), countryInfo);
+ }
+ }
+ }
+ return table;
+ }
+
+ private ProtobufEccData.AllInfo parseEccData(InputStream input) throws IOException {
+ return ProtobufEccData.AllInfo.parseFrom(new GZIPInputStream(input));
+ }
+
+ private EccInfo loadEccInfo(String isoCode, ProtobufEccData.EccInfo eccData) {
+ String phoneNumber = eccData.getPhoneNumber().trim();
+ if (phoneNumber.isEmpty()) {
+ Log.i(LOG_TAG, "Discard ecc " + phoneNumber
+ + " for " + isoCode + " due to empty phone number");
+ return null;
+ }
+
+ ArraySet<EccInfo.Type> eccTypes = new ArraySet<>(eccData.getTypesCount());
+ for (ProtobufEccData.EccInfo.Type typeData : eccData.getTypesList()) {
+ switch (typeData) {
+ case POLICE:
+ eccTypes.add(EccInfo.Type.POLICE);
+ break;
+ case AMBULANCE:
+ eccTypes.add(EccInfo.Type.AMBULANCE);
+ break;
+ case FIRE:
+ eccTypes.add(EccInfo.Type.FIRE);
+ break;
+ default:
+ // Ignores unknown types.
+ }
+ }
+
+ if (eccTypes.isEmpty()) {
+ Log.i(LOG_TAG, "Discard ecc " + phoneNumber
+ + " for " + isoCode + " due to no valid type");
+ return null;
+ }
+ return new EccInfo(phoneNumber, eccTypes);
+ }
+
+ private CountryEccInfo loadCountryEccInfo(ProtobufEccData.CountryInfo countryData) {
+ ArrayMap<String, EccInfo> eccInfoMap = new ArrayMap<>(countryData.getEccsCount());
+ for (ProtobufEccData.EccInfo eccData : countryData.getEccsList()) {
+ EccInfo eccInfo = loadEccInfo(countryData.getIsoCode(), eccData);
+ String key = eccInfo.getNumber().trim();
+ EccInfo existentEccInfo = eccInfoMap.get(key);
+ if (existentEccInfo == null) {
+ eccInfoMap.put(key, eccInfo);
+ } else {
+ // Merges types of duplicated ECC info objects.
+ ArraySet<EccInfo.Type> eccTypes = new ArraySet<>(
+ eccInfo.getTypesCount() + existentEccInfo.getTypesCount());
+ for (EccInfo.Type type : eccInfo.getTypes()) {
+ eccTypes.add(type);
+ }
+ for (EccInfo.Type type : existentEccInfo.getTypes()) {
+ eccTypes.add(type);
+ }
+ eccInfoMap.put(key, new EccInfo(eccInfo.getNumber(), eccTypes));
+ }
+ }
+
+ if (eccInfoMap.isEmpty() && !countryData.hasEccFallback()) {
+ Log.i(LOG_TAG, "Discard empty data for " + countryData.getIsoCode());
+ return null;
+ }
+ return new CountryEccInfo(countryData.getEccFallback(), eccInfoMap.values());
+ }
+}
diff --git a/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java b/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java
index 8187664..3ccd4a3 100644
--- a/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java
+++ b/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java
@@ -137,7 +137,7 @@
prefs.edit()
.putString(key + VM_NUMBER_TAG, null)
.putInt(key + FWD_SETTINGS_TAG + FWD_SETTINGS_LENGTH_TAG, 0)
- .commit();
+ .apply();
}
private static SharedPreferences getPrefs(Context context) {
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index 24c3870..5d987f7 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -211,6 +211,7 @@
// 4) Add the conference to the connection service if it is new.
if (isNewlyCreated) {
Log.d(this, "Adding the conference call");
+ mConference.updateCallRadioTechAfterCreation();
mConnectionService.addConference(mConference);
}
} else if (conferenceConnections.isEmpty()) {
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index b196d57..5722834 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -640,6 +640,7 @@
setState(mConferenceHost.getState());
updateStatusHints();
+ putExtras(mConferenceHost.getExtras());
}
/**
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 6c8dcaa..642af85 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -107,9 +107,31 @@
}
/**
+ * Trigger re-registration of this account.
+ */
+ public void reRegisterPstnPhoneAccount() {
+ PhoneAccount newAccount = buildPstnPhoneAccount(mIsEmergency, mIsDummy);
+ if (!newAccount.equals(mAccount)) {
+ Log.i(this, "reRegisterPstnPhoneAccount: subId: " + getSubId()
+ + " - re-register due to account change.");
+ mTelecomManager.registerPhoneAccount(newAccount);
+ mAccount = newAccount;
+ } else {
+ Log.i(this, "reRegisterPstnPhoneAccount: subId: " + getSubId() + " - no change");
+ }
+ }
+
+ private PhoneAccount registerPstnPhoneAccount(boolean isEmergency, boolean isDummyAccount) {
+ PhoneAccount account = buildPstnPhoneAccount(mIsEmergency, mIsDummy);
+ // Register with Telecom and put into the account entry.
+ mTelecomManager.registerPhoneAccount(account);
+ return account;
+ }
+
+ /**
* Registers the specified account with Telecom as a PhoneAccountHandle.
*/
- private PhoneAccount registerPstnPhoneAccount(boolean isEmergency, boolean isDummyAccount) {
+ private PhoneAccount buildPstnPhoneAccount(boolean isEmergency, boolean isDummyAccount) {
String dummyPrefix = isDummyAccount ? "Dummy " : "";
// Build the Phone account handle.
@@ -312,9 +334,6 @@
.setGroupId(groupId)
.build();
- // Register with Telecom and put into the account entry.
- mTelecomManager.registerPhoneAccount(account);
-
return account;
}
@@ -322,6 +341,10 @@
return mAccount != null ? mAccount.getAccountHandle() : null;
}
+ public int getSubId() {
+ return mPhone.getSubId();
+ }
+
/**
* Determines from carrier configuration whether pausing of IMS video calls is supported.
*
@@ -579,19 +602,27 @@
}
};
- private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.i(this, "User changed, re-registering phone accounts.");
+ if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+ Log.i(this, "User changed, re-registering phone accounts.");
- int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
- UserHandle currentUserHandle = new UserHandle(userHandleId);
- mIsPrimaryUser = UserManager.get(mContext).getPrimaryUser().getUserHandle()
- .equals(currentUserHandle);
+ int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+ UserHandle currentUserHandle = new UserHandle(userHandleId);
+ mIsPrimaryUser = UserManager.get(mContext).getPrimaryUser().getUserHandle()
+ .equals(currentUserHandle);
- // Any time the user changes, re-register the accounts.
- tearDownAccounts();
- setupAccounts();
+ // Any time the user changes, re-register the accounts.
+ tearDownAccounts();
+ setupAccounts();
+ } else if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(
+ intent.getAction())) {
+ Log.i(this, "Carrier-config changed, checking for phone account updates.");
+ int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ handleCarrierConfigChange(subId);
+ }
}
};
@@ -814,8 +845,10 @@
// Listen for user switches. When the user switches, we need to ensure that if the current
// use is not the primary user we disable video calling.
- mContext.registerReceiver(mUserSwitchedReceiver,
- new IntentFilter(Intent.ACTION_USER_SWITCHED));
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ mContext.registerReceiver(mReceiver, filter);
// Listen to the RTT system setting so that we update it when the user flips it.
ContentObserver rttUiSettingObserver = new ContentObserver(
@@ -951,4 +984,27 @@
mAccounts.clear();
}
}
+
+ /**
+ * Handles changes to the carrier configuration which may impact a phone account. There are
+ * some extras defined in the {@link PhoneAccount} which are based on carrier config options.
+ * Only checking for carrier config changes when the subscription is configured runs the risk of
+ * missing carrier config changes which happen later.
+ * @param subId The subid the carrier config changed for, if applicable. Will be
+ * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if not specified.
+ */
+ private void handleCarrierConfigChange(int subId) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return;
+ }
+ synchronized (mAccountsLock) {
+ for (AccountEntry entry : mAccounts) {
+ if (entry.getSubId() == subId) {
+ Log.d(this, "handleCarrierConfigChange: subId=%d, accountSubId=%d", subId,
+ entry.getSubId());
+ entry.reRegisterPstnPhoneAccount();
+ }
+ }
+ }
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index e96815c..e9eef46 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -264,6 +264,7 @@
mTelephonyConference, connection);
mTelephonyConference.addConnection(connection);
}
+ mTelephonyConference.updateCallRadioTechAfterCreation();
mConnectionService.addConference(mTelephonyConference);
} else {
Log.d(this, "Trigger recalculate later");
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 409eb47..7d25767 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -36,6 +36,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
import android.text.TextUtils;
@@ -96,6 +97,7 @@
private static final int MSG_CDMA_VOICE_PRIVACY_ON = 15;
private static final int MSG_CDMA_VOICE_PRIVACY_OFF = 16;
private static final int MSG_HANGUP = 17;
+ private static final int MSG_SET_CALL_RADIO_TECH = 18;
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -240,6 +242,31 @@
int cause = (int) msg.obj;
hangup(cause);
break;
+
+ case MSG_SET_CALL_RADIO_TECH:
+ int vrat = (int) msg.obj;
+ // Check whether Wi-Fi call tech is changed, it means call radio tech is:
+ // a) changed from IWLAN to other value, or
+ // b) changed from other value to IWLAN.
+ //
+ // In other word, below conditions are all met:
+ // 1) {@link #getCallRadioTech} is different from new vrat
+ // 2) Current call radio technology indicates Wi-Fi call, i.e. {@link #isWifi}
+ // is true, or new vrat indicates Wi-Fi call.
+ boolean isWifiTechChange = getCallRadioTech() != vrat
+ && (isWifi() || vrat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN);
+
+ // Step 1) Updates call radio tech firstly, so that afterwards Wi-Fi related
+ // update actions are taken correctly.
+ setCallRadioTech(vrat);
+
+ // Step 2) Handles Wi-Fi call tech change.
+ if (isWifiTechChange) {
+ updateConnectionProperties();
+ updateStatusHints();
+ refreshDisableAddCall();
+ }
+ break;
}
}
};
@@ -421,14 +448,14 @@
}
/**
- * Used by {@link com.android.internal.telephony.Connection} to report a change in whether
- * the call is being made over a wifi network.
+ * Used by {@link com.android.internal.telephony.Connection} to report a change for
+ * the call radio technology.
*
- * @param isWifi True if call is made over wifi.
+ * @param vrat the RIL Voice Radio Technology used for current connection.
*/
@Override
- public void onWifiChanged(boolean isWifi) {
- setWifi(isWifi);
+ public void onCallRadioTechChanged(@ServiceState.RilRadioTechnology int vrat) {
+ mHandler.obtainMessage(MSG_SET_CALL_RADIO_TECH, vrat).sendToTarget();
}
/**
@@ -599,13 +626,6 @@
private int mOriginalConnectionCapabilities;
/**
- * Determines if the {@link TelephonyConnection} is using wifi.
- * This is used when {@link TelephonyConnection#updateConnectionProperties()} is called to
- * indicate whether a call has the {@link Connection#PROPERTY_WIFI} property.
- */
- private boolean mIsWifi;
-
- /**
* Determines the audio quality is high for the {@link TelephonyConnection}.
* This is used when {@link TelephonyConnection#updateConnectionProperties}} is called to
* indicate whether a call has the {@link Connection#PROPERTY_HIGH_DEF_AUDIO} property.
@@ -883,6 +903,13 @@
Log.v(this, "Holding active call");
try {
Phone phone = mOriginalConnection.getCall().getPhone();
+
+ // New behavior for IMS -- don't use the clunky switchHoldingAndActive logic.
+ if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
+ ImsPhone imsPhone = (ImsPhone) phone;
+ imsPhone.holdActiveCall();
+ return;
+ }
Call ringingCall = phone.getRingingCall();
// Although the method says switchHoldingAndActive, it eventually calls a RIL method
@@ -912,6 +939,13 @@
Log.v(this, "performUnhold");
if (Call.State.HOLDING == mConnectionState) {
try {
+ Phone phone = mOriginalConnection.getCall().getPhone();
+ // New behavior for IMS -- don't use the clunky switchHoldingAndActive logic.
+ if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
+ ImsPhone imsPhone = (ImsPhone) phone;
+ imsPhone.unholdHeldCall();
+ return;
+ }
// Here's the deal--Telephony hold/unhold is weird because whenever there exists
// more than one call, one of them must always be active. In other words, if you
// have an active call and holding call, and you put the active call on hold, it
@@ -1016,7 +1050,7 @@
newProperties = changeBitmask(newProperties, PROPERTY_HIGH_DEF_AUDIO,
hasHighDefAudioProperty());
- newProperties = changeBitmask(newProperties, PROPERTY_WIFI, mIsWifi);
+ newProperties = changeBitmask(newProperties, PROPERTY_WIFI, isWifi());
newProperties = changeBitmask(newProperties, PROPERTY_IS_EXTERNAL_CALL,
isExternalConnection());
newProperties = changeBitmask(newProperties, PROPERTY_HAS_CDMA_VOICE_PRIVACY,
@@ -1034,7 +1068,13 @@
updateConnectionCapabilities();
updateConnectionProperties();
if (mOriginalConnection != null) {
- Uri address = getAddressFromNumber(mOriginalConnection.getAddress());
+ Uri address;
+ if (isShowingOriginalDialString()
+ && mOriginalConnection.getOrigDialString() != null) {
+ address = getAddressFromNumber(mOriginalConnection.getOrigDialString());
+ } else {
+ address = getAddressFromNumber(mOriginalConnection.getAddress());
+ }
int presentation = mOriginalConnection.getNumberPresentation();
if (!Objects.equals(address, getAddress()) ||
presentation != getAddressPresentation()) {
@@ -1069,6 +1109,15 @@
void setOriginalConnection(com.android.internal.telephony.Connection originalConnection) {
Log.v(this, "new TelephonyConnection, originalConnection: " + originalConnection);
+ if (mOriginalConnection != null && originalConnection != null
+ && !originalConnection.isIncoming()
+ && originalConnection.getOrigDialString() == null
+ && isShowingOriginalDialString()) {
+ Log.i(this, "new original dial string is null, convert to: "
+ + mOriginalConnection.getOrigDialString());
+ originalConnection.setConverted(mOriginalConnection.getOrigDialString());
+ }
+
clearOriginalConnection();
mOriginalConnectionExtras.clear();
mOriginalConnection = originalConnection;
@@ -1088,12 +1137,13 @@
// Set video state and capabilities
setVideoState(mOriginalConnection.getVideoState());
setOriginalConnectionCapabilities(mOriginalConnection.getConnectionCapabilities());
- setWifi(mOriginalConnection.isWifi());
setAudioModeIsVoip(mOriginalConnection.getAudioModeIsVoip());
setVideoProvider(mOriginalConnection.getVideoProvider());
setAudioQuality(mOriginalConnection.getAudioQuality());
setTechnologyTypeExtra();
+ setCallRadioTech(mOriginalConnection.getCallRadioTech());
+
// Post update of extras to the handler; extras are updated via the handler to ensure thread
// safety. The Extras Bundle is cloned in case the original extras are modified while they
// are being added to mOriginalConnectionExtras in updateExtras.
@@ -1210,7 +1260,7 @@
if (isCurrentVideoCall) {
return true;
- } else if (wasVideoCall && mIsWifi && !isVowifiEnabled) {
+ } else if (wasVideoCall && isWifi() && !isVowifiEnabled) {
return true;
}
return false;
@@ -1245,7 +1295,7 @@
return false;
}
- if (mIsWifi && !canWifiCallsBeHdAudio) {
+ if (isWifi() && !canWifiCallsBeHdAudio) {
return false;
}
@@ -1802,21 +1852,10 @@
}
/**
- * Sets whether the call is using wifi. Used when rebuilding the capabilities to set or unset
- * the {@link Connection#PROPERTY_WIFI} property.
- */
- public void setWifi(boolean isWifi) {
- mIsWifi = isWifi;
- updateConnectionProperties();
- updateStatusHints();
- refreshDisableAddCall();
- }
-
- /**
* Whether the call is using wifi.
*/
boolean isWifi() {
- return mIsWifi;
+ return getCallRadioTech() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
}
/**
@@ -1996,7 +2035,7 @@
}
private void updateStatusHints() {
- if (mIsWifi && getPhone() != null) {
+ if (isWifi() && getPhone() != null) {
int labelId = isValidRingingCall()
? R.string.status_hint_label_incoming_wifi_call
: R.string.status_hint_label_wifi_call;
@@ -2167,6 +2206,21 @@
return Collections.unmodifiableMap(result);
}
+ private boolean isShowingOriginalDialString() {
+ boolean showOrigDialString = false;
+ Phone phone = getPhone();
+ if (phone != null && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA)
+ && !mOriginalConnection.isIncoming()) {
+ PersistableBundle pb = getCarrierConfig();
+ if (pb != null) {
+ showOrigDialString = pb.getBoolean(CarrierConfigManager
+ .KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL);
+ Log.d(this, "showOrigDialString: " + showOrigDialString);
+ }
+ }
+ return showOrigDialString;
+ }
+
/**
* Creates a string representation of this {@link TelephonyConnection}. Primarily intended for
* use in log statements.
diff --git a/tests/src/com/android/phone/CdmaOptionsTest.java b/tests/src/com/android/phone/CdmaOptionsTest.java
index 446f2c5..c0c6317 100644
--- a/tests/src/com/android/phone/CdmaOptionsTest.java
+++ b/tests/src/com/android/phone/CdmaOptionsTest.java
@@ -15,53 +15,40 @@
*/
package com.android.phone;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
+import static com.google.common.truth.Truth.assertThat;
-import android.content.Context;
import android.os.PersistableBundle;
-import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.CarrierConfigManager;
-import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class CdmaOptionsTest {
- @Mock
- private Phone mMockPhone;
-
- private CdmaOptions mCdmaOptions;
- private Context mContext;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = InstrumentationRegistry.getContext();
- mCdmaOptions = new CdmaOptions(mMockPhone);
+ @Test
+ public void shouldAddApnExpandPreference_doesNotExpandOnGsm() {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL, true);
+ assertThat(CdmaOptions.shouldAddApnExpandPreference(PhoneConstants.PHONE_TYPE_GSM, bundle))
+ .isFalse();
}
@Test
- public void shouldAddApnExpandPreference_doesNotExpandOnGsm() {
- when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
+ public void shouldAddApnExpandPreference_showExpandOnCdma() {
PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL, true);
- assertFalse(mCdmaOptions.shouldAddApnExpandPreference(bundle));
+ assertThat(CdmaOptions.shouldAddApnExpandPreference(PhoneConstants.PHONE_TYPE_CDMA, bundle))
+ .isTrue();
+ }
- when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_CDMA);
+ @Test
+ public void shouldAddApnExpandPreference_doesNotExpandOnCdmaIfCarrierConfigDisabled() {
+ PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
- assertFalse(mCdmaOptions.shouldAddApnExpandPreference(bundle));
-
- when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_CDMA);
- bundle.putBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL, true);
- assertTrue(mCdmaOptions.shouldAddApnExpandPreference(bundle));
+ assertThat(CdmaOptions.shouldAddApnExpandPreference(PhoneConstants.PHONE_TYPE_CDMA, bundle))
+ .isFalse();
}
}
diff --git a/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java b/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java
index 6b7f825..34e3937 100644
--- a/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java
+++ b/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java
@@ -51,6 +51,7 @@
private class PhoneSearchIndexablesTestProvider extends PhoneSearchIndexablesProvider {
private boolean mIsEuiccSettingsHidden = false;
private boolean mIsEnhanced4gLteHidden = false;
+ private boolean mIsWifiCallingHidden = false;
@Override boolean isEuiccSettingsHidden() {
return mIsEuiccSettingsHidden;
@@ -60,6 +61,10 @@
return mIsEnhanced4gLteHidden;
}
+ @Override boolean isWifiCallingHidden() {
+ return mIsWifiCallingHidden;
+ }
+
public void setIsEuiccSettingsHidden(boolean isEuiccSettingsHidden) {
mIsEuiccSettingsHidden = isEuiccSettingsHidden;
}
@@ -67,6 +72,10 @@
public void setIsEnhanced4gLteHidden(boolean isEnhanced4gLteHidden) {
mIsEnhanced4gLteHidden = isEnhanced4gLteHidden;
}
+
+ public void setIsWifiCallingHidden(boolean isWifiCallingHidden) {
+ mIsWifiCallingHidden = isWifiCallingHidden;
+ }
}
@Before
@@ -115,25 +124,31 @@
mProvider.setIsEnhanced4gLteHidden(false /* isEnhanced4gLteHidden */);
mProvider.setIsEuiccSettingsHidden(false /* isEuiccSettingsHiden */);
when(mUserManager.isAdminUser()).thenReturn(false);
- Cursor cursor1 = mProvider.queryNonIndexableKeys(
+ Cursor cursor;
+ cursor = mProvider.queryNonIndexableKeys(
SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor1.getColumnNames()).isEqualTo(
+ assertThat(cursor.getColumnNames()).isEqualTo(
SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor1.getCount()).isEqualTo(16);
+ assertThat(cursor.getCount()).isEqualTo(16);
when(mUserManager.isAdminUser()).thenReturn(true);
- Cursor cursor2 = mProvider
+ cursor = mProvider
.queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor2.getCount()).isEqualTo(3);
+ assertThat(cursor.getCount()).isEqualTo(3);
mProvider.setIsEuiccSettingsHidden(true /* isEuiccSettingsHidden */);
- Cursor cursor3 = mProvider
+ cursor = mProvider
.queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor3.getCount()).isEqualTo(4);
+ assertThat(cursor.getCount()).isEqualTo(4);
mProvider.setIsEnhanced4gLteHidden(true /* isEnhanced4gLteHidden */);
- Cursor cursor4 = mProvider
+ cursor = mProvider
.queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor4.getCount()).isEqualTo(5);
+ assertThat(cursor.getCount()).isEqualTo(5);
+
+ mProvider.setIsWifiCallingHidden(true /* isWifiCallingHidden */);
+ cursor = mProvider
+ .queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
+ assertThat(cursor.getCount()).isEqualTo(6);
}
}