1 /* 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 17 package android.telecom.cts.screeningtestapp; 18 19 import android.app.Service; 20 import android.content.ComponentName; 21 import android.content.Intent; 22 import android.os.IBinder; 23 import android.telecom.CallScreeningService; 24 import android.util.Log; 25 26 import java.util.concurrent.CountDownLatch; 27 import java.util.concurrent.TimeUnit; 28 import java.util.concurrent.atomic.AtomicReference; 29 30 public class CallScreeningServiceControl extends Service { 31 private static final int ASYNC_TIMEOUT = 10000; 32 private static final String TAG = CallScreeningServiceControl.class.getSimpleName(); 33 public static final String CONTROL_INTERFACE_ACTION = 34 "android.telecom.cts.screeningtestapp.ACTION_CONTROL_CALL_SCREENING_SERVICE"; 35 public static final ComponentName CONTROL_INTERFACE_COMPONENT = 36 new ComponentName( 37 "android.telecom.cts.screeningtestapp", 38 "android.telecom.cts.screeningtestapp.CallScreeningServiceControl"); 39 40 private static CallScreeningServiceControl sCallScreeningServiceControl = null; 41 private CountDownLatch mBindingLatch = new CountDownLatch(1); 42 43 /** mIsBound represents the binding status from the test class to the test app */ 44 public static boolean mIsBound = false; 45 46 private final IBinder mControlInterface = 47 new android.telecom.cts.screeningtestapp.ICallScreeningControl.Stub() { 48 @Override 49 public void reset() { 50 Log.i(TAG, "reset: mCallResponse"); 51 mCallResponse.set( 52 new CallScreeningService.CallResponse.Builder() 53 .setDisallowCall(false) 54 .setRejectCall(false) 55 .setSkipCallLog(false) 56 .setSkipNotification(false) 57 .build()); 58 mBindingLatch = new CountDownLatch(1); 59 CtsPostCallActivity.resetPostCallActivity(); 60 } 61 62 @Override 63 public void setCallResponse( 64 boolean shouldDisallowCall, 65 boolean shouldRejectCall, 66 boolean shouldSilenceCall, 67 boolean shouldSkipCallLog, 68 boolean shouldSkipNotification) { 69 70 mCallResponse.set( 71 new CallScreeningService.CallResponse.Builder() 72 .setSkipNotification(shouldSkipNotification) 73 .setSkipCallLog(shouldSkipCallLog) 74 .setDisallowCall(shouldDisallowCall) 75 .setRejectCall(shouldRejectCall) 76 .setSilenceCall(shouldSilenceCall) 77 .build()); 78 79 Log.i( 80 TAG, 81 String.format( 82 "setCallResponse: shouldDisallowCall=[%b]," 83 + " shouldRejectCall=[%b], shouldSilenceCall=[%b]," 84 + " shouldSkipCallLog=[%b], shouldSkipNotification=[%b] ," 85 + " mCallResponse.hash=[%d] (AR)", 86 shouldDisallowCall, 87 shouldRejectCall, 88 shouldSilenceCall, 89 shouldSkipCallLog, 90 shouldSkipNotification, 91 mCallResponse.hashCode())); 92 } 93 94 @Override 95 public boolean waitForBind() { 96 try { 97 return mBindingLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 98 } catch (InterruptedException e) { 99 return false; 100 } 101 } 102 103 @Override 104 public boolean waitForActivity() { 105 return CtsPostCallActivity.waitForActivity(); 106 } 107 108 @Override 109 public String getCachedHandle() { 110 return CtsPostCallActivity.getCachedHandle().getSchemeSpecificPart(); 111 } 112 113 @Override 114 public int getCachedDisconnectCause() { 115 return CtsPostCallActivity.getCachedDisconnectCause(); 116 } 117 118 @Override 119 public boolean isBound() { 120 return mIsBound; 121 } 122 }; 123 124 private AtomicReference<CallScreeningService.CallResponse> mCallResponse = 125 new AtomicReference<>( 126 new CallScreeningService.CallResponse.Builder() 127 .setDisallowCall(false) 128 .setRejectCall(false) 129 .setSilenceCall(false) 130 .setSkipCallLog(false) 131 .setSkipNotification(false) 132 .build()); 133 getInstance()134 public static CallScreeningServiceControl getInstance() { 135 return sCallScreeningServiceControl; 136 } 137 138 @Override onBind(Intent intent)139 public IBinder onBind(Intent intent) { 140 if (CONTROL_INTERFACE_ACTION.equals(intent.getAction())) { 141 Log.i(TAG, "onBind: returning control interface"); 142 sCallScreeningServiceControl = this; 143 mIsBound = true; 144 return mControlInterface; 145 } 146 Log.i(TAG, "onBind: uh oh"); 147 return null; 148 } 149 150 @Override onUnbind(Intent intent)151 public boolean onUnbind(Intent intent) { 152 Log.i(TAG, "onUnbind: call screening control interface: intent= " + intent); 153 sCallScreeningServiceControl = null; 154 mIsBound = false; 155 super.onUnbind(intent); 156 return false; 157 } 158 onScreeningServiceBound()159 public void onScreeningServiceBound() { 160 mBindingLatch.countDown(); 161 } 162 getCallResponse()163 public CallScreeningService.CallResponse getCallResponse() { 164 CallScreeningService.CallResponse currentResponse = mCallResponse.get(); 165 Log.i( 166 TAG, 167 String.format( 168 "getCallResponse: shouldDisallowCall=[%b], " 169 + "shouldRejectCall=[%b], " 170 + "shouldSilenceCall=[%b], " 171 + "shouldSkipCallLog=[%b], " 172 + "shouldSkipNotification=[%b] , mCallResponse.hash=[%d] (AR)", 173 currentResponse.getDisallowCall(), 174 currentResponse.getRejectCall(), 175 currentResponse.getSilenceCall(), 176 currentResponse.getSkipCallLog(), 177 currentResponse.getSkipNotification(), 178 currentResponse.hashCode())); 179 return currentResponse; 180 } 181 } 182