Merge "Bring up Select Account Dialog before launching InCallUI." into lmp-dev
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index a1e9cea..ccd8941 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -708,9 +708,9 @@
void abort() {
if (mCreateConnectionProcessor != null) {
mCreateConnectionProcessor.abort();
- } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT ||
- mState == CallState.CONNECTING) {
- handleCreateConnectionFailure(DisconnectCause.LOCAL, null);
+ } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT
+ || mState == CallState.CONNECTING) {
+ handleCreateConnectionFailure(DisconnectCause.OUTGOING_CANCELED, null);
} else {
Log.v(this, "Cannot abort a call which isn't either PRE_DIAL_WAIT or CONNECTING");
}
diff --git a/src/com/android/telecomm/CallLogManager.java b/src/com/android/telecomm/CallLogManager.java
index d0668b9..ee65255 100644
--- a/src/com/android/telecomm/CallLogManager.java
+++ b/src/com/android/telecomm/CallLogManager.java
@@ -23,6 +23,7 @@
import android.telecomm.CallState;
import android.telecomm.PhoneAccountHandle;
import android.telecomm.VideoProfile;
+import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import com.android.internal.telephony.CallerInfo;
@@ -88,8 +89,9 @@
@Override
public void onCallStateChanged(Call call, int oldState, int newState) {
- if ((newState == CallState.DISCONNECTED || newState == CallState.ABORTED) &&
- oldState != CallState.PRE_DIAL_WAIT) {
+ if ((newState == CallState.DISCONNECTED || newState == CallState.ABORTED)
+ && oldState != CallState.PRE_DIAL_WAIT
+ && call.getDisconnectCause() != DisconnectCause.OUTGOING_CANCELED) {
int type;
if (!call.isIncoming()) {
type = Calls.OUTGOING_TYPE;
diff --git a/src/com/android/telecomm/ConnectionServiceRepository.java b/src/com/android/telecomm/ConnectionServiceRepository.java
index ec2c90e..efd1ba4 100644
--- a/src/com/android/telecomm/ConnectionServiceRepository.java
+++ b/src/com/android/telecomm/ConnectionServiceRepository.java
@@ -38,21 +38,6 @@
ConnectionServiceRepository() {
}
- Collection<ConnectionServiceWrapper> lookupServices() {
- PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
- Intent intent = new Intent(ConnectionService.SERVICE_INTERFACE);
- ArrayList<ConnectionServiceWrapper> services = new ArrayList<>();
-
- for (ResolveInfo entry : packageManager.queryIntentServices(intent, 0)) {
- ServiceInfo serviceInfo = entry.serviceInfo;
- if (serviceInfo != null) {
- services.add(getService(new ComponentName(
- serviceInfo.packageName, serviceInfo.name)));
- }
- }
- return services;
- }
-
ConnectionServiceWrapper getService(ComponentName componentName) {
ConnectionServiceWrapper service = mServiceCache.get(componentName);
if (service == null) {
diff --git a/src/com/android/telecomm/CreateConnectionProcessor.java b/src/com/android/telecomm/CreateConnectionProcessor.java
index 3e6e544..aacb80b 100644
--- a/src/com/android/telecomm/CreateConnectionProcessor.java
+++ b/src/com/android/telecomm/CreateConnectionProcessor.java
@@ -107,9 +107,32 @@
private void attemptNextPhoneAccount() {
Log.v(this, "attemptNextPhoneAccount");
+ PhoneAccountRegistrar registrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
+ CallAttemptRecord attempt = null;
+ if (mAttemptRecordIterator.hasNext()) {
+ attempt = mAttemptRecordIterator.next();
- if (mResponse != null && mAttemptRecordIterator.hasNext()) {
- CallAttemptRecord attempt = mAttemptRecordIterator.next();
+ if (!registrar.phoneAccountHasPermission(attempt.connectionManagerPhoneAccount)) {
+ Log.w(this,
+ "Connection mgr does not have BIND_CONNECTION_SERVICE for attempt: %s",
+ attempt);
+ attemptNextPhoneAccount();
+ return;
+ }
+
+ // If the target PhoneAccount differs from the ConnectionManager phone acount, ensure it
+ // also has BIND_CONNECTION_SERVICE permission.
+ if (!attempt.connectionManagerPhoneAccount.equals(attempt.targetPhoneAccount) &&
+ !registrar.phoneAccountHasPermission(attempt.targetPhoneAccount)) {
+ Log.w(this,
+ "Target PhoneAccount does not have BIND_CONNECTION_SERVICE for attempt: %s",
+ attempt);
+ attemptNextPhoneAccount();
+ return;
+ }
+ }
+
+ if (mResponse != null && attempt != null) {
Log.i(this, "Trying attempt %s", attempt);
ConnectionServiceWrapper service =
mRepository.getService(
diff --git a/src/com/android/telecomm/PhoneAccountRegistrar.java b/src/com/android/telecomm/PhoneAccountRegistrar.java
index 71eb95b..f3a5a0b 100644
--- a/src/com/android/telecomm/PhoneAccountRegistrar.java
+++ b/src/com/android/telecomm/PhoneAccountRegistrar.java
@@ -16,9 +16,11 @@
package com.android.telecomm;
+import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.telecomm.ConnectionService;
import android.telecomm.PhoneAccount;
import android.telecomm.PhoneAccountHandle;
@@ -45,6 +47,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.SecurityException;
import java.lang.String;
import java.util.ArrayList;
import java.util.Iterator;
@@ -231,6 +234,15 @@
// TODO: Should we implement an artificial limit for # of accounts associated with a single
// ComponentName?
public void registerPhoneAccount(PhoneAccount account) {
+ // Enforce the requirement that a connection service for a phone account has the correct
+ // permission.
+ if (!phoneAccountHasPermission(account.getAccountHandle())) {
+ Log.w(this, "Phone account %s does not have BIND_CONNECTION_SERVICE permission.",
+ account.getAccountHandle());
+ throw new SecurityException(
+ "PhoneAccount connection service requires BIND_CONNECTION_SERVICE permission.");
+ }
+
mState.accounts.add(account);
// Search for duplicates and remove any that are found.
for (int i = 0; i < mState.accounts.size() - 1; i++) {
@@ -311,6 +323,27 @@
}
}
+ /**
+ * Determines if the connection service specified by a {@link PhoneAccountHandle} has the
+ * {@link Manifest.permission#BIND_CONNECTION_SERVICE} permission.
+ *
+ * @param phoneAccountHandle The phone account to check.
+ * @return {@code True} if the phone account has permission.
+ */
+ public boolean phoneAccountHasPermission(PhoneAccountHandle phoneAccountHandle) {
+ PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
+ try {
+ ServiceInfo serviceInfo = packageManager.getServiceInfo(
+ phoneAccountHandle.getComponentName(), 0);
+
+ return serviceInfo.permission != null &&
+ serviceInfo.permission.equals(Manifest.permission.BIND_CONNECTION_SERVICE);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(this, "Name not found %s", e);
+ return false;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: Add a corresponding has(...) method to class PhoneAccount itself and remove this one
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index c17803f..d8877fb 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -29,13 +29,15 @@
<!-- Miscellaneous telecomm app-related test activities. -->
- <service android:name="com.android.telecomm.testapps.TestConnectionService">
+ <service android:name="com.android.telecomm.testapps.TestConnectionService"
+ android:permission="android.permission.BIND_CONNECTION_SERVICE" >
<intent-filter>
<action android:name="android.telecomm.ConnectionService" />
</intent-filter>
</service>
- <service android:name="com.android.telecomm.testapps.TestConnectionManager">
+ <service android:name="com.android.telecomm.testapps.TestConnectionManager"
+ android:permission="android.permission.BIND_CONNECTION_SERVICE" >
<intent-filter>
<action android:name="android.telecomm.ConnectionService" />
</intent-filter>