• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.telephony.utility;
17 
18 import android.app.Instrumentation;
19 import android.content.Context;
20 import android.device.collectors.util.SendToInstrumentation;
21 import android.os.Bundle;
22 import android.se.omapi.Channel;
23 import android.se.omapi.Reader;
24 import android.se.omapi.SEService;
25 import android.se.omapi.SEService.OnConnectedListener;
26 import android.se.omapi.Session;
27 import android.telephony.TelephonyManager;
28 
29 import java.util.Timer;
30 import java.util.TimerTask;
31 import java.util.concurrent.Executor;
32 
33 import androidx.test.InstrumentationRegistry;
34 import androidx.test.runner.AndroidJUnit4;
35 
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 
41 import static org.junit.Assert.assertNotNull;
42 
43 /**
44  * Instrumentation test that allows to get some telephony states.
45  * <p>If TelephonyManager does not exists or is not supported, a test failure will be reported
46  */
47 @RunWith(AndroidJUnit4.class)
48 public class SimCardUtil {
49 
50     private static final String SIM_STATE = "sim_state";
51     private static final String CARRIER_PRIVILEGES = "has_carried_privileges";
52     private static final String SECURED_ELEMENT = "has_secured_element";
53     private static final String SE_SERVICE = "has_se_service";
54 
55     private final long SERVICE_CONNECTION_TIME_OUT = 3000;
56 
57     private SEService mSeService;
58     private Object mServiceMutex = new Object();
59     private Timer mConnectionTimer;
60     private ServiceConnectionTimerTask mTimerTask = new ServiceConnectionTimerTask();
61     private boolean mConnected = false;
62     private final OnConnectedListener mListener = new OnConnectedListener() {
63                 @Override
64                 public void onConnected() {
65                     synchronized (mServiceMutex) {
66                         mConnected = true;
67                         mServiceMutex.notify();
68                     }
69                 }
70             };
71 
72     @Before
setUp()73     public void setUp() throws Exception {
74         mSeService = new SEService(InstrumentationRegistry.getContext(), new SynchronousExecutor(), mListener);
75         mConnectionTimer = new Timer();
76         mConnectionTimer.schedule(mTimerTask, SERVICE_CONNECTION_TIME_OUT);
77     }
78 
79     @Test
getSimCardInformation()80     public void getSimCardInformation() throws Exception {
81         // Context of the app under test.
82         Context context = InstrumentationRegistry.getTargetContext();
83         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
84 
85         TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
86         assertNotNull(tm);
87 
88         Bundle returnBundle = new Bundle();
89         // Sim card - SIM_STATE_READY 5
90         int state = tm.getSimState();
91         returnBundle.putInt(SIM_STATE, state);
92 
93         // UICC check
94         boolean carrierPrivileges = tm.hasCarrierPrivileges();
95         returnBundle.putBoolean(CARRIER_PRIVILEGES, carrierPrivileges);
96 
97         // Secured element check
98         if (waitForConnection()) {
99             Reader[] readers = mSeService.getReaders();
100             for (Reader reader : readers) {
101                 returnBundle.putBoolean(SECURED_ELEMENT, reader.isSecureElementPresent());
102                 returnBundle.putBoolean(SE_SERVICE, reader.getSEService() != null ? true : false);
103             }
104         } else {
105             returnBundle.putBoolean(SECURED_ELEMENT, false);
106             returnBundle.putBoolean(SE_SERVICE, false);
107         }
108         SendToInstrumentation.sendBundle(instrumentation, returnBundle);
109     }
110 
111     @After
tearDown()112     public void tearDown() throws Exception {
113         if (mSeService != null && mSeService.isConnected()) {
114             mSeService.shutdown();
115             mConnected = false;
116         }
117     }
118 
waitForConnection()119     private boolean waitForConnection() {
120         synchronized (mServiceMutex) {
121             if (!mConnected) {
122                 try {
123                     mServiceMutex.wait();
124                 } catch (InterruptedException e) {
125                     return false;
126                 }
127             }
128             if (!mConnected) {
129                 return false;
130             }
131             if (mConnectionTimer != null) {
132                 mConnectionTimer.cancel();
133             }
134             return true;
135         }
136     }
137 
138     private class SynchronousExecutor implements Executor {
execute(Runnable r)139         public void execute(Runnable r) {
140             r.run();
141         }
142     }
143 
144     private class ServiceConnectionTimerTask extends TimerTask {
145         @Override
run()146         public void run() {
147             synchronized (mServiceMutex) {
148                 mServiceMutex.notifyAll();
149             }
150         }
151     }
152 }
153