Sent initial data to telecomm on connection creation. (1/3)

Telecomm was not sending the initial state for new connections forcing
the connection services to postpone when they set data on the connection
which resulted in hacky code.  This CL makes use of a
ParcelableConnection to send the intial connection data.

Change-Id: If571414aba19fa1bb282e30632431962b8366cf4
This commit is contained in:
Santos Cordon
2014-07-21 01:28:28 -07:00
parent 1e586e08bf
commit e8dc4bef00
7 changed files with 228 additions and 28 deletions

View File

@@ -432,14 +432,20 @@ public abstract class ConnectionService extends Service {
public void onSuccess(ConnectionRequest request, Connection connection) {
Log.d(this, "adapter handleCreateConnectionSuccessful %s",
request.getCallId());
mAdapter.handleCreateConnectionSuccessful(request);
addConnection(request.getCallId(), connection);
// TODO: onSuccess should pass through the entire state of the connection instead of
// having to set it like this afterwards. Also, it would eliminate the hack of
// having to change the request object that we pass back.
mConnectionListener.onCallCapabilitiesChanged(
connection, connection.getCallCapabilities());
mAdapter.handleCreateConnectionSuccessful(
request,
new ParcelableConnection(
request.getAccountHandle(),
connection.getState(),
connection.getCallCapabilities(),
connection.getHandle(),
connection.getHandlePresentation(),
connection.getCallerDisplayName(),
connection.getCallerDisplayNamePresentation(),
connection.getCallVideoProvider() == null ?
null : connection.getCallVideoProvider().getInterface(),
connection.getVideoState()));
}
@Override
@@ -720,12 +726,6 @@ public abstract class ConnectionService extends Service {
mIdByConnection.put(connection, callId);
connection.addConnectionListener(mConnectionListener);
onConnectionAdded(connection);
// Trigger listeners for properties set before connection listener was added.
CallVideoProvider callVideoProvider = connection.getCallVideoProvider();
if (callVideoProvider != null) {
connection.setCallVideoProvider(callVideoProvider);
}
}
private void removeConnection(Connection connection) {

View File

@@ -74,10 +74,11 @@ final class ConnectionServiceAdapter implements DeathRecipient {
}
}
void handleCreateConnectionSuccessful(ConnectionRequest request) {
void handleCreateConnectionSuccessful(
ConnectionRequest request, ParcelableConnection connection) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
adapter.handleCreateConnectionSuccessful(request);
adapter.handleCreateConnectionSuccessful(request, connection);
} catch (RemoteException e) {
}
}
@@ -277,7 +278,9 @@ final class ConnectionServiceAdapter implements DeathRecipient {
void setCallVideoProvider(String callId, CallVideoProvider callVideoProvider) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
adapter.setCallVideoProvider(callId, callVideoProvider.getInterface());
adapter.setCallVideoProvider(
callId,
callVideoProvider == null ? null : callVideoProvider.getInterface());
} catch (RemoteException e) {
}
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright 2014, 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.telecomm;
parcelable ParcelableConnection;

View File

@@ -0,0 +1,156 @@
/*
* Copyright 2014, 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.telecomm;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.telecomm.ICallVideoProvider;
/**
* Information about a connection that is used between Telecomm and the ConnectionService.
* This is used to send initial Connection information to Telecomm when the connection is
* first created.
* @hide
*/
public final class ParcelableConnection implements Parcelable {
private PhoneAccountHandle mPhoneAccount;
private int mState;
private int mCapabilities;
private Uri mHandle;
private int mHandlePresentation;
private String mCallerDisplayName;
private int mCallerDisplayNamePresentation;
private ICallVideoProvider mCallVideoProvider;
private int mVideoState;
/** @hide */
public ParcelableConnection(
PhoneAccountHandle phoneAccount,
int state,
int capabilities,
Uri handle,
int handlePresentation,
String callerDisplayName,
int callerDisplayNamePresentation,
ICallVideoProvider callVideoProvider,
int videoState) {
mPhoneAccount = phoneAccount;
mState = state;
mCapabilities = capabilities;
mHandle = handle;
mHandlePresentation = handlePresentation;
mCallerDisplayName = callerDisplayName;
mCallerDisplayNamePresentation = callerDisplayNamePresentation;
mCallVideoProvider = callVideoProvider;
mVideoState = videoState;
}
public PhoneAccountHandle getPhoneAccount() {
return mPhoneAccount;
}
public int getState() {
return mState;
}
// Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
public int getCapabilities() {
return mCapabilities;
}
public Uri getHandle() {
return mHandle;
}
public int getHandlePresentation() {
return mHandlePresentation;
}
public String getCallerDisplayName() {
return mCallerDisplayName;
}
public int getCallerDisplayNamePresentation() {
return mCallerDisplayNamePresentation;
}
public ICallVideoProvider getCallVideoProvider() {
return mCallVideoProvider;
}
public int getVideoState() {
return mVideoState;
}
public static final Parcelable.Creator<ParcelableConnection> CREATOR =
new Parcelable.Creator<ParcelableConnection> () {
@Override
public ParcelableConnection createFromParcel(Parcel source) {
ClassLoader classLoader = ParcelableConnection.class.getClassLoader();
PhoneAccountHandle phoneAccount = source.readParcelable(classLoader);
int state = source.readInt();
int capabilities = source.readInt();
Uri handle = source.readParcelable(classLoader);
int handlePresentation = source.readInt();
String callerDisplayName = source.readString();
int callerDisplayNamePresentation = source.readInt();
ICallVideoProvider callVideoProvider =
ICallVideoProvider.Stub.asInterface(source.readStrongBinder());
int videoState = source.readInt();
return new ParcelableConnection(
phoneAccount,
state,
capabilities,
handle,
handlePresentation,
callerDisplayName,
callerDisplayNamePresentation,
callVideoProvider,
videoState);
}
@Override
public ParcelableConnection[] newArray(int size) {
return new ParcelableConnection[size];
}
};
/** {@inheritDoc} */
@Override
public int describeContents() {
return 0;
}
/** Writes ParcelableConnection object into a Parcel. */
@Override
public void writeToParcel(Parcel destination, int flags) {
destination.writeParcelable(mPhoneAccount, 0);
destination.writeInt(mState);
destination.writeInt(mCapabilities);
destination.writeParcelable(mHandle, 0);
destination.writeInt(mHandlePresentation);
destination.writeString(mCallerDisplayName);
destination.writeInt(mCallerDisplayNamePresentation);
destination.writeStrongBinder(
mCallVideoProvider != null ? mCallVideoProvider.asBinder() : null);
destination.writeInt(mVideoState);
}
}

