blob: b8e3250e0b50203619f8a5231db0576af2d44dc3 [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
Pooja Jain93124702019-11-19 18:00:46 +053038import com.android.internal.telephony.CommandsInterface;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080039import com.android.internal.telephony.CommandException;
40import com.android.internal.telephony.Phone;
41import com.android.internal.telephony.PhoneFactory;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080042import com.android.phone.settings.fdn.EditPinPreference;
43
44import java.lang.ref.WeakReference;
45
46/**
47 * This preference represents the status of call barring options, enabling/disabling
48 * the call barring option will prompt the user for the current password.
49 */
50public class CallBarringEditPreference extends EditPinPreference {
51 private static final String LOG_TAG = "CallBarringEditPreference";
52 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
53
54 private String mFacility;
55 boolean mIsActivated = false;
56 private CharSequence mEnableText;
57 private CharSequence mDisableText;
58 private CharSequence mSummaryOn;
59 private CharSequence mSummaryOff;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080060 private int mButtonClicked;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080061 private final MyHandler mHandler = new MyHandler(this);
62 private Phone mPhone;
63 private TimeConsumingPreferenceListener mTcpListener;
64
65 private static final int PW_LENGTH = 4;
66
67 /**
68 * CallBarringEditPreference constructor.
69 *
70 * @param context The context of view.
71 * @param attrs The attributes of the XML tag that is inflating EditTextPreference.
72 */
73 public CallBarringEditPreference(Context context, AttributeSet attrs) {
74 super(context, attrs);
75 // Get the summary settings, use CheckBoxPreference as the standard.
76 TypedArray typedArray = context.obtainStyledAttributes(attrs,
Meng Wang92ea32d2020-05-06 18:51:51 +000077 android.R.styleable.CheckBoxPreference, 0, 0);
78 mSummaryOn = typedArray.getString(android.R.styleable.CheckBoxPreference_summaryOn);
79 mSummaryOff = typedArray.getString(android.R.styleable.CheckBoxPreference_summaryOff);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080080 mDisableText = context.getText(R.string.disable);
81 mEnableText = context.getText(R.string.enable);
82 typedArray.recycle();
83
84 // Get default phone
85 mPhone = PhoneFactory.getDefaultPhone();
86
87 typedArray = context.obtainStyledAttributes(attrs,
88 R.styleable.CallBarringEditPreference, 0, R.style.EditPhoneNumberPreference);
89 mFacility = typedArray.getString(R.styleable.CallBarringEditPreference_facility);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +080090 typedArray.recycle();
91 }
92
93 /**
94 * CallBarringEditPreference constructor.
95 *
96 * @param context The context of view.
97 */
98 public CallBarringEditPreference(Context context) {
99 this(context, null);
100 }
101
102 void init(TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
103 if (DBG) {
104 Log.d(LOG_TAG, "init: phone id = " + phone.getPhoneId());
105 }
106 mPhone = phone;
107
108 mTcpListener = listener;
109 if (!skipReading) {
110 // Query call barring status
111 mPhone.getCallBarring(mFacility, "", mHandler.obtainMessage(
Pooja Jain93124702019-11-19 18:00:46 +0530112 MyHandler.MESSAGE_GET_CALL_BARRING), CommandsInterface.SERVICE_CLASS_VOICE);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800113 if (mTcpListener != null) {
114 mTcpListener.onStarted(this, true);
115 }
116 }
117 }
118
119 @Override
120 public void onClick(DialogInterface dialog, int which) {
121 super.onClick(dialog, which);
122 mButtonClicked = which;
123 }
124
125 @Override
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800126 protected void showDialog(Bundle state) {
Suresh Koletib74bac72019-12-16 18:11:40 +0530127 setDialogMessage(getContext().getString(R.string.messageCallBarring));
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800128 super.showDialog(state);
129 }
130
131 @Override
132 protected void onBindView(View view) {
133 super.onBindView(view);
134
135 // Sync the summary view
136 TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
137 if (summaryView != null) {
138 CharSequence sum;
139 int vis;
140
141 // Set summary depending upon mode
142 if (mIsActivated) {
143 sum = (mSummaryOn == null) ? getSummary() : mSummaryOn;
144 } else {
145 sum = (mSummaryOff == null) ? getSummary() : mSummaryOff;
146 }
147
148 if (sum != null) {
149 summaryView.setText(sum);
150 vis = View.VISIBLE;
151 } else {
152 vis = View.GONE;
153 }
154
155 if (vis != summaryView.getVisibility()) {
156 summaryView.setVisibility(vis);
157 }
158 }
159 }
160
161 @Override
162 protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
163 builder.setPositiveButton(null, null);
164 builder.setNeutralButton(mIsActivated ? mDisableText : mEnableText, this);
165 }
166
167 @Override
168 protected void onBindDialogView(View view) {
169 super.onBindDialogView(view);
170 // Default the button clicked to be the cancel button.
171 mButtonClicked = DialogInterface.BUTTON_NEGATIVE;
172
173 final EditText editText = (EditText) view.findViewById(android.R.id.edit);
174 if (editText != null) {
175 editText.setSingleLine(true);
176 editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
177 editText.setKeyListener(DigitsKeyListener.getInstance());
178
Suresh Koletib74bac72019-12-16 18:11:40 +0530179 editText.setVisibility(View.VISIBLE);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800180 }
181 }
182
183 @Override
184 protected void onDialogClosed(boolean positiveResult) {
185 super.onDialogClosed(positiveResult);
186 if (DBG) {
187 Log.d(LOG_TAG, "onDialogClosed: mButtonClicked=" + mButtonClicked + ", positiveResult="
188 + positiveResult);
189 }
190 if (mButtonClicked != DialogInterface.BUTTON_NEGATIVE) {
Suresh Koletib74bac72019-12-16 18:11:40 +0530191 String password = getEditText().getText().toString();
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800192
Suresh Koletib74bac72019-12-16 18:11:40 +0530193 // Check if the password is valid.
194 if (password == null || password.length() != PW_LENGTH) {
195 Toast.makeText(getContext(),
196 getContext().getString(R.string.call_barring_right_pwd_number),
197 Toast.LENGTH_SHORT).show();
198 return;
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800199 }
200
201 if (DBG) {
202 Log.d(LOG_TAG, "onDialogClosed: password=" + password);
203 }
204 // Send set call barring message to RIL layer.
205 mPhone.setCallBarring(mFacility, !mIsActivated, password,
Pooja Jain93124702019-11-19 18:00:46 +0530206 mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_BARRING),
207 CommandsInterface.SERVICE_CLASS_VOICE);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800208 if (mTcpListener != null) {
209 mTcpListener.onStarted(this, false);
210 }
211 }
212 }
213
214 void handleCallBarringResult(boolean status) {
215 mIsActivated = status;
216 if (DBG) {
217 Log.d(LOG_TAG, "handleCallBarringResult: mIsActivated=" + mIsActivated);
218 }
219 }
220
221 void updateSummaryText() {
222 notifyChanged();
223 notifyDependencyChange(shouldDisableDependents());
224 }
225
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800226 @Override
227 public boolean shouldDisableDependents() {
228 return mIsActivated;
229 }
230
231 // Message protocol:
232 // what: get vs. set
233 // arg1: action -- register vs. disable
234 // arg2: get vs. set for the preceding request
235 private static class MyHandler extends Handler {
236 private static final int MESSAGE_GET_CALL_BARRING = 0;
237 private static final int MESSAGE_SET_CALL_BARRING = 1;
238
239 private final WeakReference<CallBarringEditPreference> mCallBarringEditPreference;
240
241 private MyHandler(CallBarringEditPreference callBarringEditPreference) {
242 mCallBarringEditPreference =
243 new WeakReference<CallBarringEditPreference>(callBarringEditPreference);
244 }
245
246 @Override
247 public void handleMessage(Message msg) {
248 switch (msg.what) {
249 case MESSAGE_GET_CALL_BARRING:
250 handleGetCallBarringResponse(msg);
251 break;
252 case MESSAGE_SET_CALL_BARRING:
253 handleSetCallBarringResponse(msg);
254 break;
255 default:
256 break;
257 }
258 }
259
260 // Handle the response message for query CB status.
261 private void handleGetCallBarringResponse(Message msg) {
262 final CallBarringEditPreference pref = mCallBarringEditPreference.get();
263 if (pref == null) {
264 return;
265 }
266
267 if (DBG) {
268 Log.d(LOG_TAG, "handleGetCallBarringResponse: done");
269 }
270
271 AsyncResult ar = (AsyncResult) msg.obj;
272
273 if (msg.arg2 == MESSAGE_SET_CALL_BARRING) {
274 pref.mTcpListener.onFinished(pref, false);
275 } else {
276 pref.mTcpListener.onFinished(pref, true);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800277 }
278
279 // Unsuccessful query for call barring.
280 if (ar.exception != null) {
281 if (DBG) {
282 Log.d(LOG_TAG, "handleGetCallBarringResponse: ar.exception=" + ar.exception);
283 }
284 pref.mTcpListener.onException(pref, (CommandException) ar.exception);
285 } else {
286 if (ar.userObj instanceof Throwable) {
287 pref.mTcpListener.onError(pref, RESPONSE_ERROR);
288 }
289 int[] ints = (int[]) ar.result;
290 if (ints.length == 0) {
291 if (DBG) {
292 Log.d(LOG_TAG, "handleGetCallBarringResponse: ar.result.length==0");
293 }
294 pref.setEnabled(false);
295 pref.mTcpListener.onError(pref, RESPONSE_ERROR);
296 } else {
297 pref.handleCallBarringResult(ints[0] != 0);
298 if (DBG) {
299 Log.d(LOG_TAG,
300 "handleGetCallBarringResponse: CB state successfully queried: "
301 + ints[0]);
302 }
303 }
304 }
305 // Update call barring status.
306 pref.updateSummaryText();
307 }
308
309 // Handle the response message for CB settings.
310 private void handleSetCallBarringResponse(Message msg) {
311 final CallBarringEditPreference pref = mCallBarringEditPreference.get();
312 if (pref == null) {
313 return;
314 }
315
316 AsyncResult ar = (AsyncResult) msg.obj;
317
318 if (ar.exception != null || ar.userObj instanceof Throwable) {
319 if (DBG) {
320 Log.d(LOG_TAG, "handleSetCallBarringResponse: ar.exception=" + ar.exception);
321 }
322 }
323 if (DBG) {
324 Log.d(LOG_TAG, "handleSetCallBarringResponse: re-get call barring option");
325 }
326 pref.mPhone.getCallBarring(
327 pref.mFacility,
328 "",
329 obtainMessage(MESSAGE_GET_CALL_BARRING, 0, MESSAGE_SET_CALL_BARRING,
330 ar.exception),
Pooja Jain93124702019-11-19 18:00:46 +0530331 CommandsInterface.SERVICE_CLASS_VOICE);
Aida Takeshi7c3b4a32016-08-11 13:42:24 +0800332 }
333 }
334}