1 /*
2  * Copyright (C) 2019 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.mms.service;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.testng.Assert.assertThrows;
22 
23 import android.content.ContentProvider;
24 import android.content.ContentValues;
25 import android.content.Context;
26 import android.database.Cursor;
27 import android.net.Uri;
28 import android.provider.Telephony;
29 import android.telephony.data.ApnSetting;
30 
31 import androidx.test.core.app.ApplicationProvider;
32 
33 import com.android.mms.service.exception.ApnException;
34 
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.robolectric.RobolectricTestRunner;
39 import org.robolectric.fakes.RoboCursor;
40 import org.robolectric.shadows.ShadowContentResolver;
41 
42 import java.util.Arrays;
43 
44 @RunWith(RobolectricTestRunner.class)
45 public final class ApnSettingsTest {
46     private static final String APN_NAME = "mms.com";
47     private static final String ENTRY_NAME = "mms apn";
48     private static final String URI = "mmscUrl";
49     private static final String ADDRESS = "mmsProxyAddress";
50     private static final int PORT = 15;
51 
52     private Context context;
53 
54     @Before
setUp()55     public void setUp() {
56         context = ApplicationProvider.getApplicationContext();
57     }
58 
59     @Test
load_noApnSettings_throwsApnException()60     public void load_noApnSettings_throwsApnException() {
61         assertThrows(ApnException.class,
62                 () -> ApnSettings.load(context, "apnName", /* subId= */ 0, "requestId"));
63     }
64 
65     @Test
getApnSettingsFromCursor_validSettings_correctApnSettingsLoaded()66     public void getApnSettingsFromCursor_validSettings_correctApnSettingsLoaded() throws Exception {
67         createApnSettingsCursor("mmscUrl", "mmsProxy", /* proxyPort= */ "123");
68         ApnSettings apnSettings = ApnSettings.load(context, "apnName", /* subId= */ 0, "requestId");
69 
70         assertThat(apnSettings.getProxyPort()).isEqualTo(123);
71         assertThat(apnSettings.getMmscUrl()).isEqualTo("mmscUrl");
72         assertThat(apnSettings.getProxyAddress()).isEqualTo("mmsProxy");
73     }
74 
75     @Test
getApnSettingsFromCursor_nullMmsPort_defaultProxyPortUsed()76     public void getApnSettingsFromCursor_nullMmsPort_defaultProxyPortUsed() throws Exception {
77         createApnSettingsCursor("mmscUrl", "mmsProxy", /* proxyPort= */ null);
78         ApnSettings apnSettings = ApnSettings.load(context, "apnName", /* subId= */ 0, "requestId");
79         assertThat(apnSettings.getProxyPort()).isEqualTo(80);
80     }
81 
82     @Test
getApnSettingsFromCursor_emptyMmsPort_defaultProxyPortUsed()83     public void getApnSettingsFromCursor_emptyMmsPort_defaultProxyPortUsed() throws Exception {
84         createApnSettingsCursor("mmscUrl", "mmsProxy",
85                 /* proxyPort= */ "");
86         ApnSettings apnSettings = ApnSettings.load(context, "apnName", /* subId= */ 0, "requestId");
87         assertThat(apnSettings.getProxyPort()).isEqualTo(80);
88     }
89 
createApnSettingsCursor(String mmscUrl, String mmsProxy, String proxyPort)90     private void createApnSettingsCursor(String mmscUrl, String mmsProxy, String proxyPort) {
91         Object[][] apnValues =
92                 {new Object[]{ApnSetting.TYPE_MMS_STRING, mmscUrl, mmsProxy, proxyPort}};
93         RoboCursor cursor = new RoboCursor();
94         cursor.setResults(apnValues);
95         cursor.setColumnNames(Arrays.asList(Telephony.Carriers.TYPE, Telephony.Carriers.MMSC,
96                 Telephony.Carriers.MMSPROXY, Telephony.Carriers.MMSPORT));
97 
98         ShadowContentResolver.registerProviderInternal(
99                 Telephony.Carriers.CONTENT_URI.getAuthority(), new FakeApnSettingsProvider(cursor));
100     }
101 
102     @Test
getApnSettingsFromNetworkApn_normal()103     public void getApnSettingsFromNetworkApn_normal() {
104         ApnSetting networkApn = new ApnSetting.Builder().setApnName(APN_NAME)
105                 .setEntryName(ENTRY_NAME)
106                 .setApnTypeBitmask(ApnSetting.TYPE_MMS)
107                 .setMmsc(Uri.parse(URI))
108                 .setMmsProxyPort(PORT)
109                 .setMmsProxyAddress(ADDRESS).build();
110         ApnSettings apnSettings = ApnSettings.getApnSettingsFromNetworkApn(networkApn);
111         assertThat(apnSettings.getMmscUrl()).isEqualTo(URI);
112         assertThat(apnSettings.getProxyPort()).isEqualTo(PORT);
113         assertThat(apnSettings.getProxyAddress()).isEqualTo(ADDRESS);
114     }
115 
116     @Test
getApnSettingsFromNetworkApn_emptyMmsUrl_returnEmpty()117     public void getApnSettingsFromNetworkApn_emptyMmsUrl_returnEmpty() {
118         ApnSetting networkApn = new ApnSetting.Builder().setApnName(APN_NAME)
119                 .setEntryName(ENTRY_NAME)
120                 .setApnTypeBitmask(ApnSetting.TYPE_MMS)
121                 .setMmsProxyPort(PORT)
122                 .setMmsProxyAddress(ADDRESS).build();
123         ApnSettings apnSettings = ApnSettings.getApnSettingsFromNetworkApn(networkApn);
124         assertThat(apnSettings).isNull();
125     }
126 
127     @Test
getApnSettingsFromNetworkApn_nullMmsPort_defaultProxyPortUsed()128     public void getApnSettingsFromNetworkApn_nullMmsPort_defaultProxyPortUsed() {
129         ApnSetting networkApn = new ApnSetting.Builder().setApnName(APN_NAME)
130                 .setEntryName(ENTRY_NAME)
131                 .setApnTypeBitmask(ApnSetting.TYPE_MMS)
132                 .setMmsc(Uri.parse(URI))
133                 .setMmsProxyAddress(ADDRESS).build();
134         ApnSettings apnSettings = ApnSettings.getApnSettingsFromNetworkApn(networkApn);
135         assertThat(apnSettings.getProxyPort()).isEqualTo(80);
136     }
137 
138     private final class FakeApnSettingsProvider extends ContentProvider {
139 
140         private final Cursor cursor;
141 
FakeApnSettingsProvider(Cursor cursor)142         FakeApnSettingsProvider(Cursor cursor) {
143             this.cursor = cursor;
144         }
145 
146         @Override
onCreate()147         public boolean onCreate() {
148             return false;
149         }
150 
151         @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)152         public Cursor query(Uri uri, String[] projection,
153                 String selection, String[] selectionArgs, String sortOrder) {
154             return cursor;
155         }
156 
157         @Override
getType(Uri uri)158         public String getType(Uri uri) {
159             return null;
160         }
161 
162         @Override
insert(Uri uri, ContentValues values)163         public Uri insert(Uri uri, ContentValues values) {
164             return null;
165         }
166 
167         @Override
delete(Uri uri, String selection, String[] selectionArgs)168         public int delete(Uri uri, String selection, String[] selectionArgs) {
169             return 0;
170         }
171 
172         @Override
update(Uri uri, ContentValues values, String selection, String[] selectionArgs)173         public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
174             return 0;
175         }
176     }
177 
178 }
179