1 /* 2 * Copyright (C) 2019 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 17 package android.telecom.cts.redirectiontestapp; 18 19 import android.app.Service; 20 import android.content.ComponentName; 21 import android.content.Intent; 22 import android.net.Uri; 23 import android.telecom.PhoneAccountHandle; 24 import android.os.IBinder; 25 import android.telecom.CallRedirectionService; 26 import android.util.Log; 27 28 import java.util.concurrent.CountDownLatch; 29 import java.util.concurrent.TimeUnit; 30 31 public class CtsCallRedirectionServiceController extends Service { 32 private static final String TAG = CallRedirectionService.class.getSimpleName(); 33 public static final String CONTROL_INTERFACE_ACTION = 34 "android.telecom.cts.redirectiontestapp.ACTION_CONTROL_CALL_REDIRECTION_SERVICE"; 35 public static final ComponentName CONTROL_INTERFACE_COMPONENT = 36 ComponentName.unflattenFromString( 37 "android.telecom.cts.redirectiontestapp/.CtsCallRedirectionServiceController"); 38 39 // Constants for call redirection decisions 40 public static final int NO_DECISION_YET = 0; 41 public static final int RESPONSE_TIMEOUT = 1; 42 public static final int PLACE_CALL_UNMODIFIED = 2; 43 public static final int PLACE_REDIRECTED_CALL = 3; 44 public static final int CANCEL_CALL = 4; 45 public static final long TIMEOUT = 6000; 46 47 private int mDecision = NO_DECISION_YET; 48 49 // Redirection information, only valid if decision is PLACE_REDIRECTED_CALL. 50 private Uri mTargetHandle = null; 51 private Uri mDestinationUri = null; 52 private PhoneAccountHandle mRedirectedPhoneAccount = null; 53 private PhoneAccountHandle mOriginalPhoneAccount = null; 54 private boolean mConfirmFirst = false; 55 private CountDownLatch mTimeoutNotified = new CountDownLatch(1); 56 private CountDownLatch mOnPlaceCallInvoked = new CountDownLatch(1); 57 58 private static CtsCallRedirectionServiceController sCallRedirectionServiceController = null; 59 60 private final IBinder mControllerInterface = new ICtsCallRedirectionServiceController.Stub() { 61 @Override 62 public void reset() { 63 mDecision = NO_DECISION_YET; 64 mTimeoutNotified = new CountDownLatch(1); 65 mOnPlaceCallInvoked = new CountDownLatch(1); 66 } 67 68 @Override 69 public void setRedirectCall(Uri targetHandle, 70 PhoneAccountHandle redirectedPhoneAccount, 71 boolean confirmFirst) { 72 Log.i(TAG, "redirectCall"); 73 mDecision = PLACE_REDIRECTED_CALL; 74 mTargetHandle = targetHandle; 75 mRedirectedPhoneAccount = redirectedPhoneAccount; 76 mConfirmFirst = confirmFirst; 77 } 78 79 @Override 80 public void setCancelCall() { 81 Log.i(TAG, "cancelCall"); 82 mDecision = CANCEL_CALL; 83 } 84 85 @Override 86 public void setPlaceCallUnmodified() { 87 Log.i(TAG, "placeCallUnmodified"); 88 mDecision = PLACE_CALL_UNMODIFIED; 89 } 90 91 @Override 92 public void setWaitForTimeout() { 93 Log.i(TAG, "setWaitForTimeout"); 94 mDecision = RESPONSE_TIMEOUT; 95 } 96 97 @Override 98 public boolean waitForTimeoutNotified() { 99 Log.i(TAG, "waitForTimeoutNotified"); 100 try { 101 return mTimeoutNotified.await(TIMEOUT, TimeUnit.MILLISECONDS); 102 } catch (InterruptedException e) { 103 return false; 104 } 105 } 106 107 @Override 108 public boolean waitForOnPlaceCallInvoked() { 109 try { 110 return mOnPlaceCallInvoked.await(TIMEOUT, TimeUnit.MILLISECONDS); 111 } catch (InterruptedException e) { 112 return false; 113 } 114 } 115 }; 116 getInstance()117 public static CtsCallRedirectionServiceController getInstance() { 118 return sCallRedirectionServiceController; 119 } 120 121 @Override onBind(Intent intent)122 public IBinder onBind(Intent intent) { 123 if (CONTROL_INTERFACE_ACTION.equals(intent.getAction())) { 124 Log.i(TAG, "onBind: returning control interface"); 125 sCallRedirectionServiceController = this; 126 return mControllerInterface; 127 } 128 Log.i(TAG, "onBind: ACTION is not matched"); 129 return null; 130 } 131 132 @Override onUnbind(Intent intent)133 public boolean onUnbind(Intent intent) { 134 sCallRedirectionServiceController = null; 135 return false; 136 } 137 getCallRedirectionDecision()138 public int getCallRedirectionDecision() { 139 return mDecision; 140 } 141 getTargetHandle()142 public Uri getTargetHandle() { 143 return mTargetHandle; 144 } 145 getTargetPhoneAccount()146 public PhoneAccountHandle getTargetPhoneAccount() { 147 return mRedirectedPhoneAccount != null ? mRedirectedPhoneAccount : mOriginalPhoneAccount; 148 } 149 setOriginalPhoneAccount(PhoneAccountHandle originalPhoneAccount)150 public void setOriginalPhoneAccount(PhoneAccountHandle originalPhoneAccount) { 151 mOriginalPhoneAccount = originalPhoneAccount; 152 } 153 setDestinationUri(Uri destinationUri)154 public void setDestinationUri(Uri destinationUri) { 155 mDestinationUri = destinationUri; 156 } 157 isConfirmFirst()158 public boolean isConfirmFirst() { 159 return mConfirmFirst; 160 } 161 timeoutNotified()162 public void timeoutNotified() { 163 mTimeoutNotified.countDown(); 164 } 165 onPlaceCallInvoked()166 public void onPlaceCallInvoked() { 167 mOnPlaceCallInvoked.countDown(); 168 } 169 } 170