1 /* 2 * Copyright 2020 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.telephony.ims; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertFalse; 21 import static junit.framework.Assert.assertNotNull; 22 import static junit.framework.Assert.assertNull; 23 import static junit.framework.Assert.assertTrue; 24 25 import static org.mockito.Mockito.when; 26 27 import android.content.ContentValues; 28 import android.content.Context; 29 import android.telephony.SubscriptionManager; 30 import android.telephony.ims.RcsConfig; 31 import android.telephony.ims.RcsConfig.Characteristic; 32 import android.test.mock.MockContentResolver; 33 import android.test.suitebuilder.annotation.SmallTest; 34 35 import androidx.test.ext.junit.runners.AndroidJUnit4; 36 37 import com.android.internal.telephony.FakeTelephonyProvider; 38 39 import org.junit.Before; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 import org.mockito.Mock; 43 import org.mockito.MockitoAnnotations; 44 45 import java.util.Arrays; 46 47 @RunWith(AndroidJUnit4.class) 48 public final class RcsConfigTest { 49 50 private static final String TEST_RCS_CONFIG = "<?xml version=\"1.0\"?>\n" 51 + "<wap-provisioningdoc version=\"1.1\">\n" 52 + "\t<characteristic type=\"APPLICATION\">\n" 53 + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n" 54 + "\t\t<characteristic type=\"3GPP_IMS\">\n" 55 + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n" 56 + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n" 57 + "\t\t\t<characteristic type=\"Ext\">\n" 58 + "\t\t\t\t<characteristic type=\"GSMA\">\n" 59 + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n" 60 + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"1\"/>\n" 61 + "\t\t\t\t</characteristic>\n" 62 + "\t\t\t</characteristic>\n" 63 + "\t\t</characteristic>\n" 64 + "\t\t<characteristic type=\"SERVICES\">\n" 65 + "\t\t\t<parm name=\"SupportedRCSProfileVersions\" value=\"UP_2.3\"/>\n" 66 + "\t\t\t<parm name=\"ChatAuth\" value=\"1\"/>\n" 67 + "\t\t\t<parm name=\"GroupChatAuth\" value=\"1\"/>\n" 68 + "\t\t\t<parm name=\"ftAuth\" value=\"1\"/>\n" 69 + "\t\t\t<parm name=\"standaloneMsgAuth\" value=\"1\"/>\n" 70 + "\t\t\t<parm name=\"geolocPushAuth\" value=\"1\"/>\n" 71 + "\t\t\t<characteristic type=\"Ext\">\n" 72 + "\t\t\t\t<characteristic type=\"DataOff\">\n" 73 + "\t\t\t\t\t<parm name=\"rcsMessagingDataOff\" value=\"1\"/>\n" 74 + "\t\t\t\t\t<parm name=\"fileTransferDataOff\" value=\"1\"/>\n" 75 + "\t\t\t\t\t<parm name=\"mmsDataOff\" value=\"1\"/>\n" 76 + "\t\t\t\t\t<parm name=\"syncDataOff\" value=\"1\"/>\n" 77 + "\t\t\t\t\t<characteristic type=\"Ext\"/>\n" 78 + "\t\t\t\t</characteristic>\n" 79 + "\t\t\t</characteristic>\n" 80 + "\t\t</characteristic>\n" 81 + "\t\t<characteristic type=\"PRESENCE\">\n" 82 + "\t\t\t<parm name=\"client-obj-datalimit\" value=\"8192\"/>\n" 83 + "\t\t\t<parm name=\"content-serveruri\" value=\"X\"/>\n" 84 + "\t\t\t<parm name=\"source-throttlepublish\" value=\"32\"/>\n" 85 + "\t\t\t<parm name=\"max-number-ofsubscriptions-inpresence-list\" value=\"8\"/>\n" 86 + "\t\t\t<parm name=\"service-uritemplate\" value=\"X\"/>\n" 87 + "\t\t\t<parm name=\"RLS-URI\" value=\"X\"/>\n" 88 + "\t\t</characteristic>\n" 89 + "\t\t<characteristic type=\"MESSAGING\">\n" 90 + "\t\t\t<characteristic type=\"StandaloneMsg\">\n" 91 + "\t\t\t\t<parm name=\"MaxSize\" value=\"8192\"/>\n" 92 + "\t\t\t\t<parm name=\"SwitchoverSize\" value=\"1024\"/>\n" 93 + "\t\t\t\t<parm name=\"exploder-uri\" value=\"X\"/>\n" 94 + "\t\t\t</characteristic>\n" 95 + "\t\t\t<characteristic type=\"Chat\">\n" 96 + "\t\t\t\t<parm name=\"max_adhoc_group_size\" value=\"60\"/>\n" 97 + "\t\t\t\t<parm name=\"conf-fcty-uri\" value=\"X\"/>\n" 98 + "\t\t\t\t<parm name=\"AutAccept\" value=\"1\"/>\n" 99 + "\t\t\t\t<parm name=\"AutAcceptGroupChat\" value=\"1\"/>\n" 100 + "\t\t\t\t<parm name=\"TimerIdle\" value=\"120\"/>\n" 101 + "\t\t\t\t<parm name=\"MaxSize\" value=\"16384\"/>\n" 102 + "\t\t\t\t<parm name=\"ChatRevokeTimer\" value=\"0\"/>\n" 103 + "\t\t\t\t<parm name=\"reconnectGuardTimer\" value=\"0\"/>\n" 104 + "\t\t\t\t<parm name=\"cfsTrigger\" value=\"1\"/>\n" 105 + "\t\t\t</characteristic>\n" 106 + "\t\t\t<parm name=\"max1ToManyRecipients\" value=\"8\"/>\n" 107 + "\t\t\t<parm name=\"1toManySelectedTech\" value=\"1\"/>\n" 108 + "\t\t\t<parm name=\"displayNotificationSwitch\" value=\"0\"/>\n" 109 + "\t\t\t<parm name=\"contentCompressSize\" value=\"1024\"/>\n" 110 + "\t\t\t<characteristic type=\"FileTransfer\">\n" 111 + "\t\t\t\t<parm name=\"ftWarnSize\" value=\"0\"/>\n" 112 + "\t\t\t\t<parm name=\"MaxSizeFileTr\" value=\"65536\"/>\n" 113 + "\t\t\t\t<parm name=\"ftAutAccept\" value=\"1\"/>\n" 114 + "\t\t\t\t<parm name=\"ftHTTPCSURI\" value=\"X\"/>\n" 115 + "\t\t\t\t<parm name=\"ftHTTPDLURI\" value=\"X\"/>\n" 116 + "\t\t\t\t<parm name=\"ftHTTPCSUser\" value=\"X\"/>\n" 117 + "\t\t\t\t<parm name=\"ftHTTPCSPwd\" value=\"X\"/>\n" 118 + "\t\t\t\t<parm name=\"ftHTTPFallback\" value=\"X\"/>\n" 119 + "\t\t\t\t<parm name=\" ftMax1ToManyRecipients\" value=\"0\"/>\n" 120 + "\t\t\t</characteristic>\n" 121 + "\t\t\t<characteristic type=\"Chatbot\">\n" 122 + "\t\t\t\t<parm name=\"ChatbotDirectory\" value=\"X\"/>\n" 123 + "\t\t\t\t<parm name=\"BotinfoFQDNRoot\" value=\"X\"/>\n" 124 + "\t\t\t\t<part name=\"SpecificChatbotsList\" value=\"X\"/>\n" 125 + "\t\t\t\t<parm name=\"IdentityInEnrichedSearch\" value=\"1\"/>\n" 126 + "\t\t\t\t<parm name=\"PrivacyDisable\" value=\"0\"/>\n" 127 + "\t\t\t\t<parm name=\"ChatbotMsgTech\" value=\"1\"/>\n" 128 + "\t\t\t</characteristic>\n" 129 + "\t\t\t<characteristic type=\"MessageStore\">\n" 130 + "\t\t\t\t<parm name=\"MsgStoreUrl\" value=\"X\"/>\n" 131 + "\t\t\t\t<parm name=\"MsgStoreNotifUrl\" value=\"X\"/>\n" 132 + "\t\t\t\t<parm name=\"MsgStoreAuth\" value=\"X\"/>\n" 133 + "\t\t\t\t<parm name=\"MsgStoreUserName\" value=\"X\"/>\n" 134 + "\t\t\t\t<parm name=\"MsgStoreUserPwd\" value=\"X\"/>\n" 135 + "\t\t\t\t<parm name=\"EventRpting\" value=\"1\"/>\n" 136 + "\t\t\t\t<parm name=\"AuthArchive\" value=\"1\"/>\n" 137 + "\t\t\t\t<parm name=\"SMSStore\" value=\"1\"/>\n" 138 + "\t\t\t\t<parm name=\"MMSStore\" value=\"1\"/>\n" 139 + "\t\t\t</characteristic>\n" 140 + "\t\t\t<characteristic type=\"Ext\"/>\n" 141 + "\t\t</characteristic>\n" 142 + "\t</characteristic>\n" 143 + "</wap-provisioningdoc>\n"; 144 145 private static final String[][] TEST_CONFIG_VALUES = {{"rcsVolteSingleRegistration", "1"}, 146 {"SupportedRCSProfileVersions", "UP_2.3"}, {"ChatAuth", "1"}, {"GroupChatAuth", "1"}, 147 {"ftAuth", "1"}, {"standaloneMsgAuth", "1"}, {"geolocPushAuth", "1"}, 148 {"rcsMessagingDataOff", "1"}, {"fileTransferDataOff", "1"}, {"mmsDataOff", "1"}, 149 {"syncDataOff", "1"}}; 150 151 private static final String[] VALID_CHARACTERISTICS = {"APPLICATION", "3GPP_IMS", "Ext", 152 "GSMA", "SERVICES", "DaTAOFF", "PRESENCE", "MESSAGING", "Chat", "FileTransfer", 153 "Chatbot", "MessageSTORE"}; 154 private static final String[] INVALID_CHARACTERISTICS = {"APP2LICATION", "3GPPIMS", "Exte", 155 "GSMf", "SERVICE", "DaTAOn", "PRESENCE2", "MESSAG", "Ch", "File", "STORE"}; 156 private static final String[][] SUB_CHARACTERISTICS = { 157 {"APPLICATION", "3GPP_IMS", "Ext", "GSMA"}, 158 {"APPLICATION", "SERVICES", "Ext", "DataOff", "Ext"}}; 159 private static final String[][] SAME_PARMS_DIFF_CHARS_VALUE_MAP = { 160 {"MaxSize", "Chat", "16384"}, {"MaxSize", "StandaloneMsg", "8192"}}; 161 162 private static final int FAKE_SUB_ID = 1; 163 private MockContentResolver mContentResolver; 164 private FakeTelephonyProvider mFakeTelephonyProvider; 165 @Mock 166 Context mContext; 167 168 @Before setUp()169 public void setUp() { 170 MockitoAnnotations.initMocks(this); 171 mFakeTelephonyProvider = new FakeTelephonyProvider(); 172 mContentResolver = new MockContentResolver(); 173 mContentResolver.addProvider(SubscriptionManager.CONTENT_URI.getAuthority(), 174 mFakeTelephonyProvider); 175 when(mContext.getContentResolver()).thenReturn(mContentResolver); 176 createFakeSimInfo(); 177 } 178 179 @Test 180 @SmallTest testLoadAndUpdateConfigForSub()181 public void testLoadAndUpdateConfigForSub() { 182 183 byte[] currentData = RcsConfig.loadRcsConfigForSub(mContext, FAKE_SUB_ID, false); 184 185 RcsConfig.updateConfigForSub(mContext, FAKE_SUB_ID, null, false); 186 byte[] updatedData = RcsConfig.loadRcsConfigForSub(mContext, FAKE_SUB_ID, false); 187 assertNull(updatedData); 188 189 RcsConfig.updateConfigForSub(mContext, FAKE_SUB_ID, TEST_RCS_CONFIG.getBytes(), false); 190 updatedData = RcsConfig.loadRcsConfigForSub(mContext, FAKE_SUB_ID, false); 191 assertTrue(Arrays.equals(updatedData, TEST_RCS_CONFIG.getBytes())); 192 193 RcsConfig.updateConfigForSub(mContext, FAKE_SUB_ID, currentData, false); 194 updatedData = RcsConfig.loadRcsConfigForSub(mContext, FAKE_SUB_ID, false); 195 assertTrue(Arrays.equals(currentData, updatedData)); 196 } 197 198 @Test 199 @SmallTest testCompressAndDecompress()200 public void testCompressAndDecompress() { 201 byte[] compressedData = RcsConfig.compressGzip(TEST_RCS_CONFIG.getBytes()); 202 assertFalse(Arrays.equals(compressedData, TEST_RCS_CONFIG.getBytes())); 203 byte[] decompressedData = RcsConfig.decompressGzip(compressedData); 204 assertTrue(Arrays.equals(decompressedData, TEST_RCS_CONFIG.getBytes())); 205 assertNull(RcsConfig.compressGzip(null)); 206 assertNull(RcsConfig.decompressGzip(null)); 207 byte[] emptyData = new byte[0]; 208 assertEquals(emptyData, RcsConfig.compressGzip(emptyData)); 209 assertEquals(emptyData, RcsConfig.decompressGzip(emptyData)); 210 } 211 212 @Test 213 @SmallTest testParseConfig()214 public void testParseConfig() { 215 RcsConfig config = new RcsConfig(TEST_RCS_CONFIG.getBytes()); 216 217 for (int i = 0; i < TEST_CONFIG_VALUES.length; i++) { 218 assertEquals(config.getString(TEST_CONFIG_VALUES[i][0], null), 219 TEST_CONFIG_VALUES[i][1]); 220 } 221 } 222 223 @Test 224 @SmallTest testGetCharacteristic()225 public void testGetCharacteristic() { 226 RcsConfig config = new RcsConfig(TEST_RCS_CONFIG.getBytes()); 227 228 for (int i = 0; i < VALID_CHARACTERISTICS.length; i++) { 229 assertNotNull(config.getCharacteristic(VALID_CHARACTERISTICS[i])); 230 } 231 232 for (int i = 0; i < INVALID_CHARACTERISTICS.length; i++) { 233 assertNull(config.getCharacteristic(INVALID_CHARACTERISTICS[i])); 234 } 235 } 236 237 @Test 238 @SmallTest testSetAndMoveCharacteristic()239 public void testSetAndMoveCharacteristic() { 240 RcsConfig config = new RcsConfig(TEST_RCS_CONFIG.getBytes()); 241 242 for (String[] sub : SUB_CHARACTERISTICS) { 243 Characteristic[] cl = new Characteristic[sub.length]; 244 int c = 0; 245 for (String cur : sub) { 246 cl[c] = config.getCharacteristic(cur); 247 assertNotNull(cl[c]); 248 config.setCurrentCharacteristic(cl[c]); 249 c++; 250 } 251 252 while (c > 0) { 253 assertEquals(cl[--c], config.getCurrentCharacteristic()); 254 config.moveToParent(); 255 } 256 257 assertEquals(config.getRoot(), config.getCurrentCharacteristic()); 258 } 259 } 260 261 @Test 262 @SmallTest testGetDuplicateParmInDifferentCharacteristics()263 public void testGetDuplicateParmInDifferentCharacteristics() { 264 RcsConfig config = new RcsConfig(TEST_RCS_CONFIG.getBytes()); 265 for (String[] sub : SAME_PARMS_DIFF_CHARS_VALUE_MAP) { 266 config.moveToRoot(); 267 if (!sub[1].isEmpty()) { 268 config.setCurrentCharacteristic(config.getCharacteristic(sub[1])); 269 } 270 271 String value = config.getString(sub[0], ""); 272 273 assertEquals(value, sub[2]); 274 } 275 } 276 277 @Test 278 @SmallTest testIsRcsVolteSingleRegistrationSupported()279 public void testIsRcsVolteSingleRegistrationSupported() { 280 String[] vals = new String[]{"0", "1", "2"}; 281 boolean[] expectedResHome = new boolean[]{false, true, true}; 282 boolean[] expectedResRoaming = new boolean[]{false, true, false}; 283 for (int i = 0; i < vals.length; i++) { 284 String xml = "\t\t\t\t<characteristic type=\"GSMA\">\n" 285 + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"" 286 + vals[i] + "\"/>\n" + "\t\t\t\t</characteristic>\n"; 287 RcsConfig config = new RcsConfig(xml.getBytes()); 288 assertEquals(config.isRcsVolteSingleRegistrationSupported(false), expectedResHome[i]); 289 assertEquals(config.isRcsVolteSingleRegistrationSupported(true), 290 expectedResRoaming[i]); 291 } 292 } 293 createFakeSimInfo()294 private void createFakeSimInfo() { 295 ContentValues contentValues = new ContentValues(); 296 final String fakeIccId = "fakeleIccId"; 297 final String fakeCardId = "fakeCardId"; 298 contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, FAKE_SUB_ID); 299 contentValues.put(SubscriptionManager.ICC_ID, fakeIccId); 300 contentValues.put(SubscriptionManager.CARD_ID, fakeCardId); 301 mContentResolver.insert(SubscriptionManager.CONTENT_URI, contentValues); 302 } 303 } 304