Enable (@hidden) video connection support for RemoteConnections

Bug: 16958934

Change-Id: I2c618743a689303f1bec190da53a1ec42d759370
This commit is contained in:
Ihab Awad
2014-08-20 09:36:40 -07:00
parent be5b656940
commit a64627c2d3
6 changed files with 397 additions and 23 deletions

View File

@@ -139,7 +139,7 @@ public abstract class Connection {
*/
public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
private static final int MSG_SET_VIDEO_LISTENER = 1;
private static final int MSG_SET_VIDEO_CALLBACK = 1;
private static final int MSG_SET_CAMERA = 2;
private static final int MSG_SET_PREVIEW_SURFACE = 3;
private static final int MSG_SET_DISPLAY_SURFACE = 4;
@@ -154,7 +154,7 @@ public abstract class Connection {
private final VideoProvider.VideoProviderHandler
mMessageHandler = new VideoProvider.VideoProviderHandler();
private final VideoProvider.VideoProviderBinder mBinder;
private IVideoCallback mVideoListener;
private IVideoCallback mVideoCallback;
/**
* Default handler used to consolidate binder method calls onto a single thread.
@@ -163,8 +163,8 @@ public abstract class Connection {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SET_VIDEO_LISTENER:
mVideoListener = IVideoCallback.Stub.asInterface((IBinder) msg.obj);
case MSG_SET_VIDEO_CALLBACK:
mVideoCallback = IVideoCallback.Stub.asInterface((IBinder) msg.obj);
break;
case MSG_SET_CAMERA:
onSetCamera((String) msg.obj);
@@ -206,9 +206,9 @@ public abstract class Connection {
* IVideoProvider stub implementation.
*/
private final class VideoProviderBinder extends IVideoProvider.Stub {
public void setVideoListener(IBinder videoListenerBinder) {
public void setVideoCallback(IBinder videoCallbackBinder) {
mMessageHandler.obtainMessage(
MSG_SET_VIDEO_LISTENER, videoListenerBinder).sendToTarget();
MSG_SET_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
}
public void setCamera(String cameraId) {
@@ -350,9 +350,9 @@ public abstract class Connection {
* @param videoProfile The requested video call profile.
*/
public void receiveSessionModifyRequest(VideoProfile videoProfile) {
if (mVideoListener != null) {
if (mVideoCallback != null) {
try {
mVideoListener.receiveSessionModifyRequest(videoProfile);
mVideoCallback.receiveSessionModifyRequest(videoProfile);
} catch (RemoteException ignored) {
}
}
@@ -370,9 +370,9 @@ public abstract class Connection {
*/
public void receiveSessionModifyResponse(int status,
VideoProfile requestedProfile, VideoProfile responseProfile) {
if (mVideoListener != null) {
if (mVideoCallback != null) {
try {
mVideoListener.receiveSessionModifyResponse(
mVideoCallback.receiveSessionModifyResponse(
status, requestedProfile, responseProfile);
} catch (RemoteException ignored) {
}
@@ -390,9 +390,9 @@ public abstract class Connection {
* @param event The event.
*/
public void handleCallSessionEvent(int event) {
if (mVideoListener != null) {
if (mVideoCallback != null) {
try {
mVideoListener.handleCallSessionEvent(event);
mVideoCallback.handleCallSessionEvent(event);
} catch (RemoteException ignored) {
}
}
@@ -405,9 +405,9 @@ public abstract class Connection {
* @param height The updated peer video height.
*/
public void changePeerDimensions(int width, int height) {
if (mVideoListener != null) {
if (mVideoCallback != null) {
try {
mVideoListener.changePeerDimensions(width, height);
mVideoCallback.changePeerDimensions(width, height);
} catch (RemoteException ignored) {
}
}
@@ -419,9 +419,9 @@ public abstract class Connection {
* @param dataUsage The updated data usage.
*/
public void changeCallDataUsage(int dataUsage) {
if (mVideoListener != null) {
if (mVideoCallback != null) {
try {
mVideoListener.changeCallDataUsage(dataUsage);
mVideoCallback.changeCallDataUsage(dataUsage);
} catch (RemoteException ignored) {
}
}
@@ -433,9 +433,9 @@ public abstract class Connection {
* @param cameraCapabilities The changed camera capabilities.
*/
public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
if (mVideoListener != null) {
if (mVideoCallback != null) {
try {
mVideoListener.changeCameraCapabilities(cameraCapabilities);
mVideoCallback.changeCameraCapabilities(cameraCapabilities);
} catch (RemoteException ignored) {
}
}

View File

@@ -17,15 +17,18 @@
package android.telecomm;
import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IVideoCallback;
import com.android.internal.telecomm.IVideoProvider;
import android.app.PendingIntent;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.DisconnectCause;
import android.view.Surface;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -182,6 +185,18 @@ public final class RemoteConnection {
RemoteConnection connection,
List<RemoteConnection> conferenceableConnections) {}
/**
* Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
* has changed.
*
* @param connection The {@code RemoteConnection} invoking this method.
* @param videoProvider The new {@code VideoProvider} associated with this
* {@code RemoteConnection}.
* @hide
*/
public void onVideoProviderChanged(
RemoteConnection connection, VideoProvider videoProvider) {}
/**
* Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
* of has changed.
@@ -195,6 +210,185 @@ public final class RemoteConnection {
RemoteConference conference) {}
}
/** {@hide} */
public static class VideoProvider {
public abstract static class Listener {
public void onReceiveSessionModifyRequest(
VideoProvider videoProvider,
VideoProfile videoProfile) {}
public void onReceiveSessionModifyResponse(
VideoProvider videoProvider,
int status,
VideoProfile requestedProfile,
VideoProfile responseProfile) {}
public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {}
public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {}
public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {}
public void onCameraCapabilitiesChanged(
VideoProvider videoProvider,
CameraCapabilities cameraCapabilities) {}
}
private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
@Override
public void receiveSessionModifyRequest(VideoProfile videoProfile) {
for (Listener l : mListeners) {
l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile);
}
}
@Override
public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
VideoProfile responseProfile) {
for (Listener l : mListeners) {
l.onReceiveSessionModifyResponse(
VideoProvider.this,
status,
requestedProfile,
responseProfile);
}
}
@Override
public void handleCallSessionEvent(int event) {
for (Listener l : mListeners) {
l.onHandleCallSessionEvent(VideoProvider.this, event);
}
}
@Override
public void changePeerDimensions(int width, int height) {
for (Listener l : mListeners) {
l.onPeerDimensionsChanged(VideoProvider.this, width, height);
}
}
@Override
public void changeCallDataUsage(int dataUsage) {
for (Listener l : mListeners) {
l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
}
}
@Override
public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
for (Listener l : mListeners) {
l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
}
}
@Override
public IBinder asBinder() {
return null;
}
};
private final VideoCallbackServant mVideoCallbackServant =
new VideoCallbackServant(mVideoCallbackDelegate);
private final IVideoProvider mVideoProviderBinder;
/**
* ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
* load factor before resizing, 1 means we only expect a single thread to
* access the map so make only a single shard
*/
private final Set<Listener> mListeners = Collections.newSetFromMap(
new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
public VideoProvider(IVideoProvider videoProviderBinder) {
mVideoProviderBinder = videoProviderBinder;
try {
mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder());
} catch (RemoteException e) {
}
}
public void addListener(Listener l) {
mListeners.add(l);
}
public void removeListener(Listener l) {
mListeners.remove(l);
}
public void setCamera(String cameraId) {
try {
mVideoProviderBinder.setCamera(cameraId);
} catch (RemoteException e) {
}
}
public void setPreviewSurface(Surface surface) {
try {
mVideoProviderBinder.setPreviewSurface(surface);
} catch (RemoteException e) {
}
}
public void setDisplaySurface(Surface surface) {
try {
mVideoProviderBinder.setDisplaySurface(surface);
} catch (RemoteException e) {
}
}
public void setDeviceOrientation(int rotation) {
try {
mVideoProviderBinder.setDeviceOrientation(rotation);
} catch (RemoteException e) {
}
}
public void setZoom(float value) {
try {
mVideoProviderBinder.setZoom(value);
} catch (RemoteException e) {
}
}
public void sendSessionModifyRequest(VideoProfile reqProfile) {
try {
mVideoProviderBinder.sendSessionModifyRequest(reqProfile);
} catch (RemoteException e) {
}
}
public void sendSessionModifyResponse(VideoProfile responseProfile) {
try {
mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
} catch (RemoteException e) {
}
}
public void requestCameraCapabilities() {
try {
mVideoProviderBinder.requestCameraCapabilities();
} catch (RemoteException e) {
}
}
public void requestCallDataUsage() {
try {
mVideoProviderBinder.requestCallDataUsage();
} catch (RemoteException e) {
}
}
public void setPauseImage(String uri) {
try {
mVideoProviderBinder.setPauseImage(uri);
} catch (RemoteException e) {
}
}
}
private IConnectionService mConnectionService;
private final String mConnectionId;
/**
@@ -215,6 +409,7 @@ public final class RemoteConnection {
private boolean mConnected;
private int mCallCapabilities;
private int mVideoState;
private VideoProvider mVideoProvider;
private boolean mAudioModeIsVoip;
private StatusHints mStatusHints;
private Uri mHandle;
@@ -379,6 +574,14 @@ public final class RemoteConnection {
return mVideoState;
}
/**
* @return The video provider associated with this {@code RemoteConnection}.
* @hide
*/
public final VideoProvider getVideoProvider() {
return mVideoProvider;
}
/**
* @return The failure code ({@see DisconnectCause}) associated with this failed
* {@code RemoteConnection}.
@@ -684,6 +887,16 @@ public final class RemoteConnection {
}
}
/**
* @hide
*/
void setVideoProvider(VideoProvider videoProvider) {
mVideoProvider = videoProvider;
for (Listener l : mListeners) {
l.onVideoProviderChanged(this, videoProvider);
}
}
/** @hide */
void setAudioModeIsVoip(boolean isVoip) {
mAudioModeIsVoip = isVoip;

View File

@@ -74,7 +74,7 @@ final class RemoteConnectionService {
}
}
connection.setConferenceableConnections(conferenceable);
// TODO: Do we need to support video providers for remote connections?
connection.setVideoState(parcel.getVideoState());
if (connection.getState() == Connection.STATE_DISCONNECTED) {
// ... then, if it was created in a disconnected state, that indicates
// failure on the providing end, so immediately mark it destroyed
@@ -226,7 +226,8 @@ final class RemoteConnectionService {
@Override
public void setVideoProvider(String callId, IVideoProvider videoProvider) {
// not supported for remote connections.
findConnectionForAction(callId, "setVideoProvider")
.setVideoProvider(new RemoteConnection.VideoProvider(videoProvider));
}
@Override

View File

@@ -157,7 +157,7 @@ public class VideoCallImpl extends VideoCall {
mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
mBinder = new VideoCallListenerBinder();
mVideoProvider.setVideoListener(mBinder);
mVideoProvider.setVideoCallback(mBinder);
}
/** {@inheritDoc} */

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 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
R* limitations under the License.
*/
package android.telecomm;
import com.android.internal.os.SomeArgs;
import com.android.internal.telecomm.IVideoCallback;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
/**
* A component that provides an RPC servant implementation of {@link IVideoCallback},
* posting incoming messages on the main thread on a client-supplied delegate object.
*
* TODO: Generate this and similar classes using a compiler starting from AIDL interfaces.
*
* @hide
*/
final class VideoCallbackServant {
private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 0;
private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 1;
private static final int MSG_HANDLE_CALL_SESSION_EVENT = 2;
private static final int MSG_CHANGE_PEER_DIMENSIONS = 3;
private static final int MSG_CHANGE_CALL_DATA_USAGE = 4;
private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 5;
private final IVideoCallback mDelegate;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
try {
internalHandleMessage(msg);
} catch (RemoteException e) {
}
}
// Internal method defined to centralize handling of RemoteException
private void internalHandleMessage(Message msg) throws RemoteException {
switch (msg.what) {
case MSG_RECEIVE_SESSION_MODIFY_REQUEST: {
mDelegate.receiveSessionModifyRequest((VideoProfile) msg.obj);
break;
}
case MSG_RECEIVE_SESSION_MODIFY_RESPONSE: {
SomeArgs args = (SomeArgs) msg.obj;
try {
mDelegate.receiveSessionModifyResponse(
args.argi1,
(VideoProfile) args.arg1,
(VideoProfile) args.arg2);
} finally {
args.recycle();
}
break;
}
case MSG_HANDLE_CALL_SESSION_EVENT: {
SomeArgs args = (SomeArgs) msg.obj;
try {
mDelegate.handleCallSessionEvent(args.argi1);
} finally {
args.recycle();
}
break;
}
case MSG_CHANGE_PEER_DIMENSIONS: {
SomeArgs args = (SomeArgs) msg.obj;
try {
mDelegate.changePeerDimensions(args.argi1, args.argi2);
} finally {
args.recycle();
}
break;
}
case MSG_CHANGE_CALL_DATA_USAGE: {
SomeArgs args = (SomeArgs) msg.obj;
try {
mDelegate.changeCallDataUsage(args.argi1);
} finally {
args.recycle();
}
break;
}
case MSG_CHANGE_CAMERA_CAPABILITIES: {
mDelegate.changeCameraCapabilities((CameraCapabilities) msg.obj);
break;
}
}
}
};
private final IVideoCallback mStub = new IVideoCallback.Stub() {
@Override
public void receiveSessionModifyRequest(VideoProfile videoProfile) throws RemoteException {
mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST, videoProfile).sendToTarget();
}
@Override
public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
VideoProfile responseProfile) throws RemoteException {
SomeArgs args = SomeArgs.obtain();
args.argi1 = status;
args.arg1 = requestedProfile;
args.arg2 = responseProfile;
mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args).sendToTarget();
}
@Override
public void handleCallSessionEvent(int event) throws RemoteException {
SomeArgs args = SomeArgs.obtain();
args.argi1 = event;
mHandler.obtainMessage(MSG_HANDLE_CALL_SESSION_EVENT, args).sendToTarget();
}
@Override
public void changePeerDimensions(int width, int height) throws RemoteException {
SomeArgs args = SomeArgs.obtain();
args.argi1 = width;
args.argi2 = height;
mHandler.obtainMessage(MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget();
}
@Override
public void changeCallDataUsage(int dataUsage) throws RemoteException {
SomeArgs args = SomeArgs.obtain();
args.argi1 = dataUsage;
mHandler.obtainMessage(MSG_CHANGE_CALL_DATA_USAGE, args).sendToTarget();
}
@Override
public void changeCameraCapabilities(CameraCapabilities cameraCapabilities)
throws RemoteException {
mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities)
.sendToTarget();
}
};
public VideoCallbackServant(IVideoCallback delegate) {
mDelegate = delegate;
}
public IVideoCallback getStub() {
return mStub;
}
}

View File

@@ -25,7 +25,7 @@ import android.telecomm.VideoProfile;
* @hide
*/
oneway interface IVideoProvider {
void setVideoListener(IBinder videoListenerBinder);
void setVideoCallback(IBinder videoCallbackBinder);
void setCamera(String cameraId);