blob: d54b89bfd378fc324c202d3c415820caa32c9e8e [file] [log] [blame]
Aida Takeshi7c3b4a32016-08-11 13:42:24 +08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
19import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
20
21import android.app.AlertDialog;
22import android.content.Context;
23import android.content.DialogInterface;
24import android.content.res.TypedArray;
25import android.os.AsyncResult;
26import android.os.Bundle;
27import android.os.Handler;
28import android.os.Message;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080029import android.text.method.DigitsKeyListener;
30import android.text.method.PasswordTransformationMethod;
31import android.util.AttributeSet;
32import android.util.Log;
33import android.view.View;
34import android.widget.EditText;
35import android.widget.TextView;
36import android.widget.Toast;
37
38import com.android.internal.telephony.CommandException;
39import com.android.internal.telephony.Phone;
40import com.android.internal.telephony.PhoneFactory;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080041import com.android.phone.settings.fdn.EditPinPreference;
42
43import java.lang.ref.WeakReference;
44
45/**
46 * This preference represents the status of call barring options, enabling/disabling
47 * the call barring option will prompt the user for the current password.
48 */
49public class CallBarringEditPreference extends EditPinPreference {
50 private static final String LOG_TAG = "CallBarringEditPreference";
51 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
52
53 private String mFacility;
54 boolean mIsActivated = false;
55 private CharSequence mEnableText;
56 private CharSequence mDisableText;
57 private CharSequence mSummaryOn;
58 private CharSequence mSummaryOff;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080059 private int mButtonClicked;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080060 private final MyHandler mHandler = new MyHandler(this);
61 private Phone mPhone;
62 private TimeConsumingPreferenceListener mTcpListener;
63
64 private static final int PW_LENGTH = 4;
65
66 /**
67 * CallBarringEditPreference constructor.
68 *
69 * @param context The context of view.
70 * @param attrs The attributes of the XML tag that is inflating EditTextPreference.
71 */
72 public CallBarringEditPreference(Context context, AttributeSet attrs) {
73 super(context, attrs);
74 // Get the summary settings, use CheckBoxPreference as the standard.
75 TypedArray typedArray = context.obtainStyledAttributes(attrs,
76 android.R.styleable.CheckBoxPreference, 0, 0);
77 mSummaryOn = typedArray.getString(android.R.styleable.CheckBoxPreference_summaryOn);
78 mSummaryOff = typedArray.getString(android.R.styleable.CheckBoxPreference_summaryOff);
79 mDisableText = context.getText(R.string.disable);
80 mEnableText = context.getText(R.string.enable);
81 typedArray.recycle();
82
83 // Get default phone
84 mPhone = PhoneFactory.getDefaultPhone();
85
86 typedArray = context.obtainStyledAttributes(attrs,
87 R.styleable.CallBarringEditPreference, 0, R.style.EditPhoneNumberPreference);
88 mFacility = typedArray.getString(R.styleable.CallBarringEditPreference_facility);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080089 typedArray.recycle();
90 }
91
92 /**
93 * CallBarringEditPreference constructor.
94 *
95 * @param context The context of view.
96 */
97 public CallBarringEditPreference(Context context) {
98 this(context, null);
99 }
100
101 void init(TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
102 if (DBG) {
103 Log.d(LOG_TAG, "init: phone id = " + phone.getPhoneId());
104 }
105 mPhone = phone;
106
107 mTcpListener = listener;
108 if (!skipReading) {
109 // Query call barring status
110 mPhone.getCallBarring(mFacility, "", mHandler.obtainMessage(
111 MyHandler.MESSAGE_GET_CALL_BARRING), 0);
112 if (mTcpListener != null) {
113 mTcpListener.onStarted(this, true);
114 }
115 }
116 }
117
118 @Override
119 public void onClick(DialogInterface dialog, int which) {
120 super.onClick(dialog, which);
121 mButtonClicked = which;
122 }
123
124 @Override
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800125 protected void showDialog(Bundle state) {
Suresh Koletib74bac72019-12-16 18:11:40 +0530126 setDialogMessage(getContext().getString(R.string.messageCallBarring));
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800127 super.showDialog(state);
128 }
129
130 @Override
131 protected void onBindView(View view) {
132 super.onBindView(view);
133
134 // Sync the summary view
135 TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
136 if (summaryView != null) {
137 CharSequence sum;
138 int vis;
139
140 // Set summary depending upon mode
141 if (mIsActivated) {
142 sum = (mSummaryOn == null) ? getSummary() : mSummaryOn;
143 } else {
144 sum = (mSummaryOff == null) ? getSummary() : mSummaryOff;
145 }
146
147 if (sum != null) {
148 summaryView.setText(sum);
149 vis = View.VISIBLE;
150 } else {
151 vis = View.GONE;
152 }
153
154 if (vis != summaryView.getVisibility()) {
155 summaryView.setVisibility(vis);
156 }
157 }
158 }
159
160 @Override
161 protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
162 builder.setPositiveButton(null, null);
163 builder.setNeutralButton(mIsActivated ? mDisableText : mEnableText, this);
164 }
165
166 @Override
167 protected void onBindDialogView(View view) {
168 super.onBindDialogView(view);
169 // Default the button clicked to be the cancel button.
170 mButtonClicked = DialogInterface.BUTTON_NEGATIVE;
171
172 final EditText editText = (EditText) view.findViewById(android.R.id.edit);
173 if (editText != null) {
174 editText.setSingleLine(true);
175 editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
176 editText.setKeyListener(DigitsKeyListener.getInstance());
177
Suresh Koletib74bac72019-12-16 18:11:40 +0530178 editText.setVisibility(View.VISIBLE);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800179 }
180 }
181
182 @Override
183 protected void onDialogClosed(boolean positiveResult) {
184 super.onDialogClosed(positiveResult);
185 if (DBG) {
186 Log.d(LOG_TAG, "onDialogClosed: mButtonClicked=" + mButtonClicked + ", positiveResult="
187 + positiveResult);
188 }
189 if (mButtonClicked != DialogInterface.BUTTON_NEGATIVE) {
Suresh Koletib74bac72019-12-16 18:11:40 +0530190 String password = getEditText().getText().toString();
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800191
Suresh Koletib74bac72019-12-16 18:11:40 +0530192 // Check if the password is valid.
193 if (password == null || password.length() != PW_LENGTH) {
194 Toast.makeText(getContext(),
195 getContext().getString(R.string.call_barring_right_pwd_number),
196 Toast.LENGTH_SHORT).show();
197 return;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800198 }
199
200 if (DBG) {
201 Log.d(LOG_TAG, "onDialogClosed: password=" + password);
202 }
203 // Send set call barring message to RIL layer.
204 mPhone.setCallBarring(mFacility, !mIsActivated, password,
205 mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_BARRING), 0);
206 if (mTcpListener != null) {
207 mTcpListener.onStarted(this, false);
208 }
209 }
210 }
211
212 void handleCallBarringResult(boolean status) {
213 mIsActivated = status;
214 if (DBG) {
215 Log.d(LOG_TAG, "handleCallBarringResult: mIsActivated=" + mIsActivated);
216 }
217 }
218
219 void updateSummaryText() {
220 notifyChanged();
221 notifyDependencyChange(shouldDisableDependents());
222 }
223
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800224 @Override
225 public boolean shouldDisableDependents() {
226 return mIsActivated;
227 }
228
229 // Message protocol:
230 // what: get vs. set
231 // arg1: action -- register vs. disable
232 // arg2: get vs. set for the preceding request
233 private static class MyHandler extends Handler {
234 private static final int MESSAGE_GET_CALL_BARRING = 0;
235 private static final int MESSAGE_SET_CALL_BARRING = 1;
236
237 private final WeakReference<CallBarringEditPreference> mCallBarringEditPreference;
238
239 private MyHandler(CallBarringEditPreference callBarringEditPreference) {
240 mCallBarringEditPreference =
241 new WeakReference<CallBarringEditPreference>(callBarringEditPreference);
242 }
243
244 @Override
245 public void handleMessage(Message msg) {
246 switch (msg.what) {
247 case MESSAGE_GET_CALL_BARRING:
248 handleGetCallBarringResponse(msg);
249 break;
250 case MESSAGE_SET_CALL_BARRING:
251 handleSetCallBarringResponse(msg);
252 break;
253 default:
254 break;
255 }
256 }
257
258 // Handle the response message for query CB status.
259 private void handleGetCallBarringResponse(Message msg) {
260 final CallBarringEditPreference pref = mCallBarringEditPreference.get();
261 if (pref == null) {
262 return;
263 }
264
265 if (DBG) {
266 Log.d(LOG_TAG, "handleGetCallBarringResponse: done");
267 }
268
269 AsyncResult ar = (AsyncResult) msg.obj;
270
271 if (msg.arg2 == MESSAGE_SET_CALL_BARRING) {
272 pref.mTcpListener.onFinished(pref, false);
273 } else {
274 pref.mTcpListener.onFinished(pref, true);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800275 }
276
277 // Unsuccessful query for call barring.
278 if (ar.exception != null) {
279 if (DBG) {
280 Log.d(LOG_TAG, "handleGetCallBarringResponse: ar.exception=" + ar.exception);
281 }
282 pref.mTcpListener.onException(pref, (CommandException) ar.exception);
283 } else {
284 if (ar.userObj instanceof Throwable) {
285 pref.mTcpListener.onError(pref, RESPONSE_ERROR);
286 }
287 int[] ints = (int[]) ar.result;
288 if (ints.length == 0) {
289 if (DBG) {
290 Log.d(LOG_TAG, "handleGetCallBarringResponse: ar.result.length==0");
291 }
292 pref.setEnabled(false);
293 pref.mTcpListener.onError(pref, RESPONSE_ERROR);
294 } else {
295 pref.handleCallBarringResult(ints[0] != 0);
296 if (DBG) {
297 Log.d(LOG_TAG,
298 "handleGetCallBarringResponse: CB state successfully queried: "
299 + ints[0]);
300 }
301 }
302 }
303 // Update call barring status.
304 pref.updateSummaryText();
305 }
306
307 // Handle the response message for CB settings.
308 private void handleSetCallBarringResponse(Message msg) {
309 final CallBarringEditPreference pref = mCallBarringEditPreference.get();
310 if (pref == null) {
311 return;
312 }
313
314 AsyncResult ar = (AsyncResult) msg.obj;
315
316 if (ar.exception != null || ar.userObj instanceof Throwable) {
317 if (DBG) {
318 Log.d(LOG_TAG, "handleSetCallBarringResponse: ar.exception=" + ar.exception);
319 }
320 }
321 if (DBG) {
322 Log.d(LOG_TAG, "handleSetCallBarringResponse: re-get call barring option");
323 }
324 pref.mPhone.getCallBarring(
325 pref.mFacility,
326 "",
327 obtainMessage(MESSAGE_GET_CALL_BARRING, 0, MESSAGE_SET_CALL_BARRING,
328 ar.exception),
329 0);
330 }
331 }
332}