186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn/*
286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * Copyright (C) 2015 The Android Open Source Project
386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn *
486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * Licensed under the Apache License, Version 2.0 (the "License");
586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * you may not use this file except in compliance with the License.
686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * You may obtain a copy of the License at
786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn *
886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn *      http://www.apache.org/licenses/LICENSE-2.0
986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn *
1086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * Unless required by applicable law or agreed to in writing, software
1186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * distributed under the License is distributed on an "AS IS" BASIS,
1286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * See the License for the specific language governing permissions and
1486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * limitations under the License
1586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn */
1686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
1786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnpackage com.android.server.telecom;
1886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
1986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.net.Uri;
2086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.os.IBinder;
2186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.os.Looper;
2286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.os.RemoteException;
2386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.telecom.Connection;
2486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.telecom.InCallService;
2586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.telecom.VideoProfile;
2686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport android.view.Surface;
2786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
2886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport com.android.internal.telecom.IVideoCallback;
2986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport com.android.internal.telecom.IVideoProvider;
3086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
3186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport java.util.Collections;
3286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport java.util.HashMap;
3386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport java.util.Set;
3486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnimport java.util.concurrent.ConcurrentHashMap;
3586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
3686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn/**
3786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * Proxies video provider messages from {@link InCallService.VideoCall}
3886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * implementations to the underlying {@link Connection.VideoProvider} implementation.  Also proxies
3986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * callbacks from the {@link Connection.VideoProvider} to {@link InCallService.VideoCall}
4086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * implementations.
4186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn *
4286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn * Also provides a means for Telecom to send and receive these messages.
4386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn */
4486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunnpublic class VideoProviderProxy extends Connection.VideoProvider {
4586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
4686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
4786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Listener for Telecom components interested in callbacks from the video provider.
4886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
4986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    interface Listener {
5086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        void onSessionModifyRequestReceived(Call call, VideoProfile videoProfile);
5186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
5286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
5386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
5486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Set of listeners on this VideoProviderProxy.
5586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
5686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
5786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * load factor before resizing, 1 means we only expect a single thread to
5886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * access the map so make only a single shard
5986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
6086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private final Set<Listener> mListeners = Collections.newSetFromMap(
6186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
6286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
6386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /** The TelecomSystem SyncRoot used for synchronized operations. */
6486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private final TelecomSystem.SyncRoot mLock;
6586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
6686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
6786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * The {@link android.telecom.Connection.VideoProvider} implementation residing with the
6886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link android.telecom.ConnectionService} which is being wrapped by this
6986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link VideoProviderProxy}.
7086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
7186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private final IVideoProvider mConectionServiceVideoProvider;
7286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
7386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
7486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Binder used to bind to the {@link android.telecom.ConnectionService}'s
7586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link com.android.internal.telecom.IVideoCallback}.
7686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
7786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private final VideoCallListenerBinder mVideoCallListenerBinder;
7886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
7986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
8086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * The Telecom {@link Call} this {@link VideoProviderProxy} is associated with.
8186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
8286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private Call mCall;
8386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
8486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
8586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
8686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void binderDied() {
8786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            mConectionServiceVideoProvider.asBinder().unlinkToDeath(this, 0);
8886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
8986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    };
9086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
9186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
9286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Creates a new instance of the {@link VideoProviderProxy}, binding it to the passed in
9386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@code videoProvider} residing with the {@link android.telecom.ConnectionService}.
9486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
9586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
9686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param lock
9786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param videoProvider The {@link android.telecom.ConnectionService}'s video provider.
9886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param call The current call.
9986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @throws RemoteException Remote exception.
10086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
10186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    VideoProviderProxy(TelecomSystem.SyncRoot lock,
10286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            IVideoProvider videoProvider, Call call) throws RemoteException {
10386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
10486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        super(Looper.getMainLooper());
10586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
10686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mLock = lock;
10786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
10886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mConectionServiceVideoProvider = videoProvider;
10986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mConectionServiceVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
11086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
11186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mVideoCallListenerBinder = new VideoCallListenerBinder();
11286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mConectionServiceVideoProvider.addVideoCallback(mVideoCallListenerBinder);
11386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mCall = call;
11486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
11586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
11686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
11786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * IVideoCallback stub implementation.  An instance of this class receives callbacks from the
11886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@code ConnectionService}'s video provider.
11986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
12086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private final class VideoCallListenerBinder extends IVideoCallback.Stub {
12186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
12286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
12386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when a session modification request is received.
12486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
12586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param videoProfile The requested video profile.
12686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
12786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
12886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void receiveSessionModifyRequest(VideoProfile videoProfile) {
12986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
13086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("receiveSessionModifyRequest: " + videoProfile);
13186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
13286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                // Inform other Telecom components of the session modification request.
13386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                for (Listener listener : mListeners) {
13486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                    listener.onSessionModifyRequestReceived(mCall, videoProfile);
13586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                }
13686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
13786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.receiveSessionModifyRequest(videoProfile);
13886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
13986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
14086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
14186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
14286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
14386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when a session modification response is received.
14486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
14586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param status The status of the response.
14686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param requestProfile The requested video profile.
14786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param responseProfile The response video profile.
14886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
14986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
15086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void receiveSessionModifyResponse(int status, VideoProfile requestProfile,
15186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProfile responseProfile) {
15286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
15386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("receiveSessionModifyResponse: status=" + status +
15486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                        " requestProfile=" + requestProfile + " responseProfile=" +
15586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                        responseProfile);
15686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.receiveSessionModifyResponse(status, requestProfile,
15786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                        responseProfile);
15886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
15986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
16086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
16186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
16286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
16386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when a call session event occurs.
16486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
16586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param event The call session event.
16686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
16786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
16886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void handleCallSessionEvent(int event) {
16986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
17086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("handleCallSessionEvent: " + event);
17186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.handleCallSessionEvent(event);
17286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
17386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
17486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
17586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
17686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
17786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when the peer dimensions change.
17886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
17986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param width The width of the peer's video.
18086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param height The height of the peer's video.
18186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
18286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
18386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void changePeerDimensions(int width, int height) {
18486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
18586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("changePeerDimensions: width=" + width + " height=" +
18686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                        height);
18786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.changePeerDimensions(width, height);
18886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
18986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
19086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
19186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
19286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
19386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when the video quality changes.
19486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
19586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param videoQuality The video quality.
19686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
19786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
19886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void changeVideoQuality(int videoQuality) {
19986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
20086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("changeVideoQuality: " + videoQuality);
20186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.changeVideoQuality(videoQuality);
20286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
20386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
20486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
20586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
20686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
20786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when the call data usage changes.
20886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
20986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param dataUsage The data usage.
21086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
21186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
21286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void changeCallDataUsage(long dataUsage) {
21386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
21486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("changeCallDataUsage: " + dataUsage);
21586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.setCallDataUsage(dataUsage);
21686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
21786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
21886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
21986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        /**
22086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * Proxies a request from the {@link #mConectionServiceVideoProvider} to the
22186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * {@link InCallService} when the camera capabilities change.
22286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         *
22386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         * @param cameraCapabilities The camera capabilities.
22486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn         */
22586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        @Override
22686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
22786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            synchronized (mLock) {
22886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                logFromVideoProvider("changeCameraCapabilities: " + cameraCapabilities);
22986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                VideoProviderProxy.this.changeCameraCapabilities(cameraCapabilities);
23086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
23186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
23286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
23386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
23486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
23586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
23686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to change the camera.
23786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
23886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param cameraId The id of the camera.
23986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
24086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
24186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSetCamera(String cameraId) {
24286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
24386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("setCamera: " + cameraId);
24486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
24586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.setCamera(cameraId);
24686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
24786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
24886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
24986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
25086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
25186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
25286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
25386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to set the preview surface.
25486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
25586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param surface The surface.
25686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
25786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
25886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSetPreviewSurface(Surface surface) {
25986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
26086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("setPreviewSurface");
26186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
26286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.setPreviewSurface(surface);
26386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
26486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
26586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
26686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
26786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
26886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
26986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
27086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to change the display surface.
27186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
27286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param surface The surface.
27386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
27486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
27586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSetDisplaySurface(Surface surface) {
27686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
27786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("setDisplaySurface");
27886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
27986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.setDisplaySurface(surface);
28086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
28186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
28286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
28386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
28486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
28586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
28686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
28786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to change the device orientation.
28886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
28986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param rotation The device orientation, in degrees.
29086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
29186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
29286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSetDeviceOrientation(int rotation) {
29386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
29486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("setDeviceOrientation: " + rotation);
29586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
29686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.setDeviceOrientation(rotation);
29786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
29886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
29986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
30086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
30186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
30286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
30386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
30486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to change the camera zoom ratio.
30586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
30686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param value The camera zoom ratio.
30786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
30886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
30986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSetZoom(float value) {
31086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
31186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("setZoom: " + value);
31286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
31386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.setZoom(value);
31486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
31586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
31686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
31786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
31886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
31986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
32086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
32186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to provide a response to a session modification
32286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * request.
32386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
32486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param fromProfile The video properties prior to the request.
32586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param toProfile The video properties with the requested changes made.
32686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
32786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
32886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
32986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
33086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("sendSessionModifyRequest: from=" + fromProfile + " to=" + toProfile);
33186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
33286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.sendSessionModifyRequest(fromProfile, toProfile);
33386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
33486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
33586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
33686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
33786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
33886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
33986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
34086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to send a session modification request.
34186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
34286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param responseProfile The response connection video properties.
34386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
34486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
34586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSendSessionModifyResponse(VideoProfile responseProfile) {
34686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
34786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("sendSessionModifyResponse: " + responseProfile);
34886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
34986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.sendSessionModifyResponse(responseProfile);
35086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
35186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
35286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
35386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
35486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
35586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
35686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
35786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to request the camera capabilities.
35886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
35986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
36086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onRequestCameraCapabilities() {
36186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
36286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("requestCameraCapabilities");
36386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
36486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.requestCameraCapabilities();
36586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
36686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
36786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
36886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
36986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
37086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
37186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
37286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to request the connection data usage.
37386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
37486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
37586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onRequestConnectionDataUsage() {
37686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
37786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("requestCallDataUsage");
37886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
37986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.requestCallDataUsage();
38086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
38186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
38286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
38386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
38486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
38586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
38686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Proxies a request from the {@link InCallService} to the
38786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link #mConectionServiceVideoProvider} to set the pause image.
38886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
38986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param uri URI of image to display.
39086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
39186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    @Override
39286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void onSetPauseImage(Uri uri) {
39386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        synchronized (mLock) {
39486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            logFromInCall("setPauseImage: " + uri);
39586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            try {
39686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn                mConectionServiceVideoProvider.setPauseImage(uri);
39786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            } catch (RemoteException e) {
39886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            }
39986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
40086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
40186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
40286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
40386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Add a listener to this {@link VideoProviderProxy}.
40486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
40586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param listener The listener.
40686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
40786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void addListener(Listener listener) {
40886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        mListeners.add(listener);
40986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
41086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
41186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
41286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Remove a listener from this {@link VideoProviderProxy}.
41386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
41486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param listener The listener.
41586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
41686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    public void removeListener(Listener listener) {
41786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        if (listener != null) {
41886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn            mListeners.remove(listener);
41986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        }
42086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
42186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
42286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
42386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Logs a message originating from the {@link InCallService}.
42486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
42586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param toLog The message to log.
42686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
42786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private void logFromInCall(String toLog) {
42886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        Log.v(this, "IC->VP: " + toLog);
42986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
43086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn
43186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    /**
43286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * Logs a message originating from the {@link android.telecom.ConnectionService}'s
43386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * {@link Connection.VideoProvider}.
43486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     *
43586014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     * @param toLog The message to log.
43686014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn     */
43786014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    private void logFromVideoProvider(String toLog) {
43886014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn        Log.v(this, "VP->IC: " + toLog);
43986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn    }
44086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn}
441