1 /*
2  * Copyright (C) 2018 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 package com.android.ons;
17 
18 import static org.mockito.Mockito.*;
19 
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.IBinder;
24 import android.os.Looper;
25 import android.os.ServiceManager;
26 import android.telephony.AvailableNetworkInfo;
27 import android.telephony.CellIdentityLte;
28 import android.telephony.CellInfo;
29 import android.telephony.CellInfoLte;
30 import android.telephony.SubscriptionInfo;
31 import android.telephony.SubscriptionManager;
32 import android.telephony.TelephonyManager;
33 import android.util.Log;
34 
35 import com.android.internal.telephony.ISub;
36 import com.android.internal.telephony.IUpdateAvailableNetworksCallback;
37 
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 
44 import java.lang.reflect.Field;
45 import java.util.ArrayList;
46 import java.util.List;
47 import java.util.Map;
48 
49 public class ONSProfileSelectorTest extends ONSBaseTest {
50 
51     private MyONSProfileSelector mONSProfileSelector;
52     private boolean testFailed;
53     private boolean mCallbackInvoked;
54     private int mDataSubId;
55     private int mResult;
56     @Mock
57     ONSNetworkScanCtlr mONSNetworkScanCtlr;
58     @Mock
59     TelephonyManager mSubscriptionBoundTelephonyManager;
60     @Mock
61     ISub mISubMock;
62     @Mock
63     IBinder mISubBinderMock;
64     @Mock
65     SubscriptionInfo mSubInfo;
66     private Looper mLooper;
67     private static final String TAG = "ONSProfileSelectorTest";
68 
69     MyONSProfileSelector.ONSProfileSelectionCallback mONSProfileSelectionCallback =
70         new MyONSProfileSelector.ONSProfileSelectionCallback() {
71             public void onProfileSelectionDone() {
72                 mCallbackInvoked = true;
73                 setReady(true);
74             }
75         };
76 
77     public class MyONSProfileSelector extends ONSProfileSelector {
78 
79         public SubscriptionManager.OnOpportunisticSubscriptionsChangedListener mProfileChngLstnrCpy;
80         public BroadcastReceiver mProfileSelectorBroadcastReceiverCpy;
81         public ONSNetworkScanCtlr.NetworkAvailableCallBack mNetworkAvailableCallBackCpy;
82 
MyONSProfileSelector(Context c, MyONSProfileSelector.ONSProfileSelectionCallback aNSProfileSelectionCallback)83         public MyONSProfileSelector(Context c,
84             MyONSProfileSelector.ONSProfileSelectionCallback aNSProfileSelectionCallback) {
85             super(c, aNSProfileSelectionCallback);
86         }
87 
triggerProfileUpdate()88         public void triggerProfileUpdate() {
89             mHandler.sendEmptyMessage(1);
90         }
91 
updateOppSubs()92         public void updateOppSubs() {
93             updateOpportunisticSubscriptions();
94         }
95 
getCurrentPreferredData()96         public int getCurrentPreferredData() {
97             return mCurrentDataSubId;
98         }
99 
setCurrentPreferredData(int subId)100         public void setCurrentPreferredData(int subId) {
101             mCurrentDataSubId = subId;
102         }
103 
init(Context c, MyONSProfileSelector.ONSProfileSelectionCallback aNSProfileSelectionCallback)104         protected void init(Context c,
105             MyONSProfileSelector.ONSProfileSelectionCallback aNSProfileSelectionCallback) {
106             super.init(c, aNSProfileSelectionCallback);
107             this.mSubscriptionManager = ONSProfileSelectorTest.this.mSubscriptionManager;
108             this.mSubscriptionBoundTelephonyManager =
109                 ONSProfileSelectorTest.this.mSubscriptionBoundTelephonyManager;
110             mProfileChngLstnrCpy = mProfileChangeListener;
111             mProfileSelectorBroadcastReceiverCpy = null;
112             mNetworkAvailableCallBackCpy = mNetworkAvailableCallBack;
113             mNetworkScanCtlr = mONSNetworkScanCtlr;
114         }
115     }
116 
addISubService()117     private void addISubService() throws Exception {
118         Field field = ServiceManager.class.getDeclaredField("sCache");
119         field.setAccessible(true);
120         ((Map<String, IBinder>)field.get(null)).put("isub", mISubBinderMock);
121         doReturn(mISubMock).when(mISubBinderMock).queryLocalInterface(any());
122     }
123 
removeISubService()124     private void removeISubService() throws Exception {
125         Field field = ServiceManager.class.getDeclaredField("sCache");
126         field.setAccessible(true);
127         ((Map<String, IBinder>)field.get(null)).remove("isub");
128     }
129 
130     @Before
setUp()131     public void setUp() throws Exception {
132         super.setUp("ONSTest");
133         mLooper = null;
134         MockitoAnnotations.initMocks(this);
135         addISubService();
136     }
137 
138     @After
tearDown()139     public void tearDown() throws Exception {
140         removeISubService();
141         super.tearDown();
142         if (mLooper != null) {
143             mLooper.quit();
144             mLooper.getThread().join();
145         }
146     }
147 
148 
149     @Test
testStartProfileSelectionWithNoOpportunisticSub()150     public void testStartProfileSelectionWithNoOpportunisticSub() {
151         List<CellInfo> results2 = new ArrayList<CellInfo>();
152         CellIdentityLte cellIdentityLte = new CellIdentityLte(310, 210, 1, 1, 1);
153         CellInfoLte cellInfoLte = new CellInfoLte();
154         cellInfoLte.setCellIdentity(cellIdentityLte);
155         results2.add((CellInfo) cellInfoLte);
156         ArrayList<String> mccMncs = new ArrayList<>();
157         mccMncs.add("310210");
158         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(1, 1, mccMncs,
159             new ArrayList<Integer>());
160         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>();
161         availableNetworkInfos.add(availableNetworkInfo);
162 
163         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
164             @Override
165             public void onComplete(int result) {
166                 Log.d(TAG, "mResult end:" + result);
167                 mResult = result;
168             }
169         };
170 
171         mResult = -1;
172         mReady = false;
173         mCallbackInvoked = false;
174         new Thread(new Runnable() {
175             @Override
176             public void run() {
177                 Looper.prepare();
178                 doReturn(true).when(mONSNetworkScanCtlr).startFastNetworkScan(anyObject());
179                 doReturn(new ArrayList<>()).when(mSubscriptionManager)
180                     .getOpportunisticSubscriptions();
181                 mONSProfileSelector = new MyONSProfileSelector(mContext,
182                     mONSProfileSelectionCallback);
183                 mONSProfileSelector.updateOppSubs();
184                 mONSProfileSelector.startProfileSelection(availableNetworkInfos, mCallback);
185                 mLooper = Looper.myLooper();
186                 setReady(true);
187                 Looper.loop();
188             }
189         }).start();
190 
191         // Wait till initialization is complete.
192         waitUntilReady();
193         mReady = false;
194 
195         // Testing startProfileSelection without any oppotunistic data.
196         // should not get any callback invocation.
197         waitUntilReady(100);
198         assertEquals(
199                 TelephonyManager.UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE, mResult);
200         assertFalse(mCallbackInvoked);
201     }
202 
203     @Test
testStartProfileSelectionSuccess()204     public void testStartProfileSelectionSuccess() {
205         int subId = 5;
206         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
207         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(subId, "", 1, "TMO", "TMO", 1, 1,
208             "123", 1, null, "310", "210", "", false, null, "1");
209         SubscriptionInfo subscriptionInfo2 = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
210             "123", 1, null, "310", "211", "", false, null, "1");
211         subscriptionInfoList.add(subscriptionInfo);
212         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(subId);
213 
214         List<CellInfo> results2 = new ArrayList<CellInfo>();
215         CellIdentityLte cellIdentityLte = new CellIdentityLte(310, 210, 1, 1, 1);
216         CellInfoLte cellInfoLte = new CellInfoLte();
217         cellInfoLte.setCellIdentity(cellIdentityLte);
218         results2.add((CellInfo) cellInfoLte);
219         ArrayList<String> mccMncs = new ArrayList<>();
220         mccMncs.add("310210");
221         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(subId, 1, mccMncs,
222             new ArrayList<Integer>());
223         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>();
224         availableNetworkInfos.add(availableNetworkInfo);
225 
226         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
227             @Override
228             public void onComplete(int result) {
229                 mResult = result;
230             }
231         };
232 
233         mResult = -1;
234         mReady = false;
235         new Thread(new Runnable() {
236             @Override
237             public void run() {
238                 Looper.prepare();
239                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
240                     .getOpportunisticSubscriptions();
241                 doReturn(true).when(mSubscriptionManager).isActiveSubId(subId);
242                 doReturn(true).when(mSubscriptionBoundTelephonyManager).enableModemForSlot(
243                     anyInt(), anyBoolean());
244                 mONSProfileSelector = new MyONSProfileSelector(mContext,
245                     new MyONSProfileSelector.ONSProfileSelectionCallback() {
246                         public void onProfileSelectionDone() {
247                             setReady(true);
248                         }
249                     });
250                 mONSProfileSelector.updateOppSubs();
251                 mONSProfileSelector.startProfileSelection(availableNetworkInfos, mCallback);
252                 mLooper = Looper.myLooper();
253                 setReady(true);
254                 Looper.loop();
255             }
256         }).start();
257 
258         // Wait till initialization is complete.
259         waitUntilReady();
260         mReady = false;
261         mDataSubId = -1;
262 
263         // Testing startProfileSelection with oppotunistic sub.
264         // On success onProfileSelectionDone must get invoked.
265         assertFalse(mReady);
266         waitForMs(500);
267         mONSProfileSelector.mNetworkAvailableCallBackCpy.onNetworkAvailability(results2);
268         Intent callbackIntent = new Intent(MyONSProfileSelector.ACTION_SUB_SWITCH);
269         callbackIntent.putExtra("sequenceId", 1);
270         callbackIntent.putExtra("subId", subId);
271         waitUntilReady();
272         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS, mResult);
273         assertTrue(mReady);
274     }
275 
276     @Test
testStartProfileSelectionWithDifferentPrioritySubInfo()277     public void testStartProfileSelectionWithDifferentPrioritySubInfo() {
278         int PRIORITY_HIGH = 1;
279         int PRIORITY_MED = 2;
280 
281         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
282         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
283                 "123", 1, null, "310", "210", "", false, null, "1");
284         subscriptionInfoList.add(subscriptionInfo);
285         SubscriptionInfo subscriptionInfo_2 = new SubscriptionInfo(8, "", 1, "Vzw", "Vzw", 1, 1,
286                 "123", 1, null, "311", "480", "", false, null, "1");
287         subscriptionInfoList.add(subscriptionInfo_2);
288         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
289         doReturn(subscriptionInfo_2).when(mSubscriptionManager).getActiveSubscriptionInfo(8);
290 
291         List<CellInfo> results2 = new ArrayList<CellInfo>();
292         CellIdentityLte cellIdentityLte = new CellIdentityLte(310, 210, 1, 1, 1);
293         CellInfoLte cellInfoLte = new CellInfoLte();
294         cellInfoLte.setCellIdentity(cellIdentityLte);
295         results2.add((CellInfo) cellInfoLte);
296         CellIdentityLte cellIdentityLte_2 = new CellIdentityLte(311, 480, 1, 1, 1);
297         CellInfoLte cellInfoLte_2 = new CellInfoLte();
298         cellInfoLte_2.setCellIdentity(cellIdentityLte_2);
299         results2.add((CellInfo) cellInfoLte_2);
300 
301         ArrayList<String> mccMncs = new ArrayList<>();
302         mccMncs.add("310210");
303         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(5, PRIORITY_MED,
304                 mccMncs, new ArrayList<Integer>());
305         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<>();
306         availableNetworkInfos.add(availableNetworkInfo);
307         ArrayList<String> mccMncs_2 = new ArrayList<>();
308         mccMncs_2.add("311480");
309         AvailableNetworkInfo availableNetworkInfo_2 = new AvailableNetworkInfo(8, PRIORITY_HIGH,
310                 mccMncs_2, new ArrayList<Integer>());
311         availableNetworkInfos.add(availableNetworkInfo_2);
312 
313         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
314             @Override
315             public void onComplete(int result) {
316                 mResult = result;
317             }
318         };
319 
320         mResult = -1;
321         mReady = false;
322         new Thread(new Runnable() {
323             @Override
324             public void run() {
325                 Looper.prepare();
326                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
327                         .getOpportunisticSubscriptions();
328                 doReturn(true).when(mSubscriptionManager).isActiveSubId(anyInt());
329                 doReturn(true).when(mSubscriptionBoundTelephonyManager).enableModemForSlot(
330                         anyInt(), anyBoolean());
331                 mONSProfileSelector = new MyONSProfileSelector(mContext,
332                         new MyONSProfileSelector.ONSProfileSelectionCallback() {
333                             public void onProfileSelectionDone() {
334                                 setReady(true);
335                             }
336                         });
337                 mONSProfileSelector.updateOppSubs();
338                 mONSProfileSelector.startProfileSelection(availableNetworkInfos, mCallback);
339                 mLooper = Looper.myLooper();
340                 setReady(true);
341                 Looper.loop();
342             }
343         }).start();
344         waitUntilReady();
345         waitForMs(500);
346         // get high priority subId
347         int retrieveSubId = mONSProfileSelector.retrieveBestSubscription(results2);
348         mONSProfileSelector.mNetworkAvailableCallBackCpy.onNetworkAvailability(results2);
349         assertEquals(8, retrieveSubId);
350         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS, mResult);
351     }
352 
353     @Test
testStartProfileSelectionWithActivePrimarySimOnESim()354     public void testStartProfileSelectionWithActivePrimarySimOnESim() {
355         List<SubscriptionInfo> opportunisticSubscriptionInfoList = new ArrayList<SubscriptionInfo>();
356         List<SubscriptionInfo> activeSubscriptionInfoList = new ArrayList<SubscriptionInfo>();
357         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
358             "123", 1, null, "310", "210", "", true, null, "1", true, null, 1839, 1);
359         SubscriptionInfo subscriptionInfo2 = new SubscriptionInfo(6, "", 1, "TMO", "TMO", 1, 1,
360             "123", 1, null, "310", "211", "", true, null, "1", false, null, 1839, 1);
361         opportunisticSubscriptionInfoList.add(subscriptionInfo);
362         activeSubscriptionInfoList.add(subscriptionInfo2);
363         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
364         doReturn(subscriptionInfo2).when(mSubscriptionManager).getActiveSubscriptionInfo(6);
365 
366         ArrayList<String> mccMncs = new ArrayList<>();
367         mccMncs.add("310210");
368         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(5, 2, mccMncs,
369             new ArrayList<Integer>());
370         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>();
371         availableNetworkInfos.add(availableNetworkInfo);
372 
373         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
374             @Override
375             public void onComplete(int result) {
376                 mResult = result;
377             }
378         };
379 
380         mResult = -1;
381         mReady = false;
382         new Thread(new Runnable() {
383             @Override
384             public void run() {
385                 Looper.prepare();
386                 doReturn(opportunisticSubscriptionInfoList).when(mSubscriptionManager)
387                     .getOpportunisticSubscriptions();
388                 doReturn(false).when(mSubscriptionManager).isActiveSubId(anyInt());
389                 doReturn(activeSubscriptionInfoList).when(mSubscriptionManager)
390                     .getActiveSubscriptionInfoList(anyBoolean());
391                 mONSProfileSelector = new MyONSProfileSelector(mContext,
392                     new MyONSProfileSelector.ONSProfileSelectionCallback() {
393                         public void onProfileSelectionDone() {
394                             setReady(true);
395                         }
396                     });
397                 mONSProfileSelector.updateOppSubs();
398                 mONSProfileSelector.startProfileSelection(availableNetworkInfos, mCallback);
399                 mLooper = Looper.myLooper();
400                 setReady(true);
401                 Looper.loop();
402             }
403         }).start();
404 
405         // Wait till initialization is complete.
406         waitUntilReady();
407         mReady = false;
408         mDataSubId = -1;
409 
410         // Testing startProfileSelection with opportunistic sub.
411         // On success onProfileSelectionDone must get invoked.
412         assertFalse(mReady);
413         waitForMs(100);
414         Intent callbackIntent = new Intent(MyONSProfileSelector.ACTION_SUB_SWITCH);
415         callbackIntent.putExtra("sequenceId", 1);
416         callbackIntent.putExtra("subId", 5);
417         waitUntilReady();
418         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS, mResult);
419     }
420 
waitForMs(long ms)421     public static void waitForMs(long ms) {
422         try {
423             Thread.sleep(ms);
424         } catch (InterruptedException e) {
425             Log.d(TAG, "InterruptedException while waiting: " + e);
426         }
427     }
428 
429     @Test
testselectProfileForDataWithNoOpportunsticSub()430     public void testselectProfileForDataWithNoOpportunsticSub() {
431         mReady = false;
432         doReturn(new ArrayList<>()).when(mSubscriptionManager).getOpportunisticSubscriptions();
433         new Thread(new Runnable() {
434             @Override
435             public void run() {
436                 Looper.prepare();
437                 mONSProfileSelector = new MyONSProfileSelector(mContext,
438                     new MyONSProfileSelector.ONSProfileSelectionCallback() {
439                         public void onProfileSelectionDone() {
440                         }
441                     });
442                 mLooper = Looper.myLooper();
443                 setReady(true);
444                 Looper.loop();
445             }
446         }).start();
447 
448         // Wait till initialization is complete.
449         waitUntilReady();
450 
451         // Testing selectProfileForData with no oppotunistic sub and the function should
452         // return false.
453         mONSProfileSelector.selectProfileForData(1, false, null);
454     }
455 
456     @Test
testselectProfileForDataWithInActiveSub()457     public void testselectProfileForDataWithInActiveSub() {
458         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
459         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
460             "123", 1, null, "310", "210", "", false, null, "1");
461         subscriptionInfoList.add(subscriptionInfo);
462         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
463         mReady = false;
464         doReturn(new ArrayList<>()).when(mSubscriptionManager).getOpportunisticSubscriptions();
465         new Thread(new Runnable() {
466             @Override
467             public void run() {
468                 Looper.prepare();
469                 mONSProfileSelector = new MyONSProfileSelector(mContext,
470                     new MyONSProfileSelector.ONSProfileSelectionCallback() {
471                         public void onProfileSelectionDone() {
472                         }
473                     });
474                 mLooper = Looper.myLooper();
475                 setReady(true);
476                 Looper.loop();
477             }
478         }).start();
479 
480         // Wait till initialization is complete.
481         waitUntilReady();
482 
483         // Testing selectProfileForData with in active sub and the function should return false.
484         mONSProfileSelector.selectProfileForData(5, false, null);
485     }
486 
487     @Test
testselectProfileForDataWithInvalidSubId()488     public void testselectProfileForDataWithInvalidSubId() {
489         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
490         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
491             "123", 1, null, "310", "210", "", false, null, "1");
492         subscriptionInfoList.add(subscriptionInfo);
493         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
494         mReady = false;
495         doReturn(subscriptionInfoList).when(mSubscriptionManager).getOpportunisticSubscriptions();
496         doNothing().when(mSubscriptionManager).setPreferredDataSubscriptionId(
497             anyInt(), anyBoolean(), any(), any());
498         new Thread(new Runnable() {
499             @Override
500             public void run() {
501                 Looper.prepare();
502                 mONSProfileSelector = new MyONSProfileSelector(mContext,
503                     new MyONSProfileSelector.ONSProfileSelectionCallback() {
504                         public void onProfileSelectionDone() {
505                         }
506                     });
507                 mLooper = Looper.myLooper();
508                 setReady(true);
509                 Looper.loop();
510             }
511         }).start();
512 
513         // Wait till initialization is complete.
514         waitUntilReady();
515 
516         // Testing selectProfileForData with INVALID_SUBSCRIPTION_ID and the function should
517         // return true.
518         mONSProfileSelector.selectProfileForData(
519             SubscriptionManager.INVALID_SUBSCRIPTION_ID, false, null);
520     }
521 
522     @Test
testselectProfileForDataWithValidSub()523     public void testselectProfileForDataWithValidSub() {
524         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
525         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
526             "123", 1, null, "310", "210", "", false, null, "1");
527         subscriptionInfoList.add(subscriptionInfo);
528         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
529         mReady = false;
530         doReturn(subscriptionInfoList).when(mSubscriptionManager)
531             .getActiveSubscriptionInfoList();
532         doNothing().when(mSubscriptionManager).setPreferredDataSubscriptionId(
533             anyInt(), anyBoolean(), any(), any());
534         new Thread(new Runnable() {
535             @Override
536             public void run() {
537                 Looper.prepare();
538                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
539                     .getOpportunisticSubscriptions();
540                 mONSProfileSelector = new MyONSProfileSelector(mContext,
541                     new MyONSProfileSelector.ONSProfileSelectionCallback() {
542                         public void onProfileSelectionDone() {
543                         }
544                     });
545                 mONSProfileSelector.updateOppSubs();
546                 mLooper = Looper.myLooper();
547                 setReady(true);
548                 Looper.loop();
549             }
550         }).start();
551 
552         // Wait till initialization is complete.
553         waitUntilReady();
554 
555         // Testing selectProfileForData with valid opportunistic sub and the function should
556         // return true.
557         mONSProfileSelector.selectProfileForData(5, false, null);
558     }
559 
560     @Test
testStartProfileSelectionSuccessWithSameArgumentsAgain()561     public void testStartProfileSelectionSuccessWithSameArgumentsAgain() {
562         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
563         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
564             "123", 1, null, "310", "210", "", false, null, "1");
565         SubscriptionInfo subscriptionInfo2 = new SubscriptionInfo(6, "", 1, "TMO", "TMO", 1, 1,
566             "123", 1, null, "310", "211", "", false, null, "1");
567         subscriptionInfoList.add(subscriptionInfo);
568         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
569         doReturn(subscriptionInfo2).when(mSubscriptionManager).getActiveSubscriptionInfo(6);
570 
571         List<CellInfo> results2 = new ArrayList<CellInfo>();
572         CellIdentityLte cellIdentityLte = new CellIdentityLte(310, 210, 1, 1, 1);
573         CellInfoLte cellInfoLte = new CellInfoLte();
574         cellInfoLte.setCellIdentity(cellIdentityLte);
575         results2.add((CellInfo) cellInfoLte);
576         ArrayList<String> mccMncs = new ArrayList<>();
577         mccMncs.add("310210");
578         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(5, 1, mccMncs,
579             new ArrayList<Integer>());
580         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>();
581         availableNetworkInfos.add(availableNetworkInfo);
582 
583         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
584             @Override
585             public void onComplete(int result) {
586                 mResult = result;
587             }
588         };
589 
590         mResult = -1;
591         mReady = false;
592         mONSProfileSelector = new MyONSProfileSelector(mContext,
593             new MyONSProfileSelector.ONSProfileSelectionCallback() {
594                 public void onProfileSelectionDone() {
595                     setReady(true);
596                 }
597             });
598         new Thread(new Runnable() {
599             @Override
600             public void run() {
601                 Looper.prepare();
602                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
603                     .getOpportunisticSubscriptions();
604                 doReturn(true).when(mSubscriptionManager).isActiveSubId(anyInt());
605                 doReturn(true).when(mSubscriptionBoundTelephonyManager).enableModemForSlot(
606                     anyInt(), anyBoolean());
607 
608                 mONSProfileSelector.updateOppSubs();
609                 mONSProfileSelector.startProfileSelection(availableNetworkInfos, mCallback);
610                 mLooper = Looper.myLooper();
611                 setReady(true);
612                 Looper.loop();
613             }
614         }).start();
615 
616         // Wait till initialization is complete.
617         waitUntilReady();
618         mReady = false;
619         mDataSubId = -1;
620 
621         // Testing startProfileSelection with oppotunistic sub.
622         // On success onProfileSelectionDone must get invoked.
623         assertFalse(mReady);
624         waitForMs(500);
625         mONSProfileSelector.mNetworkAvailableCallBackCpy.onNetworkAvailability(results2);
626         Intent callbackIntent = new Intent(MyONSProfileSelector.ACTION_SUB_SWITCH);
627         callbackIntent.putExtra("sequenceId", 1);
628         callbackIntent.putExtra("subId", 5);
629         waitUntilReady();
630         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS, mResult);
631         assertTrue(mReady);
632 
633         mResult = -1;
634         mReady = false;
635         new Thread(new Runnable() {
636             @Override
637             public void run() {
638                 Looper.prepare();
639                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
640                     .getOpportunisticSubscriptions();
641                 doReturn(true).when(mSubscriptionManager).isActiveSubId(anyInt());
642                 doReturn(true).when(mSubscriptionBoundTelephonyManager).enableModemForSlot(
643                     anyInt(), anyBoolean());
644                 mONSProfileSelector.updateOppSubs();
645                 mONSProfileSelector.startProfileSelection(availableNetworkInfos, mCallback);
646                 mLooper = Looper.myLooper();
647                 setReady(true);
648                 Looper.loop();
649             }
650         }).start();
651 
652         // Wait till initialization is complete.
653         waitUntilReady();
654         mReady = false;
655         mDataSubId = -1;
656 
657         // Testing startProfileSelection with oppotunistic sub.
658         // On success onProfileSelectionDone must get invoked.
659         assertFalse(mReady);
660         waitForMs(500);
661         mONSProfileSelector.mNetworkAvailableCallBackCpy.onNetworkAvailability(results2);
662         waitUntilReady();
663         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS, mResult);
664         assertTrue(mReady);
665     }
666 
667     @Test
testStopProfileSelectionWithPreferredDataOnSame()668     public void testStopProfileSelectionWithPreferredDataOnSame() {
669         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
670         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
671                 "123", 1, null, "310", "210", "", true, null, "1", true, null, 0, 0);
672         subscriptionInfoList.add(subscriptionInfo);
673         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
674 
675         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
676             @Override
677             public void onComplete(int result) {
678                 mResult = result;
679             }
680         };
681 
682         mResult = -1;
683         mReady = false;
684         new Thread(new Runnable() {
685             @Override
686             public void run() {
687                 Looper.prepare();
688                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
689                         .getOpportunisticSubscriptions();
690                 doReturn(true).when(mSubscriptionManager).isActiveSubId(anyInt());
691                 doReturn(true).when(mSubscriptionBoundTelephonyManager).enableModemForSlot(
692                         anyInt(), anyBoolean());
693                 doReturn(5).when(mSubscriptionManager).getPreferredDataSubscriptionId();
694                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
695                         .getActiveSubscriptionInfoList(anyBoolean());
696 
697                 mONSProfileSelector = new MyONSProfileSelector(mContext,
698                         new MyONSProfileSelector.ONSProfileSelectionCallback() {
699                             public void onProfileSelectionDone() {
700                                 setReady(true);
701                             }
702                         });
703                 mONSProfileSelector.updateOppSubs();
704                 mONSProfileSelector.setCurrentPreferredData(5);
705                 mONSProfileSelector.stopProfileSelection(null);
706                 mLooper = Looper.myLooper();
707                 setReady(true);
708                 Looper.loop();
709             }
710         }).start();
711         waitUntilReady();
712         waitForMs(500);
713         assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mONSProfileSelector.getCurrentPreferredData());
714     }
715 
716     @Test
testStopProfileSelectionWithPreferredDataOnDifferent()717     public void testStopProfileSelectionWithPreferredDataOnDifferent() {
718         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<SubscriptionInfo>();
719         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(5, "", 1, "TMO", "TMO", 1, 1,
720                 "123", 1, null, "310", "210", "", true, null, "1", true, null, 0, 0);
721         subscriptionInfoList.add(subscriptionInfo);
722         doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(5);
723 
724         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
725             @Override
726             public void onComplete(int result) {
727                 mResult = result;
728             }
729         };
730 
731         mResult = -1;
732         mReady = false;
733         new Thread(new Runnable() {
734             @Override
735             public void run() {
736                 Looper.prepare();
737                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
738                         .getOpportunisticSubscriptions();
739                 doReturn(true).when(mSubscriptionManager).isActiveSubId(anyInt());
740                 doReturn(true).when(mSubscriptionBoundTelephonyManager).enableModemForSlot(
741                         anyInt(), anyBoolean());
742                 doReturn(4).when(mSubscriptionManager).getPreferredDataSubscriptionId();
743                 doReturn(subscriptionInfoList).when(mSubscriptionManager)
744                         .getActiveSubscriptionInfoList(anyBoolean());
745 
746                 mONSProfileSelector = new MyONSProfileSelector(mContext,
747                         new MyONSProfileSelector.ONSProfileSelectionCallback() {
748                             public void onProfileSelectionDone() {
749                                 setReady(true);
750                             }
751                         });
752                 mONSProfileSelector.updateOppSubs();
753                 mONSProfileSelector.setCurrentPreferredData(5);
754                 mONSProfileSelector.stopProfileSelection(null);
755                 mLooper = Looper.myLooper();
756                 setReady(true);
757                 Looper.loop();
758             }
759         }).start();
760         waitUntilReady();
761         waitForMs(500);
762         assertEquals(mONSProfileSelector.getCurrentPreferredData(), 5);
763     }
764 }
765