package com.android.phone;
import com.android.internal.telephony.CallBarringInfo;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.preference.Preference;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
import static com.android.phone.TimeConsumingPreferenceActivity.EXCEPTION_ERROR;
import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
interface CallBarringEditPreferencePreferenceListener {
public void onChange(Preference preference, int reason);
}
public class CallBarringEditPreference extends EditPassWordPreference {
private static final String LOG_TAG = "CallBarringEditPreference";
private static final boolean DBG = true;//(PhoneApp.DBG_LEVEL >= 2);
private static final boolean ENABLE_RIL = true;
private static final String SRC_TAGS[] = {"{0}"};
private CharSequence mSummaryOnTemplate;
private int mButtonClicked;
private int mServiceClass;
private boolean mNeedEcho = true;
private MyHandler mHandler = new MyHandler();
int mReason;
Phone phone;
CallBarringInfo mCallBarringInfo = new CallBarringInfo();
TimeConsumingPreferenceListener tcpListener;
CallBarringEditPreferencePreferenceListener mListener;
private String reasonToString(int reason){
switch (reason){
case CommandsInterface.CB_REASON_AO:
return CommandsInterface.CB_FACILITY_BAOC;
case CommandsInterface.CB_REASON_OI:
return CommandsInterface.CB_FACILITY_BAOIC;
case CommandsInterface.CB_REASON_OX:
return CommandsInterface.CB_FACILITY_BAOICxH;
case CommandsInterface.CB_REASON_AI:
return CommandsInterface.CB_FACILITY_BAIC;
case CommandsInterface.CB_REASON_IR:
return CommandsInterface.CB_FACILITY_BAICr;
case CommandsInterface.CB_REASON_AB:
return CommandsInterface.CB_FACILITY_BA_ALL;
default:
return CommandsInterface.CB_FACILITY_BAOC;
}
}
public CallBarringEditPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mSummaryOnTemplate = this.getSummaryOn();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CallBarringEditPreference, 0, R.style.EditPassWordPreference);
mServiceClass = a.getInt(R.styleable.CallBarringEditPreference_aserviceClass,
CommandsInterface.SERVICE_CLASS_VOICE);
mReason = a.getInt(R.styleable.CallBarringEditPreference_areason, 0);
a.recycle();
mCallBarringInfo.password = null;
mCallBarringInfo.reason = mReason;
mCallBarringInfo.serviceClass = mServiceClass;
mCallBarringInfo.status = 0;
if (DBG) Log.d(LOG_TAG, "mServiceClass=" + mServiceClass + ", reason=" + mReason);
}
public CallBarringEditPreference(Context context) {
this(context, null);
}
void setListener(CallBarringEditPreferencePreferenceListener listener){
mListener = listener;
}
void init(TimeConsumingPreferenceListener listener, boolean skipReading, int subId) {
phone = PhoneApp.getInstance().getPhone(subId);
tcpListener = listener;
if (!skipReading) {
if (ENABLE_RIL) {
if (DBG) Log.d(LOG_TAG, "queryFacilityLock: " + reasonToString(mReason));
phone.queryFacilityLock(reasonToString(mReason), "", mServiceClass,
mHandler.obtainMessage(MyHandler.MESSAGE_GET_LOCK,
// unused in this case
CommandsInterface.CF_ACTION_DISABLE,
MyHandler.MESSAGE_GET_LOCK, null));
} else {
mHandler.sendMessageDelayed(mHandler.obtainMessage(MyHandler.MESSAGE_GET_LOCK,
// unused in this case
CommandsInterface.CB_ACTION_DISABLE,
MyHandler.MESSAGE_GET_LOCK, null), 300);
}
if (tcpListener != null) {
tcpListener.onStarted(this, true);
}
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
super.onClick(dialog, which);
mButtonClicked = which;
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (DBG) Log.d(LOG_TAG, "mButtonClicked=" + mButtonClicked
+ ", positiveResult=" + positiveResult);
if (this.mButtonClicked == DialogInterface.BUTTON_POSITIVE) {
int action = (isToggled()? CommandsInterface.CB_ACTION_DISABLE : CommandsInterface.CB_ACTION_ENABLE);
EditText editText = getEditText();
final String password = getEditText().getText().toString();
if (DBG) Log.d(LOG_TAG, "onDialogClosed(), action: " + action + ", isToggled()" + isToggled());
if (DBG) Log.d(LOG_TAG, "mCallBarringInfo=" + mCallBarringInfo);
if (action == CommandsInterface.CB_ACTION_ENABLE
&& mCallBarringInfo != null
&& mCallBarringInfo.status == 1
/*&& password.equals(mCallBarringInfo.password*/) {
// no change, do nothing
if (DBG) Log.d(LOG_TAG, "no change, do nothing");
} else {
// set to network
if (DBG) Log.d(LOG_TAG, "reason=" + mReason + ", action=" + action
+ ", password=" + password);
// Display no forwarding password while we're waiting for
// confirmation
//setSummaryOn("");
// the interface of Phone.setCallForwardingOption has error:
// should be action, reason...
if (ENABLE_RIL){
if (DBG) Log.d(LOG_TAG, "setFacilityLock: " + reasonToString(mReason));
setPassWord(null);
phone.setFacilityLock(reasonToString(mReason), (action==CommandsInterface.CB_ACTION_ENABLE) , password, mServiceClass,
mHandler.obtainMessage(MyHandler.MESSAGE_SET_LOCK, action, MyHandler.MESSAGE_SET_LOCK));
} else{
mHandler.sendMessageDelayed(mHandler.obtainMessage(MyHandler.MESSAGE_SET_LOCK,
action,
MyHandler.MESSAGE_SET_LOCK), 300);
}
if (tcpListener != null) {
tcpListener.onStarted(this, false);
}
}
}
}
void handleCallBarringResult(CallBarringInfo cf) {
mCallBarringInfo = cf;
if (DBG) Log.d(LOG_TAG, "handleCallBarringResult done, mCallBarringInfo=" + mCallBarringInfo);
setToggled(mCallBarringInfo.status == 1);
setPassWord(null);
}
private void updateSummaryText() {
if (isToggled()) {
Log.d(LOG_TAG, "updateSummaryText");/*
CharSequence summaryOn;
final String password = getPassWord();
if (password != null && password.length() > 0) {
String values[] = { password };
summaryOn = TextUtils.replace(mSummaryOnTemplate, SRC_TAGS, values);
Log.d(LOG_TAG, "1 updateSummaryText: " + summaryOn);
} else {
summaryOn = getContext().getString(R.string.sum_cfu_enabled_no_number);
Log.d(LOG_TAG, "2 updateSummaryText: " + summaryOn);
}
setSummaryOn(summaryOn);*/
}
}
public void setNeedEcho(boolean bValue){
mNeedEcho = bValue;
}
public boolean getNeedEcho(){
return mNeedEcho;
}
// Message protocol:
// what: get vs. set
// arg1: action -- register vs. disable
// arg2: get vs. set for the preceding request
private class MyHandler extends Handler {
private static final int MESSAGE_GET_LOCK = 0;
private static final int MESSAGE_SET_LOCK = 1;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_GET_LOCK:
handleGetCBResponse(msg);
break;
case MESSAGE_SET_LOCK:
handleSetCBResponse(msg);
break;
}
}
private int getStatus(int iStatus, int iClass, int myClass) {
int myStatus = 0;
if ((myClass & iClass) == myClass){
myStatus = iStatus;
} else {
myStatus = ((iStatus == 1)?0:1);
}
if (DBG) Log.d(LOG_TAG, "getStatus(), myClass: " + myClass + ", iClass: " + iClass);
if (DBG) Log.d(LOG_TAG, "getStatus(), myStatus: " + myStatus + ", iStatus: " + iStatus);
return myStatus;
}
private void handleGetCBResponse(Message msg) {
if (DBG) Log.d(LOG_TAG, "handleGetCBResponse: done");
if (msg.arg2 == MESSAGE_SET_LOCK) {
tcpListener.onFinished(CallBarringEditPreference.this, false);
} else {
tcpListener.onFinished(CallBarringEditPreference.this, true);
}
if (ENABLE_RIL) {
AsyncResult ar = (AsyncResult) msg.obj;
//mCallBarringInfo = null;
if (ar.exception != null) {
if (DBG) Log.d(LOG_TAG, "handleGetCBResponse: ar.exception=" + ar.exception);
setEnabled(false);
tcpListener.onError(CallBarringEditPreference.this, EXCEPTION_ERROR);
} else {
if (ar.userObj instanceof Throwable) {
tcpListener.onError(CallBarringEditPreference.this, RESPONSE_ERROR);
}
int infoArray[] = (int[]) ar.result;
if (infoArray.length == 0) {
if (DBG) Log.d(LOG_TAG, "handleGetCBResponse: infoArray.length==0");
setEnabled(false);
tcpListener.onError(CallBarringEditPreference.this, RESPONSE_ERROR);
} else {
// corresponding class
mCallBarringInfo.status = getStatus(infoArray[0], infoArray[1], mServiceClass);
if (mNeedEcho){
handleCallBarringResult(mCallBarringInfo);
} else{
setPassWord(null);
}
CharSequence s = null;
// Show an alert if we got a success response but
// with unexpected values.
// Currently only handle the fail-to-disable case
// since we haven't observed fail-to-enable.
if (msg.arg2 == MESSAGE_SET_LOCK){
if (msg.arg1 == CommandsInterface.CB_ACTION_DISABLE && mCallBarringInfo.status == 1) {
switch (mReason) {
case CommandsInterface.CB_REASON_AO:
s = getContext().getText(R.string.disable_ao_forbidden);
break;
case CommandsInterface.CB_REASON_OI:
s = getContext().getText(R.string.disable_oi_forbidden);
break;
case CommandsInterface.CB_REASON_OX:
s = getContext().getText(R.string.disable_ox_forbidden);
break;
case CommandsInterface.CB_REASON_AI:
s = getContext().getText(R.string.disable_ai_forbidden);
break;
case CommandsInterface.CB_REASON_IR:
s = getContext().getText(R.string.disable_ir_forbidden);
break;
default: // not reachable
s = getContext().getText(R.string.disable_ao_forbidden);
}
}
if (msg.arg1 == CommandsInterface.CB_ACTION_ENABLE && mCallBarringInfo.status == 0) {
switch (mReason) {
case CommandsInterface.CB_REASON_AO:
s = getContext().getText(R.string.enable_ao_forbidden);
break;
case CommandsInterface.CB_REASON_OI:
s = getContext().getText(R.string.enable_oi_forbidden);
break;
case CommandsInterface.CB_REASON_OX:
s = getContext().getText(R.string.enable_ox_forbidden);
break;
case CommandsInterface.CB_REASON_AI:
s = getContext().getText(R.string.enable_ai_forbidden);
break;
case CommandsInterface.CB_REASON_IR:
s = getContext().getText(R.string.enable_ir_forbidden);
break;
case CommandsInterface.CB_REASON_AB:
s = getContext().getText(R.string.enable_ab_forbidden);
break;
default: // not reachable
s = getContext().getText(R.string.enable_ao_forbidden);
}
}
if (s != null){
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setNeutralButton(R.string.close_dialog, null);
builder.setTitle(getContext().getText(R.string.error_updating_title));
builder.setMessage(s);
builder.setCancelable(true);
builder.create().show();
}
}
}
}
}
// Now whether or not we got a new number, reset our enabled
// summary text since it may have been replaced by an empty
// placeholder.
if (mNeedEcho){
updateSummaryText();
}
}
private void handleSetCBResponse(Message msg) {
AsyncResult ar = (AsyncResult) msg.obj;
CharSequence s = null;
if (ar == null)
return;
if (ar.exception != null) {
if (DBG) Log.d(LOG_TAG, "handleSetCBResponse: ar.exception=" + ar.exception);
tcpListener.onFinished(CallBarringEditPreference.this, false);
setPassWord(null);
s = getContext().getText(R.string.cb_error);
if (s != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setNeutralButton(R.string.close_dialog, null);
builder.setTitle(getContext().getText(R.string.error_updating_title));
builder.setMessage(s);
builder.setCancelable(true);
builder.create().show();
}
} else {
tcpListener.onFinished(CallBarringEditPreference.this, false);
mListener.onChange(CallBarringEditPreference.this,mReason);
}
}
}
}