diff options
Diffstat (limited to 'telecomm')
7 files changed, 399 insertions, 25 deletions
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java index 6df117e..03db1c3 100644 --- a/telecomm/java/android/telecomm/Connection.java +++ b/telecomm/java/android/telecomm/Connection.java @@ -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) { } } diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java index d3da2ec..f709a86 100644 --- a/telecomm/java/android/telecomm/PhoneAccount.java +++ b/telecomm/java/android/telecomm/PhoneAccount.java @@ -246,7 +246,6 @@ public class PhoneAccount implements Parcelable { * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)} - * or {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(long, String, String)} * has been used to alter the callback number. * <p> * diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java index 31afb4b..8ad8d19 100644 --- a/telecomm/java/android/telecomm/RemoteConnection.java +++ b/telecomm/java/android/telecomm/RemoteConnection.java @@ -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; @@ -183,6 +186,18 @@ public final class RemoteConnection { 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; @@ -380,6 +575,14 @@ public final class RemoteConnection { } /** + * @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; diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java index 8ad0ad0..8b8e8eb 100644 --- a/telecomm/java/android/telecomm/RemoteConnectionService.java +++ b/telecomm/java/android/telecomm/RemoteConnectionService.java @@ -60,13 +60,14 @@ final class RemoteConnectionService { if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) { mPendingConnections.remove(connection); // Unconditionally initialize the connection ... - connection.setState(parcel.getState()); connection.setCallCapabilities(parcel.getCapabilities()); connection.setHandle( parcel.getHandle(), parcel.getHandlePresentation()); connection.setCallerDisplayName( parcel.getCallerDisplayName(), parcel.getCallerDisplayNamePresentation()); + // Set state after handle so that the client can identify the connection. + connection.setState(parcel.getState()); List<RemoteConnection> conferenceable = new ArrayList<>(); for (String confId : parcel.getConferenceableConnectionIds()) { if (mConnectionById.containsKey(confId)) { @@ -74,7 +75,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 +227,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 diff --git a/telecomm/java/android/telecomm/VideoCallImpl.java b/telecomm/java/android/telecomm/VideoCallImpl.java index c10865f..d33a351 100644 --- a/telecomm/java/android/telecomm/VideoCallImpl.java +++ b/telecomm/java/android/telecomm/VideoCallImpl.java @@ -157,7 +157,7 @@ public class VideoCallImpl extends VideoCall { mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0); mBinder = new VideoCallListenerBinder(); - mVideoProvider.setVideoListener(mBinder); + mVideoProvider.setVideoCallback(mBinder); } /** {@inheritDoc} */ diff --git a/telecomm/java/android/telecomm/VideoCallbackServant.java b/telecomm/java/android/telecomm/VideoCallbackServant.java new file mode 100644 index 0000000..060b8a9 --- /dev/null +++ b/telecomm/java/android/telecomm/VideoCallbackServant.java @@ -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; + } +} diff --git a/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl b/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl index 9d3ad7f..b0aa988 100644 --- a/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl +++ b/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl @@ -25,7 +25,7 @@ import android.telecomm.VideoProfile; * @hide */ oneway interface IVideoProvider { - void setVideoListener(IBinder videoListenerBinder); + void setVideoCallback(IBinder videoCallbackBinder); void setCamera(String cameraId); |