blob: 609488ce0b7204242fca2b1d98bdf9d7efc6fb22 [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;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
5
6import android.content.Context;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07007import android.os.Handler;
8import android.os.Message;
SongFerngWangcf10dc92022-01-13 19:00:22 +08009import android.os.PersistableBundle;
fionaxue46e69f2017-04-27 14:32:46 -070010import android.preference.SwitchPreference;
SongFerngWangcf10dc92022-01-13 19:00:22 +080011import android.telephony.CarrierConfigManager;
SongFerngWang0e767992021-03-31 22:08:45 +080012import android.telephony.TelephonyManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070013import android.util.AttributeSet;
14import android.util.Log;
15
Aravind Sreekumarc94dea82018-04-10 15:34:32 -070016import com.android.internal.telephony.Phone;
17
SongFerngWang0e767992021-03-31 22:08:45 +080018import java.util.concurrent.Executors;
SongFerngWangcf10dc92022-01-13 19:00:22 +080019import java.util.concurrent.ScheduledExecutorService;
20import java.util.concurrent.TimeUnit;
21import java.util.function.Consumer;
SongFerngWang0e767992021-03-31 22:08:45 +080022
fionaxue46e69f2017-04-27 14:32:46 -070023public class CallWaitingSwitchPreference extends SwitchPreference {
24 private static final String LOG_TAG = "CallWaitingSwitchPreference";
SongFerngWangcf10dc92022-01-13 19:00:22 +080025 private static final int DELAY_MILLIS_FOR_USSD = 1000;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070026 private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
27
28 private final MyHandler mHandler = new MyHandler();
Andrew Lee2b36ba22014-11-05 17:08:49 -080029 private Phone mPhone;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070030 private TimeConsumingPreferenceListener mTcpListener;
SongFerngWangcf10dc92022-01-13 19:00:22 +080031 private ScheduledExecutorService mExecutor;
SongFerngWang0e767992021-03-31 22:08:45 +080032 private TelephonyManager mTelephonyManager;
33 private boolean mIsDuringUpdateProcess = false;
34 private int mUpdateStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
35 private int mQueryStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
SongFerngWangcf10dc92022-01-13 19:00:22 +080036 private boolean mUssdMode = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070037
fionaxue46e69f2017-04-27 14:32:46 -070038 public CallWaitingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -070039 super(context, attrs, defStyle);
Santos Cordon7d4ddf62013-07-10 11:58:08 -070040 }
41
fionaxue46e69f2017-04-27 14:32:46 -070042 public CallWaitingSwitchPreference(Context context, AttributeSet attrs) {
43 this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
Santos Cordon7d4ddf62013-07-10 11:58:08 -070044 }
45
fionaxue46e69f2017-04-27 14:32:46 -070046 public CallWaitingSwitchPreference(Context context) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -070047 this(context, null);
48 }
49
Andrew Lee2b36ba22014-11-05 17:08:49 -080050 /* package */ void init(
51 TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
52 mPhone = phone;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070053 mTcpListener = listener;
SongFerngWangcf10dc92022-01-13 19:00:22 +080054 mExecutor = Executors.newSingleThreadScheduledExecutor();
SongFerngWang0e767992021-03-31 22:08:45 +080055 mTelephonyManager = getContext().getSystemService(
56 TelephonyManager.class).createForSubscriptionId(phone.getSubId());
SongFerngWangcf10dc92022-01-13 19:00:22 +080057 CarrierConfigManager configManager = getContext().getSystemService(
58 CarrierConfigManager.class);
59 PersistableBundle bundle = configManager.getConfigForSubId(phone.getSubId());
60 mUssdMode = (bundle != null) ? bundle.getBoolean(
61 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false) : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070062
63 if (!skipReading) {
SongFerngWang0e767992021-03-31 22:08:45 +080064 Log.d(LOG_TAG, "init getCallWaitingStatus");
65 mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
Santos Cordon7d4ddf62013-07-10 11:58:08 -070066 if (mTcpListener != null) {
67 mTcpListener.onStarted(this, true);
68 }
69 }
70 }
71
SongFerngWang0e767992021-03-31 22:08:45 +080072 private void queryStatusCallBack(int result) {
73 Log.d(LOG_TAG, "queryStatusCallBack: CW state " + result);
74 mQueryStatus = result;
75 mHandler.sendMessage(mHandler.obtainMessage(MyHandler.MESSAGE_UPDATE_CALL_WAITING));
76 }
77
78 private void updateStatusCallBack(int result) {
79 Log.d(LOG_TAG, "updateStatusCallBack: CW state " + result + ", and re get");
80 mUpdateStatus = result;
SongFerngWangcf10dc92022-01-13 19:00:22 +080081 if (mUssdMode) {
82 Log.d(LOG_TAG, "updateStatusCallBack: USSD mode needs to wait 1s since Framework"
83 + " has the limitation");
84 Consumer<Integer> resultListener = this::queryStatusCallBack;
85 try {
86 mExecutor.schedule(new Runnable() {
87 @Override
88 public void run() {
89 mTelephonyManager.getCallWaitingStatus(mExecutor, resultListener);
90 }
91 }, DELAY_MILLIS_FOR_USSD, TimeUnit.MILLISECONDS);
92 } catch (Exception e) {
93 Log.d(LOG_TAG, "Exception while waiting: " + e);
94 }
95 } else {
96 mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
97 }
SongFerngWang0e767992021-03-31 22:08:45 +080098 }
99
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700100 @Override
101 protected void onClick() {
102 super.onClick();
SongFerngWang0e767992021-03-31 22:08:45 +0800103 mTelephonyManager.setCallWaitingEnabled(isChecked(), mExecutor, this::updateStatusCallBack);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700104 if (mTcpListener != null) {
SongFerngWang0e767992021-03-31 22:08:45 +0800105 mIsDuringUpdateProcess = true;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700106 mTcpListener.onStarted(this, false);
107 }
108 }
109
110 private class MyHandler extends Handler {
SongFerngWang0e767992021-03-31 22:08:45 +0800111 static final int MESSAGE_UPDATE_CALL_WAITING = 0;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700112
113 @Override
114 public void handleMessage(Message msg) {
115 switch (msg.what) {
SongFerngWang0e767992021-03-31 22:08:45 +0800116 case MESSAGE_UPDATE_CALL_WAITING:
117 updateUi();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700118 break;
119 }
120 }
121
SongFerngWang0e767992021-03-31 22:08:45 +0800122 private void updateUi() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700123 if (mTcpListener != null) {
SongFerngWang0e767992021-03-31 22:08:45 +0800124 if (mIsDuringUpdateProcess) {
fionaxue46e69f2017-04-27 14:32:46 -0700125 mTcpListener.onFinished(CallWaitingSwitchPreference.this, false);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700126 } else {
fionaxue46e69f2017-04-27 14:32:46 -0700127 mTcpListener.onFinished(CallWaitingSwitchPreference.this, true);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700128 }
129 }
130
SongFerngWang0e767992021-03-31 22:08:45 +0800131 if (mIsDuringUpdateProcess && (
132 mUpdateStatus == TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED
133 || mUpdateStatus
134 == TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR)) {
135 Log.d(LOG_TAG, "handleSetCallWaitingResponse: Exception");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700136 if (mTcpListener != null) {
SongFerngWang0e767992021-03-31 22:08:45 +0800137 mTcpListener.onError(CallWaitingSwitchPreference.this, EXCEPTION_ERROR);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700138 }
SongFerngWang0e767992021-03-31 22:08:45 +0800139 } else if (mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED
140 || mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR) {
141 Log.d(LOG_TAG, "handleGetCallWaitingResponse: Exception");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700142 if (mTcpListener != null) {
fionaxue46e69f2017-04-27 14:32:46 -0700143 mTcpListener.onError(CallWaitingSwitchPreference.this, RESPONSE_ERROR);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700144 }
145 } else {
SongFerngWang0e767992021-03-31 22:08:45 +0800146 if (mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_ENABLED) {
147 setChecked(true);
148 } else {
149 setChecked(false);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700150 }
151 }
SongFerngWang0e767992021-03-31 22:08:45 +0800152 mIsDuringUpdateProcess = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700153 }
154 }
155}