• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 static junit.framework.Assert.assertEquals;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.anyString;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.when;
30 
31 import android.Manifest;
32 import android.content.ComponentName;
33 import android.content.Intent;
34 import android.content.ServiceConnection;
35 import android.content.pm.ResolveInfo;
36 import android.content.pm.ServiceInfo;
37 import android.os.IBinder;
38 import android.os.RemoteException;
39 import android.os.UserHandle;
40 import android.telecom.ParcelableCall;
41 
42 import com.android.internal.telecom.ICallDiagnosticService;
43 import com.android.server.telecom.Call;
44 import com.android.server.telecom.CallDiagnosticServiceController;
45 import com.android.server.telecom.TelecomSystem;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.junit.runners.JUnit4;
51 import org.mockito.ArgumentCaptor;
52 import org.mockito.Mock;
53 import org.mockito.Mockito;
54 import org.mockito.MockitoAnnotations;
55 
56 import java.util.ArrayList;
57 import java.util.List;
58 
59 @RunWith(JUnit4.class)
60 public class CallDiagnosticServiceControllerTest {
61     private static final String TEST_CDS_PACKAGE = "com.test.stuff";
62     private static final String TEST_PACKAGE = "com.android.telecom.calldiagnosticservice";
63     private static final String TEST_CLASS =
64             "com.android.telecom.calldiagnosticservice.TestService";
65     private static final ComponentName TEST_COMPONENT = new ComponentName(TEST_PACKAGE, TEST_CLASS);
66     private static final List<ResolveInfo> RESOLVE_INFOS = new ArrayList<>();
67     private static final ResolveInfo TEST_RESOLVE_INFO = new ResolveInfo();
68     static {
69         TEST_RESOLVE_INFO.serviceInfo = new ServiceInfo();
70         TEST_RESOLVE_INFO.serviceInfo.packageName = TEST_PACKAGE;
71         TEST_RESOLVE_INFO.serviceInfo.name = TEST_CLASS;
72         TEST_RESOLVE_INFO.serviceInfo.permission = Manifest.permission.BIND_CALL_DIAGNOSTIC_SERVICE;
73         RESOLVE_INFOS.add(TEST_RESOLVE_INFO);
74     }
75     private static final String ID_1 = "1";
76     private static final String ID_2 = "2";
77 
78     @Mock
79     private CallDiagnosticServiceController.ContextProxy mContextProxy;
80     @Mock
81     private Call mCall;
82     @Mock
83     private Call mCallTwo;
84     @Mock
85     private ICallDiagnosticService mICallDiagnosticService;
86     private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
87 
88     private CallDiagnosticServiceController mCallDiagnosticService;
89     private ServiceConnection mServiceConnection;
90 
91     @Before
setUp()92     public void setUp() throws Exception {
93         MockitoAnnotations.initMocks(this);
94 
95         when(mCall.getId()).thenReturn(ID_1);
96         when(mCall.isSimCall()).thenReturn(true);
97         when(mCall.isExternalCall()).thenReturn(false);
98 
99         when(mCallTwo.getId()).thenReturn(ID_2);
100         when(mCallTwo.isSimCall()).thenReturn(true);
101         when(mCallTwo.isExternalCall()).thenReturn(false);
102         mServiceConnection = null;
103 
104         // Mock out the context and other junk that we depend on.
105         when(mContextProxy.queryIntentServicesAsUser(any(Intent.class), anyInt(), anyInt()))
106                 .thenReturn(RESOLVE_INFOS);
107         when(mContextProxy.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
108                 anyInt(), any(UserHandle.class))).thenReturn(true);
109         when(mContextProxy.getCurrentUserHandle()).thenReturn(UserHandle.CURRENT);
110 
111         mCallDiagnosticService = new CallDiagnosticServiceController(mContextProxy,
112                 TEST_PACKAGE, mLock);
113     }
114 
115     /**
116      * Verify no binding takes place for a non-sim call.
117      */
118     @Test
testNoBindOnNonSimCall()119     public void testNoBindOnNonSimCall() {
120         Call mockCall = Mockito.mock(Call.class);
121         when(mockCall.isSimCall()).thenReturn(false);
122 
123         mCallDiagnosticService.onCallAdded(mockCall);
124 
125         verify(mContextProxy, never()).bindServiceAsUser(any(Intent.class),
126                 any(ServiceConnection.class), anyInt(), any(UserHandle.class));
127     }
128 
129     /**
130      * Verify no binding takes place for a SIM external call.
131      */
132     @Test
testNoBindOnExternalCall()133     public void testNoBindOnExternalCall() {
134         Call mockCall = Mockito.mock(Call.class);
135         when(mockCall.isSimCall()).thenReturn(true);
136         when(mockCall.isExternalCall()).thenReturn(true);
137 
138         mCallDiagnosticService.onCallAdded(mockCall);
139 
140         verify(mContextProxy, never()).bindServiceAsUser(any(Intent.class),
141                 any(ServiceConnection.class), anyInt(), any(UserHandle.class));
142     }
143 
144     /**
145      * Verify a valid SIM call causes binding to initiate.
146      */
147     @Test
testAddSimCallCausesBind()148     public void testAddSimCallCausesBind() throws RemoteException {
149         mCallDiagnosticService.onCallAdded(mCall);
150 
151         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
152         ArgumentCaptor<ServiceConnection> serviceConnectionCaptor = ArgumentCaptor.forClass(
153                 ServiceConnection.class);
154         verify(mContextProxy).bindServiceAsUser(intentCaptor.capture(),
155                 serviceConnectionCaptor.capture(), anyInt(), any(UserHandle.class));
156         assertEquals(TEST_PACKAGE, intentCaptor.getValue().getPackage());
157 
158         // Now we'll pretend bind completed and we sent back the binder.
159         IBinder mockBinder = mock(IBinder.class);
160         when(mockBinder.queryLocalInterface(anyString())).thenReturn(mICallDiagnosticService);
161         serviceConnectionCaptor.getValue().onServiceConnected(TEST_COMPONENT, mockBinder);
162         mServiceConnection = serviceConnectionCaptor.getValue();
163 
164         // Make sure it's sent
165         verify(mICallDiagnosticService).initializeDiagnosticCall(any(ParcelableCall.class));
166     }
167 
168     /**
169      * Verify removing the active call causes it to be removed from the CallDiagnosticService and
170      * that an unbind takes place.
171      */
172     @Test
testRemoveSimCallCausesRemoveAndUnbind()173     public void testRemoveSimCallCausesRemoveAndUnbind() throws RemoteException {
174         testAddSimCallCausesBind();
175         mCallDiagnosticService.onCallRemoved(mCall);
176 
177         verify(mICallDiagnosticService).removeDiagnosticCall(eq(ID_1));
178         verify(mContextProxy).unbindService(eq(mServiceConnection));
179     }
180 
181     /**
182      * Try to add and remove two and verify bind/unbind.
183      */
184     @Test
testAddTwo()185     public void testAddTwo() throws RemoteException {
186         testAddSimCallCausesBind();
187         mCallDiagnosticService.onCallAdded(mCallTwo);
188         verify(mICallDiagnosticService, times(2)).initializeDiagnosticCall(
189                 any(ParcelableCall.class));
190 
191         mCallDiagnosticService.onCallRemoved(mCall);
192         // Not yet!
193         verify(mContextProxy, never()).unbindService(eq(mServiceConnection));
194 
195         mCallDiagnosticService.onCallRemoved(mCallTwo);
196 
197         verify(mICallDiagnosticService).removeDiagnosticCall(eq(ID_1));
198         verify(mICallDiagnosticService).removeDiagnosticCall(eq(ID_2));
199         verify(mContextProxy).unbindService(eq(mServiceConnection));
200     }
201 
202     /**
203      * Verifies we can override the call diagnostic service package to a test package (used by CTS
204      * tests).
205      */
206     @Test
testTestOverride()207     public void testTestOverride() {
208         mCallDiagnosticService.setTestCallDiagnosticService(TEST_CDS_PACKAGE);
209         mCallDiagnosticService.onCallAdded(mCall);
210 
211         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
212         verify(mContextProxy).bindServiceAsUser(intentCaptor.capture(),
213                 any(ServiceConnection.class), anyInt(), any(UserHandle.class));
214         assertEquals(TEST_CDS_PACKAGE, intentCaptor.getValue().getPackage());
215     }
216 }
217