1/*
2 * Copyright (C) 2017 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
17package com.android.internal.telephony;
18
19import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertNull;
22import static org.mockito.Matchers.eq;
23import static org.mockito.Mockito.doReturn;
24
25import android.database.Cursor;
26import android.database.MatrixCursor;
27import android.net.Uri;
28import android.os.HandlerThread;
29import android.provider.Telephony.CarrierId;
30import android.provider.Telephony.Carriers;
31import android.test.mock.MockContentProvider;
32import android.test.mock.MockContentResolver;
33import android.test.suitebuilder.annotation.SmallTest;
34
35import org.junit.After;
36import org.junit.Before;
37import org.junit.Test;
38
39import java.util.Arrays;
40
41public class CarrierIdentifierTest extends TelephonyTest {
42    private static final String MCCMNC = "311480";
43    private static final String NAME = "VZW";
44    private static final int CID_VZW = 1;
45
46    private static final String SPN_FI = "PROJECT FI";
47    private static final String NAME_FI = "FI";
48    private static final int CID_FI = 2;
49
50    private static final String NAME_DOCOMO = "DOCOMO";
51    private static final String APN_DOCOMO = "mopera.net";
52    private static final int CID_DOCOMO = 3;
53
54    private static final String NAME_TMO = "TMO";
55    private static final String GID1 = "ae";
56    private static final int CID_TMO = 4;
57
58    private static final int CID_UNKNOWN = -1;
59
60    // events to trigger carrier identification
61    private static final int SIM_LOAD_EVENT       = 1;
62    private static final int SIM_ABSENT_EVENT     = 2;
63    private static final int SPN_OVERRIDE_EVENT   = 3;
64    private static final int PREFER_APN_SET_EVENT = 5;
65
66    private CarrierIdentifier mCarrierIdentifier;
67    private CarrierIdentifierHandler mCarrierIdentifierHandler;
68
69    private class CarrierIdentifierHandler extends HandlerThread {
70        private CarrierIdentifierHandler(String name) {
71            super(name);
72        }
73
74        @Override
75        public void onLooperPrepared() {
76            mCarrierIdentifier = new CarrierIdentifier(mPhone);
77            setReady(true);
78        }
79    }
80
81    @Before
82    public void setUp() throws Exception {
83        logd("CarrierIdentifierTest +Setup!");
84        super.setUp(getClass().getSimpleName());
85        ((MockContentResolver) mContext.getContentResolver()).addProvider(
86                CarrierId.AUTHORITY, new CarrierIdContentProvider());
87        // start handler thread
88        mCarrierIdentifierHandler = new CarrierIdentifierHandler(getClass().getSimpleName());
89        mCarrierIdentifierHandler.start();
90        waitUntilReady();
91        logd("CarrierIdentifierTest -Setup!");
92    }
93
94    @After
95    public void tearDown() throws Exception {
96        logd("CarrierIdentifier -tearDown");
97        mCarrierIdentifier.removeCallbacksAndMessages(null);
98        mCarrierIdentifier = null;
99        mCarrierIdentifierHandler.quit();
100        super.tearDown();
101    }
102
103    @Test
104    @SmallTest
105    public void testCarrierMatch() {
106        int phoneId = mPhone.getPhoneId();
107        doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
108        // trigger sim loading event
109        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
110        waitForMs(200);
111        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
112        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
113
114        doReturn(SPN_FI).when(mTelephonyManager).getSimOperatorNameForPhone(eq(phoneId));
115        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
116        waitForMs(200);
117        assertEquals(CID_FI, mCarrierIdentifier.getCarrierId());
118        assertEquals(NAME_FI, mCarrierIdentifier.getCarrierName());
119
120        doReturn(GID1).when(mPhone).getGroupIdLevel1();
121        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
122        waitForMs(200);
123        assertEquals(CID_TMO, mCarrierIdentifier.getCarrierId());
124        assertEquals(NAME_TMO, mCarrierIdentifier.getCarrierName());
125    }
126
127    @Test
128    @SmallTest
129    public void testCarrierMatchSpnOverride() {
130        int phoneId = mPhone.getPhoneId();
131        doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
132        // trigger sim loading event
133        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
134        waitForMs(200);
135        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
136        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
137        // spn override
138        doReturn(SPN_FI).when(mTelephonyManager).getSimOperatorNameForPhone(eq(phoneId));
139        mCarrierIdentifier.sendEmptyMessage(SPN_OVERRIDE_EVENT);
140        waitForMs(200);
141        assertEquals(CID_FI, mCarrierIdentifier.getCarrierId());
142        assertEquals(NAME_FI, mCarrierIdentifier.getCarrierName());
143    }
144
145    @Test
146    @SmallTest
147    public void testCarrierMatchSimAbsent() {
148        int phoneId = mPhone.getPhoneId();
149        doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
150        // trigger sim loading event
151        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
152        waitForMs(200);
153        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
154        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
155        // trigger sim absent event
156        mCarrierIdentifier.sendEmptyMessage(SIM_ABSENT_EVENT);
157        waitForMs(200);
158        assertEquals(CID_UNKNOWN, mCarrierIdentifier.getCarrierId());
159        assertNull(mCarrierIdentifier.getCarrierName());
160    }
161
162    @Test
163    @SmallTest
164    public void testCarrierNoMatch() {
165        // un-configured MCCMNC
166        int phoneId = mPhone.getPhoneId();
167        doReturn("12345").when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
168        // trigger sim loading event
169        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
170        waitForMs(200);
171        assertEquals(CID_UNKNOWN, mCarrierIdentifier.getCarrierId());
172        assertNull(mCarrierIdentifier.getCarrierName());
173    }
174
175    @Test
176    @SmallTest
177    public void testCarrierMatchPreferApnChange() {
178        int phoneId = mPhone.getPhoneId();
179        doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
180        // trigger sim loading event
181        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
182        waitForMs(200);
183        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
184        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
185        // mock apn
186        ((MockContentResolver) mContext.getContentResolver()).addProvider(
187                Carriers.CONTENT_URI.getAuthority(), new CarrierIdContentProvider());
188        mCarrierIdentifier.sendEmptyMessage(PREFER_APN_SET_EVENT);
189        waitForMs(200);
190        assertEquals(CID_DOCOMO, mCarrierIdentifier.getCarrierId());
191        assertEquals(NAME_DOCOMO, mCarrierIdentifier.getCarrierName());
192    }
193
194    private class CarrierIdContentProvider extends MockContentProvider {
195        @Override
196        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
197                String sortOrder) {
198            logd("CarrierIdContentProvider: query");
199            logd("   uri = " + uri);
200            logd("   projection = " + Arrays.toString(projection));
201            logd("   selection = " + selection);
202            logd("   selectionArgs = " + Arrays.toString(selectionArgs));
203            logd("   sortOrder = " + sortOrder);
204
205            if (CarrierId.All.CONTENT_URI.getAuthority().equals(
206                    uri.getAuthority())) {
207                MatrixCursor mc = new MatrixCursor(
208                        new String[]{CarrierId._ID,
209                                CarrierId.All.MCCMNC,
210                                CarrierId.All.GID1,
211                                CarrierId.All.GID2,
212                                CarrierId.All.PLMN,
213                                CarrierId.All.IMSI_PREFIX_XPATTERN,
214                                CarrierId.All.ICCID_PREFIX,
215                                CarrierId.All.SPN,
216                                CarrierId.All.APN,
217                                CarrierId.CARRIER_NAME,
218                                CarrierId.CARRIER_ID});
219
220                mc.addRow(new Object[] {
221                        1,                      // id
222                        MCCMNC,                 // mccmnc
223                        null,                   // gid1
224                        null,                   // gid2
225                        null,                   // plmn
226                        null,                   // imsi_prefix
227                        null,                   // iccid_prefix
228                        null,                   // spn
229                        null,                   // apn
230                        NAME,                   // carrier name
231                        CID_VZW,                // cid
232                });
233                mc.addRow(new Object[] {
234                        2,                      // id
235                        MCCMNC,                 // mccmnc
236                        GID1,                   // gid1
237                        null,                   // gid2
238                        null,                   // plmn
239                        null,                   // imsi_prefix
240                        null,                   // iccid_prefix
241                        null,                   // spn
242                        null,                   // apn
243                        NAME_TMO,               // carrier name
244                        CID_TMO,                // cid
245                });
246                mc.addRow(new Object[] {
247                        3,                      // id
248                        MCCMNC,                 // mccmnc
249                        null,                   // gid1
250                        null,                   // gid2
251                        null,                   // plmn
252                        null,                   // imsi_prefix
253                        null,                   // iccid_prefix
254                        SPN_FI,                 // spn
255                        null,                   // apn
256                        NAME_FI,                // carrier name
257                        CID_FI,                 // cid
258                });
259                mc.addRow(new Object[] {
260                        4,                      // id
261                        MCCMNC,                 // mccmnc
262                        null,                   // gid1
263                        null,                   // gid2
264                        null,                   // plmn
265                        null,                   // imsi_prefix
266                        null,                   // iccid_prefix
267                        null,                   // spn
268                        APN_DOCOMO,             // apn
269                        NAME_DOCOMO,            // carrier name
270                        CID_DOCOMO,             // cid
271                });
272                return mc;
273            } else if (Carriers.CONTENT_URI.getAuthority().equals(uri.getAuthority())) {
274                MatrixCursor mc = new MatrixCursor(new String[]{Carriers._ID, Carriers.APN});
275                mc.addRow(new Object[] {
276                        1,                      // id
277                        APN_DOCOMO              // apn
278                });
279                return mc;
280            }
281            return null;
282        }
283        @Override
284        public int update(android.net.Uri uri, android.content.ContentValues values,
285                java.lang.String selection, java.lang.String[] selectionArgs) {
286            return 0;
287        }
288    }
289}
290