1 /*
2  * Copyright (C) 2016 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.services.telephony;
18 
19 import android.content.AttributionSource;
20 import android.content.ContentResolver;
21 import android.os.Process;
22 import android.os.UserHandle;
23 import android.telephony.TelephonyManager;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.ArgumentMatchers.anyString;
28 import static org.mockito.ArgumentMatchers.notNull;
29 import static org.mockito.Mockito.doNothing;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.when;
32 
33 import android.content.Context;
34 import android.content.res.Resources;
35 import android.os.Bundle;
36 import android.os.PersistableBundle;
37 import android.telecom.PhoneAccountHandle;
38 import android.telecom.VideoProfile;
39 import android.telephony.CarrierConfigManager;
40 
41 import com.android.ims.ImsCall;
42 import com.android.internal.telephony.Call;
43 import com.android.internal.telephony.CallStateException;
44 import com.android.internal.telephony.Connection;
45 import com.android.internal.telephony.Phone;
46 import com.android.internal.telephony.PhoneConstants;
47 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
48 import com.android.internal.telephony.imsphone.ImsExternalConnection;
49 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
50 
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 
54 import java.util.ArrayList;
55 import java.util.List;
56 
57 /**
58  * Mock Telephony Connection used in TelephonyConferenceController.java for testing purpose
59  */
60 
61 public class TestTelephonyConnection extends TelephonyConnection {
62 
63     @Mock
64     com.android.internal.telephony.Connection mMockRadioConnection;
65 
66     @Mock
67     Call mMockCall;
68 
69     @Mock
70     Context mMockContext;
71 
72     @Mock
73     ContentResolver mMockContentResolver;
74 
75     @Mock
76     Resources mMockResources;
77 
78     @Mock
79     TelephonyManager mMockTelephonyManager;
80 
81     @Mock
82     EmergencyNumberTracker mEmergencyNumberTracker;
83 
84     @Mock
85     ImsPhoneConnection mImsPhoneConnection;
86 
87     @Mock
88     ImsExternalConnection mImsExternalConnection;
89 
90     @Mock
91     ImsCall mImsCall;
92 
93     @Mock
94     TelecomAccountRegistry mTelecomAccountRegistry;
95 
96     @Mock
97     CarrierConfigManager mCarrierConfigManager;
98 
99     private boolean mIsImsConnection;
100     private boolean mIsImsExternalConnection;
101     private boolean mIsConferenceSupported = true;
102     private Phone mMockPhone;
103     private int mNotifyPhoneAccountChangedCount = 0;
104     private List<String> mLastConnectionEvents = new ArrayList<>();
105     private List<Bundle> mLastConnectionEventExtras = new ArrayList<>();
106     private Object mLock = new Object();
107     private PersistableBundle mCarrierConfig = new PersistableBundle();
108     private boolean mOriginalConnectionCleared;
109 
110     @Override
getOriginalConnection()111     public com.android.internal.telephony.Connection getOriginalConnection() {
112         if (mIsImsExternalConnection) {
113             return mImsExternalConnection;
114         } else if (mIsImsConnection) {
115             return mImsPhoneConnection;
116         } else {
117             return mMockRadioConnection;
118         }
119     }
120 
121     @Override
getCall()122     protected Call getCall() {
123         return mMockCall;
124     }
125 
TestTelephonyConnection()126     public TestTelephonyConnection() {
127         super(null, null, android.telecom.Call.Details.DIRECTION_INCOMING);
128         MockitoAnnotations.initMocks(this);
129 
130         AttributionSource attributionSource = new AttributionSource.Builder(
131                 Process.myUid()).build();
132 
133         mIsImsConnection = false;
134         mIsImsExternalConnection = false;
135         mMockPhone = mock(Phone.class);
136         mMockContext = mock(Context.class);
137         mMockTelephonyManager = mock(TelephonyManager.class);
138         mOriginalConnection = mMockRadioConnection;
139         // Set up mMockRadioConnection and mMockPhone to contain an active call
140         when(mMockRadioConnection.getState()).thenReturn(Call.State.ACTIVE);
141         when(mOriginalConnection.getState()).thenReturn(Call.State.ACTIVE);
142         when(mMockRadioConnection.getAudioCodec()).thenReturn(
143                 android.telecom.Connection.AUDIO_CODEC_AMR);
144         when(mImsPhoneConnection.getAudioCodec()).thenReturn(
145                 android.telecom.Connection.AUDIO_CODEC_AMR);
146         when(mMockRadioConnection.getCall()).thenReturn(mMockCall);
147         when(mMockRadioConnection.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
148         when(mImsPhoneConnection.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
149         doNothing().when(mMockRadioConnection).addListener(any(Connection.Listener.class));
150         doNothing().when(mMockRadioConnection).addPostDialListener(
151                 any(Connection.PostDialListener.class));
152         when(mEmergencyNumberTracker.getEmergencyNumber(anyString())).thenReturn(null);
153         when(mMockPhone.getEmergencyNumberTracker()).thenReturn(mEmergencyNumberTracker);
154         when(mMockPhone.getRingingCall()).thenReturn(mMockCall);
155         when(mMockPhone.getContext()).thenReturn(mMockContext);
156         when(mMockPhone.getCurrentSubscriberUris()).thenReturn(null);
157         when(mMockContext.getResources()).thenReturn(mMockResources);
158         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
159         when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
160                 .thenReturn(mMockTelephonyManager);
161         when(mMockContext.getAttributionSource()).thenReturn(attributionSource);
162         when(mMockContentResolver.getUserId()).thenReturn(UserHandle.USER_CURRENT);
163         when(mMockContentResolver.getAttributionSource()).thenReturn(attributionSource);
164         when(mMockResources.getBoolean(anyInt())).thenReturn(false);
165         when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone);
166         when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
167         when(mMockCall.getState()).thenReturn(Call.State.ACTIVE);
168         when(mMockCall.getPhone()).thenReturn(mMockPhone);
169         when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone);
170         when(mImsPhoneConnection.getImsCall()).thenReturn(mImsCall);
171         when(mTelecomAccountRegistry.isMergeCallSupported(notNull(PhoneAccountHandle.class)))
172                 .thenReturn(mIsConferenceSupported);
173         when(mTelecomAccountRegistry.isMergeImsCallSupported(notNull(PhoneAccountHandle.class)))
174                 .thenReturn(mIsImsConnection);
175         when(mTelecomAccountRegistry
176                 .isVideoConferencingSupported(notNull(PhoneAccountHandle.class))).thenReturn(false);
177         when(mTelecomAccountRegistry
178                 .isMergeOfWifiCallsAllowedWhenVoWifiOff(notNull(PhoneAccountHandle.class)))
179                 .thenReturn(false);
180         try {
181             doNothing().when(mMockCall).hangup();
182         } catch (CallStateException e) {
183             e.printStackTrace();
184         }
185     }
186 
setMockPhone(Phone newPhone)187     public void setMockPhone(Phone newPhone) {
188         mMockPhone = newPhone;
189     }
190 
191     @Override
getPhone()192     public Phone getPhone() {
193         return mMockPhone;
194     }
195 
cloneConnection()196     public TelephonyConnection cloneConnection() {
197         return this;
198     }
199 
200     @Override
notifyPhoneAccountChanged(PhoneAccountHandle pHandle)201     public void notifyPhoneAccountChanged(PhoneAccountHandle pHandle) {
202         mNotifyPhoneAccountChangedCount++;
203     }
204 
205     @Override
sendConnectionEvent(String event, Bundle extras)206     public void sendConnectionEvent(String event, Bundle extras) {
207         mLastConnectionEvents.add(event);
208         mLastConnectionEventExtras.add(extras);
209     }
210 
211     @Override
clearOriginalConnection()212     void clearOriginalConnection() {
213         mOriginalConnectionCleared = true;
214     }
215 
isOriginalConnectionCleared()216     boolean isOriginalConnectionCleared() {
217         return mOriginalConnectionCleared;
218     }
219 
resetOriginalConnectionCleared()220     void resetOriginalConnectionCleared() {
221         mOriginalConnectionCleared = false;
222     }
223 
224     @Override
getCarrierConfig()225     public PersistableBundle getCarrierConfig() {
226         // Depends on PhoneGlobals for context in TelephonyConnection, do not implement during
227         // testing.
228         return mCarrierConfig;
229     }
230 
231     @Override
refreshConferenceSupported()232     public void refreshConferenceSupported() {
233         if (mIsImsConnection) {
234             super.refreshConferenceSupported();
235         }
236     }
237 
238     @Override
getResourceText(int messageId)239     public CharSequence getResourceText(int messageId) {
240         return "TEST";
241     }
242 
243     @Override
getResourceString(int id)244     public String getResourceString(int id) {
245         return "TEST";
246     }
247 
248     @Override
setConferenceSupported(boolean conferenceSupported)249     public void setConferenceSupported(boolean conferenceSupported) {
250         mIsConferenceSupported = conferenceSupported;
251     }
252 
253     @Override
isConferenceSupported()254     public boolean isConferenceSupported() {
255         return mIsConferenceSupported;
256     }
257 
258     @Override
getTelecomAccountRegistry(Context context)259     public TelecomAccountRegistry getTelecomAccountRegistry(Context context) {
260         return mTelecomAccountRegistry;
261     }
262 
setIsVideoCall(boolean isVideoCall)263     public void setIsVideoCall(boolean isVideoCall) {
264         if (isVideoCall) {
265             setVideoState(VideoProfile.STATE_TX_ENABLED);
266         } else {
267             setVideoState(VideoProfile.STATE_AUDIO_ONLY);
268         }
269     }
270 
setWasVideoCall(boolean wasVideoCall)271     public void setWasVideoCall(boolean wasVideoCall) {
272         when(mImsCall.wasVideoCall()).thenReturn(wasVideoCall);
273     }
274 
275     @Override
isWfcEnabled(Phone phone)276     boolean isWfcEnabled(Phone phone) {
277         // Requires ImsManager dependencies, mock for test.
278         return true;
279     }
280 
getNotifyPhoneAccountChangedCount()281     public int getNotifyPhoneAccountChangedCount() {
282         return mNotifyPhoneAccountChangedCount;
283     }
284 
getLastConnectionEvents()285     public List<String> getLastConnectionEvents() {
286         return mLastConnectionEvents;
287     }
288 
getLastConnectionEventExtras()289     public List<Bundle> getLastConnectionEventExtras() {
290         return mLastConnectionEventExtras;
291     }
292 
setIsImsConnection(boolean isImsConnection)293     public void setIsImsConnection(boolean isImsConnection) {
294         mIsImsConnection = isImsConnection;
295         when(mTelecomAccountRegistry.isMergeImsCallSupported(notNull(PhoneAccountHandle.class)))
296                 .thenReturn(isImsConnection && mIsConferenceSupported);
297     }
298 
setIsImsExternalConnection(boolean isExternalConnection)299     public void setIsImsExternalConnection(boolean isExternalConnection) {
300         mIsImsExternalConnection = isExternalConnection;
301     }
302 
setDownGradeVideoCall(boolean downgrade)303     public void setDownGradeVideoCall(boolean downgrade) {
304         PersistableBundle bundle = new PersistableBundle();
305         bundle.putBoolean(CarrierConfigManager.KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL,
306                 downgrade);
307         when(mMockContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
308                 .thenReturn(mCarrierConfigManager);
309         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
310     }
311 
getCarrierConfigBundle()312     public PersistableBundle getCarrierConfigBundle() {
313         return mCarrierConfig;
314     }
315 
getMockImsPhoneConnection()316     public ImsPhoneConnection getMockImsPhoneConnection() {
317         return mImsPhoneConnection;
318     }
319 
setMockImsPhoneConnection(ImsPhoneConnection connection)320     public void setMockImsPhoneConnection(ImsPhoneConnection connection) {
321         mImsPhoneConnection = connection;
322     }
323 }
324