Merge "Add color to PhoneAccount objects (2/3)" into lmp-sprout-dev
diff --git a/src/com/android/server/telecom/BluetoothPhoneService.java b/src/com/android/server/telecom/BluetoothPhoneService.java
index ad6d490..62f4f5a 100644
--- a/src/com/android/server/telecom/BluetoothPhoneService.java
+++ b/src/com/android/server/telecom/BluetoothPhoneService.java
@@ -299,7 +299,7 @@
case MSG_QUERY_PHONE_STATE:
try {
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(true /* force */);
} finally {
if (request != null) {
request.setResult(true);
@@ -317,28 +317,28 @@
private CallsManagerListener mCallsManagerListener = new CallsManagerListenerBase() {
@Override
public void onCallAdded(Call call) {
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(false /* force */);
}
@Override
public void onCallRemoved(Call call) {
mClccIndexMap.remove(call);
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(false /* force */);
}
@Override
public void onCallStateChanged(Call call, int oldState, int newState) {
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(false /* force */);
}
@Override
public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(false /* force */);
}
@Override
public void onIsConferencedChanged(Call call) {
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(false /* force */);
}
};
@@ -412,7 +412,7 @@
registerReceiver(mBluetoothAdapterReceiver, intentFilter);
CallsManager.getInstance().addListener(mCallsManagerListener);
- updateHeadsetWithCallState();
+ updateHeadsetWithCallState(false /* force */);
}
@Override
@@ -581,13 +581,18 @@
index, direction, state, isPartOfConference, Log.piiHandle(address),
addressType);
}
- mBluetoothHeadset.clccResponse(
- index, direction, state, 0, isPartOfConference, address, addressType);
+
+ if (mBluetoothHeadset != null) {
+ mBluetoothHeadset.clccResponse(
+ index, direction, state, 0, isPartOfConference, address, addressType);
+ }
}
private void sendClccEndMarker() {
// End marker is recognized with an index value of 0. All other parameters are ignored.
- mBluetoothHeadset.clccResponse(0 /* index */, 0, 0, 0, false, null, 0);
+ if (mBluetoothHeadset != null) {
+ mBluetoothHeadset.clccResponse(0 /* index */, 0, 0, 0, false, null, 0);
+ }
}
/**
@@ -609,7 +614,14 @@
return i;
}
- private void updateHeadsetWithCallState() {
+ /**
+ * Sends an update of the current call state to the current Headset.
+ *
+ * @param force {@code true} if the headset state should be sent regardless if no changes to the
+ * state have occurred, {@code false} if the state should only be sent if the state has
+ * changed.
+ */
+ private void updateHeadsetWithCallState(boolean force) {
CallsManager callsManager = getCallsManager();
Call activeCall = callsManager.getActiveCall();
Call ringingCall = callsManager.getRingingCall();
@@ -650,7 +662,8 @@
numHeldCalls != mNumHeldCalls ||
bluetoothCallState != mBluetoothCallState ||
!TextUtils.equals(ringingAddress, mRingingAddress) ||
- ringingAddressType != mRingingAddressType)) {
+ ringingAddressType != mRingingAddressType ||
+ force)) {
// If the call is transitioning into the alerting state, send DIALING first.
// Some devices expect to see a DIALING state prior to seeing an ALERTING state
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index ca72ec8..85463eb 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -70,6 +70,8 @@
void onFailedOutgoingCall(Call call, DisconnectCause disconnectCause);
void onSuccessfulIncomingCall(Call call);
void onFailedIncomingCall(Call call);
+ void onSuccessfulUnknownCall(Call call, int callState);
+ void onFailedUnknownCall(Call call);
void onRingbackRequested(Call call, boolean ringbackRequested);
void onPostDialWait(Call call, String remaining);
void onCallCapabilitiesChanged(Call call);
@@ -99,6 +101,10 @@
@Override
public void onFailedIncomingCall(Call call) {}
@Override
+ public void onSuccessfulUnknownCall(Call call, int callState) {}
+ @Override
+ public void onFailedUnknownCall(Call call) {}
+ @Override
public void onRingbackRequested(Call call, boolean ringbackRequested) {}
@Override
public void onPostDialWait(Call call, String remaining) {}
@@ -167,6 +173,11 @@
/** True if this is an incoming call. */
private final boolean mIsIncoming;
+ /** True if this is a currently unknown call that was not previously tracked by CallsManager,
+ * and did not originate via the regular incoming/outgoing call code paths.
+ */
+ private boolean mIsUnknown;
+
/**
* The time this call was created. Beyond logging and such, may also be used for bookkeeping
* and specifically for marking certain call attempts as failed attempts.
@@ -286,6 +297,8 @@
// switches every time the user hits "swap".
private Call mConferenceLevelActiveCall = null;
+ private boolean mIsLocallyDisconnecting = false;
+
/**
* Persists the specified parameters and initializes the new instance.
*
@@ -361,6 +374,7 @@
maybeLoadCannedSmsResponses();
if (mState == CallState.DISCONNECTED) {
+ setLocallyDisconnecting(false);
fixParentAfterDisconnect();
}
}
@@ -660,7 +674,11 @@
mConferenceableCalls.add(idMapper.getCall(id));
}
- if (mIsIncoming) {
+ if (mIsUnknown) {
+ for (Listener l : mListeners) {
+ l.onSuccessfulUnknownCall(this, getStateFromConnectionState(connection.getState()));
+ }
+ } else if (mIsIncoming) {
// We do not handle incoming calls immediately when they are verified by the connection
// service. We allow the caller-info-query code to execute first so that we can read the
// direct-to-voicemail property before deciding if we want to show the incoming call to
@@ -686,7 +704,11 @@
setDisconnectCause(disconnectCause);
CallsManager.getInstance().markCallAsDisconnected(this, disconnectCause);
- if (mIsIncoming) {
+ if (mIsUnknown) {
+ for (Listener listener : mListeners) {
+ listener.onFailedUnknownCall(this);
+ }
+ } else if (mIsIncoming) {
for (Listener listener : mListeners) {
listener.onFailedIncomingCall(this);
}
@@ -725,6 +747,9 @@
* Attempts to disconnect the call through the connection service.
*/
void disconnect() {
+ // Track that the call is now locally disconnecting.
+ setLocallyDisconnecting(true);
+
if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT ||
mState == CallState.CONNECTING) {
Log.v(this, "Aborting call %s", this);
@@ -1255,6 +1280,32 @@
}
}
+ public boolean isUnknown() {
+ return mIsUnknown;
+ }
+
+ public void setIsUnknown(boolean isUnknown) {
+ mIsUnknown = isUnknown;
+ }
+
+ /**
+ * Determines if this call is in a disconnecting state.
+ *
+ * @return {@code true} if this call is locally disconnecting.
+ */
+ public boolean isLocallyDisconnecting() {
+ return mIsLocallyDisconnecting;
+ }
+
+ /**
+ * Sets whether this call is in a disconnecting state.
+ *
+ * @param isLocallyDisconnecting {@code true} if this call is locally disconnecting.
+ */
+ private void setLocallyDisconnecting(boolean isLocallyDisconnecting) {
+ mIsLocallyDisconnecting = isLocallyDisconnecting;
+ }
+
static int getStateFromConnectionState(int state) {
switch (state) {
case Connection.STATE_INITIALIZING:
diff --git a/src/com/android/server/telecom/CallActivity.java b/src/com/android/server/telecom/CallActivity.java
index b249788..7022327 100644
--- a/src/com/android/server/telecom/CallActivity.java
+++ b/src/com/android/server/telecom/CallActivity.java
@@ -78,6 +78,7 @@
return;
}
+ verifyCallAction(intent);
String action = intent.getAction();
if (Intent.ACTION_CALL.equals(action) ||
@@ -89,6 +90,17 @@
}
}
+ private void verifyCallAction(Intent intent) {
+ if (CallActivity.class.getName().equals(intent.getComponent().getClassName())) {
+ // If we were launched directly from the CallActivity, not one of its more privileged
+ // aliases, then make sure that only the non-privileged actions are allowed.
+ if (!Intent.ACTION_CALL.equals(intent.getAction())) {
+ Log.w(this, "Attempt to deliver non-CALL action; forcing to CALL");
+ intent.setAction(Intent.ACTION_CALL);
+ }
+ }
+ }
+
private void processOutgoingCallIntent(Intent intent) {
Uri handle = intent.getData();
String scheme = handle.getScheme();
@@ -112,11 +124,20 @@
}
intent.putExtra(CallReceiver.KEY_IS_DEFAULT_DIALER, isDefaultDialer());
- sendBroadcastToReceiver(intent, false /* isIncoming */);
+
+ if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+ CallReceiver.processOutgoingCallIntent(getApplicationContext(), intent);
+ } else {
+ sendBroadcastToReceiver(intent, false /* isIncoming */);
+ }
}
private void processIncomingCallIntent(Intent intent) {
- sendBroadcastToReceiver(intent, true /* isIncoming */);
+ if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+ CallReceiver.processIncomingCallIntent(intent);
+ } else {
+ sendBroadcastToReceiver(intent, true /* isIncoming */);
+ }
}
private boolean isDefaultDialer() {
@@ -147,8 +168,7 @@
*/
private boolean sendBroadcastToReceiver(Intent intent, boolean incoming) {
intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, incoming);
- // Clear out any flags set previously since we don't need it for the broadcast.
- intent.setFlags(0);
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.setClass(this, CallReceiver.class);
Log.d(this, "Sending broadcast as user to CallReceiver- isIncoming: %s", incoming);
sendBroadcastAsUser(intent, UserHandle.OWNER);
diff --git a/src/com/android/server/telecom/CallReceiver.java b/src/com/android/server/telecom/CallReceiver.java
index fe82b67..17ca3e5 100644
--- a/src/com/android/server/telecom/CallReceiver.java
+++ b/src/com/android/server/telecom/CallReceiver.java
@@ -19,17 +19,23 @@
* the primary user.
*/
public class CallReceiver extends BroadcastReceiver {
+ private static final String TAG = CallReceiver.class.getName();
+ static final String KEY_IS_UNKNOWN_CALL = "is_unknown_call";
static final String KEY_IS_INCOMING_CALL = "is_incoming_call";
static final String KEY_IS_DEFAULT_DIALER =
"is_default_dialer";
@Override
public void onReceive(Context context, Intent intent) {
+ final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);
final boolean isIncomingCall = intent.getBooleanExtra(KEY_IS_INCOMING_CALL, false);
- Log.d(this, "onReceive - isIncomingCall: %s", isIncomingCall);
+ Log.i(this, "onReceive - isIncomingCall: %s isUnknownCall: %s", isIncomingCall,
+ isUnknownCall);
- if (isIncomingCall) {
+ if (isUnknownCall) {
+ processUnknownCallIntent(intent);
+ } else if (isIncomingCall) {
processIncomingCallIntent(intent);
} else {
processOutgoingCallIntent(context, intent);
@@ -41,7 +47,7 @@
*
* @param intent Call intent containing data about the handle to call.
*/
- private void processOutgoingCallIntent(Context context, Intent intent) {
+ static void processOutgoingCallIntent(Context context, Intent intent) {
Uri handle = intent.getData();
String scheme = handle.getScheme();
String uriString = handle.getSchemeSpecificPart();
@@ -84,16 +90,16 @@
}
}
- private void processIncomingCallIntent(Intent intent) {
+ static void processIncomingCallIntent(Intent intent) {
PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(
TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
if (phoneAccountHandle == null) {
- Log.w(this, "Rejecting incoming call due to null phone account");
+ Log.w(TAG, "Rejecting incoming call due to null phone account");
return;
}
if (phoneAccountHandle.getComponentName() == null) {
- Log.w(this, "Rejecting incoming call due to null component name");
+ Log.w(TAG, "Rejecting incoming call due to null component name");
return;
}
@@ -105,16 +111,33 @@
clientExtras = Bundle.EMPTY;
}
- Log.d(this, "Processing incoming call from connection service [%s]",
+ Log.d(TAG, "Processing incoming call from connection service [%s]",
phoneAccountHandle.getComponentName());
getCallsManager().processIncomingCallIntent(phoneAccountHandle, clientExtras);
}
- CallsManager getCallsManager() {
+ private void processUnknownCallIntent(Intent intent) {
+ PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(
+ TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+
+ if (phoneAccountHandle == null) {
+ Log.w(this, "Rejecting unknown call due to null phone account");
+ return;
+ }
+ if (phoneAccountHandle.getComponentName() == null) {
+ Log.w(this, "Rejecting unknown call due to null component name");
+ return;
+ }
+
+ getCallsManager().addNewUnknownCall(phoneAccountHandle, intent.getExtras());
+ }
+
+ static CallsManager getCallsManager() {
return CallsManager.getInstance();
}
- private void disconnectCallAndShowErrorDialog(Context context, Call call, int errorCode) {
+ private static void disconnectCallAndShowErrorDialog(
+ Context context, Call call, int errorCode) {
call.disconnect();
final Intent errorIntent = new Intent(context, ErrorDialogActivity.class);
int errorMessageId = -1;
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 1b0a9e3..52c0b44 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -32,6 +32,7 @@
import android.telephony.TelephonyManager;
import com.android.internal.util.IndentingPrintWriter;
+
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -226,6 +227,20 @@
}
@Override
+ public void onSuccessfulUnknownCall(Call call, int callState) {
+ setCallState(call, callState);
+ Log.i(this, "onSuccessfulUnknownCall for call %s", call);
+ addCall(call);
+ }
+
+ @Override
+ public void onFailedUnknownCall(Call call) {
+ Log.i(this, "onFailedUnknownCall for call %s", call);
+ setCallState(call, CallState.DISCONNECTED);
+ call.removeListener(this);
+ }
+
+ @Override
public void onRingbackRequested(Call call, boolean ringback) {
for (CallsManagerListener listener : mListeners) {
listener.onRingbackRequested(call, ringback);
@@ -336,6 +351,27 @@
call.startCreateConnection(mPhoneAccountRegistrar);
}
+ void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+ Uri handle = extras.getParcelable(TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE);
+ Log.i(this, "addNewUnknownCall with handle: %s", Log.pii(handle));
+ Call call = new Call(
+ mContext,
+ mConnectionServiceRepository,
+ handle,
+ null /* gatewayInfo */,
+ null /* connectionManagerPhoneAccount */,
+ phoneAccountHandle,
+ // Use onCreateIncomingConnection in TelephonyConnectionService, so that we attach
+ // to the existing connection instead of trying to create a new one.
+ true /* isIncoming */,
+ false /* isConference */);
+ call.setConnectTimeMillis(System.currentTimeMillis());
+ call.setIsUnknown(true);
+ call.setExtras(extras);
+ call.addListener(this);
+ call.startCreateConnection(mPhoneAccountRegistrar);
+ }
+
/**
* Kicks off the first steps to creating an outgoing call so that InCallUI can launch.
*
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index cacdc81..32c6107 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -643,7 +643,8 @@
call.getHandle(),
extras,
call.getVideoState()),
- call.isIncoming());
+ call.isIncoming(),
+ call.isUnknown());
} catch (RemoteException e) {
Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
mPendingResponses.remove(callId).handleCreateConnectionFailure(
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 6aae49b..0c6e25d 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -31,7 +31,7 @@
import java.util.Objects;
/**
- * This class creates connections to place new outgoing calls to attached to an existing incoming
+ * This class creates connections to place new outgoing calls or to attach to an existing incoming
* call. In either case, this class cycles through a set of connection services until:
* - a connection service returns a newly created connection in which case the call is displayed
* to the user
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 2dc30da..78553ad 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -261,8 +261,6 @@
private void bind() {
ThreadUtil.checkOnMainThread();
if (mInCallServices.isEmpty()) {
- mServiceConnections.clear();
-
PackageManager packageManager = mContext.getPackageManager();
Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
@@ -289,11 +287,14 @@
continue;
}
- Log.i(this, "Attempting to bind to InCall " + serviceInfo.packageName);
InCallServiceConnection inCallServiceConnection = new InCallServiceConnection();
ComponentName componentName = new ComponentName(serviceInfo.packageName,
serviceInfo.name);
+ Log.i(this, "Attempting to bind to InCall %s, is dupe? %b ",
+ serviceInfo.packageName,
+ mServiceConnections.containsKey(componentName));
+
if (!mServiceConnections.containsKey(componentName)) {
Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
intent.setComponent(componentName);
@@ -444,6 +445,10 @@
state = CallState.DISCONNECTED;
}
+ if (call.isLocallyDisconnecting() && state != CallState.DISCONNECTED) {
+ state = CallState.DISCONNECTING;
+ }
+
String parentCallId = null;
Call parentCall = call.getParentCall();
if (parentCall != null) {
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index 4e866a1..d645009 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -361,7 +361,7 @@
systemDialerIntent.setData(handle);
systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.v(this, "calling startActivity for default dialer: %s", systemDialerIntent);
- mContext.startActivity(systemDialerIntent);
+ mContext.startActivityAsUser(systemDialerIntent, UserHandle.CURRENT);
}
/**
@@ -393,15 +393,6 @@
* number.
*/
private void rewriteCallIntentAction(Intent intent, boolean isPotentialEmergencyNumber) {
- if (CallActivity.class.getName().equals(intent.getComponent().getClassName())) {
- // If we were launched directly from the CallActivity, not one of its more privileged
- // aliases, then make sure that only the non-privileged actions are allowed.
- if (!Intent.ACTION_CALL.equals(intent.getAction())) {
- Log.w(this, "Attempt to deliver non-CALL action; forcing to CALL");
- intent.setAction(Intent.ACTION_CALL);
- }
- }
-
String action = intent.getAction();
/* Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed. */
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 299ca24..fbbe1c9 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -37,6 +37,7 @@
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
+
// TODO: Needed for move to system service: import com.android.internal.R;
import com.android.internal.telecom.ITelecomService;
import com.android.internal.util.IndentingPrintWriter;
@@ -472,6 +473,29 @@
}
}
+ /**
+ * @see android.telecom.TelecomManager#addNewUnknownCall
+ */
+ @Override
+ public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+ if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null &&
+ TelephonyUtil.isPstnComponentName(phoneAccountHandle.getComponentName())) {
+ mAppOpsManager.checkPackage(
+ Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
+
+ Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
+ intent.setClass(mContext, CallReceiver.class);
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.putExtras(extras);
+ intent.putExtra(CallReceiver.KEY_IS_UNKNOWN_CALL, true);
+ intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+ mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+ } else {
+ Log.i(this, "Null phoneAccountHandle or not initiated by Telephony. Ignoring request"
+ + " to add new unknown call.");
+ }
+ }
+
//
// Supporting methods for the ITelecomService interface implementation.
//
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index cd9b77f..9c09a40 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -69,6 +69,7 @@
</intent-filter>
<intent-filter>
<action android:name="android.telecom.testapps.ACTION_START_INCOMING_CALL" />
+ <action android:name="android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
diff --git a/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java b/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
index 6105f3e..a835bf1 100644
--- a/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
+++ b/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
@@ -22,14 +22,18 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.telecom.CallState;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.util.Log;
/**
* This class receives the notification callback intents used to update call states for
* {@link TestConnectionService}.
*/
public class CallNotificationReceiver extends BroadcastReceiver {
+
+ static final String TAG = CallNotificationReceiver.class.getSimpleName();
/**
* Exit intent action is sent when the user clicks the "exit" action of the
* TestConnectionService notification. Used to cancel (remove) the notification.
@@ -83,4 +87,22 @@
TelecomManager.from(context).addNewIncomingCall(phoneAccount, extras);
}
+
+ public static void addNewUnknownCall(Context context, Uri handle, Bundle extras) {
+ Log.i(TAG, "Adding new unknown call with handle " + handle);
+ PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
+ new ComponentName(context, TestConnectionService.class),
+ CallServiceNotifier.SIM_SUBSCRIPTION_ID);
+
+ if (extras == null) {
+ extras = new Bundle();
+ }
+
+ if (handle != null) {
+ extras.putParcelable(TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE, handle);
+ extras.putParcelable(TestConnectionService.EXTRA_HANDLE, handle);
+ }
+
+ TelecomManager.from(context).addNewUnknownCall(phoneAccount, extras);
+ }
}
diff --git a/tests/src/com/android/server/telecom/testapps/TestCallActivity.java b/tests/src/com/android/server/telecom/testapps/TestCallActivity.java
index f5e24ec..9c9a40b 100644
--- a/tests/src/com/android/server/telecom/testapps/TestCallActivity.java
+++ b/tests/src/com/android/server/telecom/testapps/TestCallActivity.java
@@ -36,21 +36,25 @@
public static final String ACTION_NEW_INCOMING_CALL =
"android.telecom.testapps.ACTION_START_INCOMING_CALL";
+ /*
+ * Action to exercise TelecomManager.addNewUnknownCall().
+ */
+ public static final String ACTION_NEW_UNKNOWN_CALL =
+ "android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL";
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
final Intent intent = getIntent();
- if (intent != null && intent.getData() != null) {
- startIncomingCallBroadcast(intent.getData());
+ final String action = intent != null ? intent.getAction() : null;
+ final Uri data = intent != null ? intent.getData() : null;
+ if (ACTION_NEW_INCOMING_CALL.equals(action) && data != null) {
+ CallNotificationReceiver.sendIncomingCallIntent(this, data, false);
+ } if (ACTION_NEW_UNKNOWN_CALL.equals(action) && data != null) {
+ CallNotificationReceiver.addNewUnknownCall(this, data, intent.getExtras());
+ } else {
+ CallServiceNotifier.getInstance().updateNotification(this);
}
- CallServiceNotifier.getInstance().updateNotification(this);
finish();
}
-
- /**
- * Bypass the notification and start the test incoming call directly.
- */
- private void startIncomingCallBroadcast(Uri handle) {
- CallNotificationReceiver.sendIncomingCallIntent(this, handle, false);
- }
}
diff --git a/tests/src/com/android/server/telecom/testapps/TestConnectionService.java b/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
index b327462..389373f 100644
--- a/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -267,6 +267,7 @@
originalHandle + "]");
final TestConnection connection = new TestConnection(false /* isIncoming */);
+ connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
// If the number starts with 555, then we handle it ourselves. If not, then we
// use a remote connection service.
@@ -341,6 +342,31 @@
}
}
+ @Override
+ public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+ final ConnectionRequest request) {
+ PhoneAccountHandle accountHandle = request.getAccountHandle();
+ ComponentName componentName = new ComponentName(this, TestConnectionService.class);
+ if (accountHandle != null && componentName.equals(accountHandle.getComponentName())) {
+ final TestConnection connection = new TestConnection(false);
+ final Bundle extras = request.getExtras();
+ final Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
+
+ Uri handle = providedHandle == null ?
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(false), null)
+ : providedHandle;
+
+ connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
+ connection.setDialing();
+
+ addCall(connection);
+ return connection;
+ } else {
+ return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.ERROR,
+ "Invalid inputs: " + accountHandle + " " + componentName));
+ }
+ }
+
private void activateCall(TestConnection connection) {
if (mMediaPlayer == null) {
mMediaPlayer = createMediaPlayer();