Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9802f0d0 authored by Ihab Awad's avatar Ihab Awad Committed by Android (Google) Code Review
Browse files

Merge "Enable (@hidden) video connection support for RemoteConnections" into lmp-dev

parents 73f41d91 a64627c2
Loading
Loading
Loading
Loading
+18 −18
Original line number Original line Diff line number Diff line
@@ -139,7 +139,7 @@ public abstract class Connection {
         */
         */
        public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
        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_CAMERA = 2;
        private static final int MSG_SET_PREVIEW_SURFACE = 3;
        private static final int MSG_SET_PREVIEW_SURFACE = 3;
        private static final int MSG_SET_DISPLAY_SURFACE = 4;
        private static final int MSG_SET_DISPLAY_SURFACE = 4;
@@ -154,7 +154,7 @@ public abstract class Connection {
        private final VideoProvider.VideoProviderHandler
        private final VideoProvider.VideoProviderHandler
                mMessageHandler = new VideoProvider.VideoProviderHandler();
                mMessageHandler = new VideoProvider.VideoProviderHandler();
        private final VideoProvider.VideoProviderBinder mBinder;
        private final VideoProvider.VideoProviderBinder mBinder;
        private IVideoCallback mVideoListener;
        private IVideoCallback mVideoCallback;


        /**
        /**
         * Default handler used to consolidate binder method calls onto a single thread.
         * Default handler used to consolidate binder method calls onto a single thread.
@@ -163,8 +163,8 @@ public abstract class Connection {
            @Override
            @Override
            public void handleMessage(Message msg) {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                switch (msg.what) {
                    case MSG_SET_VIDEO_LISTENER:
                    case MSG_SET_VIDEO_CALLBACK:
                        mVideoListener = IVideoCallback.Stub.asInterface((IBinder) msg.obj);
                        mVideoCallback = IVideoCallback.Stub.asInterface((IBinder) msg.obj);
                        break;
                        break;
                    case MSG_SET_CAMERA:
                    case MSG_SET_CAMERA:
                        onSetCamera((String) msg.obj);
                        onSetCamera((String) msg.obj);
@@ -206,9 +206,9 @@ public abstract class Connection {
         * IVideoProvider stub implementation.
         * IVideoProvider stub implementation.
         */
         */
        private final class VideoProviderBinder extends IVideoProvider.Stub {
        private final class VideoProviderBinder extends IVideoProvider.Stub {
            public void setVideoListener(IBinder videoListenerBinder) {
            public void setVideoCallback(IBinder videoCallbackBinder) {
                mMessageHandler.obtainMessage(
                mMessageHandler.obtainMessage(
                        MSG_SET_VIDEO_LISTENER, videoListenerBinder).sendToTarget();
                        MSG_SET_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
            }
            }


            public void setCamera(String cameraId) {
            public void setCamera(String cameraId) {
@@ -350,9 +350,9 @@ public abstract class Connection {
         * @param videoProfile The requested video call profile.
         * @param videoProfile The requested video call profile.
         */
         */
        public void receiveSessionModifyRequest(VideoProfile videoProfile) {
        public void receiveSessionModifyRequest(VideoProfile videoProfile) {
            if (mVideoListener != null) {
            if (mVideoCallback != null) {
                try {
                try {
                    mVideoListener.receiveSessionModifyRequest(videoProfile);
                    mVideoCallback.receiveSessionModifyRequest(videoProfile);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
@@ -370,9 +370,9 @@ public abstract class Connection {
         */
         */
        public void receiveSessionModifyResponse(int status,
        public void receiveSessionModifyResponse(int status,
                VideoProfile requestedProfile, VideoProfile responseProfile) {
                VideoProfile requestedProfile, VideoProfile responseProfile) {
            if (mVideoListener != null) {
            if (mVideoCallback != null) {
                try {
                try {
                    mVideoListener.receiveSessionModifyResponse(
                    mVideoCallback.receiveSessionModifyResponse(
                            status, requestedProfile, responseProfile);
                            status, requestedProfile, responseProfile);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
@@ -390,9 +390,9 @@ public abstract class Connection {
         * @param event The event.
         * @param event The event.
         */
         */
        public void handleCallSessionEvent(int event) {
        public void handleCallSessionEvent(int event) {
            if (mVideoListener != null) {
            if (mVideoCallback != null) {
                try {
                try {
                    mVideoListener.handleCallSessionEvent(event);
                    mVideoCallback.handleCallSessionEvent(event);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
@@ -405,9 +405,9 @@ public abstract class Connection {
         * @param height The updated peer video height.
         * @param height The updated peer video height.
         */
         */
        public void changePeerDimensions(int width, int height) {
        public void changePeerDimensions(int width, int height) {
            if (mVideoListener != null) {
            if (mVideoCallback != null) {
                try {
                try {
                    mVideoListener.changePeerDimensions(width, height);
                    mVideoCallback.changePeerDimensions(width, height);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
@@ -419,9 +419,9 @@ public abstract class Connection {
         * @param dataUsage The updated data usage.
         * @param dataUsage The updated data usage.
         */
         */
        public void changeCallDataUsage(int dataUsage) {
        public void changeCallDataUsage(int dataUsage) {
            if (mVideoListener != null) {
            if (mVideoCallback != null) {
                try {
                try {
                    mVideoListener.changeCallDataUsage(dataUsage);
                    mVideoCallback.changeCallDataUsage(dataUsage);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
@@ -433,9 +433,9 @@ public abstract class Connection {
         * @param cameraCapabilities The changed camera capabilities.
         * @param cameraCapabilities The changed camera capabilities.
         */
         */
        public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
        public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
            if (mVideoListener != null) {
            if (mVideoCallback != null) {
                try {
                try {
                    mVideoListener.changeCameraCapabilities(cameraCapabilities);
                    mVideoCallback.changeCameraCapabilities(cameraCapabilities);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
+214 −1
Original line number Original line Diff line number Diff line
@@ -17,15 +17,18 @@
package android.telecomm;
package android.telecomm;


import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IVideoCallback;
import com.android.internal.telecomm.IVideoProvider;


import android.app.PendingIntent;
import android.app.PendingIntent;
import android.net.Uri;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.telephony.DisconnectCause;
import android.telephony.DisconnectCause;
import android.view.Surface;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentHashMap;
@@ -182,6 +185,18 @@ public final class RemoteConnection {
                RemoteConnection connection,
                RemoteConnection connection,
                List<RemoteConnection> conferenceableConnections) {}
                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
         * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
         * of has changed.
         * of has changed.
@@ -195,6 +210,185 @@ public final class RemoteConnection {
                RemoteConference conference) {}
                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 IConnectionService mConnectionService;
    private final String mConnectionId;
    private final String mConnectionId;
    /**
    /**
@@ -215,6 +409,7 @@ public final class RemoteConnection {
    private boolean mConnected;
    private boolean mConnected;
    private int mCallCapabilities;
    private int mCallCapabilities;
    private int mVideoState;
    private int mVideoState;
    private VideoProvider mVideoProvider;
    private boolean mAudioModeIsVoip;
    private boolean mAudioModeIsVoip;
    private StatusHints mStatusHints;
    private StatusHints mStatusHints;
    private Uri mHandle;
    private Uri mHandle;
@@ -379,6 +574,14 @@ public final class RemoteConnection {
        return mVideoState;
        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
     * @return The failure code ({@see DisconnectCause}) associated with this failed
     * {@code RemoteConnection}.
     * {@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 */
    /** @hide */
    void setAudioModeIsVoip(boolean isVoip) {
    void setAudioModeIsVoip(boolean isVoip) {
        mAudioModeIsVoip = isVoip;
        mAudioModeIsVoip = isVoip;
+3 −2
Original line number Original line Diff line number Diff line
@@ -74,7 +74,7 @@ final class RemoteConnectionService {
                    }
                    }
                }
                }
                connection.setConferenceableConnections(conferenceable);
                connection.setConferenceableConnections(conferenceable);
                // TODO: Do we need to support video providers for remote connections?
                connection.setVideoState(parcel.getVideoState());
                if (connection.getState() == Connection.STATE_DISCONNECTED) {
                if (connection.getState() == Connection.STATE_DISCONNECTED) {
                    // ... then, if it was created in a disconnected state, that indicates
                    // ... then, if it was created in a disconnected state, that indicates
                    // failure on the providing end, so immediately mark it destroyed
                    // failure on the providing end, so immediately mark it destroyed
@@ -226,7 +226,8 @@ final class RemoteConnectionService {


        @Override
        @Override
        public void setVideoProvider(String callId, IVideoProvider videoProvider) {
        public void setVideoProvider(String callId, IVideoProvider videoProvider) {
            // not supported for remote connections.
            findConnectionForAction(callId, "setVideoProvider")
                    .setVideoProvider(new RemoteConnection.VideoProvider(videoProvider));
        }
        }


        @Override
        @Override
+1 −1
Original line number Original line Diff line number Diff line
@@ -157,7 +157,7 @@ public class VideoCallImpl extends VideoCall {
        mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
        mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);


        mBinder = new VideoCallListenerBinder();
        mBinder = new VideoCallListenerBinder();
        mVideoProvider.setVideoListener(mBinder);
        mVideoProvider.setVideoCallback(mBinder);
    }
    }


    /** {@inheritDoc} */
    /** {@inheritDoc} */
+160 −0
Original line number Original line Diff line number Diff line
/*
 * 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;
    }
}
Loading