Loading src/com/android/server/telecom/DefaultDialerCache.java 0 → 100644 +180 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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; import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; import android.telecom.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; public class DefaultDialerCache { private static final String LOG_TAG = "DefaultDialerCache"; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.startSession("DDC.oR"); try { String packageName; if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) { packageName = intent.getData().getSchemeSpecificPart(); } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { packageName = intent.getData().getSchemeSpecificPart(); } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { packageName = null; } else { return; } synchronized (mLock) { refreshCachesForUsersWithPackage(packageName); } } finally { Log.endSession(); } } }; private final Handler mHandler = new Handler(Looper.getMainLooper()); private final ContentObserver mDefaultDialerObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { Log.startSession("DDC.oC"); try { // We don't get the user ID of the user that changed here, so we'll have to // refresh all of the users. synchronized (mLock) { refreshCachesForUsersWithPackage(null); } } finally { Log.endSession(); } } @Override public boolean deliverSelfNotifications() { return true; } }; private final Context mContext; private final TelecomServiceImpl.DefaultDialerManagerAdapter mDefaultDialerManagerAdapter; private final TelecomSystem.SyncRoot mLock; private final String mSystemDialerName; private SparseArray<String> mCurrentDefaultDialerPerUser = new SparseArray<>(); public DefaultDialerCache(Context context, TelecomServiceImpl.DefaultDialerManagerAdapter defaultDialerManagerAdapter, TelecomSystem.SyncRoot lock) { mContext = context; mDefaultDialerManagerAdapter = defaultDialerManagerAdapter; mLock = lock; mSystemDialerName = mContext.getResources().getString(R.string.ui_default_package); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addDataScheme("package"); context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null); Uri defaultDialerSetting = Settings.Secure.getUriFor(Settings.Secure.DIALER_DEFAULT_APPLICATION); context.getContentResolver() .registerContentObserver(defaultDialerSetting, false, mDefaultDialerObserver, UserHandle.USER_ALL); } public String getDefaultDialerApplication(int userId) { if (userId == UserHandle.USER_CURRENT) { userId = ActivityManager.getCurrentUser(); } if (userId < 0) { Log.w(LOG_TAG, "Attempting to get default dialer for a meta-user %d", userId); return null; } synchronized (mLock) { String defaultDialer = mCurrentDefaultDialerPerUser.get(userId); if (defaultDialer != null) { return defaultDialer; } } return refreshCacheForUser(userId); } public String getDefaultDialerApplication() { return getDefaultDialerApplication(mContext.getUserId()); } public boolean isDefaultOrSystemDialer(Context context, String packageName) { String defaultDialer = getDefaultDialerApplication(context.getUserId()); return Objects.equals(packageName, defaultDialer) || Objects.equals(packageName, mSystemDialerName); } private String refreshCacheForUser(int userId) { String currentDefaultDialer = mDefaultDialerManagerAdapter.getDefaultDialerApplication(mContext, userId); synchronized (mLock) { mCurrentDefaultDialerPerUser.put(userId, currentDefaultDialer); } return currentDefaultDialer; } /** * Refreshes the cache for users that currently have packageName as their cached default dialer. * If packageName is null, refresh all caches. * @param packageName Name of the affected package. */ private void refreshCachesForUsersWithPackage(String packageName) { for (int i = 0; i < mCurrentDefaultDialerPerUser.size(); i++) { int userId = mCurrentDefaultDialerPerUser.keyAt(i); if (packageName == null || Objects.equals(packageName, mCurrentDefaultDialerPerUser.get(userId))) { String newDefaultDialer = refreshCacheForUser(userId); Log.i(LOG_TAG, "Refreshing default dialer for user %d: now %s", userId, newDefaultDialer); } } } /** * registerContentObserver is really hard to mock out, so here is a getter method for the * content observer for testing instead. * @return The content observer */ @VisibleForTesting public ContentObserver getContentObserver() { return mDefaultDialerObserver; } } No newline at end of file tests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ <!-- TODO: Needed because we call ActivityManager.getCurrentUser() statically. --> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <!-- Used to access TelephonyManager APIs --> Loading tests/src/com/android/server/telecom/tests/ComponentContextFixture.java +6 −0 Original line number Diff line number Diff line Loading @@ -258,6 +258,12 @@ public class ComponentContextFixture implements TestFixture<Context> { return null; } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle handle, IntentFilter filter, String broadcastPermission, Handler scheduler) { return null; } @Override public void sendBroadcast(Intent intent) { // TODO -- need to ensure this is captured Loading tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java 0 → 100644 +221 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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 android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import com.android.server.telecom.DefaultDialerCache; import com.android.server.telecom.TelecomServiceImpl; import com.android.server.telecom.TelecomSystem; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class DefaultDialerCacheTest extends TelecomTestCase { private static final String DIALER1 = "com.android.dialer"; private static final String DIALER2 = "xyz.abc.dialer"; private static final String DIALER3 = "aaa.bbb.ccc.ddd"; private static final int USER0 = 0; private static final int USER1 = 1; private static final int USER2 = 2; private DefaultDialerCache mDefaultDialerCache; private ContentObserver mDefaultDialerSettingObserver; private BroadcastReceiver mPackageChangeReceiver; @Mock private TelecomServiceImpl.DefaultDialerManagerAdapter mMockDefaultDialerManager; public void setUp() throws Exception { super.setUp(); mContext = mComponentContextFixture.getTestDouble().getApplicationContext(); ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class); mDefaultDialerCache = new DefaultDialerCache( mContext, mMockDefaultDialerManager, new TelecomSystem.SyncRoot() { }); verify(mContext).registerReceiverAsUser( receiverCaptor.capture(), eq(UserHandle.ALL), any(IntentFilter.class), isNull(String.class), isNull(Handler.class)); mPackageChangeReceiver = receiverCaptor.getValue(); mDefaultDialerSettingObserver = mDefaultDialerCache.getContentObserver(); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0))) .thenReturn(DIALER1); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER1))) .thenReturn(DIALER2); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER2))) .thenReturn(DIALER3); } @SmallTest public void testThreeUsers() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testDialer1PackageChanged() { // Populate the caches first assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED, Uri.fromParts("package", DIALER1, null)); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0))) .thenReturn(DIALER2); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER2); } @SmallTest public void testRandomOtherPackageChanged() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED, Uri.fromParts("package", "red.orange.blue", null)); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testPackageRemovedWithoutReplace() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED, Uri.fromParts("package", DIALER1, null)); packageChangeIntent.putExtra(Intent.EXTRA_REPLACING, false); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testPackageAdded() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_ADDED, Uri.fromParts("package", "ppp.qqq.zzz", null)); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testPackageRemovedWithReplace() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED, Uri.fromParts("package", DIALER1, null)); packageChangeIntent.putExtra(Intent.EXTRA_REPLACING, true); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testDefaultDialerSettingChanged() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0))) .thenReturn(DIALER2); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER1))) .thenReturn(DIALER2); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER2))) .thenReturn(DIALER2); mDefaultDialerSettingObserver.onChange(false); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER2); } } Loading
src/com/android/server/telecom/DefaultDialerCache.java 0 → 100644 +180 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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; import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; import android.telecom.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; public class DefaultDialerCache { private static final String LOG_TAG = "DefaultDialerCache"; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.startSession("DDC.oR"); try { String packageName; if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) { packageName = intent.getData().getSchemeSpecificPart(); } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { packageName = intent.getData().getSchemeSpecificPart(); } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { packageName = null; } else { return; } synchronized (mLock) { refreshCachesForUsersWithPackage(packageName); } } finally { Log.endSession(); } } }; private final Handler mHandler = new Handler(Looper.getMainLooper()); private final ContentObserver mDefaultDialerObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { Log.startSession("DDC.oC"); try { // We don't get the user ID of the user that changed here, so we'll have to // refresh all of the users. synchronized (mLock) { refreshCachesForUsersWithPackage(null); } } finally { Log.endSession(); } } @Override public boolean deliverSelfNotifications() { return true; } }; private final Context mContext; private final TelecomServiceImpl.DefaultDialerManagerAdapter mDefaultDialerManagerAdapter; private final TelecomSystem.SyncRoot mLock; private final String mSystemDialerName; private SparseArray<String> mCurrentDefaultDialerPerUser = new SparseArray<>(); public DefaultDialerCache(Context context, TelecomServiceImpl.DefaultDialerManagerAdapter defaultDialerManagerAdapter, TelecomSystem.SyncRoot lock) { mContext = context; mDefaultDialerManagerAdapter = defaultDialerManagerAdapter; mLock = lock; mSystemDialerName = mContext.getResources().getString(R.string.ui_default_package); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addDataScheme("package"); context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null); Uri defaultDialerSetting = Settings.Secure.getUriFor(Settings.Secure.DIALER_DEFAULT_APPLICATION); context.getContentResolver() .registerContentObserver(defaultDialerSetting, false, mDefaultDialerObserver, UserHandle.USER_ALL); } public String getDefaultDialerApplication(int userId) { if (userId == UserHandle.USER_CURRENT) { userId = ActivityManager.getCurrentUser(); } if (userId < 0) { Log.w(LOG_TAG, "Attempting to get default dialer for a meta-user %d", userId); return null; } synchronized (mLock) { String defaultDialer = mCurrentDefaultDialerPerUser.get(userId); if (defaultDialer != null) { return defaultDialer; } } return refreshCacheForUser(userId); } public String getDefaultDialerApplication() { return getDefaultDialerApplication(mContext.getUserId()); } public boolean isDefaultOrSystemDialer(Context context, String packageName) { String defaultDialer = getDefaultDialerApplication(context.getUserId()); return Objects.equals(packageName, defaultDialer) || Objects.equals(packageName, mSystemDialerName); } private String refreshCacheForUser(int userId) { String currentDefaultDialer = mDefaultDialerManagerAdapter.getDefaultDialerApplication(mContext, userId); synchronized (mLock) { mCurrentDefaultDialerPerUser.put(userId, currentDefaultDialer); } return currentDefaultDialer; } /** * Refreshes the cache for users that currently have packageName as their cached default dialer. * If packageName is null, refresh all caches. * @param packageName Name of the affected package. */ private void refreshCachesForUsersWithPackage(String packageName) { for (int i = 0; i < mCurrentDefaultDialerPerUser.size(); i++) { int userId = mCurrentDefaultDialerPerUser.keyAt(i); if (packageName == null || Objects.equals(packageName, mCurrentDefaultDialerPerUser.get(userId))) { String newDefaultDialer = refreshCacheForUser(userId); Log.i(LOG_TAG, "Refreshing default dialer for user %d: now %s", userId, newDefaultDialer); } } } /** * registerContentObserver is really hard to mock out, so here is a getter method for the * content observer for testing instead. * @return The content observer */ @VisibleForTesting public ContentObserver getContentObserver() { return mDefaultDialerObserver; } } No newline at end of file
tests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ <!-- TODO: Needed because we call ActivityManager.getCurrentUser() statically. --> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <!-- Used to access TelephonyManager APIs --> Loading
tests/src/com/android/server/telecom/tests/ComponentContextFixture.java +6 −0 Original line number Diff line number Diff line Loading @@ -258,6 +258,12 @@ public class ComponentContextFixture implements TestFixture<Context> { return null; } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle handle, IntentFilter filter, String broadcastPermission, Handler scheduler) { return null; } @Override public void sendBroadcast(Intent intent) { // TODO -- need to ensure this is captured Loading
tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java 0 → 100644 +221 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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 android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import com.android.server.telecom.DefaultDialerCache; import com.android.server.telecom.TelecomServiceImpl; import com.android.server.telecom.TelecomSystem; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class DefaultDialerCacheTest extends TelecomTestCase { private static final String DIALER1 = "com.android.dialer"; private static final String DIALER2 = "xyz.abc.dialer"; private static final String DIALER3 = "aaa.bbb.ccc.ddd"; private static final int USER0 = 0; private static final int USER1 = 1; private static final int USER2 = 2; private DefaultDialerCache mDefaultDialerCache; private ContentObserver mDefaultDialerSettingObserver; private BroadcastReceiver mPackageChangeReceiver; @Mock private TelecomServiceImpl.DefaultDialerManagerAdapter mMockDefaultDialerManager; public void setUp() throws Exception { super.setUp(); mContext = mComponentContextFixture.getTestDouble().getApplicationContext(); ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class); mDefaultDialerCache = new DefaultDialerCache( mContext, mMockDefaultDialerManager, new TelecomSystem.SyncRoot() { }); verify(mContext).registerReceiverAsUser( receiverCaptor.capture(), eq(UserHandle.ALL), any(IntentFilter.class), isNull(String.class), isNull(Handler.class)); mPackageChangeReceiver = receiverCaptor.getValue(); mDefaultDialerSettingObserver = mDefaultDialerCache.getContentObserver(); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0))) .thenReturn(DIALER1); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER1))) .thenReturn(DIALER2); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER2))) .thenReturn(DIALER3); } @SmallTest public void testThreeUsers() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testDialer1PackageChanged() { // Populate the caches first assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED, Uri.fromParts("package", DIALER1, null)); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0))) .thenReturn(DIALER2); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER2); } @SmallTest public void testRandomOtherPackageChanged() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED, Uri.fromParts("package", "red.orange.blue", null)); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testPackageRemovedWithoutReplace() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED, Uri.fromParts("package", DIALER1, null)); packageChangeIntent.putExtra(Intent.EXTRA_REPLACING, false); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testPackageAdded() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_ADDED, Uri.fromParts("package", "ppp.qqq.zzz", null)); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testPackageRemovedWithReplace() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); Intent packageChangeIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED, Uri.fromParts("package", DIALER1, null)); packageChangeIntent.putExtra(Intent.EXTRA_REPLACING, true); mPackageChangeReceiver.onReceive(mContext, packageChangeIntent); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER1)); verify(mMockDefaultDialerManager, times(1)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); } @SmallTest public void testDefaultDialerSettingChanged() { assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER1); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER3); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER0))) .thenReturn(DIALER2); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER1))) .thenReturn(DIALER2); when(mMockDefaultDialerManager.getDefaultDialerApplication(any(Context.class), eq(USER2))) .thenReturn(DIALER2); mDefaultDialerSettingObserver.onChange(false); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER0)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); verify(mMockDefaultDialerManager, times(2)) .getDefaultDialerApplication(any(Context.class), eq(USER2)); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER0), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER1), DIALER2); assertEquals(mDefaultDialerCache.getDefaultDialerApplication(USER2), DIALER2); } }