blob: a56036a5f97b1ade85f921c07ab55e5ac759f4a3 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.telecom.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Xml;
import androidx.test.InstrumentationRegistry;
import com.android.internal.telecom.IConnectionService;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.telecom.AppLabelProxy;
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneAccountRegistrar.DefaultPhoneAccountHandle;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
@RunWith(JUnit4.class)
public class PhoneAccountRegistrarTest extends TelecomTestCase {
private static final int MAX_VERSION = Integer.MAX_VALUE;
private static final String FILE_NAME = "phone-account-registrar-test-1223.xml";
private static final String TEST_LABEL = "right";
private PhoneAccountRegistrar mRegistrar;
@Mock private TelecomManager mTelecomManager;
@Mock private DefaultDialerCache mDefaultDialerCache;
@Mock private AppLabelProxy mAppLabelProxy;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
mComponentContextFixture.setTelecomManager(mTelecomManager);
new File(
mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(),
FILE_NAME)
.delete();
when(mDefaultDialerCache.getDefaultDialerApplication(anyInt()))
.thenReturn("com.android.dialer");
when(mAppLabelProxy.getAppLabel(anyString()))
.thenReturn(TEST_LABEL);
mRegistrar = new PhoneAccountRegistrar(
mComponentContextFixture.getTestDouble().getApplicationContext(),
FILE_NAME, mDefaultDialerCache, mAppLabelProxy);
}
@Override
@After
public void tearDown() throws Exception {
mRegistrar = null;
new File(
mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(),
FILE_NAME)
.delete();
super.tearDown();
}
@MediumTest
@Test
public void testPhoneAccountHandle() throws Exception {
PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0");
PhoneAccountHandle result = roundTripXml(this, input,
PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext);
assertPhoneAccountHandleEquals(input, result);
PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null);
PhoneAccountHandle resultN = roundTripXml(this, inputN,
PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext);
Log.i(this, "inputN = %s, resultN = %s", inputN, resultN);
assertPhoneAccountHandleEquals(inputN, resultN);
}
@MediumTest
@Test
public void testPhoneAccount() throws Exception {
Bundle testBundle = new Bundle();
testBundle.putInt("EXTRA_INT_1", 1);
testBundle.putInt("EXTRA_INT_100", 100);
testBundle.putBoolean("EXTRA_BOOL_TRUE", true);
testBundle.putBoolean("EXTRA_BOOL_FALSE", false);
testBundle.putString("EXTRA_STR1", "Hello");
testBundle.putString("EXTRA_STR2", "There");
PhoneAccount input = makeQuickAccountBuilder("id0", 0)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.setExtras(testBundle)
.setIsEnabled(true)
.build();
PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml,
mContext);
assertPhoneAccountEquals(input, result);
}
@SmallTest
@Test
public void testFilterPhoneAccountForTest() throws Exception {
ComponentName componentA = new ComponentName("a", "a");
ComponentName componentB1 = new ComponentName("b", "b1");
ComponentName componentB2 = new ComponentName("b", "b2");
ComponentName componentC = new ComponentName("c", "c");
PhoneAccount simAccountA = new PhoneAccount.Builder(
makeQuickAccountHandle(componentA, "1"), "1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
List<PhoneAccount> accountAList = new ArrayList<>();
accountAList.add(simAccountA);
PhoneAccount simAccountB1 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentB1, "2"), "2")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
PhoneAccount simAccountB2 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentB2, "3"), "3")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
List<PhoneAccount> accountBList = new ArrayList<>();
accountBList.add(simAccountB1);
accountBList.add(simAccountB2);
PhoneAccount simAccountC = new PhoneAccount.Builder(
makeQuickAccountHandle(componentC, "4"), "4")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
List<PhoneAccount> accountCList = new ArrayList<>();
accountCList.add(simAccountC);
List<PhoneAccount> allAccounts = new ArrayList<>();
allAccounts.addAll(accountAList);
allAccounts.addAll(accountBList);
allAccounts.addAll(accountCList);
assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
mRegistrar.setTestPhoneAccountPackageNameFilter(componentA.getPackageName());
assertEquals(accountAList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
mRegistrar.setTestPhoneAccountPackageNameFilter(componentB1.getPackageName());
assertEquals(accountBList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
mRegistrar.setTestPhoneAccountPackageNameFilter(componentC.getPackageName());
assertEquals(accountCList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
mRegistrar.setTestPhoneAccountPackageNameFilter(null);
assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
}
@MediumTest
@Test
public void testDefaultPhoneAccountHandleEmptyGroup() throws Exception {
DefaultPhoneAccountHandle input = new DefaultPhoneAccountHandle(Process.myUserHandle(),
makeQuickAccountHandle("i1"), "");
when(UserManager.get(mContext).getSerialNumberForUser(input.userHandle))
.thenReturn(0L);
when(UserManager.get(mContext).getUserForSerialNumber(0L))
.thenReturn(input.userHandle);
DefaultPhoneAccountHandle result = roundTripXml(this, input,
PhoneAccountRegistrar.sDefaultPhoneAcountHandleXml, mContext);
assertDefaultPhoneAccountHandleEquals(input, result);
}
/**
* Test to ensure non-supported values
* @throws Exception
*/
@MediumTest
@Test
public void testPhoneAccountExtrasEdge() throws Exception {
Bundle testBundle = new Bundle();
// Ensure null values for string are not persisted.
testBundle.putString("EXTRA_STR2", null);
//
// Ensure unsupported data types are not persisted.
testBundle.putShort("EXTRA_SHORT", (short) 2);
testBundle.putByte("EXTRA_BYTE", (byte) 1);
testBundle.putParcelable("EXTRA_PARC", new Rect(1, 1, 1, 1));
// Put in something valid so the bundle exists.
testBundle.putString("EXTRA_OK", "OK");
PhoneAccount input = makeQuickAccountBuilder("id0", 0)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.setExtras(testBundle)
.build();
PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml,
mContext);
Bundle extras = result.getExtras();
assertFalse(extras.keySet().contains("EXTRA_STR2"));
assertFalse(extras.keySet().contains("EXTRA_SHORT"));
assertFalse(extras.keySet().contains("EXTRA_BYTE"));
assertFalse(extras.keySet().contains("EXTRA_PARC"));
}
@MediumTest
@Test
public void testState() throws Exception {
PhoneAccountRegistrar.State input = makeQuickState();
PhoneAccountRegistrar.State result = roundTripXml(this, input,
PhoneAccountRegistrar.sStateXml,
mContext);
assertStateEquals(input, result);
}
private void registerAndEnableAccount(PhoneAccount account) {
mRegistrar.registerPhoneAccount(account);
mRegistrar.enablePhoneAccount(account.getAccountHandle(), true);
}
@MediumTest
@Test
public void testAccounts() throws Exception {
int i = 0;
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++)
.setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
| PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build());
registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++)
.setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
| PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build());
registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++)
.setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
| PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build());
registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++)
.setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
.build());
assertEquals(4, mRegistrar.getAllPhoneAccountsOfCurrentUser().size());
assertEquals(3, mRegistrar.getCallCapablePhoneAccountsOfCurrentUser(null, false).size());
assertEquals(null, mRegistrar.getSimCallManagerOfCurrentUser());
assertEquals(null, mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL));
}
@MediumTest
@Test
public void testSimCallManager() throws Exception {
// TODO
}
@MediumTest
@Test
public void testDefaultOutgoing() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
// By default, there is no default outgoing account (nothing has been registered)
assertNull(
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
// Register one tel: account
PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount, "tel_acct")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.build());
PhoneAccountHandle defaultAccount =
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
assertEquals(telAccount, defaultAccount);
// Add a SIP account, make sure tel: doesn't change
PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct");
registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
.build());
defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_SIP);
assertEquals(sipAccount, defaultAccount);
defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL);
assertEquals(telAccount, defaultAccount);
// Add a connection manager, make sure tel: doesn't change
PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct");
registerAndEnableAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct")
.setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.build());
defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL);
assertEquals(telAccount, defaultAccount);
// Unregister the tel: account, make sure there is no tel: default now.
mRegistrar.unregisterPhoneAccount(telAccount);
assertNull(
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
}
@MediumTest
@Test
public void testReplacePhoneAccountByGroup() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
// By default, there is no default outgoing account (nothing has been registered)
assertNull(
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
// Register one tel: account
PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
PhoneAccountHandle defaultAccount =
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
assertEquals(telAccount1, defaultAccount);
// Add call capable SIP account, make sure tel: doesn't change
PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct");
registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.build());
defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL);
assertEquals(telAccount1, defaultAccount);
// Replace tel: account with another in the same Group
PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL);
assertEquals(telAccount2, defaultAccount);
assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
}
@MediumTest
@Test
public void testAddSameDefault() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
// By default, there is no default outgoing account (nothing has been registered)
assertNull(
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
// Register one tel: account
PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
PhoneAccountHandle defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertEquals(telAccount1, defaultAccount);
mRegistrar.unregisterPhoneAccount(telAccount1);
// Register Emergency Account and unregister
PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct");
registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.build());
defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertNull(defaultAccount);
mRegistrar.unregisterPhoneAccount(emerAccount);
// Re-register the same account and make sure the default is in place
registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertEquals(telAccount1, defaultAccount);
}
@MediumTest
@Test
public void testAddSameGroup() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
// By default, there is no default outgoing account (nothing has been registered)
assertNull(
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
// Register one tel: account
PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
PhoneAccountHandle defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertEquals(telAccount1, defaultAccount);
mRegistrar.unregisterPhoneAccount(telAccount1);
// Register Emergency Account and unregister
PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct");
registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.build());
defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertNull(defaultAccount);
mRegistrar.unregisterPhoneAccount(emerAccount);
// Re-register a new account with the same group
PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertEquals(telAccount2, defaultAccount);
}
@MediumTest
@Test
public void testAddSameGroupButDifferentComponent() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
// By default, there is no default outgoing account (nothing has been registered)
assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL));
// Register one tel: account
PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
PhoneAccountHandle defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertEquals(telAccount1, defaultAccount);
assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
// Register a new account with the same group, but different Component, so don't replace
// Default
PhoneAccountHandle telAccount2 = makeQuickAccountHandle(
new ComponentName("other1", "other2"), "tel_acct2");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount2));
defaultAccount =
mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
assertEquals(telAccount1, defaultAccount);
}
@MediumTest
@Test
public void testAddSameGroupButDifferentComponent2() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
// By default, there is no default outgoing account (nothing has been registered)
assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
PhoneAccount.SCHEME_TEL));
// Register first tel: account
PhoneAccountHandle telAccount1 = makeQuickAccountHandle(
new ComponentName("other1", "other2"), "tel_acct1");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
// Register second account with the same group, but a second Component, so don't replace
// Default
PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
PhoneAccountHandle defaultAccount =
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
assertEquals(telAccount1, defaultAccount);
// Register third account with the second component name, but same group id
PhoneAccountHandle telAccount3 = makeQuickAccountHandle("tel_acct3");
registerAndEnableAccount(new PhoneAccount.Builder(telAccount3, "tel_acct3")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.setGroupId("testGroup")
.build());
// Make sure that the default account is still the original PhoneAccount and that the
// second PhoneAccount with the second ComponentName was replaced by the third PhoneAccount
defaultAccount =
mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
assertEquals(telAccount1, defaultAccount);
assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount2));
assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount3));
}
@MediumTest
@Test
public void testPhoneAccountParceling() throws Exception {
PhoneAccountHandle handle = makeQuickAccountHandle("foo");
roundTripPhoneAccount(new PhoneAccount.Builder(handle, null).build());
roundTripPhoneAccount(new PhoneAccount.Builder(handle, "foo").build());
roundTripPhoneAccount(
new PhoneAccount.Builder(handle, "foo")
.setAddress(Uri.parse("tel:123456"))
.setCapabilities(23)
.setHighlightColor(0xf0f0f0)
.setIcon(Icon.createWithResource(
"com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
// TODO: set icon tint (0xfefefe)
.setShortDescription("short description")
.setSubscriptionAddress(Uri.parse("tel:2345678"))
.setSupportedUriSchemes(Arrays.asList("tel", "sip"))
.setGroupId("testGroup")
.build());
roundTripPhoneAccount(
new PhoneAccount.Builder(handle, "foo")
.setAddress(Uri.parse("tel:123456"))
.setCapabilities(23)
.setHighlightColor(0xf0f0f0)
.setIcon(Icon.createWithBitmap(
BitmapFactory.decodeResource(
InstrumentationRegistry.getContext().getResources(),
R.drawable.stat_sys_phone_call)))
.setShortDescription("short description")
.setSubscriptionAddress(Uri.parse("tel:2345678"))
.setSupportedUriSchemes(Arrays.asList("tel", "sip"))
.setGroupId("testGroup")
.build());
}
/**
* Tests ability to register a self-managed PhoneAccount; verifies that the user defined label
* is overridden.
* @throws Exception
*/
@MediumTest
@Test
public void testSelfManagedPhoneAccount() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
PhoneAccountHandle selfManagedHandle = makeQuickAccountHandle(
new ComponentName("self", "managed"), "selfie1");
PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, "Wrong")
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
.build();
mRegistrar.registerPhoneAccount(selfManagedAccount);
PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle);
assertEquals(TEST_LABEL, registeredAccount.getLabel());
}
/**
* Tests to ensure that when registering a self-managed PhoneAccount, it cannot also be defined
* as a call provider, connection manager, or sim subscription.
* @throws Exception
*/
@MediumTest
@Test
public void testSelfManagedCapabilityOverride() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
PhoneAccountHandle selfManagedHandle = makeQuickAccountHandle(
new ComponentName("self", "managed"), "selfie1");
PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, TEST_LABEL)
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
.build();
mRegistrar.registerPhoneAccount(selfManagedAccount);
PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle);
assertEquals(PhoneAccount.CAPABILITY_SELF_MANAGED, registeredAccount.getCapabilities());
}
@MediumTest
@Test
public void testSortSimFirst() throws Exception {
ComponentName componentA = new ComponentName("a", "a");
ComponentName componentB = new ComponentName("b", "b");
mComponentContextFixture.addConnectionService(componentA,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentB,
Mockito.mock(IConnectionService.class));
PhoneAccount simAccount = new PhoneAccount.Builder(
makeQuickAccountHandle(componentB, "2"), "2")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
.setIsEnabled(true)
.build();
PhoneAccount nonSimAccount = new PhoneAccount.Builder(
makeQuickAccountHandle(componentA, "1"), "1")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
registerAndEnableAccount(nonSimAccount);
registerAndEnableAccount(simAccount);
List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle());
assertTrue(accounts.get(0).getLabel().toString().equals("2"));
assertTrue(accounts.get(1).getLabel().toString().equals("1"));
}
@MediumTest
@Test
public void testSortBySortOrder() throws Exception {
ComponentName componentA = new ComponentName("a", "a");
ComponentName componentB = new ComponentName("b", "b");
ComponentName componentC = new ComponentName("c", "c");
mComponentContextFixture.addConnectionService(componentA,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentB,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentC,
Mockito.mock(IConnectionService.class));
Bundle account1Extras = new Bundle();
account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1);
PhoneAccount account1 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentA, "c"), "c")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setExtras(account1Extras)
.build();
Bundle account2Extras = new Bundle();
account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2);
PhoneAccount account2 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentB, "b"), "b")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setExtras(account2Extras)
.build();
PhoneAccount account3 = new PhoneAccount.Builder(
makeQuickAccountHandle(componentC, "c"), "a")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build();
registerAndEnableAccount(account3);
registerAndEnableAccount(account2);
registerAndEnableAccount(account1);
List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle());
assertTrue(accounts.get(0).getLabel().toString().equals("c"));
assertTrue(accounts.get(1).getLabel().toString().equals("b"));
assertTrue(accounts.get(2).getLabel().toString().equals("a"));
}
@MediumTest
@Test
public void testSortByLabel() throws Exception {
ComponentName componentA = new ComponentName("a", "a");
ComponentName componentB = new ComponentName("b", "b");
ComponentName componentC = new ComponentName("c", "c");
mComponentContextFixture.addConnectionService(componentA,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentB,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentC,
Mockito.mock(IConnectionService.class));
PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(componentA, "c"),
"c")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build();
PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(componentB, "b"),
"b")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build();
PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(componentC, "a"),
"a")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build();
registerAndEnableAccount(account1);
registerAndEnableAccount(account2);
registerAndEnableAccount(account3);
List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle());
assertTrue(accounts.get(0).getLabel().toString().equals("a"));
assertTrue(accounts.get(1).getLabel().toString().equals("b"));
assertTrue(accounts.get(2).getLabel().toString().equals("c"));
}
@MediumTest
@Test
public void testSortAll() throws Exception {
ComponentName componentA = new ComponentName("a", "a");
ComponentName componentB = new ComponentName("b", "b");
ComponentName componentC = new ComponentName("c", "c");
ComponentName componentW = new ComponentName("w", "w");
ComponentName componentX = new ComponentName("x", "x");
ComponentName componentY = new ComponentName("y", "y");
ComponentName componentZ = new ComponentName("z", "z");
mComponentContextFixture.addConnectionService(componentA,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentB,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentC,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentW,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentX,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentY,
Mockito.mock(IConnectionService.class));
mComponentContextFixture.addConnectionService(componentZ,
Mockito.mock(IConnectionService.class));
Bundle account1Extras = new Bundle();
account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2);
PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "y"), "y")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
.setExtras(account1Extras)
.build();
Bundle account2Extras = new Bundle();
account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1);
PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "z"), "z")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
.setExtras(account2Extras)
.build();
PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "x"), "x")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
.build();
PhoneAccount account4 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "w"), "w")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
.build();
PhoneAccount account5 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "b"), "b")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build();
PhoneAccount account6 = new PhoneAccount.Builder(makeQuickAccountHandle(
makeQuickConnectionServiceComponentName(), "c"), "a")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build();
registerAndEnableAccount(account1);
registerAndEnableAccount(account2);
registerAndEnableAccount(account3);
registerAndEnableAccount(account4);
registerAndEnableAccount(account5);
registerAndEnableAccount(account6);
List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle());
// Sim accts ordered by sort order first
assertTrue(accounts.get(0).getLabel().toString().equals("z"));
assertTrue(accounts.get(1).getLabel().toString().equals("y"));
// Sim accts with no sort order next
assertTrue(accounts.get(2).getLabel().toString().equals("w"));
assertTrue(accounts.get(3).getLabel().toString().equals("x"));
// Other accts sorted by label next
assertTrue(accounts.get(4).getLabel().toString().equals("a"));
assertTrue(accounts.get(5).getLabel().toString().equals("b"));
}
/**
* Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)}
* to ensure disabled accounts are filtered out of results when requested.
* @throws Exception
*/
@MediumTest
@Test
public void testGetByEnabledState() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id1", 1)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.build());
assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL,
false /* includeDisabled */, Process.myUserHandle()).size());
assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL,
true /* includeDisabled */, Process.myUserHandle()).size());
}
/**
* Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)}
* to ensure scheme filtering operates.
* @throws Exception
*/
@MediumTest
@Test
public void testGetByScheme() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
registerAndEnableAccount(makeQuickAccountBuilder("id1", 1)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP))
.build());
registerAndEnableAccount(makeQuickAccountBuilder("id2", 2)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
.build());
assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
false /* includeDisabled */, Process.myUserHandle()).size());
assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL,
false /* includeDisabled */, Process.myUserHandle()).size());
assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(null, false /* includeDisabled */,
Process.myUserHandle()).size());
}
/**
* Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle,
* int)} to ensure capability filtering operates.
* @throws Exception
*/
@MediumTest
@Test
public void testGetByCapability() throws Exception {
mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
Mockito.mock(IConnectionService.class));
registerAndEnableAccount(makeQuickAccountBuilder("id1", 1)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER
| PhoneAccount.CAPABILITY_VIDEO_CALLING)
.setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP))
.build());
registerAndEnableAccount(makeQuickAccountBuilder("id2", 2)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP))
.build());
assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
false /* includeDisabled */, Process.myUserHandle()).size(),
PhoneAccount.CAPABILITY_VIDEO_CALLING);
assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
false /* includeDisabled */, Process.myUserHandle()).size(), 0 /* none extra */);
assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
false /* includeDisabled */, Process.myUserHandle()).size(),
PhoneAccount.CAPABILITY_RTT);
}
/**
* Tests {@link PhoneAccount#equals(Object)} operator.
* @throws Exception
*/
@MediumTest
@Test
public void testPhoneAccountEquality() throws Exception {
PhoneAccountHandle handle = new PhoneAccountHandle(new ComponentName("foo", "bar"), "id");
PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, "label");
builder.addSupportedUriScheme("tel");
builder.setAddress(Uri.fromParts("tel", "6505551212", null));
builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
Bundle extras = new Bundle();
extras.putInt("INT", 1);
extras.putString("STR", "str");
builder.setExtras(extras);
builder.setGroupId("group");
builder.setHighlightColor(1);
builder.setShortDescription("short");
builder.setSubscriptionAddress(Uri.fromParts("tel", "6505551213", null));
builder.setSupportedAudioRoutes(2);
PhoneAccount account1 = builder.build();
PhoneAccount account2 = builder.build();
assertEquals(account1, account2);
}
/**
* Tests {@link PhoneAccountHandle#areFromSamePackage(PhoneAccountHandle,
* PhoneAccountHandle)} comparison.
*/
@SmallTest
@Test
public void testSamePhoneAccountHandlePackage() {
PhoneAccountHandle a = new PhoneAccountHandle(new ComponentName("packageA", "class1"),
"id1");
PhoneAccountHandle b = new PhoneAccountHandle(new ComponentName("packageA", "class2"),
"id2");
PhoneAccountHandle c = new PhoneAccountHandle(new ComponentName("packageA", "class1"),
"id3");
PhoneAccountHandle d = new PhoneAccountHandle(new ComponentName("packageB", "class1"),
"id1");
assertTrue(PhoneAccountHandle.areFromSamePackage(null, null));
assertTrue(PhoneAccountHandle.areFromSamePackage(a, b));
assertTrue(PhoneAccountHandle.areFromSamePackage(a, c));
assertTrue(PhoneAccountHandle.areFromSamePackage(b, c));
assertFalse(PhoneAccountHandle.areFromSamePackage(a, d));
assertFalse(PhoneAccountHandle.areFromSamePackage(b, d));
assertFalse(PhoneAccountHandle.areFromSamePackage(c, d));
assertFalse(PhoneAccountHandle.areFromSamePackage(a, null));
assertFalse(PhoneAccountHandle.areFromSamePackage(b, null));
assertFalse(PhoneAccountHandle.areFromSamePackage(c, null));
assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
}
private static ComponentName makeQuickConnectionServiceComponentName() {
return new ComponentName(
"com.android.server.telecom.tests",
"com.android.server.telecom.tests.MockConnectionService");
}
private static PhoneAccountHandle makeQuickAccountHandle(String id) {
return makeQuickAccountHandle(makeQuickConnectionServiceComponentName(), id);
}
private static PhoneAccountHandle makeQuickAccountHandle(ComponentName name, String id) {
return new PhoneAccountHandle(name, id, Process.myUserHandle());
}
private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
return new PhoneAccount.Builder(
makeQuickAccountHandle(id),
"label" + idx);
}
private PhoneAccount makeQuickAccount(String id, int idx) {
return makeQuickAccountBuilder(id, idx)
.setAddress(Uri.parse("http://foo.com/" + idx))
.setSubscriptionAddress(Uri.parse("tel:555-000" + idx))
.setCapabilities(idx)
.setIcon(Icon.createWithResource(
"com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
.setShortDescription("desc" + idx)
.setIsEnabled(true)
.build();
}
private static void roundTripPhoneAccount(PhoneAccount original) throws Exception {
PhoneAccount copy = null;
{
Parcel parcel = Parcel.obtain();
parcel.writeParcelable(original, 0);
parcel.setDataPosition(0);
copy = parcel.readParcelable(PhoneAccountRegistrarTest.class.getClassLoader());
parcel.recycle();
}
assertPhoneAccountEquals(original, copy);
}
private static <T> T roundTripXml(
Object self,
T input,
PhoneAccountRegistrar.XmlSerialization<T> xml,
Context context)
throws Exception {
Log.d(self, "Input = %s", input);
byte[] data;
{
XmlSerializer serializer = new FastXmlSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
xml.writeToXml(input, serializer, context);
serializer.flush();
data = baos.toByteArray();
}
Log.i(self, "====== XML data ======\n%s", new String(data));
T result = null;
{
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null);
parser.nextTag();
result = xml.readFromXml(parser, MAX_VERSION, context);
}
Log.i(self, "result = " + result);
return result;
}
private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) {
if (a != b) {
assertEquals(
a.getComponentName().getPackageName(),
b.getComponentName().getPackageName());
assertEquals(
a.getComponentName().getClassName(),
b.getComponentName().getClassName());
assertEquals(a.getId(), b.getId());
}
}
private static void assertIconEquals(Icon a, Icon b) {
if (a != b) {
if (a != null && b != null) {
assertEquals(a.toString(), b.toString());
} else {
fail("Icons not equal: " + a + ", " + b);
}
}
}
private static void assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a,
DefaultPhoneAccountHandle b) {
if (a != b) {
if (a!= null && b != null) {
assertEquals(a.userHandle, b.userHandle);
assertPhoneAccountHandleEquals(a.phoneAccountHandle, b.phoneAccountHandle);
} else {
fail("Default phone account handles are not equal: " + a + ", " + b);
}
}
}
private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) {
if (a != b) {
if (a != null && b != null) {
assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle());
assertEquals(a.getAddress(), b.getAddress());
assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress());
assertEquals(a.getCapabilities(), b.getCapabilities());
assertIconEquals(a.getIcon(), b.getIcon());
assertEquals(a.getHighlightColor(), b.getHighlightColor());
assertEquals(a.getLabel(), b.getLabel());
assertEquals(a.getShortDescription(), b.getShortDescription());
assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes());
assertBundlesEqual(a.getExtras(), b.getExtras());
assertEquals(a.isEnabled(), b.isEnabled());
} else {
fail("Phone accounts not equal: " + a + ", " + b);
}
}
}
private static void assertBundlesEqual(Bundle a, Bundle b) {
if (a == null && b == null) {
return;
}
assertNotNull(a);
assertNotNull(b);
Set<String> keySetA = a.keySet();
Set<String> keySetB = b.keySet();
assertTrue("Bundle keys not the same", keySetA.containsAll(keySetB));
assertTrue("Bundle keys not the same", keySetB.containsAll(keySetA));
for (String keyA : keySetA) {
assertEquals("Bundle value not the same", a.get(keyA), b.get(keyA));
}
}
private static void assertStateEquals(
PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) {
assertEquals(a.defaultOutgoingAccountHandles.size(),
b.defaultOutgoingAccountHandles.size());
for (Map.Entry<UserHandle, DefaultPhoneAccountHandle> e :
a.defaultOutgoingAccountHandles.entrySet()) {
assertDefaultPhoneAccountHandleEquals(e.getValue(),
b.defaultOutgoingAccountHandles.get(e.getKey()));
}
assertEquals(a.accounts.size(), b.accounts.size());
for (int i = 0; i < a.accounts.size(); i++) {
assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i));
}
}
private PhoneAccountRegistrar.State makeQuickState() {
PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State();
s.accounts.add(makeQuickAccount("id0", 0));
s.accounts.add(makeQuickAccount("id1", 1));
s.accounts.add(makeQuickAccount("id2", 2));
PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
new ComponentName("pkg0", "cls0"), "id0");
UserHandle userHandle = phoneAccountHandle.getUserHandle();
when(UserManager.get(mContext).getSerialNumberForUser(userHandle))
.thenReturn(0L);
when(UserManager.get(mContext).getUserForSerialNumber(0L))
.thenReturn(userHandle);
s.defaultOutgoingAccountHandles
.put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle,
"testGroup"));
return s;
}
}