1 /* 2 * Copyright (C) 2014 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.server.telecom.tests.unit; 18 19 import com.android.internal.util.FastXmlSerializer; 20 import com.android.server.telecom.Log; 21 import com.android.server.telecom.PhoneAccountRegistrar; 22 23 import org.xmlpull.v1.XmlPullParser; 24 import org.xmlpull.v1.XmlSerializer; 25 26 import android.content.ComponentName; 27 import android.content.Context; 28 import android.net.Uri; 29 import android.telecom.PhoneAccount; 30 import android.telecom.PhoneAccountHandle; 31 import android.test.AndroidTestCase; 32 import android.util.Xml; 33 34 import java.io.BufferedInputStream; 35 import java.io.BufferedOutputStream; 36 import java.io.ByteArrayInputStream; 37 import java.io.ByteArrayOutputStream; 38 import java.io.File; 39 40 public class PhoneAccountRegistrarTest extends AndroidTestCase { 41 42 private static final String FILE_NAME = "phone-account-registrar-test.xml"; 43 private PhoneAccountRegistrar mRegistrar; 44 45 @Override setUp()46 public void setUp() { 47 mRegistrar = new PhoneAccountRegistrar(getContext(), FILE_NAME); 48 } 49 50 @Override tearDown()51 public void tearDown() { 52 mRegistrar = null; 53 new File(getContext().getFilesDir(), FILE_NAME).delete(); 54 } 55 testPhoneAccountHandle()56 public void testPhoneAccountHandle() throws Exception { 57 PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 58 PhoneAccountHandle result = roundTrip(this, input, 59 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 60 assertPhoneAccountHandleEquals(input, result); 61 62 PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null); 63 PhoneAccountHandle resultN = roundTrip(this, inputN, 64 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 65 Log.i(this, "inputN = %s, resultN = %s", inputN, resultN); 66 assertPhoneAccountHandleEquals(inputN, resultN); 67 } 68 testPhoneAccount()69 public void testPhoneAccount() throws Exception { 70 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 71 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 72 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 73 .build(); 74 PhoneAccount result = roundTrip(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 75 mContext); 76 assertPhoneAccountEquals(input, result); 77 } 78 testState()79 public void testState() throws Exception { 80 PhoneAccountRegistrar.State input = makeQuickState(); 81 PhoneAccountRegistrar.State result = roundTrip(this, input, PhoneAccountRegistrar.sStateXml, 82 mContext); 83 assertStateEquals(input, result); 84 } 85 testAccounts()86 public void testAccounts() throws Exception { 87 int i = 0; 88 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 89 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 90 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 91 .build()); 92 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 93 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 94 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 95 .build()); 96 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 97 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 98 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 99 .build()); 100 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 101 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 102 .build()); 103 104 assertEquals(4, mRegistrar.getAllPhoneAccountHandles().size()); 105 assertEquals(3, mRegistrar.getCallCapablePhoneAccounts().size()); 106 assertEquals(null, mRegistrar.getSimCallManager()); 107 assertEquals(null, mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL)); 108 } 109 testSimCallManager()110 public void testSimCallManager() throws Exception { 111 PhoneAccountHandle simManager = makeQuickAccountHandle("sim_mgr"); 112 PhoneAccount simManagerAccount = new PhoneAccount.Builder(simManager, "sim_mgr") 113 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER 114 | PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 115 .build(); 116 mRegistrar.registerPhoneAccount(simManagerAccount); 117 assertNull(mRegistrar.getSimCallManager()); 118 119 // Test the basic case 120 mRegistrar.setSimCallManager(simManager); 121 assertEquals(simManager, mRegistrar.getSimCallManager()); 122 123 // Make sure clearing it works, too 124 mRegistrar.unregisterPhoneAccount(simManager); 125 assertNull(mRegistrar.getSimCallManager()); 126 127 // Re-registering it makes the setting come back 128 mRegistrar.registerPhoneAccount(simManagerAccount); 129 assertEquals(simManager, mRegistrar.getSimCallManager()); 130 131 // Make sure that the manager has CAPABILITY_CONNECTION_MANAGER 132 PhoneAccountHandle simManagerImposter = makeQuickAccountHandle("imposter"); 133 PhoneAccount simManagerImposterAccount = 134 new PhoneAccount.Builder(simManagerImposter, "imposter") 135 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 136 .build(); 137 mRegistrar.registerPhoneAccount(simManagerImposterAccount); 138 139 mRegistrar.setSimCallManager(null); 140 assertNull(mRegistrar.getSimCallManager()); 141 mRegistrar.setSimCallManager(simManagerImposter); 142 assertNull(mRegistrar.getSimCallManager()); 143 } 144 testDefaultOutgoing()145 public void testDefaultOutgoing() { 146 // By default, there is no default outgoing account (nothing has been registered) 147 assertNull(mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL)); 148 149 // Register one tel: account 150 PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct"); 151 mRegistrar.registerPhoneAccount(new PhoneAccount.Builder(telAccount, "tel_acct") 152 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 153 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 154 .build()); 155 PhoneAccountHandle defaultAccount = 156 mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 157 assertEquals(telAccount, defaultAccount); 158 159 // Add a SIP account, make sure tel: doesn't change 160 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 161 mRegistrar.registerPhoneAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 162 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 163 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP) 164 .build()); 165 defaultAccount = mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_SIP); 166 assertEquals(sipAccount, defaultAccount); 167 defaultAccount = mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 168 assertEquals(telAccount, defaultAccount); 169 170 // Add a connection manager, make sure tel: doesn't change 171 PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct"); 172 mRegistrar.registerPhoneAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct") 173 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 174 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 175 .build()); 176 defaultAccount = mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 177 assertEquals(telAccount, defaultAccount); 178 179 // Unregister the tel: account, make sure there is no tel: default now. 180 mRegistrar.unregisterPhoneAccount(telAccount); 181 assertNull(mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL)); 182 } 183 makeQuickAccountHandle(String id)184 private static PhoneAccountHandle makeQuickAccountHandle(String id) { 185 return new PhoneAccountHandle( 186 new ComponentName( 187 "com.android.server.telecom.tests", 188 "com.android.server.telecom.tests.MockConnectionService" 189 ), 190 id 191 ); 192 } 193 makeQuickAccountBuilder(String id, int idx)194 private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) { 195 return new PhoneAccount.Builder( 196 makeQuickAccountHandle(id), 197 "label" + idx 198 ); 199 } 200 makeQuickAccount(String id, int idx)201 private PhoneAccount makeQuickAccount(String id, int idx) { 202 return makeQuickAccountBuilder(id, idx) 203 .setAddress(Uri.parse("http://foo.com/" + idx)) 204 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx)) 205 .setCapabilities(idx) 206 .setIconResId(idx) 207 .setShortDescription("desc" + idx) 208 .build(); 209 } 210 roundTrip( Object self, T input, PhoneAccountRegistrar.XmlSerialization<T> xml, Context context)211 private static <T> T roundTrip( 212 Object self, 213 T input, 214 PhoneAccountRegistrar.XmlSerialization<T> xml, 215 Context context) 216 throws Exception { 217 Log.d(self, "Input = %s", input); 218 219 byte[] data; 220 { 221 XmlSerializer serializer = new FastXmlSerializer(); 222 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 223 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 224 xml.writeToXml(input, serializer); 225 serializer.flush(); 226 data = baos.toByteArray(); 227 } 228 229 Log.d(self, "====== XML data ======\n%s", new String(data)); 230 231 T result = null; 232 { 233 XmlPullParser parser = Xml.newPullParser(); 234 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null); 235 parser.nextTag(); 236 result = xml.readFromXml(parser, 0, context); 237 } 238 239 Log.d(self, "result = " + result); 240 241 return result; 242 } 243 assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b)244 private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) { 245 if (a != b) { 246 assertEquals( 247 a.getComponentName().getPackageName(), 248 b.getComponentName().getPackageName()); 249 assertEquals( 250 a.getComponentName().getClassName(), 251 b.getComponentName().getClassName()); 252 assertEquals(a.getId(), b.getId()); 253 } 254 } 255 assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b)256 private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) { 257 if (a != b) { 258 assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle()); 259 assertEquals(a.getAddress(), b.getAddress()); 260 assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress()); 261 assertEquals(a.getCapabilities(), b.getCapabilities()); 262 assertEquals(a.getIconResId(), b.getIconResId()); 263 assertEquals(a.getLabel(), b.getLabel()); 264 assertEquals(a.getShortDescription(), b.getShortDescription()); 265 assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes()); 266 } 267 } 268 assertStateEquals( PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b)269 private static void assertStateEquals( 270 PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) { 271 assertPhoneAccountHandleEquals(a.defaultOutgoing, b.defaultOutgoing); 272 assertPhoneAccountHandleEquals(a.simCallManager, b.simCallManager); 273 assertEquals(a.accounts.size(), b.accounts.size()); 274 for (int i = 0; i < a.accounts.size(); i++) { 275 assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i)); 276 } 277 } 278 makeQuickState()279 private PhoneAccountRegistrar.State makeQuickState() { 280 PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State(); 281 s.accounts.add(makeQuickAccount("id0", 0)); 282 s.accounts.add(makeQuickAccount("id1", 1)); 283 s.accounts.add(makeQuickAccount("id2", 2)); 284 s.defaultOutgoing = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 285 s.simCallManager = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id1"); 286 return s; 287 } 288 }