blob: 00407f3ab33ba639f9509b59b71972fa4f309c28 [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001package com.android.phone;
2
SongFerngWang0e767992021-03-31 22:08:45 +08003import static com.android.phone.TimeConsumingPreferenceActivity.EXCEPTION_ERROR;
SongFerngWangebda2c52022-01-11 15:28:38 +08004import static com.android.phone.TimeConsumingPreferenceActivity.FDN_CHECK_FAILURE;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
6
7import android.content.Context;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07008import android.os.Handler;
9import android.os.Message;
SongFerngWangcf10dc92022-01-13 19:00:22 +080010import android.os.PersistableBundle;
fionaxue46e69f2017-04-27 14:32:46 -070011import android.preference.SwitchPreference;
SongFerngWangcf10dc92022-01-13 19:00:22 +080012import android.telephony.CarrierConfigManager;
SongFerngWang0e767992021-03-31 22:08:45 +080013import android.telephony.TelephonyManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070014import android.util.AttributeSet;
15import android.util.Log;
16
Aravind Sreekumarc94dea82018-04-10 15:34:32 -070017import com.android.internal.telephony.Phone;
18
SongFerngWang0e767992021-03-31 22:08:45 +080019import java.util.concurrent.Executors;
SongFerngWangcf10dc92022-01-13 19:00:22 +080020import java.util.concurrent.ScheduledExecutorService;
21import java.util.concurrent.TimeUnit;
22import java.util.function.Consumer;
SongFerngWang0e767992021-03-31 22:08:45 +080023
fionaxue46e69f2017-04-27 14:32:46 -070024public class CallWaitingSwitchPreference extends SwitchPreference {
25 private static final String LOG_TAG = "CallWaitingSwitchPreference";
SongFerngWangcf10dc92022-01-13 19:00:22 +080026 private static final int DELAY_MILLIS_FOR_USSD = 1000;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070027 private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
28
29 private final MyHandler mHandler = new MyHandler();
Andrew Lee2b36ba22014-11-05 17:08:49 -080030 private Phone mPhone;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070031 private TimeConsumingPreferenceListener mTcpListener;
SongFerngWangcf10dc92022-01-13 19:00:22 +080032 private ScheduledExecutorService mExecutor;
SongFerngWang0e767992021-03-31 22:08:45 +080033 private TelephonyManager mTelephonyManager;
34 private boolean mIsDuringUpdateProcess = false;
35 private int mUpdateStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
36 private int mQueryStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
SongFerngWangcf10dc92022-01-13 19:00:22 +080037 private boolean mUssdMode = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070038
fionaxue46e69f2017-04-27 14:32:46 -070039 public CallWaitingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -070040 super(context, attrs, defStyle);
Santos Cordon7d4ddf62013-07-10 11:58:08 -070041 }
42
fionaxue46e69f2017-04-27 14:32:46 -070043 public CallWaitingSwitchPreference(Context context, AttributeSet attrs) {
44 this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
Santos Cordon7d4ddf62013-07-10 11:58:08 -070045 }
46
fionaxue46e69f2017-04-27 14:32:46 -070047 public CallWaitingSwitchPreference(Context context) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -070048 this(context, null);
49 }
50
Andrew Lee2b36ba22014-11-05 17:08:49 -080051 /* package */ void init(
52 TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
53 mPhone = phone;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070054 mTcpListener = listener;
SongFerngWangcf10dc92022-01-13 19:00:22 +080055 mExecutor = Executors.newSingleThreadScheduledExecutor();
SongFerngWang0e767992021-03-31 22:08:45 +080056 mTelephonyManager = getContext().getSystemService(
57 TelephonyManager.class).createForSubscriptionId(phone.getSubId());
SongFerngWangcf10dc92022-01-13 19:00:22 +080058 CarrierConfigManager configManager = getContext().getSystemService(
59 CarrierConfigManager.class);
60 PersistableBundle bundle = configManager.getConfigForSubId(phone.getSubId());
61 mUssdMode = (bundle != null) ? bundle.getBoolean(
62 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false) : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070063
64 if (!skipReading) {
SongFerngWang0e767992021-03-31 22:08:45 +080065 Log.d(LOG_TAG, "init getCallWaitingStatus");
66 mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
Santos Cordon7d4ddf62013-07-10 11:58:08 -070067 if (mTcpListener != null) {
68 mTcpListener.onStarted(this, true);
69 }
70 }
71 }
72
SongFerngWang0e767992021-03-31 22:08:45 +080073 private void queryStatusCallBack(int result) {
74 Log.d(LOG_TAG, "queryStatusCallBack: CW state " + result);
75 mQueryStatus = result;
76 mHandler.sendMessage(mHandler.obtainMessage(MyHandler.MESSAGE_UPDATE_CALL_WAITING));
77 }
78
79 private void updateStatusCallBack(int result) {
80 Log.d(LOG_TAG, "updateStatusCallBack: CW state " + result + ", and re get");
81 mUpdateStatus = result;
SongFerngWangcf10dc92022-01-13 19:00:22 +080082 if (mUssdMode) {
83 Log.d(LOG_TAG, "updateStatusCallBack: USSD mode needs to wait 1s since Framework"
84 + " has the limitation");
85 Consumer<Integer> resultListener = this::queryStatusCallBack;
86 try {
87 mExecutor.schedule(new Runnable() {
88 @Override
89 public void run() {
90 mTelephonyManager.getCallWaitingStatus(mExecutor, resultListener);
91 }
92 }, DELAY_MILLIS_FOR_USSD, TimeUnit.MILLISECONDS);
93 } catch (Exception e) {
94 Log.d(LOG_TAG, "Exception while waiting: " + e);
95 }
96 } else {
97 mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
98 }
SongFerngWang0e767992021-03-31 22:08:45 +080099 }
100
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700101 @Override
102 protected void onClick() {
103 super.onClick();
SongFerngWang0e767992021-03-31 22:08:45 +0800104 mTelephonyManager.setCallWaitingEnabled(isChecked(), mExecutor, this::updateStatusCallBack);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700105 if (mTcpListener != null) {
SongFerngWang0e767992021-03-31 22:08:45 +0800106 mIsDuringUpdateProcess = true;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700107 mTcpListener.onStarted(this, false);
108 }
109 }
110
111 private class MyHandler extends Handler {
SongFerngWang0e767992021-03-31 22:08:45 +0800112 static final int MESSAGE_UPDATE_CALL_WAITING = 0;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700113
114 @Override
115 public void handleMessage(Message msg) {
116 switch (msg.what) {
SongFerngWang0e767992021-03-31 22:08:45 +0800117 case MESSAGE_UPDATE_CALL_WAITING:
118 updateUi();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700119 break;
120 }
121 }
122
SongFerngWang0e767992021-03-31 22:08:45 +0800123 private void updateUi() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700124 if (mTcpListener != null) {
SongFerngWang0e767992021-03-31 22:08:45 +0800125 if (mIsDuringUpdateProcess) {
fionaxue46e69f2017-04-27 14:32:46 -0700126 mTcpListener.onFinished(CallWaitingSwitchPreference.this, false);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700127 } else {
fionaxue46e69f2017-04-27 14:32:46 -0700128 mTcpListener.onFinished(CallWaitingSwitchPreference.this, true);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700129 }
130 }
131
SongFerngWangebda2c52022-01-11 15:28:38 +0800132 if (mQueryStatus != TelephonyManager.CALL_WAITING_STATUS_ENABLED
133 && mQueryStatus != TelephonyManager.CALL_WAITING_STATUS_DISABLED
134 && mQueryStatus != TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR) {
135 Log.d(LOG_TAG, "handleGetCallWaitingResponse: Exception:" + mQueryStatus);
136 int error = EXCEPTION_ERROR;
137 switch (mQueryStatus) {
138 case TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE:
139 error = FDN_CHECK_FAILURE;
140 break;
141 default:
142 error = EXCEPTION_ERROR;
143 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700144 }
SongFerngWangebda2c52022-01-11 15:28:38 +0800145 if (mTcpListener != null) {
146 mTcpListener.onError(CallWaitingSwitchPreference.this, error);
147 }
148 } else if (mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR
149 || (mIsDuringUpdateProcess && (
150 mUpdateStatus != TelephonyManager.CALL_WAITING_STATUS_ENABLED
151 && mUpdateStatus != TelephonyManager.CALL_WAITING_STATUS_DISABLED))) {
152 Log.d(LOG_TAG, "handleSetCallWaitingResponse: Exception");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700153 if (mTcpListener != null) {
fionaxue46e69f2017-04-27 14:32:46 -0700154 mTcpListener.onError(CallWaitingSwitchPreference.this, RESPONSE_ERROR);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700155 }
156 } else {
SongFerngWang0e767992021-03-31 22:08:45 +0800157 if (mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_ENABLED) {
158 setChecked(true);
159 } else {
160 setChecked(false);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700161 }
162 }
SongFerngWang0e767992021-03-31 22:08:45 +0800163 mIsDuringUpdateProcess = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700164 }
165 }
166}