| /* |
| * Copyright (C) 2018 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 android.telecom.cts; |
| |
| import static android.telecom.cts.TestUtils.TEST_PHONE_ACCOUNT_HANDLE; |
| import static android.telecom.cts.TestUtils.shouldTestTelecom; |
| |
| import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; |
| |
| import android.content.ComponentName; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.telecom.Call; |
| import android.telecom.PhoneAccountHandle; |
| import android.telecom.PhoneAccountSuggestion; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.concurrent.TimeUnit; |
| import java.util.stream.Collectors; |
| |
| public class PhoneAccountSuggestionServiceTest extends BaseTelecomTestWithMockServices { |
| private static final long TEST_TIMEOUT = 5000; |
| private PhoneAccountHandle mCachedDefaultHandle; |
| |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| |
| if (shouldTestTelecom(mContext) && TestUtils.hasTelephonyFeature(mContext)) { |
| TestUtils.setCtsPhoneAccountSuggestionService(getInstrumentation(), |
| new ComponentName(mContext, CtsPhoneAccountSuggestionService.class)); |
| mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT); |
| mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT_2); |
| mCachedDefaultHandle = mTelecomManager.getUserSelectedOutgoingPhoneAccount(); |
| runWithShellPermissionIdentity( |
| () -> mTelecomManager.setUserSelectedOutgoingPhoneAccount(null)); |
| TestUtils.enablePhoneAccount(getInstrumentation(), TestUtils.TEST_PHONE_ACCOUNT_HANDLE); |
| TestUtils.enablePhoneAccount( |
| getInstrumentation(), TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2); |
| CtsPhoneAccountSuggestionService.enableService(mContext); |
| } |
| } |
| |
| @Override |
| public void tearDown() throws Exception { |
| if (shouldTestTelecom(mContext) && TestUtils.hasTelephonyFeature(mContext)) { |
| if (mInCallCallbacks.getService().getLastCall() != null) { |
| mInCallCallbacks.getService().getLastCall().disconnect(); |
| } |
| TestUtils.setCtsPhoneAccountSuggestionService(getInstrumentation(), null); |
| mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT_HANDLE); |
| mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2); |
| runWithShellPermissionIdentity(() -> |
| mTelecomManager.setUserSelectedOutgoingPhoneAccount(mCachedDefaultHandle)); |
| CtsPhoneAccountSuggestionService.disableService(mContext); |
| } |
| super.tearDown(); |
| } |
| |
| public void testSuggestionFlow() throws Exception { |
| if (!shouldTestTelecom(mContext) || !TestUtils.hasTelephonyFeature(mContext)) { |
| return; |
| } |
| |
| CtsPhoneAccountSuggestionService.sSuggestionsToProvide = List.of( |
| new PhoneAccountSuggestion(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, |
| PhoneAccountSuggestion.REASON_NONE, |
| false), |
| new PhoneAccountSuggestion(TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2, |
| PhoneAccountSuggestion.REASON_FREQUENT, |
| true)); |
| |
| Uri number = createTestNumber(); |
| mTelecomManager.placeCall(number, new Bundle()); |
| |
| assertEquals(number.getSchemeSpecificPart(), |
| CtsPhoneAccountSuggestionService.sSuggestionRequestQueue.poll( |
| TEST_TIMEOUT, TimeUnit.MILLISECONDS)); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| final MockInCallService inCallService = mInCallCallbacks.getService(); |
| Call phoneAcctSelectCall = inCallService.getLastCall(); |
| assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, phoneAcctSelectCall.getState()); |
| List<PhoneAccountSuggestion> receivedSuggestions = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.EXTRA_SUGGESTED_PHONE_ACCOUNTS); |
| assertTrue(CtsPhoneAccountSuggestionService.sSuggestionsToProvide.size() |
| <= receivedSuggestions.size()); |
| assertTrue(receivedSuggestions.containsAll( |
| CtsPhoneAccountSuggestionService.sSuggestionsToProvide)); |
| } |
| |
| public void testSuggestionTimeout() throws Exception { |
| if (!shouldTestTelecom(mContext) || !TestUtils.hasTelephonyFeature(mContext)) { |
| return; |
| } |
| |
| CtsPhoneAccountSuggestionService.sSuggestionsToProvide = List.of( |
| new PhoneAccountSuggestion(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, |
| PhoneAccountSuggestion.REASON_NONE, |
| false), |
| new PhoneAccountSuggestion(TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2, |
| PhoneAccountSuggestion.REASON_FREQUENT, |
| true)); |
| |
| // Force a Telecom time out |
| CtsPhoneAccountSuggestionService.sSuggestionWaitTime = |
| 2 * 1000 * TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S; |
| |
| Uri number = createTestNumber(); |
| mTelecomManager.placeCall(number, new Bundle()); |
| |
| assertEquals(number.getSchemeSpecificPart(), |
| CtsPhoneAccountSuggestionService.sSuggestionRequestQueue.poll( |
| TEST_TIMEOUT, TimeUnit.MILLISECONDS)); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| final MockInCallService inCallService = mInCallCallbacks.getService(); |
| Call phoneAcctSelectCall = inCallService.getLastCall(); |
| assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, phoneAcctSelectCall.getState()); |
| List<PhoneAccountSuggestion> receivedSuggestions = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.EXTRA_SUGGESTED_PHONE_ACCOUNTS); |
| |
| List<PhoneAccountHandle> receivedAccounts = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.AVAILABLE_PHONE_ACCOUNTS); |
| // We don't need to assert anything about the contents, just make sure that we get |
| // some default suggestions that match up with the available accounts. |
| assertEquals(receivedAccounts.size(), receivedSuggestions.size()); |
| assertTrue(receivedAccounts.containsAll(getHandlesFromSuggestions(receivedSuggestions))); |
| } |
| |
| public void testEmptySuggestions() throws Exception { |
| if (!shouldTestTelecom(mContext) || !TestUtils.hasTelephonyFeature(mContext)) { |
| return; |
| } |
| |
| CtsPhoneAccountSuggestionService.sSuggestionsToProvide = Collections.emptyList(); |
| |
| Uri number = createTestNumber(); |
| mTelecomManager.placeCall(number, new Bundle()); |
| |
| assertEquals(number.getSchemeSpecificPart(), |
| CtsPhoneAccountSuggestionService.sSuggestionRequestQueue.poll( |
| TEST_TIMEOUT, TimeUnit.MILLISECONDS)); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| final MockInCallService inCallService = mInCallCallbacks.getService(); |
| Call phoneAcctSelectCall = inCallService.getLastCall(); |
| assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, phoneAcctSelectCall.getState()); |
| List<PhoneAccountSuggestion> receivedSuggestions = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.EXTRA_SUGGESTED_PHONE_ACCOUNTS); |
| List<PhoneAccountHandle> receivedAccounts = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.AVAILABLE_PHONE_ACCOUNTS); |
| assertEquals(receivedAccounts.size(), receivedSuggestions.size()); |
| assertTrue(receivedAccounts.containsAll(getHandlesFromSuggestions(receivedSuggestions))); |
| } |
| |
| public void testPartialSuggestions() throws Exception { |
| if (!shouldTestTelecom(mContext) || !TestUtils.hasTelephonyFeature(mContext)) { |
| return; |
| } |
| |
| CtsPhoneAccountSuggestionService.sSuggestionsToProvide = List.of( |
| new PhoneAccountSuggestion(TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2, |
| PhoneAccountSuggestion.REASON_FREQUENT, |
| true)); |
| |
| Uri number = createTestNumber(); |
| mTelecomManager.placeCall(number, new Bundle()); |
| |
| assertEquals(number.getSchemeSpecificPart(), |
| CtsPhoneAccountSuggestionService.sSuggestionRequestQueue.poll( |
| TEST_TIMEOUT, TimeUnit.MILLISECONDS)); |
| |
| if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, |
| TimeUnit.SECONDS)) { |
| fail("No call added to InCallService."); |
| } |
| |
| final MockInCallService inCallService = mInCallCallbacks.getService(); |
| Call phoneAcctSelectCall = inCallService.getLastCall(); |
| assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, phoneAcctSelectCall.getState()); |
| List<PhoneAccountSuggestion> receivedSuggestions = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.EXTRA_SUGGESTED_PHONE_ACCOUNTS); |
| List<PhoneAccountHandle> receivedAccounts = |
| phoneAcctSelectCall.getDetails().getIntentExtras() |
| .getParcelableArrayList(Call.AVAILABLE_PHONE_ACCOUNTS); |
| assertEquals(receivedAccounts.size(), receivedSuggestions.size()); |
| // Make sure the received list contains the one that we provided. |
| assertTrue(receivedSuggestions |
| .containsAll(CtsPhoneAccountSuggestionService.sSuggestionsToProvide)); |
| // Make sure the framework filled in the other one. |
| assertEquals(1, receivedSuggestions.stream() |
| .filter(s -> TEST_PHONE_ACCOUNT_HANDLE.equals(s.getPhoneAccountHandle())) |
| .count()); |
| } |
| |
| private static List<PhoneAccountHandle> getHandlesFromSuggestions( |
| List<PhoneAccountSuggestion> s) { |
| return s.stream().map(PhoneAccountSuggestion::getPhoneAccountHandle) |
| .collect(Collectors.toList()); |
| } |
| } |