View File

@@ -18,6 +18,7 @@ package android.telecomm;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Parcel;
@@ -181,7 +182,7 @@ public class PhoneAccount implements Parcelable {
}
try {
return packageContext.getResources().getDrawable(resId);
} catch (MissingResourceException e) {
} catch (NotFoundException|MissingResourceException e) {
Log.e(this, e, "Cannot find icon %d in package %s",
resId, mAccountHandle.getComponentName().getPackageName());
return null;

View File

@@ -19,18 +19,17 @@ package android.telecomm;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.net.Uri;
import android.os.IBinder.DeathRecipient;
import android.os.Handler;
import android.os.IBinder.DeathRecipient;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.DisconnectCause;
import android.text.TextUtils;
import com.android.internal.os.SomeArgs;
import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IConnectionServiceAdapter;
import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.RemoteServiceCallback;
import java.util.LinkedList;
@@ -80,11 +79,27 @@ final class RemoteConnectionService implements DeathRecipient {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
ConnectionRequest request = (ConnectionRequest) msg.obj;
if (isPendingConnection(request.getCallId())) {
mConnection = new RemoteConnection(mConnectionService, request.getCallId());
mPendingResponse.onSuccess(request, mConnection);
clearPendingInformation();
SomeArgs args = (SomeArgs) msg.obj;
try {
ConnectionRequest request = (ConnectionRequest) args.arg1;
if (isPendingConnection(request.getCallId())) {
ParcelableConnection parcel = (ParcelableConnection) args.arg2;
mConnection = new RemoteConnection(
mConnectionService, request.getCallId());
mConnection.setState(parcel.getState());
mConnection.setCallCapabilities(parcel.getCapabilities());
mConnection.setHandle(
parcel.getHandle(), parcel.getHandlePresentation());
mConnection.setCallerDisplayName(
parcel.getCallerDisplayName(),
parcel.getCallerDisplayNamePresentation());
// TODO: Do we need to support video providers for remote connections?
mPendingResponse.onSuccess(request, mConnection);
clearPendingInformation();
}
} finally {
args.recycle();
}
break;
}
@@ -242,8 +257,12 @@ final class RemoteConnectionService implements DeathRecipient {
private final IConnectionServiceAdapter mAdapter = new IConnectionServiceAdapter.Stub() {
@Override
public void handleCreateConnectionSuccessful(ConnectionRequest request) {
mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, request).sendToTarget();
public void handleCreateConnectionSuccessful(
ConnectionRequest request, ParcelableConnection connection) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = request;
args.arg2 = connection;
mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
}
@Override

View File

@@ -19,6 +19,7 @@ package com.android.internal.telecomm;
import android.app.PendingIntent;
import android.net.Uri;
import android.telecomm.ConnectionRequest;
import android.telecomm.ParcelableConnection;
import android.telecomm.StatusHints;
import com.android.internal.telecomm.ICallVideoProvider;
@@ -32,7 +33,8 @@ import com.android.internal.telecomm.RemoteServiceCallback;
* {@hide}
*/
oneway interface IConnectionServiceAdapter {
void handleCreateConnectionSuccessful(in ConnectionRequest request);
void handleCreateConnectionSuccessful(
in ConnectionRequest request, in ParcelableConnection connection);
void handleCreateConnectionFailed(
in ConnectionRequest request, int errorCode, String errorMessage);