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