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.imsserviceentitlement;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.anyBoolean;
22 import static org.mockito.Mockito.never;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import android.app.job.JobParameters;
27 import android.app.job.JobScheduler;
28 import android.content.Context;
29 import android.os.PersistableBundle;
30 import android.telephony.CarrierConfigManager;
31 import android.telephony.SubscriptionInfo;
32 import android.telephony.SubscriptionManager;
33 import android.util.SparseArray;
34 
35 import androidx.test.core.app.ApplicationProvider;
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import com.android.imsserviceentitlement.entitlement.EntitlementResult;
39 import com.android.imsserviceentitlement.job.JobManager;
40 import com.android.imsserviceentitlement.ts43.Ts43SmsOverIpStatus;
41 import com.android.imsserviceentitlement.ts43.Ts43VolteStatus;
42 import com.android.imsserviceentitlement.ts43.Ts43VowifiStatus;
43 import com.android.imsserviceentitlement.ts43.Ts43VowifiStatus.AddrStatus;
44 import com.android.imsserviceentitlement.ts43.Ts43VowifiStatus.EntitlementStatus;
45 import com.android.imsserviceentitlement.ts43.Ts43VowifiStatus.ProvStatus;
46 import com.android.imsserviceentitlement.ts43.Ts43VowifiStatus.TcStatus;
47 import com.android.imsserviceentitlement.utils.ImsUtils;
48 
49 import org.junit.Before;
50 import org.junit.Rule;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.mockito.Mock;
54 import org.mockito.Spy;
55 import org.mockito.junit.MockitoJUnit;
56 import org.mockito.junit.MockitoRule;
57 
58 import java.lang.reflect.Field;
59 
60 @RunWith(AndroidJUnit4.class)
61 public class ImsEntitlementPollingServiceTest {
62     @Rule public final MockitoRule rule = MockitoJUnit.rule();
63 
64     @Spy private Context mContext = ApplicationProvider.getApplicationContext();
65 
66     @Mock private ImsUtils mImsUtils;
67     @Mock private JobParameters mJobParameters;
68     @Mock private SubscriptionManager mSubscriptionManager;
69     @Mock private SubscriptionInfo mSubscriptionInfo;
70     @Mock private ImsEntitlementApi mImsEntitlementApi;
71     @Mock private CarrierConfigManager mCarrierConfigManager;
72 
73     private ImsEntitlementPollingService mService;
74     private JobScheduler mScheduler;
75 
76     private static final int SUB_ID = 1;
77     private static final int SLOT_ID = 0;
78 
79     @Before
setUp()80     public void setUp() throws Exception {
81         mService = new ImsEntitlementPollingService();
82         mService.attachBaseContext(mContext);
83         mService.onCreate();
84         mService.onBind(null);
85         mService.injectImsEntitlementApi(mImsEntitlementApi);
86         mScheduler = mContext.getSystemService(JobScheduler.class);
87         setActivedSubscription();
88         setupImsUtils();
89         setJobParameters();
90         setWfcEnabledByUser(true);
91         setImsProvisioningBool(false);
92     }
93 
94     @Test
doEntitlementCheck_isWfcEnabledByUserFalse_doNothing()95     public void doEntitlementCheck_isWfcEnabledByUserFalse_doNothing() throws Exception {
96         setWfcEnabledByUser(false);
97 
98         mService.onStartJob(mJobParameters);
99         mService.mOngoingTask.get(); // wait for job finish.
100 
101         verify(mImsEntitlementApi, never()).checkEntitlementStatus();
102     }
103 
104 
105     @Test
doEntitlementCheck_shouldTurnOffWfc_disableWfc()106     public void doEntitlementCheck_shouldTurnOffWfc_disableWfc() throws Exception {
107         EntitlementResult entitlementResult = getEntitlementResult(sDisableVoWiFi);
108         when(mImsEntitlementApi.checkEntitlementStatus()).thenReturn(entitlementResult);
109 
110         mService.onStartJob(mJobParameters);
111         mService.mOngoingTask.get(); // wait for job finish.
112 
113         verify(mImsUtils).disableWfc();
114     }
115 
116     @Test
doEntitlementCheck_shouldNotTurnOffWfc_enableWfc()117     public void doEntitlementCheck_shouldNotTurnOffWfc_enableWfc() throws Exception {
118         EntitlementResult entitlementResult = getEntitlementResult(sEnableVoWiFi);
119         when(mImsEntitlementApi.checkEntitlementStatus()).thenReturn(entitlementResult);
120 
121         mService.onStartJob(mJobParameters);
122         mService.mOngoingTask.get(); // wait for job finish.
123 
124         verify(mImsUtils, never()).disableWfc();
125     }
126 
127     @Test
doEntitlementCheck_shouldTurnOffImsApps_setAllProvisionedFalse()128     public void doEntitlementCheck_shouldTurnOffImsApps_setAllProvisionedFalse() throws Exception {
129         setImsProvisioningBool(true);
130         EntitlementResult entitlementResult = getImsEntitlementResult(
131                 sDisableVoWiFi,
132                 sDisableVoLte,
133                 sDisableSmsoverip
134         );
135         when(mImsEntitlementApi.checkEntitlementStatus()).thenReturn(entitlementResult);
136 
137         mService.onStartJob(mJobParameters);
138         mService.mOngoingTask.get(); // wait for job finish.
139 
140         verify(mImsUtils).setVolteProvisioned(false);
141         verify(mImsUtils).setVowifiProvisioned(false);
142         verify(mImsUtils).setSmsoipProvisioned(false);
143     }
144 
145     @Test
doEntitlementCheck_shouldTurnOnImsApps_setAllProvisionedTrue()146     public void doEntitlementCheck_shouldTurnOnImsApps_setAllProvisionedTrue() throws Exception {
147         setImsProvisioningBool(true);
148         EntitlementResult entitlementResult = getImsEntitlementResult(
149                 sEnableVoWiFi,
150                 sEnableVoLte,
151                 sEnableSmsoverip
152         );
153         when(mImsEntitlementApi.checkEntitlementStatus()).thenReturn(entitlementResult);
154 
155         mService.onStartJob(mJobParameters);
156         mService.mOngoingTask.get(); // wait for job finish.
157 
158         verify(mImsUtils).setVolteProvisioned(true);
159         verify(mImsUtils).setVowifiProvisioned(true);
160         verify(mImsUtils).setSmsoipProvisioned(true);
161     }
162 
163     @Test
doEntitlementCheck_ImsEntitlementShouldRetry_rescheduleJob()164     public void doEntitlementCheck_ImsEntitlementShouldRetry_rescheduleJob() throws Exception {
165         setImsProvisioningBool(true);
166         EntitlementResult entitlementResult =
167                 EntitlementResult.builder().setRetryAfterSeconds(120).build();
168         when(mImsEntitlementApi.checkEntitlementStatus()).thenReturn(entitlementResult);
169 
170         mService.onStartJob(mJobParameters);
171         mService.mOngoingTask.get(); // wait for job finish.
172 
173         verify(mImsUtils, never()).setVolteProvisioned(anyBoolean());
174         verify(mImsUtils, never()).setVowifiProvisioned(anyBoolean());
175         verify(mImsUtils, never()).setSmsoipProvisioned(anyBoolean());
176         assertThat(
177                 mScheduler.getPendingJob(
178                         jobIdWithSubId(JobManager.QUERY_ENTITLEMENT_STATUS_JOB_ID, SUB_ID)))
179                 .isNotNull();
180     }
181 
182     @Test
doEntitlementCheck_WfcEntitlementShouldRetry_rescheduleJob()183     public void doEntitlementCheck_WfcEntitlementShouldRetry_rescheduleJob() throws Exception {
184         EntitlementResult entitlementResult =
185                 EntitlementResult.builder().setRetryAfterSeconds(120).build();
186         when(mImsEntitlementApi.checkEntitlementStatus()).thenReturn(entitlementResult);
187 
188         mService.onStartJob(mJobParameters);
189         mService.mOngoingTask.get(); // wait for job finish.
190 
191         verify(mImsUtils, never()).setVolteProvisioned(anyBoolean());
192         verify(mImsUtils, never()).setVowifiProvisioned(anyBoolean());
193         verify(mImsUtils, never()).setSmsoipProvisioned(anyBoolean());
194         assertThat(
195                 mScheduler.getPendingJob(
196                         jobIdWithSubId(JobManager.QUERY_ENTITLEMENT_STATUS_JOB_ID, SUB_ID)))
197                 .isNotNull();
198     }
199 
200     @Test
enqueueJob_hasJob()201     public void enqueueJob_hasJob() {
202         ImsEntitlementPollingService.enqueueJob(mContext, SUB_ID, 0);
203 
204         assertThat(
205                 mScheduler.getPendingJob(
206                         jobIdWithSubId(JobManager.QUERY_ENTITLEMENT_STATUS_JOB_ID, SUB_ID)))
207                 .isNotNull();
208     }
209 
setActivedSubscription()210     private void setActivedSubscription() {
211         when(mSubscriptionInfo.getSimSlotIndex()).thenReturn(SLOT_ID);
212         when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mSubscriptionInfo);
213         when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE))
214                 .thenReturn(mSubscriptionManager);
215     }
216 
setupImsUtils()217     private void setupImsUtils() throws Exception {
218         SparseArray<ImsUtils> imsUtilsInstances = new SparseArray<>();
219         imsUtilsInstances.put(SUB_ID, mImsUtils);
220         Field field = ImsUtils.class.getDeclaredField("sInstances");
221         field.setAccessible(true);
222         field.set(null, imsUtilsInstances);
223     }
224 
setWfcEnabledByUser(boolean isEnabled)225     private void setWfcEnabledByUser(boolean isEnabled) {
226         when(mImsUtils.isWfcEnabledByUser()).thenReturn(isEnabled);
227     }
228 
setJobParameters()229     private void setJobParameters() {
230         PersistableBundle bundle = new PersistableBundle();
231         bundle.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SUB_ID);
232         bundle.putInt(JobManager.EXTRA_SLOT_ID, SLOT_ID);
233         when(mJobParameters.getExtras()).thenReturn(bundle);
234         when(mJobParameters.getJobId()).thenReturn(JobManager.QUERY_ENTITLEMENT_STATUS_JOB_ID);
235     }
236 
setImsProvisioningBool(boolean provisioning)237     private void setImsProvisioningBool(boolean provisioning) {
238         PersistableBundle carrierConfig = new PersistableBundle();
239         carrierConfig.putBoolean(
240                 CarrierConfigManager.ImsServiceEntitlement.KEY_IMS_PROVISIONING_BOOL,
241                 provisioning
242         );
243         when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(carrierConfig);
244         when(mContext.getSystemService(CarrierConfigManager.class))
245                 .thenReturn(mCarrierConfigManager);
246     }
247 
getEntitlementResult(Ts43VowifiStatus vowifiStatus)248     private static EntitlementResult getEntitlementResult(Ts43VowifiStatus vowifiStatus) {
249         return EntitlementResult.builder()
250                 .setVowifiStatus(vowifiStatus)
251                 .build();
252     }
253 
getImsEntitlementResult( Ts43VowifiStatus vowifiStatus, Ts43VolteStatus volteStatus, Ts43SmsOverIpStatus smsOverIpStatus)254     private static EntitlementResult getImsEntitlementResult(
255             Ts43VowifiStatus vowifiStatus,
256             Ts43VolteStatus volteStatus,
257             Ts43SmsOverIpStatus smsOverIpStatus) {
258         return EntitlementResult.builder()
259                 .setVowifiStatus(vowifiStatus)
260                 .setVolteStatus(volteStatus)
261                 .setSmsoveripStatus(smsOverIpStatus)
262                 .build();
263     }
264 
jobIdWithSubId(int jobId, int subId)265     private int jobIdWithSubId(int jobId, int subId) {
266         return 1000 * subId + jobId;
267     }
268 
269     private static final Ts43VowifiStatus sDisableVoWiFi =
270             Ts43VowifiStatus.builder()
271                     .setEntitlementStatus(EntitlementStatus.DISABLED)
272                     .setTcStatus(TcStatus.NOT_AVAILABLE)
273                     .setAddrStatus(AddrStatus.NOT_AVAILABLE)
274                     .setProvStatus(ProvStatus.NOT_PROVISIONED)
275                     .build();
276 
277     private static final Ts43VowifiStatus sEnableVoWiFi =
278             Ts43VowifiStatus.builder()
279                     .setEntitlementStatus(EntitlementStatus.ENABLED)
280                     .setTcStatus(TcStatus.AVAILABLE)
281                     .setAddrStatus(AddrStatus.AVAILABLE)
282                     .setProvStatus(ProvStatus.PROVISIONED)
283                     .build();
284 
285     private static final Ts43VolteStatus sDisableVoLte =
286             Ts43VolteStatus.builder()
287                     .setEntitlementStatus(EntitlementStatus.DISABLED)
288                     .build();
289 
290     private static final Ts43VolteStatus sEnableVoLte =
291             Ts43VolteStatus.builder()
292                     .setEntitlementStatus(EntitlementStatus.ENABLED)
293                     .build();
294 
295     private static final Ts43SmsOverIpStatus sDisableSmsoverip =
296             Ts43SmsOverIpStatus.builder()
297                     .setEntitlementStatus(EntitlementStatus.DISABLED)
298                     .build();
299 
300     private static final Ts43SmsOverIpStatus sEnableSmsoverip =
301             Ts43SmsOverIpStatus.builder()
302                     .setEntitlementStatus(EntitlementStatus.ENABLED)
303                     .build();
304 }
305