Merge "Also set call direction during single party call emulation" into rvc-dev
diff --git a/res/layout/sim_ndp.xml b/res/layout/sim_ndp.xml
index 5e3c472..5f03d7b 100644
--- a/res/layout/sim_ndp.xml
+++ b/res/layout/sim_ndp.xml
@@ -29,6 +29,7 @@
android:layout_centerInParent="true">
<TextView
+ android:id="@+id/perso_subtype_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index ccef876..e2c5779 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -294,7 +294,7 @@
<string name="carrier_settings_euicc_summary" msgid="2027941166597330117">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> — <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
<string name="mobile_data_settings_title" msgid="7228249980933944101">"بيانات الجوّال"</string>
<string name="mobile_data_settings_summary" msgid="5012570152029118471">"الوصول إلى البيانات باستخدام شبكة الجوّال"</string>
- <string name="data_usage_disable_mobile" msgid="5669109209055988308">"هل تريد إيقاف تفعيل بيانات الجوّال؟"</string>
+ <string name="data_usage_disable_mobile" msgid="5669109209055988308">"هل تريد إيقاف بيانات الجوّال؟"</string>
<string name="sim_selection_required_pref" msgid="6985901872978341314">"يلزم التحديد"</string>
<string name="sim_change_data_title" msgid="9142726786345906606">"هل تريد تغيير شريحة SIM للبيانات؟"</string>
<string name="sim_change_data_message" msgid="3567358694255933280">"هل تريد استخدام <xliff:g id="NEW_SIM">%1$s</xliff:g> بدلاً من <xliff:g id="OLD_SIM">%2$s</xliff:g> لبيانات الجوّال؟"</string>
@@ -704,7 +704,7 @@
<string name="change_pin_confirm_pins_dont_match" msgid="305164501222587215">"أرقام التعريف الشخصي غير متطابقة"</string>
<string name="change_pin_succeeded" msgid="2504705600693014403">"تمّ تحديث رقم التعريف الشخصي للبريد الصوتي"</string>
<string name="change_pin_system_error" msgid="7772788809875146873">"يتعذر تعيين رقم التعريف الشخصي"</string>
- <string name="mobile_data_status_roaming_turned_off_subtext" msgid="6840673347416227054">"تم إيقاف تفعيل تجوال البيانات"</string>
+ <string name="mobile_data_status_roaming_turned_off_subtext" msgid="6840673347416227054">"تم إيقاف تجوال البيانات"</string>
<string name="mobile_data_status_roaming_turned_on_subtext" msgid="5615757897768777865">"تم تفعيل تجوال البيانات"</string>
<string name="mobile_data_status_roaming_without_plan_subtext" msgid="6536671968072284677">"التجوال قيد التشغيل حاليًا، يتطلب خطة بيانات"</string>
<string name="mobile_data_status_roaming_with_plan_subtext" msgid="2576177169108123095">"التجوال قيد التشغيل حاليًا، خطة البيانات نشطة"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index e83c315..948c7cc 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -49,12 +49,12 @@
<string name="add_vm_number_str" msgid="7368168964435881637">"Nummer hinzufügen"</string>
<string name="voice_number_setting_primary_user_only" msgid="3394706575741912843">"Mailboxeinstellungen können nur vom primären Nutzer geändert werden."</string>
<string name="puk_unlocked" msgid="4627340655215746511">"Deine SIM-Karte wurde entsperrt. Dein Telefon wird nun entsperrt..."</string>
- <string name="label_ndp" msgid="7617392683877410341">"PIN zur Entsperrung des SIM-Netzwerks"</string>
+ <string name="label_ndp" msgid="7617392683877410341">"Entsperr-PIN für netzgebundenes Gerät"</string>
<string name="sim_ndp_unlock_text" msgid="7737338355451978338">"Entsperren"</string>
<string name="sim_ndp_dismiss_text" msgid="89667342248929777">"Verwerfen"</string>
- <string name="requesting_unlock" msgid="930512210309437741">"Netzwerkentsperrung wird angefordert..."</string>
- <string name="unlock_failed" msgid="7103543844840661366">"Anfrage für Entsperrung des Netzwerks war nicht erfolgreich."</string>
- <string name="unlock_success" msgid="32681089371067565">"Entsperrung des Netzwerks nicht erfolgreich."</string>
+ <string name="requesting_unlock" msgid="930512210309437741">"Entsperrung des netzgebundenen Geräts wird angefordert..."</string>
+ <string name="unlock_failed" msgid="7103543844840661366">"Entsperranforderung für netzgebundenes Gerät war nicht erfolgreich."</string>
+ <string name="unlock_success" msgid="32681089371067565">"Entsperrung des netzgebundenen Geräts war nicht erfolgreich."</string>
<string name="mobile_network_settings_not_available" msgid="8678168497517090039">"Mobile Netzwerkeinstellungen sind für diesen Nutzer nicht verfügbar."</string>
<string name="labelGSMMore" msgid="7354182269461281543">"GSM-Anrufeinstellungen"</string>
<string name="labelGsmMore_with_label" msgid="3206015314393246224">"GSM-Anrufeinstellungen (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index bde92dc..7e32dd2 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -867,7 +867,7 @@
<string name="radio_info_dds" msgid="1122593144425697126">"Sous-identifiant de la carte SIM par défaut :"</string>
<string name="radio_info_dl_kbps" msgid="2382922659525318726">"Bande passante de téléchargement (kb/s) :"</string>
<string name="radio_info_ul_kbps" msgid="2102225400904799036">"Bande passante de téléversement (kb/s) :"</string>
- <string name="radio_info_signal_location_label" msgid="6188435197086550049">"Données de la position de la cellule (discontinuées) :"</string>
+ <string name="radio_info_signal_location_label" msgid="6188435197086550049">"Données de la position de la cellule (obsolètes) :"</string>
<string name="radio_info_phy_chan_config" msgid="1277949603275436081">"Configuration du canal physique LTE :"</string>
<string name="radio_info_cell_info_refresh_rate" msgid="670511448975997340">"Taux d\'actualisation des données de la cellule :"</string>
<string name="radio_info_cellinfo_label" msgid="8199062974670377659">"Données des mesures de toutes les cellules :"</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e8a0bed..8218a84 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -259,7 +259,7 @@
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
- <item name="emergencyButtonBackgroundColor">#3cffffff</item>
+ <item name="emergencyButtonBackgroundColor">#10ffffff</item>
<item name="dialpadTheme">@style/Dialpad_DarkTransparent.Emergency</item>
</style>
diff --git a/sip/res/values-in/strings.xml b/sip/res/values-in/strings.xml
index 535e5ac..709205c 100644
--- a/sip/res/values-in/strings.xml
+++ b/sip/res/values-in/strings.xml
@@ -40,7 +40,7 @@
<string name="registration_status_registering" msgid="7986331597809521791">"Mendaftarkan..."</string>
<string name="registration_status_still_trying" msgid="7178623685868766282">"Masih mencoba..."</string>
<string name="registration_status_not_receiving" msgid="3873074208531938401">"Tidak menerima panggilan."</string>
- <string name="registration_status_no_data" msgid="2987064560116584121">"Pendaftaran akun terhenti karena tidak ada sambungan internet."</string>
+ <string name="registration_status_no_data" msgid="2987064560116584121">"Pendaftaran akun terhenti karena tidak ada koneksi internet."</string>
<string name="registration_status_no_wifi_data" msgid="685470618241482948">"Pendaftaran akun terhenti karena tidak ada sambungan Wi-Fi."</string>
<string name="registration_status_not_running" msgid="6236403137652262659">"Pendaftaran akun gagal."</string>
<string name="registration_status_done" msgid="6787397199273357721">"Menerima panggilan."</string>
@@ -71,7 +71,7 @@
<string name="all_empty_alert" msgid="6085603517610199098">"Masukkan detail akun SIP baru."</string>
<string name="empty_alert" msgid="3693655518612836718">"<xliff:g id="INPUT_FIELD_NAME">%s</xliff:g> diwajibkan dan tidak boleh kosong."</string>
<string name="not_a_valid_port" msgid="3664668836663491376">"Nomor port harus dalam rentang 1000 dan 65534."</string>
- <string name="no_internet_available" msgid="161720645084325479">"Untuk melakukan panggilan SIP, periksa sambungan internet terlebih dahulu."</string>
+ <string name="no_internet_available" msgid="161720645084325479">"Untuk melakukan panggilan SIP, periksa koneksi internet terlebih dahulu."</string>
<string name="no_wifi_available" msgid="1179092018692306312">"Anda harus tersambung ke jaringan Wi-Fi untuk melakukan panggilan SIP (gunakan setelan Nirkabel & Jaringan)."</string>
<string name="no_voip" msgid="3366395789297981738">"Panggilan SIP tidak didukung"</string>
<string name="sip_system_decide" msgid="197230378376326430">"Otomatis"</string>
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 9699e1b..e3a7de6 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -103,8 +103,10 @@
private CarrierServiceConnection[] mServiceConnection;
// Whether we are bound to a service for each phone
private boolean[] mServiceBound;
- // Whether we have sent config change bcast for each phone id.
+ // Whether we have sent config change broadcast for each phone id.
private boolean[] mHasSentConfigChange;
+ // Whether the broadcast was sent from EVENT_SYSTEM_UNLOCKED, to track rebroadcasts
+ private boolean[] mFromSystemUnlocked;
// SubscriptionInfoUpdater
private final SubscriptionInfoUpdater mSubscriptionInfoUpdater;
@@ -200,11 +202,13 @@
case EVENT_SYSTEM_UNLOCKED: {
for (int i = 0; i < TelephonyManager.from(mContext).getActiveModemCount();
++i) {
- // When user unlock device, we should only try to send broadcast again if we
- // have sent it before unlock. This will avoid we try to load carrier config
- // when SIM is still loading when unlock happens.
+ // When the user unlocks the device, send the broadcast again (with a
+ // rebroadcast extra) if we have sent it before unlock. This will avoid
+ // trying to load the carrier config when the SIM is still loading when the
+ // unlock happens.
if (mHasSentConfigChange[i]) {
logdWithLocalLog("System unlocked");
+ mFromSystemUnlocked[i] = true;
updateConfigForPhoneId(i);
}
}
@@ -538,6 +542,7 @@
mServiceConnection = new CarrierServiceConnection[numPhones];
mServiceBound = new boolean[numPhones];
mHasSentConfigChange = new boolean[numPhones];
+ mFromSystemUnlocked = new boolean[numPhones];
// Make this service available through ServiceManager.
TelephonyFrameworkInitializer
.getTelephonyServiceManager().getCarrierConfigServiceRegisterer().register(this);
@@ -636,6 +641,8 @@
}
}
intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, phoneId);
+ intent.putExtra(CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK,
+ mFromSystemUnlocked[phoneId]);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
int[] subIds = SubscriptionManager.getSubId(phoneId);
if (subIds != null && subIds.length > 0) {
@@ -643,8 +650,8 @@
} else {
logd("Broadcast CARRIER_CONFIG_CHANGED for phone " + phoneId);
}
-
mHasSentConfigChange[phoneId] = true;
+ mFromSystemUnlocked[phoneId] = false;
}
/** Binds to the default or carrier config app. */
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index c6bac02..5d630af 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -20,6 +20,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.annotation.ColorInt;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -44,7 +45,6 @@
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -72,6 +72,7 @@
import com.android.phone.common.dialpad.DialpadKeyButton;
import com.android.phone.common.util.ViewUtil;
import com.android.phone.common.widget.ResizingTextEditText;
+import com.android.telephony.Rlog;
import java.util.ArrayList;
import java.util.List;
@@ -151,6 +152,11 @@
/** Size limit of emergency shortcut buttons container. **/
private static final int SHORTCUT_SIZE_LIMIT = 3;
+ private static final float COLOR_DELTA = 1.0f / 16.0f;
+
+ /** Dial button color, from packages/apps/PhoneCommon/res/drawable-mdpi/fab_green.png **/
+ @ColorInt private static final int DIALER_GREEN = 0xff00c853;
+
ResizingTextEditText mDigits;
private View mDialButton;
private View mDelete;
@@ -719,8 +725,12 @@
isEmergencyNumber = true;
phoneToMakeCall = mShortcutViewConfig.getPhoneInfo();
} else {
- isEmergencyNumber = getSystemService(TelephonyManager.class)
- .isEmergencyNumber(mLastNumber);
+ try {
+ isEmergencyNumber = getSystemService(TelephonyManager.class)
+ .isEmergencyNumber(mLastNumber);
+ } catch (IllegalStateException ise) {
+ isEmergencyNumber = false;
+ }
}
if (isEmergencyNumber) {
@@ -1196,11 +1206,52 @@
private static int getPrimaryColor(WallpaperColors colors) {
if (colors != null) {
- return colors.getPrimaryColor().toArgb();
+ // Android accessibility scanner
+ // (https://support.google.com/accessibility/android/answer/7158390)
+ // suggest small text and graphics have a contrast ratio greater than
+ // 4.5 with background color. The color generated from wallpaper may not
+ // follow this rule. Calculate a proper color here.
+ Color primary = colors.getPrimaryColor();
+ Color text = Color.valueOf(Color.WHITE);
+ Color dial = Color.valueOf(DIALER_GREEN);
+ // If current primary color can't follow the contrast ratio rule, make it
+ // deeper and try again.
+ while (!checkContrastRatio(primary, text)) {
+ primary = getDeeper(primary);
+ }
+ while (!checkContrastRatio(primary, dial)) {
+ primary = getDeeper(primary);
+ }
+ return primary.toArgb();
}
// It's possible that wallpaper colors are null (e.g. when colors are being
// processed or a live wallpaper is used). In this case, fallback to same
// behavior as when shortcut view is enabled.
return Color.BLACK;
}
+
+ private static Color getDeeper(Color color) {
+ float r = color.red() - COLOR_DELTA;
+ float g = color.green() - COLOR_DELTA;
+ float b = color.blue() - COLOR_DELTA;
+ if (r < 0f) r = 0f;
+ if (g < 0f) g = 0f;
+ if (b < 0f) b = 0f;
+ return Color.valueOf(r, g, b);
+ }
+
+ private static boolean checkContrastRatio(Color color1, Color color2) {
+ float lum1 = color1.luminance();
+ float lum2 = color2.luminance();
+ double cr;
+ if (lum1 >= lum2) {
+ cr = (lum1 + 0.05) / (lum2 + 0.05);
+ } else {
+ cr = (lum2 + 0.05) / (lum1 + 0.05);
+ }
+
+ // Make cr greater than 5.0 instead of 4.5 to guarantee that transparent white
+ // text and graphics can have contrast ratio greather than 4.5 with background.
+ return cr > 5.0;
+ }
}
diff --git a/src/com/android/phone/IccNetworkDepersonalizationPanel.java b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
index 8bd10a2..7d854cd 100644
--- a/src/com/android/phone/IccNetworkDepersonalizationPanel.java
+++ b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
@@ -22,7 +22,10 @@
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextUtils;
@@ -37,6 +40,8 @@
import android.widget.TextView;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
/**
* "SIM network unlock" PIN entry screen.
@@ -52,7 +57,8 @@
* Tracks whether there is an instance of the network depersonalization dialog showing or not.
* Ensures only a single instance of the dialog is visible.
*/
- private static boolean sShowingDialog = false;
+ private static boolean [] sShowingDialog =
+ new boolean[TelephonyManager.getDefault().getSimCount()];
//debug constants
private static final boolean DBG = false;
@@ -61,29 +67,48 @@
private static final int EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT = 100;
private Phone mPhone;
+ private int mPersoSubtype;
+ private static IccNetworkDepersonalizationPanel [] sNdpPanel =
+ new IccNetworkDepersonalizationPanel[TelephonyManager.getDefault().getSimCount()];
//UI elements
private EditText mPinEntry;
private LinearLayout mEntryPanel;
private LinearLayout mStatusPanel;
+ private TextView mPersoSubtypeText;
+ private PersoSubState mPersoSubState;
private TextView mStatusText;
private Button mUnlockButton;
private Button mDismissButton;
+ enum statusType {
+ ENTRY,
+ IN_PROGRESS,
+ ERROR,
+ SUCCESS
+ }
+
/**
* Shows the network depersonalization dialog, but only if it is not already visible.
*/
- public static void showDialog(Phone phone) {
- if (sShowingDialog) {
+ public static void showDialog(Phone phone, int subType) {
+ int phoneId = phone == null ? 0: phone.getPhoneId();
+ if (sShowingDialog[phoneId]) {
Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; skipped already shown.");
return;
}
Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; showing dialog.");
- sShowingDialog = true;
- IccNetworkDepersonalizationPanel ndpPanel =
- new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance(), phone);
- ndpPanel.show();
+ sShowingDialog[phoneId] = true;
+ sNdpPanel[phoneId] = new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance(),
+ phone, subType);
+ sNdpPanel[phoneId].show();
+ }
+
+ public static void dialogDismiss(int phoneId) {
+ if (sNdpPanel[phoneId] != null && sShowingDialog[phoneId]) {
+ sNdpPanel[phoneId].dismiss();
+ }
}
//private textwatcher to control text entry.
@@ -109,37 +134,41 @@
AsyncResult res = (AsyncResult) msg.obj;
if (res.exception != null) {
if (DBG) log("network depersonalization request failure.");
- indicateError();
+ displayStatus(statusType.ERROR.name());
postDelayed(new Runnable() {
- public void run() {
- hideAlert();
- mPinEntry.getText().clear();
- mPinEntry.requestFocus();
- }
- }, 3000);
+ public void run() {
+ hideAlert();
+ mPinEntry.getText().clear();
+ mPinEntry.requestFocus();
+ }
+ }, 3000);
} else {
if (DBG) log("network depersonalization success.");
- indicateSuccess();
+ displayStatus(statusType.SUCCESS.name());
postDelayed(new Runnable() {
- public void run() {
- dismiss();
- }
- }, 3000);
+ public void run() {
+ dismiss();
+ }
+ }, 3000);
}
}
}
};
+
//constructor
public IccNetworkDepersonalizationPanel(Context context) {
super(context);
mPhone = PhoneGlobals.getPhone();
+ mPersoSubtype = PersoSubState.PERSOSUBSTATE_SIM_NETWORK.ordinal();
}
//constructor
- public IccNetworkDepersonalizationPanel(Context context, Phone phone) {
+ public IccNetworkDepersonalizationPanel(Context context, Phone phone,
+ int subtype) {
super(context);
mPhone = phone == null ? PhoneGlobals.getPhone() : phone;
+ mPersoSubtype = subtype;
}
@Override
@@ -158,6 +187,8 @@
span.setSpan(mPinEntryWatcher, 0, text.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
mEntryPanel = (LinearLayout) findViewById(R.id.entry_panel);
+ mPersoSubtypeText = (TextView) findViewById(R.id.perso_subtype_text);
+ displayStatus(statusType.ENTRY.name());
mUnlockButton = (Button) findViewById(R.id.ndp_unlock);
mUnlockButton.setOnClickListener(mUnlockListener);
@@ -190,7 +221,8 @@
public void onStop() {
super.onStop();
Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; hiding dialog.");
- sShowingDialog = false;
+ int phoneId = mPhone == null ? 0 : mPhone.getPhoneId();
+ sShowingDialog[phoneId] = false;
}
//Mirrors IccPinUnlockPanel.onKeyDown().
@@ -210,29 +242,45 @@
return;
}
- if (DBG) log("requesting network depersonalization with code " + pin);
- mPhone.getIccCard().supplyNetworkDepersonalization(pin,
- Message.obtain(mHandler, EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT));
- indicateBusy();
+ log("Requesting De-Personalization for subtype " + mPersoSubtype);
+
+ try {
+ mPhone.getIccCard().supplySimDepersonalization(mPersoSubState,pin,
+ Message.obtain(mHandler, EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT));
+ } catch (NullPointerException ex) {
+ log("NullPointerException @supplySimDepersonalization" + ex);
+ }
+ displayStatus(statusType.IN_PROGRESS.name());
}
};
- private void indicateBusy() {
- mStatusText.setText(R.string.requesting_unlock);
- mEntryPanel.setVisibility(View.GONE);
- mStatusPanel.setVisibility(View.VISIBLE);
- }
+ private void displayStatus(String type) {
+ int label = 0;
- private void indicateError() {
- mStatusText.setText(R.string.unlock_failed);
- mEntryPanel.setVisibility(View.GONE);
- mStatusPanel.setVisibility(View.VISIBLE);
- }
+ mPersoSubState = PersoSubState.values()[mPersoSubtype];
+ log("displayStatus mPersoSubState: " +mPersoSubState.name() +"type: " +type);
- private void indicateSuccess() {
- mStatusText.setText(R.string.unlock_success);
- mEntryPanel.setVisibility(View.GONE);
- mStatusPanel.setVisibility(View.VISIBLE);
+ label = getContext().getResources().getIdentifier(mPersoSubState.name()
+ + "_" + type, "string", "android");
+
+ if (label == 0) {
+ log ("Unable to get the PersoSubType string");
+ return;
+ }
+
+ if(!PersoSubState.isPersoLocked(mPersoSubState)) {
+ log ("Unsupported Perso Subtype :" + mPersoSubState.name());
+ return;
+ }
+
+ if (type == statusType.ENTRY.name()) {
+ String displayText = getContext().getString(label);
+ mPersoSubtypeText.setText(displayText);
+ } else {
+ mStatusText.setText(label);
+ mEntryPanel.setVisibility(View.GONE);
+ mStatusPanel.setVisibility(View.VISIBLE);
+ }
}
private void hideAlert() {
@@ -241,13 +289,13 @@
}
View.OnClickListener mDismissListener = new View.OnClickListener() {
- public void onClick(View v) {
- if (DBG) log("mDismissListener: skipping depersonalization...");
- dismiss();
- }
- };
+ public void onClick(View v) {
+ if (DBG) log("mDismissListener: skipping depersonalization...");
+ dismiss();
+ }
+ };
private void log(String msg) {
- Log.v(TAG, "[IccNetworkDepersonalizationPanel] " + msg);
+ Log.d(TAG, "[IccNetworkDepersonalizationPanel] " + msg);
}
}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 810ccdf..5e3c224 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -205,6 +205,16 @@
private final SettingsObserver mSettingsObserver;
+ private static class EventSimStateChangedBag {
+ final int mPhoneId;
+ final String mIccStatus;
+
+ EventSimStateChangedBag(int phoneId, String iccStatus) {
+ mPhoneId = phoneId;
+ mIccStatus = iccStatus;
+ }
+ }
+
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -225,7 +235,8 @@
// they enter a valid SIM network PIN.
Log.i(LOG_TAG, "show sim depersonal panel");
Phone phone = (Phone) ((AsyncResult) msg.obj).userObj;
- IccNetworkDepersonalizationPanel.showDialog(phone);
+ int subType = (Integer)((AsyncResult)msg.obj).result;
+ IccNetworkDepersonalizationPanel.showDialog(phone, subType);
}
break;
@@ -253,8 +264,9 @@
// Marks the event where the SIM goes into ready state.
// Right now, this is only used for the PUK-unlocking
// process.
- if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)
- || msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_LOADED)) {
+ EventSimStateChangedBag bag = (EventSimStateChangedBag)msg.obj;
+ if (bag.mIccStatus == IccCardConstants.INTENT_VALUE_ICC_READY
+ || bag.mIccStatus == IccCardConstants.INTENT_VALUE_ICC_LOADED) {
// when the right event is triggered and there
// are UI objects in the foreground, we close
// them to display the lock panel.
@@ -266,6 +278,8 @@
mPUKEntryProgressDialog.dismiss();
mPUKEntryProgressDialog = null;
}
+ Log.i(LOG_TAG, "Dismissing depersonal panel");
+ IccNetworkDepersonalizationPanel.dialogDismiss(bag.mPhoneId);
}
break;
@@ -650,14 +664,9 @@
PhoneUtils.unregisterIccStatus(mHandler, phoneId);
PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED, phoneId);
}
- if (mPUKEntryActivity != null) {
- // if an attempt to un-PUK-lock the device was made, while we're
- // receiving this state change notification, notify the handler.
- // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
- // been attempted.
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
- intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)));
- }
+ String iccStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
+ new EventSimStateChangedBag(phoneId, iccStatus)));
} else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index fee5ecc..98af8e6 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -5509,7 +5509,6 @@
/**
* Set the preferred network type.
- * Used for device configuration by some CDMA operators.
*
* @param networkType the preferred network type, defined in RILConstants.java.
* @return true on success; false on any failure.
@@ -5523,7 +5522,11 @@
try {
Settings.Global.putInt(mApp.getContentResolver(),
Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
- return setPreferredNetworkTypesInternal(subId);
+
+ Boolean success = (Boolean) sendRequest(
+ CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
+ if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
+ return success;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -5561,38 +5564,15 @@
public boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setAllowedNetworkTypes");
- final long identity = Binder.clearCallingIdentity();
- try {
- SubscriptionManager.setSubscriptionProperty(subId,
- SubscriptionManager.ALLOWED_NETWORK_TYPES,
- String.valueOf(allowedNetworkTypes));
- return setPreferredNetworkTypesInternal(subId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- private boolean setPreferredNetworkTypesInternal(int subId) {
- long networkTypeBitMask = RadioAccessFamily.getRafFromNetworkType(
- Settings.Global.getInt(mApp.getContentResolver(),
- Settings.Global.PREFERRED_NETWORK_MODE + subId,
- RILConstants.PREFERRED_NETWORK_MODE));
- long allowedNetworkTypes = SubscriptionManager.getLongSubscriptionProperty(
- subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
- int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(
- (int) (networkTypeBitMask & allowedNetworkTypes));
+ SubscriptionManager.setSubscriptionProperty(subId,
+ SubscriptionManager.ALLOWED_NETWORK_TYPES,
+ String.valueOf(allowedNetworkTypes));
- if (DBG) {
- log("setPreferredNetworkTypesInternal: subId " + subId
- + " networkTypes " + networkTypeBitMask
- + " allowedNetworkTypes " + allowedNetworkTypes
- + " networkMode " + networkMode);
- }
-
- Boolean success = (Boolean) sendRequest(
- CMD_SET_PREFERRED_NETWORK_TYPE, networkMode, subId);
- if (DBG) log("setPreferredNetworkTypesInternal: " + (success ? "ok" : "fail"));
- return success;
+ int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
+ Settings.Global.PREFERRED_NETWORK_MODE + subId,
+ RILConstants.PREFERRED_NETWORK_MODE);
+ return setPreferredNetworkType(subId, preferredNetworkMode);
}
/**
@@ -5755,14 +5735,13 @@
}
}
- private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim,
+ private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
Phone phone) {
//load access rules from carrier configs, and check those as well: b/139133814
SubscriptionController subController = SubscriptionController.getInstance();
if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
|| subController == null) return privilegeFromSim;
- int uid = Binder.getCallingUid();
PackageManager pkgMgr = phone.getContext().getPackageManager();
String[] packages = pkgMgr.getPackagesForUid(uid);
@@ -5816,7 +5795,7 @@
return getCarrierPrivilegeStatusFromCarrierConfigRules(
card.getCarrierPrivilegeStatusForCurrentTransaction(
- phone.getContext().getPackageManager()), phone);
+ phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
}
@Override
@@ -5835,7 +5814,7 @@
}
return getCarrierPrivilegeStatusFromCarrierConfigRules(
profile.getCarrierPrivilegeStatusForUid(
- phone.getContext().getPackageManager(), uid), phone);
+ phone.getContext().getPackageManager(), uid), uid, phone);
}
@Override
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index bd015e3..36618c5 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -288,9 +288,8 @@
private boolean isEmergency() {
Phone phone = getPhone();
- return phone != null &&
- PhoneNumberUtils.isLocalEmergencyNumber(
- phone.getContext(), getAddress().getSchemeSpecificPart());
+ return phone != null && getAddress() != null && PhoneNumberUtils.isLocalEmergencyNumber(
+ phone.getContext(), getAddress().getSchemeSpecificPart());
}
/**
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 1a8aa07..f243462 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -348,6 +348,9 @@
case android.telephony.DisconnectCause.DATA_LIMIT_REACHED:
resourceId = R.string.callFailed_data_limit_reached;
break;
+ case android.telephony.DisconnectCause.WIFI_LOST:
+ resourceId = R.string.callFailed_wifi_lost;
+ break;
case android.telephony.DisconnectCause.ALREADY_DIALING:
resourceId = R.string.callFailed_already_dialing;
break;
@@ -867,6 +870,7 @@
case android.telephony.DisconnectCause.NORMAL:
case android.telephony.DisconnectCause.NORMAL_UNSPECIFIED:
case android.telephony.DisconnectCause.VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED:
+ case android.telephony.DisconnectCause.WIFI_LOST:
default:
return ToneGenerator.TONE_PROP_PROMPT;
}
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index fccdb72..f739603 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -20,7 +20,6 @@
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
-import android.os.PersistableBundle;
import android.telecom.Connection;
import android.telecom.Connection.VideoProvider;
import android.telecom.DisconnectCause;
@@ -28,7 +27,6 @@
import android.telecom.StatusHints;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
-import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.util.Pair;
@@ -38,7 +36,6 @@
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneUtils;
import com.android.phone.R;
import com.android.telephony.Rlog;
@@ -79,6 +76,126 @@
}
/**
+ * Abstracts out carrier configuration items specific to the conference.
+ */
+ public static class CarrierConfiguration {
+ /**
+ * Builds and instance of {@link CarrierConfiguration}.
+ */
+ public static class Builder {
+ private boolean mIsMaximumConferenceSizeEnforced = false;
+ private int mMaximumConferenceSize = 5;
+ private boolean mShouldLocalDisconnectEmptyConference = false;
+ private boolean mIsHoldAllowed = false;
+
+ /**
+ * Sets whether the maximum size of the conference is enforced.
+ * @param isMaximumConferenceSizeEnforced {@code true} if conference size enforced.
+ * @return builder instance.
+ */
+ public Builder setIsMaximumConferenceSizeEnforced(
+ boolean isMaximumConferenceSizeEnforced) {
+ mIsMaximumConferenceSizeEnforced = isMaximumConferenceSizeEnforced;
+ return this;
+ }
+
+ /**
+ * Sets the maximum size of an IMS conference.
+ * @param maximumConferenceSize Max conference size.
+ * @return builder instance.
+ */
+ public Builder setMaximumConferenceSize(int maximumConferenceSize) {
+ mMaximumConferenceSize = maximumConferenceSize;
+ return this;
+ }
+
+ /**
+ * Sets whether an empty conference should be locally disconnected.
+ * @param shouldLocalDisconnectEmptyConference {@code true} if conference should be
+ * locally disconnected if empty.
+ * @return builder instance.
+ */
+ public Builder setShouldLocalDisconnectEmptyConference(
+ boolean shouldLocalDisconnectEmptyConference) {
+ mShouldLocalDisconnectEmptyConference = shouldLocalDisconnectEmptyConference;
+ return this;
+ }
+
+ /**
+ * Sets whether holding the conference is allowed.
+ * @param isHoldAllowed {@code true} if holding is allowed.
+ * @return builder instance.
+ */
+ public Builder setIsHoldAllowed(boolean isHoldAllowed) {
+ mIsHoldAllowed = isHoldAllowed;
+ return this;
+ }
+
+ /**
+ * Build instance of {@link CarrierConfiguration}.
+ * @return carrier config instance.
+ */
+ public ImsConference.CarrierConfiguration build() {
+ return new ImsConference.CarrierConfiguration(mIsMaximumConferenceSizeEnforced,
+ mMaximumConferenceSize, mShouldLocalDisconnectEmptyConference,
+ mIsHoldAllowed);
+ }
+ }
+
+ private CarrierConfiguration(boolean isMaximumConferenceSizeEnforced,
+ int maximumConferenceSize, boolean shouldLocalDisconnectEmptyConference,
+ boolean isHoldAllowed) {
+ mIsMaximumConferenceSizeEnforced = isMaximumConferenceSizeEnforced;
+ mMaximumConferenceSize = maximumConferenceSize;
+ mShouldLocalDisconnectEmptyConference = shouldLocalDisconnectEmptyConference;
+ mIsHoldAllowed = isHoldAllowed;
+ }
+
+ private boolean mIsMaximumConferenceSizeEnforced;
+
+ private int mMaximumConferenceSize;
+
+ private boolean mShouldLocalDisconnectEmptyConference;
+
+ private boolean mIsHoldAllowed;
+
+ /**
+ * Determines whether the {@link ImsConference} should enforce a size limit based on
+ * {@link #getMaximumConferenceSize()}.
+ * {@code true} if maximum size limit should be enforced, {@code false} otherwise.
+ */
+ public boolean isMaximumConferenceSizeEnforced() {
+ return mIsMaximumConferenceSizeEnforced;
+ }
+
+ /**
+ * Determines the maximum number of participants (not including the host) in a conference
+ * which is enforced when {@link #isMaximumConferenceSizeEnforced()} is {@code true}.
+ */
+ public int getMaximumConferenceSize() {
+ return mMaximumConferenceSize;
+ }
+
+ /**
+ * Determines whether this {@link ImsConference} should locally disconnect itself when the
+ * number of participants in the conference drops to zero.
+ * {@code true} if empty conference should be locally disconnected, {@code false}
+ * otherwise.
+ */
+ public boolean shouldLocalDisconnectEmptyConference() {
+ return mShouldLocalDisconnectEmptyConference;
+ }
+
+ /**
+ * Determines whether holding the conference is permitted or not.
+ * {@code true} if hold is permitted, {@code false} otherwise.
+ */
+ public boolean isHoldAllowed() {
+ return mIsHoldAllowed;
+ }
+ }
+
+ /**
* Listener used to respond to changes to the underlying radio connection for the conference
* host connection. Used to respond to SRVCC changes.
*/
@@ -260,6 +377,7 @@
private boolean mIsHoldable;
private boolean mCouldManageConference;
private FeatureFlagProxy mFeatureFlagProxy;
+ private final CarrierConfiguration mCarrierConfig;
private boolean mIsEmulatingSinglePartyCall = false;
private boolean mIsUsingSimCallManager = false;
@@ -301,12 +419,13 @@
public ImsConference(TelecomAccountRegistry telecomAccountRegistry,
TelephonyConnectionServiceProxy telephonyConnectionService,
TelephonyConnection conferenceHost, PhoneAccountHandle phoneAccountHandle,
- FeatureFlagProxy featureFlagProxy) {
+ FeatureFlagProxy featureFlagProxy, CarrierConfiguration carrierConfig) {
super(phoneAccountHandle);
mTelecomAccountRegistry = telecomAccountRegistry;
mFeatureFlagProxy = featureFlagProxy;
+ mCarrierConfig = carrierConfig;
// Specify the connection time of the conference to be the connection time of the original
// connection.
@@ -323,7 +442,7 @@
int capabilities = Connection.CAPABILITY_MUTE |
Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN;
- if (canHoldImsCalls()) {
+ if (mCarrierConfig.isHoldAllowed()) {
capabilities |= Connection.CAPABILITY_SUPPORT_HOLD | Connection.CAPABILITY_HOLD;
mIsHoldable = true;
}
@@ -491,6 +610,8 @@
} catch (CallStateException e) {
Log.e(this, e, "Exception thrown trying to hangup conference");
}
+ } else {
+ Log.w(this, "onDisconnect - null call");
}
}
@@ -935,6 +1056,14 @@
if (newParticipantsAdded || oldParticipantsRemoved) {
updateManageConference();
}
+
+ // If the conference is empty and we're supposed to do a local disconnect, do so now.
+ if (mCarrierConfig.shouldLocalDisconnectEmptyConference()
+ && oldParticipantCount > 0 && newParticipantCount == 0) {
+ Log.i(this, "handleConferenceParticipantsUpdate: empty conference; "
+ + "local disconnect.");
+ onDisconnect();
+ }
}
}
@@ -1347,51 +1476,6 @@
return sb.toString();
}
- private boolean canHoldImsCalls() {
- PersistableBundle b = getCarrierConfig();
- // Return true if the CarrierConfig is unavailable
- return b == null || b.getBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL);
- }
-
- private PersistableBundle getCarrierConfig() {
- if (mConferenceHost == null) {
- return null;
- }
-
- Phone phone = mConferenceHost.getPhone();
- if (phone == null) {
- return null;
- }
- return PhoneGlobals.getInstance().getCarrierConfigForSubId(phone.getSubId());
- }
-
- /**
- * @return {@code true} if the carrier associated with the conference requires that the maximum
- * size of the conference is enforced, {@code false} otherwise.
- */
- public boolean isMaximumConferenceSizeEnforced() {
- PersistableBundle b = getCarrierConfig();
- // Return false if the CarrierConfig is unavailable
- return b != null && b.getBoolean(
- CarrierConfigManager.KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL);
- }
-
- /**
- * @return The maximum size of a conference call where
- * {@link #isMaximumConferenceSizeEnforced()} is true.
- */
- public int getMaximumConferenceSize() {
- PersistableBundle b = getCarrierConfig();
-
- // If there is no carrier config its really a problem, but we'll still define a sane limit
- // of 5 so that we can still make a conference.
- if (b == null) {
- Log.w(this, "getMaximumConferenceSize - failed to get conference size");
- return 5;
- }
- return b.getInt(CarrierConfigManager.KEY_IMS_CONFERENCE_SIZE_LIMIT_INT);
- }
-
/**
* @return The number of participants in the conference.
*/
@@ -1404,8 +1488,8 @@
* participants in the conference has reached the limit, {@code false} otherwise.
*/
public boolean isFullConference() {
- return isMaximumConferenceSizeEnforced()
- && getNumberOfParticipants() >= getMaximumConferenceSize();
+ return mCarrierConfig.isMaximumConferenceSizeEnforced()
+ && getNumberOfParticipants() >= mCarrierConfig.getMaximumConferenceSize();
}
/**
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 8789ba8..1d1c5d8 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -16,12 +16,16 @@
package com.android.services.telephony;
+import android.content.Context;
+import android.os.PersistableBundle;
import android.telecom.Conference;
import android.telecom.Conferenceable;
import android.telecom.Connection;
import android.telecom.ConnectionService;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccountHandle;
+import android.telephony.CarrierConfigManager;
+
import com.android.telephony.Rlog;
import com.android.internal.telephony.Phone;
@@ -403,6 +407,7 @@
PhoneAccountHandle phoneAccountHandle = null;
// Attempt to determine the phone account associated with the conference host connection.
+ ImsConference.CarrierConfiguration carrierConfig = null;
if (connection.getPhone() != null &&
connection.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
Phone imsPhone = connection.getPhone();
@@ -410,10 +415,11 @@
// base GSM or CDMA phone, not on the ImsPhone itself).
phoneAccountHandle =
PhoneUtils.makePstnPhoneAccountHandle(imsPhone.getDefaultPhone());
+ carrierConfig = getCarrierConfig(imsPhone);
}
ImsConference conference = new ImsConference(mTelecomAccountRegistry, mConnectionService,
- conferenceHostConnection, phoneAccountHandle, mFeatureFlagProxy);
+ conferenceHostConnection, phoneAccountHandle, mFeatureFlagProxy, carrierConfig);
conference.setState(conferenceHostConnection.getState());
conference.addTelephonyConferenceListener(mConferenceListener);
conference.updateConferenceParticipantsAfterCreation();
@@ -433,4 +439,33 @@
// conferenceable connections for the conference to show merge calls option.
recalculateConferenceable();
}
+
+ public static ImsConference.CarrierConfiguration getCarrierConfig(Phone phone) {
+ ImsConference.CarrierConfiguration.Builder config =
+ new ImsConference.CarrierConfiguration.Builder();
+ if (phone == null) {
+ return config.build();
+ }
+
+ CarrierConfigManager cfgManager = (CarrierConfigManager)
+ phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (cfgManager != null) {
+ PersistableBundle bundle = cfgManager.getConfigForSubId(phone.getSubId());
+ boolean isMaximumConferenceSizeEnforced = bundle.getBoolean(
+ CarrierConfigManager.KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL);
+ int maximumConferenceSize = bundle.getInt(
+ CarrierConfigManager.KEY_IMS_CONFERENCE_SIZE_LIMIT_INT);
+ boolean isHoldAllowed = bundle.getBoolean(
+ CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL);
+ boolean shouldLocalDisconnectOnEmptyConference = bundle.getBoolean(
+ CarrierConfigManager.KEY_LOCAL_DISCONNECT_EMPTY_IMS_CONFERENCE_BOOL);
+
+ config.setIsMaximumConferenceSizeEnforced(isMaximumConferenceSizeEnforced)
+ .setMaximumConferenceSize(maximumConferenceSize)
+ .setIsHoldAllowed(isHoldAllowed)
+ .setShouldLocalDisconnectEmptyConference(
+ shouldLocalDisconnectOnEmptyConference);
+ }
+ return config.build();
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 0b60e37..f1b44bf 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -71,6 +71,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -246,12 +247,20 @@
@Override
public boolean isCurrentEmergencyNumber(String number) {
- return mTelephonyManager.isEmergencyNumber(number);
+ try {
+ return mTelephonyManager.isEmergencyNumber(number);
+ } catch (IllegalStateException ise) {
+ return false;
+ }
}
@Override
public Map<Integer, List<EmergencyNumber>> getCurrentEmergencyNumberList() {
- return mTelephonyManager.getEmergencyNumberList();
+ try {
+ return mTelephonyManager.getEmergencyNumberList();
+ } catch (IllegalStateException ise) {
+ return new HashMap<>();
+ }
}
}
@@ -571,9 +580,11 @@
}
TelephonyConnection connection = (TelephonyConnection)conn;
+
ImsConference conference = new ImsConference(TelecomAccountRegistry.getInstance(this),
mTelephonyConnectionServiceProxy, connection,
- phoneAccountHandle, () -> true);
+ phoneAccountHandle, () -> true,
+ ImsConferenceController.getCarrierConfig(connection.getPhone()));
mImsConferenceController.addConference(conference);
conference.setVideoState(connection,
connection.getVideoState());
@@ -1639,7 +1650,10 @@
private void placeOutgoingConnection(
TelephonyConnection connection, Phone phone, int videoState, Bundle extras) {
- String number = connection.getAddress().getSchemeSpecificPart();
+
+ String number = (connection.getAddress() != null)
+ ? connection.getAddress().getSchemeSpecificPart()
+ : "";
com.android.internal.telephony.Connection originalConnection = null;
try {
diff --git a/tests/src/com/android/phone/LocationAccessPolicyTest.java b/tests/src/com/android/phone/LocationAccessPolicyTest.java
index 2061f38..b2489e7 100644
--- a/tests/src/com/android/phone/LocationAccessPolicyTest.java
+++ b/tests/src/com/android/phone/LocationAccessPolicyTest.java
@@ -147,6 +147,9 @@
}
}
+ private static final int TESTING_UID = 10001;
+ private static final int TESTING_PID = 8009;
+
@Mock Context mContext;
@Mock AppOpsManager mAppOpsManager;
@Mock LocationManager mLocationManager;
@@ -195,15 +198,18 @@
anyInt(), anyString(), nullable(String.class), nullable(String.class)))
.thenReturn(s.coarseAppOp);
+ // set this permission to denied by default, and only allow for the proper pid/uid
+ // combination
+ when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
if (s.isDynamicLocationEnabled) {
when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class))).thenReturn(true);
when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ eq(TESTING_PID), eq(TESTING_UID)))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
} else {
when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class)))
.thenReturn(false);
- when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
}
ApplicationInfo fakeAppInfo = new ApplicationInfo();
@@ -222,8 +228,8 @@
.setMethod("test")
.setCallingPackage("com.android.test")
.setCallingFeatureId(null)
- .setCallingPid(10001)
- .setCallingUid(10001);
+ .setCallingPid(TESTING_PID)
+ .setCallingUid(TESTING_UID);
}
@Parameterized.Parameters(name = "{0}")
diff --git a/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java b/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
new file mode 100644
index 0000000..7f9efdc
--- /dev/null
+++ b/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony;
+
+import static android.media.ToneGenerator.TONE_PROP_PROMPT;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.TestCase.assertEquals;
+
+import android.telephony.DisconnectCause;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DisconnectCauseUtilTest {
+ /**
+ * Verifies that a call drop due to loss of WIFI results in a disconnect cause of error and that
+ * the label, description and tone are all present.
+ */
+ @Test
+ public void testDropDueToWifiLoss() {
+ android.telecom.DisconnectCause tcCause = DisconnectCauseUtil.toTelecomDisconnectCause(
+ DisconnectCause.WIFI_LOST);
+ assertEquals(android.telecom.DisconnectCause.ERROR, tcCause.getCode());
+ assertEquals(TONE_PROP_PROMPT, tcCause.getTone());
+ assertNotNull(tcCause.getDescription());
+ assertNotNull(tcCause.getReason());
+ }
+}
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index a01a64f..b84aca1 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -43,6 +43,7 @@
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
+import java.util.Collections;
public class ImsConferenceTest {
@Mock
@@ -73,7 +74,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
ConferenceParticipant participant1 = new ConferenceParticipant(
Uri.parse("tel:6505551212"),
@@ -122,7 +124,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
// Start off with 3 participants.
ConferenceParticipant participant1 = new ConferenceParticipant(
@@ -185,7 +188,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
// Start off with 3 participants.
ConferenceParticipant participant1 = new ConferenceParticipant(
@@ -242,7 +246,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
// Setup the initial conference state with 2 participants.
ConferenceParticipant participant1 = new ConferenceParticipant(
@@ -300,7 +305,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
final boolean[] isConferenceState = new boolean[1];
TelephonyConferenceBase.TelephonyConferenceListener conferenceListener =
@@ -356,7 +362,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
ConferenceParticipant participant1 = new ConferenceParticipant(
Uri.parse("tel:6505551212"),
@@ -381,7 +388,8 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
ConferenceParticipant participant1 = new ConferenceParticipant(
Uri.parse("tel:6505551212"),
@@ -412,13 +420,14 @@
@Test
@SmallTest
- public void testNormalConference() {
+ public void testNormalConference() throws Exception {
when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
.thenReturn(false);
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> false /* featureFlagProxy */);
+ null /* phoneAccountHandle */, () -> false /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
ConferenceParticipant participant1 = new ConferenceParticipant(
Uri.parse("tel:6505551212"),
@@ -440,5 +449,45 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1));
assertEquals(1, imsConference.getNumberOfParticipants());
+
+ // Drop to 0 participants; should not hangup the conf now
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost, Collections.emptyList());
+ assertEquals(0, imsConference.getNumberOfParticipants());
+ verify(mConferenceHost.mMockCall, never()).hangup();
+ }
+
+ @Test
+ @SmallTest
+ public void testLocalDisconnectOnEmptyConference() throws Exception {
+ when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+ .thenReturn(false);
+
+ ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+ mMockTelephonyConnectionServiceProxy, mConferenceHost,
+ null /* phoneAccountHandle */, () -> false /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder()
+ .setShouldLocalDisconnectEmptyConference(true)
+ .build());
+
+ ConferenceParticipant participant1 = new ConferenceParticipant(
+ Uri.parse("tel:6505551212"),
+ "A",
+ Uri.parse("sip:6505551212@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+ ConferenceParticipant participant2 = new ConferenceParticipant(
+ Uri.parse("tel:6505551213"),
+ "A",
+ Uri.parse("sip:6505551213@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1, participant2));
+ assertEquals(2, imsConference.getNumberOfParticipants());
+
+ // Drop to 0 participants; should have a hangup request.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost, Collections.emptyList());
+ assertEquals(0, imsConference.getNumberOfParticipants());
+ verify(mConferenceHost.mMockCall).hangup();
}
}
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index 5b31c0f..8b7a477 100644
--- a/tests/src/com/android/services/telephony/TestTelephonyConnection.java
+++ b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
@@ -30,6 +30,7 @@
import static org.mockito.Mockito.when;
import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -72,6 +73,11 @@
return mMockRadioConnection;
}
+ @Override
+ protected Call getCall() {
+ return mMockCall;
+ }
+
public TestTelephonyConnection() {
super(null, null, false);
MockitoAnnotations.initMocks(this);
@@ -100,6 +106,11 @@
when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
when(mMockCall.getState()).thenReturn(Call.State.ACTIVE);
when(mMockCall.getPhone()).thenReturn(mMockPhone);
+ try {
+ doNothing().when(mMockCall).hangup();
+ } catch (CallStateException e) {
+ e.printStackTrace();
+ }
}
@Override