Call waiting support USSD function

-Add USSD function
-Call waiting uses TelephonyManager's get/set methods
Bug: 112177857
Test: build pass. Manual test: set/get call waiting.

Change-Id: Ia03fd4ddef1defb1f0f9091c58ab0f1e43936457
diff --git a/src/com/android/phone/CallWaitingSwitchPreference.java b/src/com/android/phone/CallWaitingSwitchPreference.java
index 41442fe..01dd3b2 100644
--- a/src/com/android/phone/CallWaitingSwitchPreference.java
+++ b/src/com/android/phone/CallWaitingSwitchPreference.java
@@ -1,18 +1,21 @@
 package com.android.phone;
 
+import static com.android.phone.TimeConsumingPreferenceActivity.EXCEPTION_ERROR;
 import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
 
 import android.content.Context;
-import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.preference.SwitchPreference;
+import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 
-import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.Phone;
 
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
 public class CallWaitingSwitchPreference extends SwitchPreference {
     private static final String LOG_TAG = "CallWaitingSwitchPreference";
     private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
@@ -20,6 +23,11 @@
     private final MyHandler mHandler = new MyHandler();
     private Phone mPhone;
     private TimeConsumingPreferenceListener mTcpListener;
+    private Executor mExecutor;
+    private TelephonyManager mTelephonyManager;
+    private boolean mIsDuringUpdateProcess = false;
+    private int mUpdateStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
+    private int mQueryStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
 
     public CallWaitingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -37,101 +45,84 @@
             TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
         mPhone = phone;
         mTcpListener = listener;
+        mExecutor = Executors.newSingleThreadExecutor();
+        mTelephonyManager = getContext().getSystemService(
+                TelephonyManager.class).createForSubscriptionId(phone.getSubId());
 
         if (!skipReading) {
-            mPhone.getCallWaiting(mHandler.obtainMessage(MyHandler.MESSAGE_GET_CALL_WAITING,
-                    MyHandler.MESSAGE_GET_CALL_WAITING, MyHandler.MESSAGE_GET_CALL_WAITING));
+            Log.d(LOG_TAG, "init getCallWaitingStatus");
+            mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
             if (mTcpListener != null) {
                 mTcpListener.onStarted(this, true);
             }
         }
     }
 
+    private void queryStatusCallBack(int result) {
+        Log.d(LOG_TAG, "queryStatusCallBack: CW state " + result);
+        mQueryStatus = result;
+        mHandler.sendMessage(mHandler.obtainMessage(MyHandler.MESSAGE_UPDATE_CALL_WAITING));
+    }
+
+    private void updateStatusCallBack(int result) {
+        Log.d(LOG_TAG, "updateStatusCallBack: CW state " + result + ", and re get");
+        mUpdateStatus = result;
+        mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
+    }
+
     @Override
     protected void onClick() {
         super.onClick();
-
-        mPhone.setCallWaiting(isChecked(),
-                mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_WAITING));
+        mTelephonyManager.setCallWaitingEnabled(isChecked(), mExecutor, this::updateStatusCallBack);
         if (mTcpListener != null) {
+            mIsDuringUpdateProcess = true;
             mTcpListener.onStarted(this, false);
         }
     }
 
     private class MyHandler extends Handler {
-        static final int MESSAGE_GET_CALL_WAITING = 0;
-        static final int MESSAGE_SET_CALL_WAITING = 1;
+        static final int MESSAGE_UPDATE_CALL_WAITING = 0;
 
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MESSAGE_GET_CALL_WAITING:
-                    handleGetCallWaitingResponse(msg);
-                    break;
-                case MESSAGE_SET_CALL_WAITING:
-                    handleSetCallWaitingResponse(msg);
+                case MESSAGE_UPDATE_CALL_WAITING:
+                    updateUi();
                     break;
             }
         }
 
-        private void handleGetCallWaitingResponse(Message msg) {
-            AsyncResult ar = (AsyncResult) msg.obj;
-
+        private void updateUi() {
             if (mTcpListener != null) {
-                if (msg.arg2 == MESSAGE_SET_CALL_WAITING) {
+                if (mIsDuringUpdateProcess) {
                     mTcpListener.onFinished(CallWaitingSwitchPreference.this, false);
                 } else {
                     mTcpListener.onFinished(CallWaitingSwitchPreference.this, true);
                 }
             }
 
-            if (ar.exception instanceof CommandException) {
-                if (DBG) {
-                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: CommandException=" +
-                            ar.exception);
-                }
+            if (mIsDuringUpdateProcess && (
+                    mUpdateStatus == TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED
+                            || mUpdateStatus
+                            == TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR)) {
+                Log.d(LOG_TAG, "handleSetCallWaitingResponse: Exception");
                 if (mTcpListener != null) {
-                    mTcpListener.onException(CallWaitingSwitchPreference.this,
-                            (CommandException)ar.exception);
+                    mTcpListener.onError(CallWaitingSwitchPreference.this, EXCEPTION_ERROR);
                 }
-            } else if (ar.userObj instanceof Throwable || ar.exception != null) {
-                // Still an error case but just not a CommandException.
-                if (DBG) {
-                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: Exception" + ar.exception);
-                }
+            } else if (mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED
+                    || mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR) {
+                Log.d(LOG_TAG, "handleGetCallWaitingResponse: Exception");
                 if (mTcpListener != null) {
                     mTcpListener.onError(CallWaitingSwitchPreference.this, RESPONSE_ERROR);
                 }
             } else {
-                if (DBG) {
-                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: CW state successfully queried.");
-                }
-                int[] cwArray = (int[])ar.result;
-                // If cwArray[0] is = 1, then cwArray[1] must follow,
-                // with the TS 27.007 service class bit vector of services
-                // for which call waiting is enabled.
-                try {
-                    setChecked(((cwArray[0] == 1) && ((cwArray[1] & 0x01) == 0x01)));
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    Log.e(LOG_TAG, "handleGetCallWaitingResponse: improper result: err ="
-                            + e.getMessage());
+                if (mQueryStatus == TelephonyManager.CALL_WAITING_STATUS_ENABLED) {
+                    setChecked(true);
+                } else {
+                    setChecked(false);
                 }
             }
-        }
-
-        private void handleSetCallWaitingResponse(Message msg) {
-            AsyncResult ar = (AsyncResult) msg.obj;
-
-            if (ar.exception != null) {
-                if (DBG) {
-                    Log.d(LOG_TAG, "handleSetCallWaitingResponse: ar.exception=" + ar.exception);
-                }
-                //setEnabled(false);
-            }
-            if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: re get");
-
-            mPhone.getCallWaiting(obtainMessage(MESSAGE_GET_CALL_WAITING,
-                    MESSAGE_SET_CALL_WAITING, MESSAGE_SET_CALL_WAITING, ar.exception));
+            mIsDuringUpdateProcess = false;
         }
     }
 }