1 /* 2 * Copyright (C) 2015 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 com.android.server.telecom.tests; 18 19 import com.android.internal.telecom.IInCallAdapter; 20 import com.android.internal.telecom.IInCallService; 21 22 import org.mockito.Mockito; 23 24 import android.os.Bundle; 25 import android.os.IBinder; 26 import android.os.IInterface; 27 import android.os.RemoteException; 28 import android.telecom.CallAudioState; 29 import android.telecom.ParcelableCall; 30 31 import java.util.HashMap; 32 import java.util.Map; 33 import java.util.concurrent.CountDownLatch; 34 import java.util.concurrent.TimeUnit; 35 36 /** 37 * Controls a test {@link IInCallService} as would be provided by an InCall UI on a system. 38 */ 39 public class InCallServiceFixture implements TestFixture<IInCallService> { 40 41 public String mLatestCallId; 42 public IInCallAdapter mInCallAdapter; 43 public CallAudioState mCallAudioState; 44 public final Map<String, ParcelableCall> mCallById = new HashMap<>(); 45 public final Map<String, String> mPostDialById = new HashMap<>(); 46 public final Map<String, String> mPostDialWaitById = new HashMap<>(); 47 public boolean mBringToForeground; 48 public boolean mShowDialpad; 49 public boolean mCanAddCall; 50 public boolean mSilenceRinger; 51 public CountDownLatch mUpdateCallLock = new CountDownLatch(1); 52 public CountDownLatch mAddCallLock = new CountDownLatch(1); 53 54 public class FakeInCallService extends IInCallService.Stub { 55 @Override setInCallAdapter(IInCallAdapter inCallAdapter)56 public void setInCallAdapter(IInCallAdapter inCallAdapter) throws RemoteException { 57 if (mInCallAdapter != null && inCallAdapter != null) { 58 throw new RuntimeException("Adapter is already set"); 59 } 60 if (mInCallAdapter == null && inCallAdapter == null) { 61 throw new RuntimeException("Adapter was never set"); 62 } 63 mInCallAdapter = inCallAdapter; 64 } 65 66 @Override addCall(ParcelableCall call)67 public void addCall(ParcelableCall call) throws RemoteException { 68 if (mCallById.containsKey(call.getId())) { 69 throw new RuntimeException("Call " + call.getId() + " already added"); 70 } 71 mLatestCallId = call.getId(); 72 mCallById.put(call.getId(), call); 73 mAddCallLock.countDown(); 74 } 75 76 @Override updateCall(ParcelableCall call)77 public void updateCall(ParcelableCall call) throws RemoteException { 78 if (!mCallById.containsKey(call.getId())) { 79 // This used to throw an exception, however the actual InCallService implementation 80 // ignores updates for calls which don't yet exist. This is not a problem as when 81 // a call is added to an InCallService its entire state is parceled and sent to the 82 // InCallService. 83 return; 84 } 85 mLatestCallId = call.getId(); 86 mCallById.put(call.getId(), call); 87 mUpdateCallLock.countDown(); 88 } 89 90 @Override setPostDial(String callId, String remaining)91 public void setPostDial(String callId, String remaining) throws RemoteException { 92 mPostDialWaitById.remove(callId); 93 mPostDialById.put(callId, remaining); 94 } 95 96 @Override setPostDialWait(String callId, String remaining)97 public void setPostDialWait(String callId, String remaining) throws RemoteException { 98 mPostDialById.remove(callId); 99 mPostDialWaitById.put(callId, remaining); 100 } 101 102 @Override onCallAudioStateChanged(CallAudioState audioState)103 public void onCallAudioStateChanged(CallAudioState audioState) throws RemoteException { 104 mCallAudioState = audioState; 105 } 106 107 @Override bringToForeground(boolean showDialpad)108 public void bringToForeground(boolean showDialpad) throws RemoteException { 109 mBringToForeground = true; 110 mShowDialpad = showDialpad; 111 } 112 113 @Override onCanAddCallChanged(boolean canAddCall)114 public void onCanAddCallChanged(boolean canAddCall) throws RemoteException { 115 mCanAddCall = canAddCall; 116 } 117 118 @Override silenceRinger()119 public void silenceRinger() throws RemoteException { 120 mSilenceRinger = true; 121 } 122 123 @Override onConnectionEvent(String callId, String event, Bundle extras)124 public void onConnectionEvent(String callId, String event, Bundle extras) 125 throws RemoteException { 126 } 127 128 @Override onRttUpgradeRequest(String callId, int id)129 public void onRttUpgradeRequest(String callId, int id) throws RemoteException { 130 } 131 132 @Override onRttInitiationFailure(String callId, int reason)133 public void onRttInitiationFailure(String callId, int reason) throws RemoteException { 134 } 135 136 @Override asBinder()137 public IBinder asBinder() { 138 return this; 139 } 140 141 @Override queryLocalInterface(String descriptor)142 public IInterface queryLocalInterface(String descriptor) { 143 return this; 144 } 145 146 @Override onHandoverFailed(String callId, int error)147 public void onHandoverFailed(String callId, int error) {} 148 149 @Override onHandoverComplete(String callId)150 public void onHandoverComplete(String callId) {} 151 } 152 153 private IInCallService.Stub mInCallServiceFake = new FakeInCallService(); 154 private IInCallService.Stub mInCallServiceSpy = Mockito.spy(mInCallServiceFake); 155 InCallServiceFixture()156 public InCallServiceFixture() throws Exception { } 157 158 @Override getTestDouble()159 public IInCallService getTestDouble() { 160 return mInCallServiceSpy; 161 } 162 getCall(String id)163 public ParcelableCall getCall(String id) { 164 return mCallById.get(id); 165 } 166 getInCallAdapter()167 public IInCallAdapter getInCallAdapter() { 168 return mInCallAdapter; 169 } 170 waitForUpdate()171 public void waitForUpdate() { 172 try { 173 mUpdateCallLock.await(5000, TimeUnit.MILLISECONDS); 174 } catch (InterruptedException ie) { 175 return; 176 } 177 mUpdateCallLock = new CountDownLatch(1); 178 } 179 waitUntilNumCalls(int numCalls)180 public void waitUntilNumCalls(int numCalls) { 181 if (mCallById.size() == numCalls) { 182 return; 183 } 184 mAddCallLock = new CountDownLatch(1); 185 186 try { 187 mAddCallLock.await(5000, TimeUnit.MILLISECONDS); 188 } catch (InterruptedException ie) { 189 return; 190 } 191 } 192 } 193