Wiring videoState through from telephony.
- Adding call video state history tracking, which is used to ensure we log whether video was active at any point to the call log. - Adding logging of video state to call log. Bug: 16285417 Bug: 16013178 Change-Id: I3b47c88b13dc73941ca80463fc0c6ae7cdd86749
This commit is contained in:
parent
3b055eea07
commit
0a388fc566
|
@ -16,14 +16,11 @@
|
|||
|
||||
package com.android.telecomm;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentUris;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.telecomm.CallPropertyPresentation;
|
||||
import android.telecomm.CallState;
|
||||
import android.telecomm.ConnectionRequest;
|
||||
|
@ -31,7 +28,6 @@ import android.telecomm.GatewayInfo;
|
|||
import android.telecomm.PhoneAccount;
|
||||
import android.telecomm.Response;
|
||||
import android.telecomm.StatusHints;
|
||||
import android.telecomm.TelecommConstants;
|
||||
import android.telephony.DisconnectCause;
|
||||
import android.telephony.PhoneNumberUtils;
|
||||
import android.text.TextUtils;
|
||||
|
@ -202,6 +198,12 @@ final class Call implements CreateConnectionResponse {
|
|||
|
||||
private boolean mSpeakerphoneOn;
|
||||
|
||||
/**
|
||||
* Tracks the video states which were applicable over the duration of a call.
|
||||
* See {@link android.telecomm.VideoCallProfile} for a list of valid video states.
|
||||
*/
|
||||
private int mVideoStateHistory;
|
||||
|
||||
private int mVideoState;
|
||||
|
||||
/**
|
||||
|
@ -294,7 +296,9 @@ final class Call implements CreateConnectionResponse {
|
|||
if (mConnectionService != null && mConnectionService.getComponentName() != null) {
|
||||
component = mConnectionService.getComponentName().flattenToShortString();
|
||||
}
|
||||
return String.format(Locale.US, "[%s, %s, %s]", mState, component, Log.piiHandle(mHandle));
|
||||
|
||||
return String.format(Locale.US, "[%s, %s, %s, %d]", mState, component,
|
||||
Log.piiHandle(mHandle), getVideoState());
|
||||
}
|
||||
|
||||
CallState getState() {
|
||||
|
@ -1068,15 +1072,29 @@ final class Call implements CreateConnectionResponse {
|
|||
}
|
||||
|
||||
/**
|
||||
* At the start of the call, determines the desired video state for the call.
|
||||
* Returns the video states which were applicable over the duration of a call.
|
||||
* See {@link android.telecomm.VideoCallProfile} for a list of valid video states.
|
||||
*
|
||||
* @return The video states applicable over the duration of the call.
|
||||
*/
|
||||
public int getVideoStateHistory() {
|
||||
return mVideoStateHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the current video state for the call.
|
||||
* For an outgoing call determines the desired video state for the call.
|
||||
* Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
|
||||
* {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL},
|
||||
* {@link android.telecomm.VideoCallProfile#VIDEO_STATE_TX_ENABLED},
|
||||
* {@link android.telecomm.VideoCallProfile#VIDEO_STATE_RX_ENABLED}.
|
||||
*
|
||||
* @param videoState The desired video state for the call.
|
||||
* @param videoState The video state for the call.
|
||||
*/
|
||||
public void setVideoState(int videoState) {
|
||||
// Track which video states were applicable over the duration of the call.
|
||||
mVideoStateHistory = mVideoStateHistory | videoState;
|
||||
|
||||
mVideoState = videoState;
|
||||
for (Listener l : mListeners) {
|
||||
l.onVideoStateChanged(this);
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.os.AsyncTask;
|
|||
import android.provider.CallLog.Calls;
|
||||
import android.telecomm.CallState;
|
||||
import android.telecomm.PhoneAccount;
|
||||
import android.telecomm.VideoCallProfile;
|
||||
import android.telephony.PhoneNumberUtils;
|
||||
|
||||
import com.android.internal.telephony.CallerInfo;
|
||||
|
@ -120,9 +121,10 @@ final class CallLogManager extends CallsManagerListenerBase {
|
|||
final int presentation = getPresentation(call);
|
||||
final PhoneAccount account = call.getPhoneAccount();
|
||||
|
||||
// TODO: Once features and data usage are available, wire them up here.
|
||||
logCall(call.getCallerInfo(), logNumber, presentation, callLogType, Calls.FEATURES_NONE,
|
||||
account, creationTime, age, null);
|
||||
// TODO(vt): Once data usage is available, wire it up here.
|
||||
int callFeatures = getCallFeatures(call.getVideoStateHistory());
|
||||
logCall(call.getCallerInfo(), logNumber, presentation, callLogType, callFeatures, account,
|
||||
creationTime, age, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,6 +172,20 @@ final class CallLogManager extends CallsManagerListenerBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the video state of the call, determines the call features applicable for the call.
|
||||
*
|
||||
* @param videoState The video state.
|
||||
* @return The call features.
|
||||
*/
|
||||
private static int getCallFeatures(int videoState) {
|
||||
if ((videoState & VideoCallProfile.VIDEO_STATE_TX_ENABLED)
|
||||
== VideoCallProfile.VIDEO_STATE_TX_ENABLED) {
|
||||
return Calls.FEATURES_VIDEO;
|
||||
}
|
||||
return Calls.FEATURES_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the phone number from the call, and then process it before returning the
|
||||
* actual number that is to be logged.
|
||||
|
|
|
@ -76,6 +76,7 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
|
|||
private static final int MSG_SET_STATUS_HINTS = 18;
|
||||
private static final int MSG_SET_HANDLE = 19;
|
||||
private static final int MSG_SET_CALLER_DISPLAY_NAME = 20;
|
||||
private static final int MSG_SET_VIDEO_STATE = 21;
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
|
@ -308,6 +309,12 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MSG_SET_VIDEO_STATE: {
|
||||
call = mCallIdMapper.getCall(msg.obj);
|
||||
if (call != null) {
|
||||
call.setVideoState(msg.arg1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -443,6 +450,13 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
|
|||
mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoState(String callId, int videoState) {
|
||||
logIncoming("setVideoState %s %d", callId, videoState);
|
||||
mCallIdMapper.checkValidCallId(callId);
|
||||
mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, callId).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioModeIsVoip(String callId, boolean isVoip) {
|
||||
logIncoming("setAudioModeIsVoip %s %b", callId, isVoip);
|
||||
|
|
|
@ -156,7 +156,7 @@ public class TelecommServiceImpl extends ITelecommService.Stub {
|
|||
PhoneAccount registeredAccount = mPhoneAccountRegistrar.getRegisteredAccount(account);
|
||||
if (registeredAccount != null) {
|
||||
return new PhoneAccountMetadata(
|
||||
registeredAccount, 0, account.getComponentName().getPackageName(), null);
|
||||
registeredAccount, 0, account.getComponentName().getPackageName(), null, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<string name="app_name">TelecommTests</string>
|
||||
|
||||
<!-- String for the TestCallActivity -->
|
||||
<string name="testCallActivityLabel">Test CallService App</string>
|
||||
<string name="testCallActivityLabel">Test Connection Service App</string>
|
||||
|
||||
<!-- String for the TestDialerActivity -->
|
||||
<string name="testDialerActivityLabel">Test Dialer</string>
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
package com.android.telecomm.testapps;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.telecomm.PhoneAccount;
|
||||
import android.telecomm.TelecommConstants;
|
||||
|
||||
/**
|
||||
* This class receives the notification callback intents used to update call states for
|
||||
|
@ -35,6 +39,10 @@ public class CallNotificationReceiver extends BroadcastReceiver {
|
|||
"com.android.telecomm.testapps.ACTION_REGISTER_PHONE_ACCOUNT";
|
||||
static final String ACTION_SHOW_ALL_PHONE_ACCOUNTS =
|
||||
"com.android.telecomm.testapps.ACTION_SHOW_ALL_PHONE_ACCOUNTS";
|
||||
static final String ACTION_VIDEO_CALL =
|
||||
"com.android.telecomm.testapps.ACTION_VIDEO_CALL";
|
||||
static final String ACTION_AUDIO_CALL =
|
||||
"com.android.telecomm.testapps.ACTION_AUDIO_CALL";
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
|
@ -46,6 +54,40 @@ public class CallNotificationReceiver extends BroadcastReceiver {
|
|||
CallServiceNotifier.getInstance().registerPhoneAccount(context);
|
||||
} else if (ACTION_SHOW_ALL_PHONE_ACCOUNTS.equals(action)) {
|
||||
CallServiceNotifier.getInstance().showAllPhoneAccounts(context);
|
||||
} else if (ACTION_VIDEO_CALL.equals(action)) {
|
||||
sendIncomingCallIntent(context, true);
|
||||
} else if (ACTION_AUDIO_CALL.equals(action)) {
|
||||
sendIncomingCallIntent(context, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the intent to add an incoming call through Telecomm.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param isVideoCall {@code True} if this is a video call.
|
||||
*/
|
||||
private void sendIncomingCallIntent(Context context, boolean isVideoCall) {
|
||||
// Create intent for adding an incoming call.
|
||||
Intent intent = new Intent(TelecommConstants.ACTION_INCOMING_CALL);
|
||||
// TODO(santoscordon): Use a private @hide permission to make sure this only goes to
|
||||
// Telecomm instead of setting the package explicitly.
|
||||
intent.setPackage("com.android.telecomm");
|
||||
|
||||
PhoneAccount phoneAccount = new PhoneAccount(
|
||||
new ComponentName(context, TestConnectionService.class),
|
||||
null /* id */,
|
||||
null /* handle */,
|
||||
PhoneAccount.CAPABILITY_CALL_PROVIDER);
|
||||
intent.putExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT, phoneAccount);
|
||||
|
||||
// For the purposes of testing, indicate whether the incoming call is a video call by
|
||||
// stashing an indicator in the EXTRA_INCOMING_CALL_EXTRAS.
|
||||
Bundle extras = new Bundle();
|
||||
extras.putBoolean(TestConnectionService.IS_VIDEO_CALL, isVideoCall);
|
||||
|
||||
intent.putExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS, extras);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.content.ComponentName;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.telecomm.PhoneAccount;
|
||||
import android.telecomm.PhoneAccountMetadata;
|
||||
import android.telecomm.TelecommConstants;
|
||||
|
@ -92,7 +93,8 @@ public class CallServiceNotifier {
|
|||
"testapps_TestConnectionService_Account_ID",
|
||||
Uri.parse("tel:555-TEST"),
|
||||
PhoneAccount.CAPABILITY_CALL_PROVIDER);
|
||||
PhoneAccountMetadata metadata = new PhoneAccountMetadata(phoneAccount, 0, null, null);
|
||||
PhoneAccountMetadata metadata = new PhoneAccountMetadata(phoneAccount, 0, null, null,
|
||||
false);
|
||||
|
||||
TelecommManager telecommManager =
|
||||
(TelecommManager) context.getSystemService(Context.TELECOMM_SERVICE);
|
||||
|
@ -122,7 +124,10 @@ public class CallServiceNotifier {
|
|||
*/
|
||||
private Notification getPhoneAccountNotification(Context context) {
|
||||
final Notification.Builder builder = new Notification.Builder(context);
|
||||
builder.setOngoing(true);
|
||||
// Both notifications have buttons and only the first one with buttons will show its
|
||||
// buttons. Since the phone accounts notification is always first, setting false ensures
|
||||
// it can be dismissed to use the other notification.
|
||||
builder.setOngoing(false);
|
||||
builder.setPriority(Notification.PRIORITY_HIGH);
|
||||
|
||||
final PendingIntent intent = createShowAllPhoneAccountsIntent(context);
|
||||
|
@ -146,16 +151,12 @@ public class CallServiceNotifier {
|
|||
final Notification.Builder builder = new Notification.Builder(context);
|
||||
builder.setOngoing(true);
|
||||
builder.setPriority(Notification.PRIORITY_HIGH);
|
||||
|
||||
final PendingIntent intent = createIncomingCallIntent(context, false /* isVideoCall */);
|
||||
builder.setContentIntent(intent);
|
||||
|
||||
builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
|
||||
builder.setContentText("Test calls via CallService API");
|
||||
builder.setContentTitle("TestConnectionService");
|
||||
builder.setContentTitle("Test Connection Service");
|
||||
|
||||
addAddCallAction(builder, context);
|
||||
addAddVideoCallAction(builder, context);
|
||||
addAddCallAction(builder, context);
|
||||
addExitAction(builder, context);
|
||||
|
||||
return builder.build();
|
||||
|
@ -190,27 +191,21 @@ public class CallServiceNotifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates the intent to add an incoming call through Telecomm.
|
||||
* Creates the intent to start an incoming video call
|
||||
*/
|
||||
private PendingIntent createIncomingCallIntent(Context context, boolean isVideoCall) {
|
||||
log("Creating incoming call pending intent.");
|
||||
private PendingIntent createIncomingVideoCall(Context context) {
|
||||
final Intent intent = new Intent(CallNotificationReceiver.ACTION_VIDEO_CALL,
|
||||
null, context, CallNotificationReceiver.class);
|
||||
return PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
}
|
||||
|
||||
// Create intent for adding an incoming call.
|
||||
Intent intent = new Intent(TelecommConstants.ACTION_INCOMING_CALL);
|
||||
// TODO(santoscordon): Use a private @hide permission to make sure this only goes to
|
||||
// Telecomm instead of setting the package explicitly.
|
||||
intent.setPackage("com.android.telecomm");
|
||||
|
||||
PhoneAccount phoneAccount = new PhoneAccount(
|
||||
new ComponentName(context, TestConnectionService.class),
|
||||
null /* id */,
|
||||
null /* handle */,
|
||||
PhoneAccount.CAPABILITY_CALL_PROVIDER);
|
||||
intent.putExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT, phoneAccount);
|
||||
|
||||
mStartVideoCall = isVideoCall;
|
||||
|
||||
return PendingIntent.getActivity(context, 0, intent, 0);
|
||||
/**
|
||||
* Creates the intent to start an incoming audio call
|
||||
*/
|
||||
private PendingIntent createIncomingAudioCall(Context context) {
|
||||
final Intent intent = new Intent(CallNotificationReceiver.ACTION_AUDIO_CALL,
|
||||
null, context, CallNotificationReceiver.class);
|
||||
return PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,15 +213,14 @@ public class CallServiceNotifier {
|
|||
* @param builder The Notification Builder.
|
||||
*/
|
||||
private void addAddCallAction(Notification.Builder builder, Context context) {
|
||||
// Set pending intent on the notification builder.
|
||||
builder.addAction(0, "Add Call", createIncomingCallIntent(context, false /* isVideoCall */));
|
||||
builder.addAction(0, "Add Call", createIncomingAudioCall(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an action to the Notification Builder to add an incoming video call through Telecomm.
|
||||
*/
|
||||
private void addAddVideoCallAction(Notification.Builder builder, Context context) {
|
||||
builder.addAction(0, "Add Video", createIncomingCallIntent(context, true /* isVideoCall */));
|
||||
builder.addAction(0, "Add Video", createIncomingVideoCall(context));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,7 @@ import android.util.Log;
|
|||
|
||||
import com.android.telecomm.tests.R;
|
||||
|
||||
import java.lang.String;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -53,6 +54,12 @@ public class TestConnectionService extends ConnectionService {
|
|||
public static final String EXTRA_GATEWAY_ORIGINAL_URI =
|
||||
"com.android.phone.extra.GATEWAY_ORIGINAL_URI";
|
||||
|
||||
/**
|
||||
* Intent extra used to pass along whether a call is video or audio based on the user's choice
|
||||
* in the notification.
|
||||
*/
|
||||
public static final String IS_VIDEO_CALL = "IsVideoCall";
|
||||
|
||||
private final class TestConnection extends Connection {
|
||||
private final RemoteConnection.Listener mProxyListener = new RemoteConnection.Listener() {
|
||||
@Override
|
||||
|
@ -93,6 +100,11 @@ public class TestConnectionService extends ConnectionService {
|
|||
setStatusHints(statusHints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoStateChanged(RemoteConnection connection, int videoState) {
|
||||
setVideoState(videoState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {
|
||||
setHandle(handle, presentation);
|
||||
|
@ -252,6 +264,7 @@ public class TestConnectionService extends ConnectionService {
|
|||
mIsIncoming ? Connection.State.RINGING: Connection.State.DIALING);
|
||||
|
||||
mCalls.add(connection);
|
||||
|
||||
ConnectionRequest remoteRequest = new ConnectionRequest(
|
||||
request.getAccount(),
|
||||
mOriginalRequest.getCallId(),
|
||||
|
@ -362,6 +375,7 @@ public class TestConnectionService extends ConnectionService {
|
|||
Bundle extras = originalRequest.getExtras();
|
||||
String gatewayPackage = extras.getString(EXTRA_GATEWAY_PROVIDER_PACKAGE);
|
||||
Uri originalHandle = extras.getParcelable(EXTRA_GATEWAY_ORIGINAL_URI);
|
||||
|
||||
log("gateway package [" + gatewayPackage + "], original handle [" +
|
||||
originalHandle + "]");
|
||||
|
||||
|
@ -382,6 +396,7 @@ public class TestConnectionService extends ConnectionService {
|
|||
|
||||
TestConnection connection = new TestConnection(null, Connection.State.DIALING);
|
||||
mCalls.add(connection);
|
||||
|
||||
callback.onSuccess(request, connection);
|
||||
connection.startOutgoing();
|
||||
} else {
|
||||
|
@ -412,16 +427,20 @@ public class TestConnectionService extends ConnectionService {
|
|||
if (account != null && componentName.equals(account.getComponentName())) {
|
||||
// Use dummy number for testing incoming calls.
|
||||
Uri handle = Uri.fromParts(SCHEME_TEL, "5551234", null);
|
||||
boolean isVideoCall = CallServiceNotifier.getInstance().shouldStartVideoCall();
|
||||
|
||||
TestConnection connection = new TestConnection(null, Connection.State.DIALING);
|
||||
// Get the stashed intent extra that determines if this is a video call or audio call.
|
||||
Bundle extras = request.getExtras();
|
||||
boolean isVideoCall = extras.getBoolean(IS_VIDEO_CALL);
|
||||
|
||||
TestConnection connection = new TestConnection(null, Connection.State.RINGING);
|
||||
if (isVideoCall) {
|
||||
connection.setCallVideoProvider(new TestCallVideoProvider(getApplicationContext()));
|
||||
}
|
||||
|
||||
mCalls.add(connection);
|
||||
int videoState = isVideoCall ?
|
||||
VideoCallProfile.VIDEO_STATE_BIDIRECTIONAL : request.getVideoState();
|
||||
VideoCallProfile.VIDEO_STATE_BIDIRECTIONAL :
|
||||
VideoCallProfile.VIDEO_STATE_AUDIO_ONLY;
|
||||
mCalls.add(connection);
|
||||
|
||||
ConnectionRequest newRequest = new ConnectionRequest(
|
||||
request.getAccount(),
|
||||
request.getCallId(),
|
||||
|
@ -430,6 +449,7 @@ public class TestConnectionService extends ConnectionService {
|
|||
request.getExtras(),
|
||||
videoState);
|
||||
response.onSuccess(newRequest, connection);
|
||||
connection.setVideoState(videoState);
|
||||
} else {
|
||||
SimpleResponse<Uri, List<PhoneAccount>> accountResponse =
|
||||
new SimpleResponse<Uri, List<PhoneAccount>>() {
|
||||
|
|
Loading…
Reference in New Issue