blob: 46b2cc8cfe522cc68ac749a3cfd87b2ba901efd0 [file] [log] [blame]
package com.android.phone;
import android.app.ActionBar;
import android.content.ContentProvider;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.UserHandle;
import android.os.SystemProperties;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import java.util.ArrayList;
public class GsmUmtsCallForwardOptions extends TimeConsumingPreferenceActivity
implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
private static final String LOG_TAG = "GsmUmtsCallForwardOptions";
private static final String NUM_PROJECTION[] = {
android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER
};
public static final String CALL_FORWARD_INTENT = "org.codeaurora.settings.CDMA_CALL_FORWARDING";
private static final String BUTTON_CFU_KEY = "button_cfu_key";
private static final String BUTTON_CFB_KEY = "button_cfb_key";
private static final String BUTTON_CFNRY_KEY = "button_cfnry_key";
private static final String BUTTON_CFNRC_KEY = "button_cfnrc_key";
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;
private CallForwardEditPreference mButtonCFNRy;
private CallForwardEditPreference mButtonCFNRc;
private final ArrayList<CallForwardEditPreference> mPreferences =
new ArrayList<CallForwardEditPreference> ();
private int mInitIndex= 0;
private boolean mFirstResume;
private Bundle mIcicle;
private Phone mPhone;
private SubscriptionInfoHelper mSubscriptionInfoHelper;
private boolean mReplaceInvalidCFNumbers;
private int mServiceClass;
private BroadcastReceiver mReceiver = null;
private SubscriptionManager mSubscriptionManager;
private boolean mCheckData = false;
AlertDialog.Builder builder = null;
private CarrierConfigManager mCarrierConfig;
private boolean mCallForwardByUssd;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.callforward_options);
mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
mSubscriptionInfoHelper.setActionBarTitle(
getActionBar(), getResources(), R.string.call_forwarding_settings_with_label);
mPhone = mSubscriptionInfoHelper.getPhone();
mCarrierConfig = (CarrierConfigManager)
getSystemService(CARRIER_CONFIG_SERVICE);
if (mCarrierConfig != null) {
PersistableBundle pb = mCarrierConfig.getConfigForSubId(mPhone.getSubId());
mCheckData = pb.getBoolean("check_mobile_data_for_cf");
}
PersistableBundle b = null;
boolean supportCFB = true;
boolean supportCFNRc = true;
boolean supportCFNRy = true;
if (mSubscriptionInfoHelper.hasSubId()) {
b = PhoneGlobals.getInstance().getCarrierConfigForSubId(
mSubscriptionInfoHelper.getSubId());
} else {
b = PhoneGlobals.getInstance().getCarrierConfig();
}
if (b != null) {
mReplaceInvalidCFNumbers = b.getBoolean(
CarrierConfigManager.KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL);
mCallForwardByUssd = b.getBoolean(
CarrierConfigManager.KEY_USE_CALL_FORWARDING_USSD_BOOL);
supportCFB = b.getBoolean(
CarrierConfigManager.KEY_CALL_FORWARDING_WHEN_BUSY_SUPPORTED_BOOL);
supportCFNRc = b.getBoolean(
CarrierConfigManager.KEY_CALL_FORWARDING_WHEN_UNREACHABLE_SUPPORTED_BOOL);
supportCFNRy = b.getBoolean(
CarrierConfigManager.KEY_CALL_FORWARDING_WHEN_UNANSWERED_SUPPORTED_BOOL);
}
PreferenceScreen prefSet = getPreferenceScreen();
mButtonCFU = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFU_KEY);
mButtonCFB = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFB_KEY);
mButtonCFNRy = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRY_KEY);
mButtonCFNRc = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRC_KEY);
mButtonCFU.setParentActivity(this, mButtonCFU.reason);
mButtonCFB.setParentActivity(this, mButtonCFB.reason);
mButtonCFNRy.setParentActivity(this, mButtonCFNRy.reason);
mButtonCFNRc.setParentActivity(this, mButtonCFNRc.reason);
mPreferences.add(mButtonCFU);
layoutCallForwardItem(supportCFB, mButtonCFB, prefSet);
layoutCallForwardItem(supportCFNRy, mButtonCFNRy, prefSet);
layoutCallForwardItem(supportCFNRc, mButtonCFNRc, prefSet);
if (mCallForwardByUssd) {
//the call forwarding ussd command's behavior is similar to the call forwarding when
//unanswered,so only display the call forwarding when unanswered item.
prefSet.removePreference(mButtonCFU);
prefSet.removePreference(mButtonCFB);
prefSet.removePreference(mButtonCFNRc);
mPreferences.remove(mButtonCFU);
mPreferences.remove(mButtonCFB);
mPreferences.remove(mButtonCFNRc);
mButtonCFNRy.setDependency(null);
}
// we wait to do the initialization until onResume so that the
// TimeConsumingPreferenceActivity dialog can display as it
// relies on onResume / onPause to maintain its foreground state.
/*Retrieve Call Forward ServiceClass*/
Intent intent = getIntent();
Log.d(LOG_TAG, "Intent is " + intent);
mServiceClass = intent.getIntExtra(PhoneUtils.SERVICE_CLASS,
CommandsInterface.SERVICE_CLASS_VOICE);
Log.d(LOG_TAG, "serviceClass: " + mServiceClass);
mFirstResume = true;
mIcicle = icicle;
ActionBar actionBar = getActionBar();
if (actionBar != null) {
// android.R.id.home will be triggered in onOptionsItemSelected()
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
private void layoutCallForwardItem(boolean support, CallForwardEditPreference preference,
PreferenceScreen prefSet) {
if (support) {
mPreferences.add(preference);
} else {
prefSet.removePreference(preference);
}
}
/**
* Receiver for intent broadcasts the Phone app cares about.
*/
private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
String state = intent.getStringExtra(PhoneConstants.STATE_KEY);
final String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
Log.d(LOG_TAG, "apntype is: " + apnType + " state is: " + state);
if (PhoneConstants.DataState.DISCONNECTED.name().equals(state) &&
PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
Log.d(LOG_TAG, "default data is disconnected.");
checkDataStatus();
}
}
}
}
public void checkDataStatus() {
// check the active data sub.
int sub = mPhone.getSubId();
int slotId = mSubscriptionManager.getSlotIndex(sub);
int defaultDataSub = mSubscriptionManager.getDefaultDataSubscriptionId();
Log.d(LOG_TAG, "isUtEnabled = " + mPhone.isUtEnabled() + ", checkData= " + mCheckData);
// Find out if the sim card is ready.
boolean isSimReady = TelephonyManager.from(this).getSimState(slotId)
== TelephonyManager.SIM_STATE_READY;
if (!isSimReady) {
Log.d(LOG_TAG, "SIM is not ready!");
String title = (String)this.getResources().getText(R.string.sim_is_not_ready);
String message = (String)this.getResources()
.getText(R.string.sim_is_not_ready);
showAlertDialog(title, message);
return;
}
if (mPhone != null) {
int activeNetworkType = getActiveNetworkType();
boolean isDataRoaming = mPhone.getServiceState().getDataRoaming();
boolean isDataRoamingEnabled = mPhone.getDataRoamingEnabled();
boolean promptForDataRoaming = isDataRoaming && !isDataRoamingEnabled;
Log.d(LOG_TAG, "activeNetworkType = " + getActiveNetworkType() + ", sub = " + sub +
", defaultDataSub = " + defaultDataSub + ", isDataRoaming = " +
isDataRoaming + ", isDataRoamingEnabled= " + isDataRoamingEnabled);
if ((sub != defaultDataSub) && !mPhone.isUtEnabled()) {
Log.d(LOG_TAG, "Show dds switch dialog if data sub is not on current sub");
showSwitchDdsDialog(slotId);
return;
}
if (mPhone.isUtEnabled() && mCheckData) {
boolean isDataEnabled = TelephonyManager.from(this).getDataEnabled(sub);
Log.d(LOG_TAG, "isDataEnabled: " + isDataEnabled);
if ((!isDataEnabled || activeNetworkType != ConnectivityManager.TYPE_MOBILE)
&& !(activeNetworkType == ConnectivityManager.TYPE_NONE
&& promptForDataRoaming)) {
Log.d(LOG_TAG,
"Show alert dialog if data sub is not on current sub or WLAN is on");
String title = (String)this.getResources().getText(R.string.no_mobile_data);
String message = (String)this.getResources()
.getText(R.string.cf_setting_mobile_data_alert);
showAlertDialog(title, message);
return;
}
if (promptForDataRoaming) {
Log.d(LOG_TAG, "Show alert dialog if data roaming is disabled");
String title = (String)this.getResources()
.getText(R.string.no_mobile_data_roaming);
String message = (String)this.getResources()
.getText(R.string.cf_setting_mobile_data_roaming_alert);
showAlertDialog(title, message);
return;
}
if (sub != defaultDataSub) {
Log.d(LOG_TAG, "Show data in use indication if data sub is not on current sub");
showDataInuseToast();
}
}
}
initCallforwarding();
}
@Override
public void onClick(DialogInterface dialog, int id) {
if (id == DialogInterface.BUTTON_POSITIVE) {
Intent newIntent = new Intent("android.settings.SETTINGS");
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
}
finish();
return;
}
private int getActiveNetworkType() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(
Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo ni = cm.getActiveNetworkInfo();
if ((ni == null) || !ni.isConnected()){
return ConnectivityManager.TYPE_NONE;
}
return ni.getType();
}
return ConnectivityManager.TYPE_NONE;
}
//prompt dialog to notify user turn off Enhance 4G LTE switch
private boolean isPromptTurnOffEnhance4GLTE(Phone phone) {
if (phone == null || phone.getImsPhone() == null) {
return false;
}
ImsManager imsMgr = ImsManager.getInstance(this, phone.getPhoneId());
try {
if (imsMgr.getImsServiceState() != ImsFeature.STATE_READY) {
Log.d(LOG_TAG, "ImsServiceStatus is not ready!");
return false;
}
} catch (ImsException ex) {
Log.d(LOG_TAG, "Exception when trying to get ImsServiceStatus: " + ex);
return false;
}
return imsMgr.isEnhanced4gLteModeSettingEnabledByUser()
&& imsMgr.isNonTtyOrTtyOnVolteEnabled()
&& !phone.isUtEnabled()
&& !phone.isVolteEnabled()
&& !phone.isVideoEnabled();
}
@Override
public void onResume() {
super.onResume();
if (mCarrierConfig.getConfigForSubId(mPhone.getSubId())
.getBoolean(CarrierConfigManager.KEY_CDMA_CW_CF_ENABLED_BOOL)
&& isPromptTurnOffEnhance4GLTE(mPhone)) {
String title = (String)this.getResources()
.getText(R.string.ut_not_support);
String msg = (String)this.getResources()
.getText(R.string.ct_ut_not_support_close_4glte);
showAlertDialog(title, msg);
return;
}
if (mCheckData) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
mReceiver = new PhoneAppBroadcastReceiver();
registerReceiver(mReceiver, intentFilter);
final SubscriptionManager mSubscriptionManager = SubscriptionManager.from(this);
checkDataStatus();
} else {
initCallforwarding();
}
}
private void initCallforwarding () {
if (mFirstResume) {
if (mIcicle == null) {
Log.d(LOG_TAG, "start to init ");
CallForwardEditPreference pref = mPreferences.get(mInitIndex);
pref.init(this, mPhone, mReplaceInvalidCFNumbers, mServiceClass, mCallForwardByUssd);
pref.startCallForwardOptionsQuery();
} else {
mInitIndex = mPreferences.size();
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, mServiceClass, mCallForwardByUssd);
pref.restoreCallForwardInfo(cf);
}
}
mFirstResume = false;
mIcicle = null;
}
}
private void showDataInuseToast() {
String message = (String)this.getResources()
.getText(R.string.mobile_data_alert);
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
private void showSwitchDdsDialog(int slotId) {
String title = (String)this.getResources().getText(R.string.no_mobile_data);
int simId = slotId + 1;
String message = (String)this.getResources()
.getText(R.string.switch_dds_to_sub_alert) + String.valueOf(simId);
if (builder == null) {
builder=new AlertDialog.Builder(this);
builder.setTitle(title);
builder.setMessage(message);
builder.setIconAttribute(android.R.attr.alertDialogIcon);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent newIntent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
newIntent.putExtra(Settings.EXTRA_SUB_ID,mPhone.getSubId());
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
builder.create().show();
}
}
@Override
public void onPause() {
super.onPause();
if (mCheckData && mReceiver != null) {
unregisterReceiver(mReceiver);
}
for (CallForwardEditPreference pref : mPreferences) {
pref.deInit();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
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);
}
outState.putParcelable(pref.getKey(), bundle);
}
}
@Override
public void onFinished(Preference preference, boolean reading) {
if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
if (mInitIndex == 0 && mButtonCFU.isAutoRetryCfu()) {
Log.i(LOG_TAG, "auto retry case: ");
CarrierConfigManager carrierConfig = (CarrierConfigManager)
getSystemService(CARRIER_CONFIG_SERVICE);
if(carrierConfig != null && mPhone != null
&& carrierConfig.getConfigForSubId(mPhone.getSubId())
.getBoolean(CarrierConfigManager.KEY_CDMA_CW_CF_ENABLED_BOOL)) {
if (isPromptTurnOffEnhance4GLTE(mPhone)) {
String title = (String)this.getResources()
.getText(R.string.ut_not_support);
String msg = (String)this.getResources()
.getText(R.string.ct_ut_not_support_close_4glte);
showAlertDialog(title, msg);
}else if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ){
Log.i(LOG_TAG, "auto retry and switch to cmda method UI.");
Intent intent = new Intent(CALL_FORWARD_INTENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}
} else {
mInitIndex++;
CallForwardEditPreference pref = mPreferences.get(mInitIndex);
pref.init(this, mPhone, mReplaceInvalidCFNumbers, mServiceClass, mCallForwardByUssd);
pref.startCallForwardOptionsQuery();
}
}
super.onFinished(preference, reading);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult: done");
if (resultCode != RESULT_OK) {
Log.d(LOG_TAG, "onActivityResult: contact picker result not OK.");
return;
}
Cursor cursor = null;
try {
// check if the URI returned by the user belongs to the user
final int currentUser = UserHandle.getUserId(Process.myUid());
if (currentUser
!= ContentProvider.getUserIdFromUri(data.getData(), currentUser)) {
Log.w(LOG_TAG, "onActivityResult: Contact data of different user, "
+ "cannot access");
return;
}
cursor = getContentResolver().query(data.getData(),
NUM_PROJECTION, null, null, null);
if ((cursor == null) || (!cursor.moveToFirst())) {
Log.d(LOG_TAG, "onActivityResult: bad contact data, no results found.");
return;
}
switch (requestCode) {
case CommandsInterface.CF_REASON_UNCONDITIONAL:
mButtonCFU.onPickActivityResult(cursor.getString(0));
break;
case CommandsInterface.CF_REASON_BUSY:
mButtonCFB.onPickActivityResult(cursor.getString(0));
break;
case CommandsInterface.CF_REASON_NO_REPLY:
mButtonCFNRy.onPickActivityResult(cursor.getString(0));
break;
case CommandsInterface.CF_REASON_NOT_REACHABLE:
mButtonCFNRc.onPickActivityResult(cursor.getString(0));
break;
default:
// TODO: may need exception here.
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int itemId = item.getItemId();
if (itemId == android.R.id.home) { // See ActionBar#setDisplayHomeAsUpEnabled()
CallFeaturesSetting.goUpToTopLevelSetting(this, mSubscriptionInfoHelper);
return true;
}
return super.onOptionsItemSelected(item);
}
private void showAlertDialog(String title, String message) {
Dialog dialog = new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.setOnCancelListener(this)
.create();
dialog.show();
}
}