1 package com.android.phone;
2 
3 import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
4 
5 import android.content.Context;
6 import android.os.AsyncResult;
7 import android.os.Handler;
8 import android.os.Message;
9 import android.preference.ListPreference;
10 import android.telephony.CarrierConfigManager;
11 import android.util.AttributeSet;
12 import android.util.Log;
13 
14 import com.android.internal.telephony.CommandException;
15 import com.android.internal.telephony.CommandsInterface;
16 import com.android.internal.telephony.Phone;
17 
18 /**
19  * {@link ListPreference} for CLIR (Calling Line Identification Restriction).
20  * Right now this is used for "Caller ID" setting.
21  */
22 public class CLIRListPreference extends ListPreference {
23     private static final String LOG_TAG = "CLIRListPreference";
24     private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
25 
26     private final MyHandler mHandler = new MyHandler();
27     private Phone mPhone;
28     private TimeConsumingPreferenceListener mTcpListener;
29 
30     private final String[] mEntries = getContext().getResources()
31             .getStringArray(R.array.clir_display_values);
32     private final String[] mValues = getContext().getResources()
33             .getStringArray(R.array.clir_values);
34     private boolean mConfigSupportNetworkDefault;
35 
36     int clirArray[];
37 
CLIRListPreference(Context context, AttributeSet attrs)38     public CLIRListPreference(Context context, AttributeSet attrs) {
39         super(context, attrs);
40     }
41 
CLIRListPreference(Context context)42     public CLIRListPreference(Context context) {
43         this(context, null);
44     }
45 
46     @Override
onDialogClosed(boolean positiveResult)47     protected void onDialogClosed(boolean positiveResult) {
48         super.onDialogClosed(positiveResult);
49 
50         if (positiveResult && (getValue() != null)) {
51             mPhone.setOutgoingCallerIdDisplay(convertValueToCLIRMode(getValue()),
52                     mHandler.obtainMessage(MyHandler.MESSAGE_SET_CLIR));
53             if (mTcpListener != null) {
54                 mTcpListener.onStarted(this, false);
55             }
56         } else {
57             Log.d(LOG_TAG, String.format("onDialogClosed: positiveResult=%b value=%s -- do nothing",
58                         positiveResult, getValue()));
59         }
60     }
61 
init( TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone)62     /* package */ void init(
63             TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
64         mPhone = phone;
65         mTcpListener = listener;
66         mConfigSupportNetworkDefault = PhoneGlobals.getInstance()
67                 .getCarrierConfigForSubId(mPhone.getSubId())
68                 .getBoolean(CarrierConfigManager.KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL);
69         // When "Network default" is not supported, create entries with remaining two values.
70         if (!mConfigSupportNetworkDefault) {
71             String[] noNetworkDefaultEntries = {mEntries[CommandsInterface.CLIR_INVOCATION],
72                     mEntries[CommandsInterface.CLIR_SUPPRESSION]};
73             String[] noNetworkDefaultValues = {mValues[CommandsInterface.CLIR_INVOCATION],
74                     mValues[CommandsInterface.CLIR_SUPPRESSION]};
75             setEntries(noNetworkDefaultEntries);
76             setEntryValues(noNetworkDefaultValues);
77         }
78 
79         if (!skipReading) {
80             Log.i(LOG_TAG, "init: requesting CLIR");
81             mPhone.getOutgoingCallerIdDisplay(mHandler.obtainMessage(MyHandler.MESSAGE_GET_CLIR,
82                     MyHandler.MESSAGE_GET_CLIR, MyHandler.MESSAGE_GET_CLIR));
83             if (mTcpListener != null) {
84                 mTcpListener.onStarted(this, true);
85             }
86         }
87     }
88 
handleGetCLIRResult(int tmpClirArray[])89     /* package */ void handleGetCLIRResult(int tmpClirArray[]) {
90         clirArray = tmpClirArray;
91         final boolean enabled =
92                 tmpClirArray[1] == 1 || tmpClirArray[1] == 3 || tmpClirArray[1] == 4;
93         setEnabled(enabled);
94 
95         // set the value of the preference based upon the clirArgs.
96         int value = CommandsInterface.CLIR_DEFAULT;
97         switch (tmpClirArray[1]) {
98             case 1: // Permanently provisioned
99             case 3: // Temporary presentation disallowed
100             case 4: // Temporary presentation allowed
101                 switch (tmpClirArray[0]) {
102                     case 1: // CLIR invoked
103                         value = CommandsInterface.CLIR_INVOCATION;
104                         break;
105                     case 2: // CLIR suppressed
106                         value = CommandsInterface.CLIR_SUPPRESSION;
107                         break;
108                     case 0: // Network default
109                     default:
110                         value = CommandsInterface.CLIR_DEFAULT;
111                         break;
112                 }
113                 break;
114             case 0: // Not Provisioned
115             case 2: // Unknown (network error, etc)
116             default:
117                 value = CommandsInterface.CLIR_DEFAULT;
118                 break;
119         }
120         value = (!mConfigSupportNetworkDefault && value == CommandsInterface.CLIR_DEFAULT)
121                 ? CommandsInterface.CLIR_SUPPRESSION : value;
122 
123         setValue(mValues[value]);
124 
125         // set the string summary to reflect the value
126         int summary = R.string.sum_default_caller_id;
127         switch (value) {
128             case CommandsInterface.CLIR_SUPPRESSION:
129                 summary = R.string.sum_show_caller_id;
130                 break;
131             case CommandsInterface.CLIR_INVOCATION:
132                 summary = R.string.sum_hide_caller_id;
133                 break;
134             case CommandsInterface.CLIR_DEFAULT:
135                 summary = R.string.sum_default_caller_id;
136                 break;
137         }
138         setSummary(summary);
139     }
140 
141     /**
142      * When "Network default" is hidden, UI list index(0-1) doesn't match CLIR Mode(0-2 for Modem).
143      * In order to send request to Modem, it is necessary to convert value to CLIR Mode.
144      * ("Hide" = CommandsInterface.CLIR_INVOCATION, "Show" = CommandsInterface.CLIR_SUPPRESSION)
145      *
146      * @param String of entry value.
147      * @return "CommandInterface.CLIR_*" for Modem.
148      */
convertValueToCLIRMode(String value)149     private int convertValueToCLIRMode(String value) {
150         if (mValues[CommandsInterface.CLIR_INVOCATION].equals(value)) {
151             return CommandsInterface.CLIR_INVOCATION;
152         } else if (mValues[CommandsInterface.CLIR_SUPPRESSION].equals(value)) {
153             return CommandsInterface.CLIR_SUPPRESSION;
154         } else {
155             return mConfigSupportNetworkDefault ? CommandsInterface.CLIR_DEFAULT :
156                     CommandsInterface.CLIR_SUPPRESSION;
157         }
158     }
159 
160     private class MyHandler extends Handler {
161         static final int MESSAGE_GET_CLIR = 0;
162         static final int MESSAGE_SET_CLIR = 1;
163 
164         @Override
handleMessage(Message msg)165         public void handleMessage(Message msg) {
166             switch (msg.what) {
167                 case MESSAGE_GET_CLIR:
168                     handleGetCLIRResponse(msg);
169                     break;
170                 case MESSAGE_SET_CLIR:
171                     handleSetCLIRResponse(msg);
172                     break;
173             }
174         }
175 
handleGetCLIRResponse(Message msg)176         private void handleGetCLIRResponse(Message msg) {
177             AsyncResult ar = (AsyncResult) msg.obj;
178 
179             if (msg.arg2 == MESSAGE_SET_CLIR) {
180                 mTcpListener.onFinished(CLIRListPreference.this, false);
181             } else {
182                 mTcpListener.onFinished(CLIRListPreference.this, true);
183             }
184             clirArray = null;
185             if (ar.exception != null) {
186                 Log.i(LOG_TAG, "handleGetCLIRResponse: ar.exception=" + ar.exception);
187                 mTcpListener.onException(CLIRListPreference.this, (CommandException) ar.exception);
188             } else if (ar.userObj instanceof Throwable) {
189                 Log.i(LOG_TAG, "handleGetCLIRResponse: ar.throwable=" + ar.userObj);
190                 mTcpListener.onError(CLIRListPreference.this, RESPONSE_ERROR);
191             } else {
192                 int clirArray[] = (int[]) ar.result;
193                 if (clirArray.length != 2) {
194                     mTcpListener.onError(CLIRListPreference.this, RESPONSE_ERROR);
195                 } else {
196                     Log.i(LOG_TAG, "handleGetCLIRResponse: CLIR successfully queried,"
197                                 + " clirArray[0]=" + clirArray[0]
198                                 + ", clirArray[1]=" + clirArray[1]);
199                     handleGetCLIRResult(clirArray);
200                 }
201             }
202         }
203 
handleSetCLIRResponse(Message msg)204         private void handleSetCLIRResponse(Message msg) {
205             AsyncResult ar = (AsyncResult) msg.obj;
206 
207             if (ar.exception != null) {
208                 if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: ar.exception="+ar.exception);
209                 //setEnabled(false);
210             }
211             if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: re get");
212 
213             mPhone.getOutgoingCallerIdDisplay(obtainMessage(MESSAGE_GET_CLIR,
214                     MESSAGE_SET_CLIR, MESSAGE_SET_CLIR, ar.exception));
215         }
216     }
217 }
218