PhoneAccountRegistrarTest.java revision aa383cca668afd8578a6e007c3ea360768dc52f6
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 17package com.android.server.telecom.tests; 18 19import android.annotation.TargetApi; 20import android.os.Binder; 21 22import com.android.internal.telecom.IConnectionService; 23import com.android.internal.util.FastXmlSerializer; 24import com.android.server.telecom.Log; 25import com.android.server.telecom.PhoneAccountRegistrar; 26 27import org.mockito.Mockito; 28import org.xmlpull.v1.XmlPullParser; 29import org.xmlpull.v1.XmlSerializer; 30 31import android.content.ComponentName; 32import android.content.Context; 33import android.graphics.Bitmap; 34import android.graphics.BitmapFactory; 35import android.net.Uri; 36import android.os.Parcel; 37import android.telecom.PhoneAccount; 38import android.telecom.PhoneAccountHandle; 39import android.util.Xml; 40 41import java.io.BufferedInputStream; 42import java.io.BufferedOutputStream; 43import java.io.ByteArrayInputStream; 44import java.io.ByteArrayOutputStream; 45import java.io.File; 46import java.util.Arrays; 47 48public class PhoneAccountRegistrarTest extends TelecomTestCase { 49 50 private static final int MAX_VERSION = Integer.MAX_VALUE; 51 private static final String FILE_NAME = "phone-account-registrar-test-1223.xml"; 52 private PhoneAccountRegistrar mRegistrar; 53 54 @Override 55 public void setUp() throws Exception { 56 super.setUp(); 57 mComponentContextFixture = new ComponentContextFixture(); 58 new File( 59 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 60 FILE_NAME) 61 .delete(); 62 mRegistrar = new PhoneAccountRegistrar( 63 mComponentContextFixture.getTestDouble().getApplicationContext(), 64 FILE_NAME); 65 } 66 67 @Override 68 public void tearDown() throws Exception { 69 mRegistrar = null; 70 mComponentContextFixture = null; 71 new File( 72 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 73 FILE_NAME) 74 .delete(); 75 super.tearDown(); 76 } 77 78 public void testPhoneAccountHandle() throws Exception { 79 PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 80 PhoneAccountHandle result = roundTripXml(this, input, 81 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 82 assertPhoneAccountHandleEquals(input, result); 83 84 PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null); 85 PhoneAccountHandle resultN = roundTripXml(this, inputN, 86 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 87 Log.i(this, "inputN = %s, resultN = %s", inputN, resultN); 88 assertPhoneAccountHandleEquals(inputN, resultN); 89 } 90 91 public void testPhoneAccount() throws Exception { 92 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 93 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 94 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 95 .build(); 96 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 97 mContext); 98 assertPhoneAccountEquals(input, result); 99 } 100 101 public void testState() throws Exception { 102 PhoneAccountRegistrar.State input = makeQuickState(); 103 PhoneAccountRegistrar.State result = roundTripXml(this, input, 104 PhoneAccountRegistrar.sStateXml, 105 mContext); 106 assertStateEquals(input, result); 107 } 108 109 public void testAccounts() throws Exception { 110 int i = 0; 111 112 mComponentContextFixture.addConnectionService( 113 makeQuickConnectionServiceComponentName(), 114 Mockito.mock(IConnectionService.class)); 115 116 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 117 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 118 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 119 .build()); 120 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 121 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 122 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 123 .build()); 124 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 125 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 126 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 127 .build()); 128 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id" + i, i++) 129 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 130 .build()); 131 132 assertEquals(4, mRegistrar.getAllPhoneAccountHandles().size()); 133 assertEquals(3, mRegistrar.getCallCapablePhoneAccounts().size()); 134 assertEquals(null, mRegistrar.getSimCallManager()); 135 assertEquals(null, mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL)); 136 } 137 138 public void testSimCallManager() throws Exception { 139 mComponentContextFixture.addConnectionService( 140 makeQuickConnectionServiceComponentName(), 141 Mockito.mock(IConnectionService.class)); 142 143 PhoneAccountHandle simManager = makeQuickAccountHandle("sim_mgr"); 144 PhoneAccount simManagerAccount = new PhoneAccount.Builder(simManager, "sim_mgr") 145 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER 146 | PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 147 .build(); 148 mRegistrar.registerPhoneAccount(simManagerAccount); 149 assertNull(mRegistrar.getSimCallManager()); 150 151 // Test the basic case 152 mRegistrar.setSimCallManager(simManager); 153 assertEquals(simManager, mRegistrar.getSimCallManager()); 154 155 // Make sure clearing it works, too 156 mRegistrar.unregisterPhoneAccount(simManager); 157 assertNull(mRegistrar.getSimCallManager()); 158 159 // Re-registering it makes the setting come back 160 mRegistrar.registerPhoneAccount(simManagerAccount); 161 assertEquals(simManager, mRegistrar.getSimCallManager()); 162 163 // Make sure that the manager has CAPABILITY_CONNECTION_MANAGER 164 PhoneAccountHandle simManagerImposter = makeQuickAccountHandle("imposter"); 165 PhoneAccount simManagerImposterAccount = 166 new PhoneAccount.Builder(simManagerImposter, "imposter") 167 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 168 .build(); 169 mRegistrar.registerPhoneAccount(simManagerImposterAccount); 170 171 mRegistrar.setSimCallManager(null); 172 assertNull(mRegistrar.getSimCallManager()); 173 mRegistrar.setSimCallManager(simManagerImposter); 174 assertNull(mRegistrar.getSimCallManager()); 175 } 176 177 public void testDefaultOutgoing() throws Exception { 178 mComponentContextFixture.addConnectionService( 179 makeQuickConnectionServiceComponentName(), 180 Mockito.mock(IConnectionService.class)); 181 182 // By default, there is no default outgoing account (nothing has been registered) 183 assertNull(mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL)); 184 185 // Register one tel: account 186 PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct"); 187 mRegistrar.registerPhoneAccount(new PhoneAccount.Builder(telAccount, "tel_acct") 188 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 189 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 190 .build()); 191 PhoneAccountHandle defaultAccount = 192 mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 193 assertEquals(telAccount, defaultAccount); 194 195 // Add a SIP account, make sure tel: doesn't change 196 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 197 mRegistrar.registerPhoneAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 198 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 199 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP) 200 .build()); 201 defaultAccount = mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_SIP); 202 assertEquals(sipAccount, defaultAccount); 203 defaultAccount = mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 204 assertEquals(telAccount, defaultAccount); 205 206 // Add a connection manager, make sure tel: doesn't change 207 PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct"); 208 mRegistrar.registerPhoneAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct") 209 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 210 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 211 .build()); 212 defaultAccount = mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 213 assertEquals(telAccount, defaultAccount); 214 215 // Unregister the tel: account, make sure there is no tel: default now. 216 mRegistrar.unregisterPhoneAccount(telAccount); 217 assertNull(mRegistrar.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL)); 218 } 219 220 public void testPhoneAccountParceling() throws Exception { 221 PhoneAccountHandle handle = makeQuickAccountHandle("foo"); 222 roundTripPhoneAccount(new PhoneAccount.Builder(handle, null).build()); 223 roundTripPhoneAccount(new PhoneAccount.Builder(handle, "foo").build()); 224 roundTripPhoneAccount( 225 new PhoneAccount.Builder(handle, "foo") 226 .setAddress(Uri.parse("tel:123456")) 227 .setCapabilities(23) 228 .setHighlightColor(0xf0f0f0) 229 .setIcon( 230 "com.android.server.telecom.tests", 231 R.drawable.stat_sys_phone_call, 232 0xfefefe) 233 .setShortDescription("short description") 234 .setSubscriptionAddress(Uri.parse("tel:2345678")) 235 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 236 .build()); 237 roundTripPhoneAccount( 238 new PhoneAccount.Builder(handle, "foo") 239 .setAddress(Uri.parse("tel:123456")) 240 .setCapabilities(23) 241 .setHighlightColor(0xf0f0f0) 242 .setIcon( 243 BitmapFactory.decodeResource( 244 getContext().getResources(), 245 R.drawable.stat_sys_phone_call)) 246 .setShortDescription("short description") 247 .setSubscriptionAddress(Uri.parse("tel:2345678")) 248 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 249 .build()); 250 } 251 252 private static ComponentName makeQuickConnectionServiceComponentName() { 253 return new ComponentName( 254 "com.android.server.telecom.tests", 255 "com.android.server.telecom.tests.MockConnectionService"); 256 } 257 258 private static PhoneAccountHandle makeQuickAccountHandle(String id) { 259 return new PhoneAccountHandle( 260 makeQuickConnectionServiceComponentName(), 261 id, 262 Binder.getCallingUserHandle()); 263 } 264 265 private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) { 266 return new PhoneAccount.Builder( 267 makeQuickAccountHandle(id), 268 "label" + idx); 269 } 270 271 private PhoneAccount makeQuickAccount(String id, int idx) { 272 return makeQuickAccountBuilder(id, idx) 273 .setAddress(Uri.parse("http://foo.com/" + idx)) 274 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx)) 275 .setCapabilities(idx) 276 .setIcon("com.android.server.telecom.tests", R.drawable.stat_sys_phone_call) 277 .setShortDescription("desc" + idx) 278 .build(); 279 } 280 281 private static void roundTripPhoneAccount(PhoneAccount original) throws Exception { 282 PhoneAccount copy = null; 283 284 { 285 Parcel parcel = Parcel.obtain(); 286 parcel.writeParcelable(original, 0); 287 parcel.setDataPosition(0); 288 copy = parcel.readParcelable(PhoneAccountRegistrarTest.class.getClassLoader()); 289 parcel.recycle(); 290 } 291 292 assertPhoneAccountEquals(original, copy); 293 } 294 295 private static <T> T roundTripXml( 296 Object self, 297 T input, 298 PhoneAccountRegistrar.XmlSerialization<T> xml, 299 Context context) 300 throws Exception { 301 Log.d(self, "Input = %s", input); 302 303 byte[] data; 304 { 305 XmlSerializer serializer = new FastXmlSerializer(); 306 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 307 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 308 xml.writeToXml(input, serializer, context); 309 serializer.flush(); 310 data = baos.toByteArray(); 311 } 312 313 Log.d(self, "====== XML data ======\n%s", new String(data)); 314 315 T result = null; 316 { 317 XmlPullParser parser = Xml.newPullParser(); 318 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null); 319 parser.nextTag(); 320 result = xml.readFromXml(parser, MAX_VERSION, context); 321 } 322 323 Log.d(self, "result = " + result); 324 325 return result; 326 } 327 328 private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) { 329 if (a != b) { 330 assertEquals( 331 a.getComponentName().getPackageName(), 332 b.getComponentName().getPackageName()); 333 assertEquals( 334 a.getComponentName().getClassName(), 335 b.getComponentName().getClassName()); 336 assertEquals(a.getId(), b.getId()); 337 } 338 } 339 340 private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) { 341 if (a != b) { 342 assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle()); 343 assertEquals(a.getAddress(), b.getAddress()); 344 assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress()); 345 assertEquals(a.getCapabilities(), b.getCapabilities()); 346 assertEquals(a.getIconResId(), b.getIconResId()); 347 assertEquals(a.getIconPackageName(), b.getIconPackageName()); 348 assertBitmapEquals(a.getIconBitmap(), b.getIconBitmap()); 349 assertEquals(a.getIconTint(), b.getIconTint()); 350 assertEquals(a.getHighlightColor(), b.getHighlightColor()); 351 assertEquals(a.getLabel(), b.getLabel()); 352 assertEquals(a.getShortDescription(), b.getShortDescription()); 353 assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes()); 354 } 355 } 356 357 private static void assertBitmapEquals(Bitmap a, Bitmap b) { 358 if (a == null || b == null) { 359 assertEquals(null, a); 360 assertEquals(null, b); 361 } else { 362 assertEquals(a.getWidth(), b.getWidth()); 363 assertEquals(a.getHeight(), b.getHeight()); 364 for (int x = 0; x < a.getWidth(); x++) { 365 for (int y = 0; y < a.getHeight(); y++) { 366 assertEquals(a.getPixel(x, y), b.getPixel(x, y)); 367 } 368 } 369 } 370 } 371 372 private static void assertStateEquals( 373 PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) { 374 assertPhoneAccountHandleEquals(a.defaultOutgoing, b.defaultOutgoing); 375 assertPhoneAccountHandleEquals(a.simCallManager, b.simCallManager); 376 assertEquals(a.accounts.size(), b.accounts.size()); 377 for (int i = 0; i < a.accounts.size(); i++) { 378 assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i)); 379 } 380 } 381 382 private PhoneAccountRegistrar.State makeQuickState() { 383 PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State(); 384 s.accounts.add(makeQuickAccount("id0", 0)); 385 s.accounts.add(makeQuickAccount("id1", 1)); 386 s.accounts.add(makeQuickAccount("id2", 2)); 387 s.defaultOutgoing = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 388 s.simCallManager = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id1"); 389 return s; 390 } 391} 392