1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.incallui;
18
19import android.telecom.Connection;
20import android.telecom.Connection.VideoProvider;
21import android.telecom.InCallService.VideoCall;
22import android.telecom.VideoProfile;
23import android.telecom.VideoProfile.CameraCapabilities;
24
25/**
26 * Implements the InCallUI VideoCall Callback.
27 */
28public class InCallVideoCallCallback extends VideoCall.Callback {
29
30    /**
31     * The call associated with this {@link InCallVideoCallCallback}.
32     */
33    private Call mCall;
34
35    /**
36     * Creates an instance of the call video client, specifying the call it is related to.
37     *
38     * @param call The call.
39     */
40    public InCallVideoCallCallback(Call call) {
41        mCall = call;
42    }
43
44    /**
45     * Handles an incoming session modification request.
46     *
47     * @param videoProfile The requested video call profile.
48     */
49    @Override
50    public void onSessionModifyRequestReceived(VideoProfile videoProfile) {
51        Log.d(this, " onSessionModifyRequestReceived videoProfile=" + videoProfile);
52        int previousVideoState = CallUtils.getUnPausedVideoState(mCall.getVideoState());
53        int newVideoState = CallUtils.getUnPausedVideoState(videoProfile.getVideoState());
54
55        boolean wasVideoCall = CallUtils.isVideoCall(previousVideoState);
56        boolean isVideoCall = CallUtils.isVideoCall(newVideoState);
57
58        // Check for upgrades to video and downgrades to audio.
59        if (wasVideoCall && !isVideoCall) {
60            InCallVideoCallCallbackNotifier.getInstance().downgradeToAudio(mCall);
61        } else if (previousVideoState != newVideoState) {
62            InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoRequest(mCall,
63                newVideoState);
64        }
65    }
66
67    /**
68     * Handles a session modification response.
69     *
70     * @param status Status of the session modify request. Valid values are
71     *            {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS},
72     *            {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL},
73     *            {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID}
74     * @param requestedProfile
75     * @param responseProfile The actual profile changes made by the peer device.
76     */
77    @Override
78    public void onSessionModifyResponseReceived(int status, VideoProfile requestedProfile,
79            VideoProfile responseProfile) {
80        Log.d(this, "onSessionModifyResponseReceived status=" + status + " requestedProfile="
81                + requestedProfile + " responseProfile=" + responseProfile);
82        if (status != VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS) {
83            // Report the reason the upgrade failed as the new session modification state.
84            if (status == VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT) {
85                mCall.setSessionModificationState(
86                        Call.SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT);
87            } else {
88                if (status == VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE) {
89                    mCall.setSessionModificationState(
90                            Call.SessionModificationState.REQUEST_REJECTED);
91                } else {
92                    mCall.setSessionModificationState(
93                            Call.SessionModificationState.REQUEST_FAILED);
94                }
95            }
96            InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoFail(status, mCall);
97        } else if (requestedProfile != null && responseProfile != null) {
98            boolean modifySucceeded = requestedProfile.getVideoState() ==
99                    responseProfile.getVideoState();
100            boolean isVideoCall = CallUtils.isVideoCall(responseProfile.getVideoState());
101            if (modifySucceeded && isVideoCall) {
102                InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoSuccess(mCall);
103            } else if (!modifySucceeded && isVideoCall) {
104                InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoFail(status, mCall);
105            } else if (modifySucceeded && !isVideoCall) {
106                InCallVideoCallCallbackNotifier.getInstance().downgradeToAudio(mCall);
107            }
108        } else {
109            Log.d(this, "onSessionModifyResponseReceived request and response Profiles are null");
110        }
111        // Finally clear the outstanding request.
112        mCall.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
113    }
114
115    /**
116     * Handles a call session event.
117     *
118     * @param event The event.
119     */
120    @Override
121    public void onCallSessionEvent(int event) {
122        InCallVideoCallCallbackNotifier.getInstance().callSessionEvent(event);
123    }
124
125    /**
126     * Handles a change to the peer video dimensions.
127     *
128     * @param width  The updated peer video width.
129     * @param height The updated peer video height.
130     */
131    @Override
132    public void onPeerDimensionsChanged(int width, int height) {
133        InCallVideoCallCallbackNotifier.getInstance().peerDimensionsChanged(mCall, width, height);
134    }
135
136    /**
137     * Handles a change to the video quality of the call.
138     *
139     * @param videoQuality The updated video call quality.
140     */
141    @Override
142    public void onVideoQualityChanged(int videoQuality) {
143        InCallVideoCallCallbackNotifier.getInstance().videoQualityChanged(mCall, videoQuality);
144    }
145
146    /**
147     * Handles a change to the call data usage.  No implementation as the in-call UI does not
148     * display data usage.
149     *
150     * @param dataUsage The updated data usage.
151     */
152    @Override
153    public void onCallDataUsageChanged(long dataUsage) {
154        Log.d(this, "onCallDataUsageChanged: dataUsage = " + dataUsage);
155        InCallVideoCallCallbackNotifier.getInstance().callDataUsageChanged(dataUsage);
156    }
157
158    /**
159     * Handles changes to the camera capabilities.  No implementation as the in-call UI does not
160     * make use of camera capabilities.
161     *
162     * @param cameraCapabilities The changed camera capabilities.
163     */
164    @Override
165    public void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities) {
166        if (cameraCapabilities != null) {
167            InCallVideoCallCallbackNotifier.getInstance().cameraDimensionsChanged(
168                    mCall, cameraCapabilities.getWidth(), cameraCapabilities.getHeight());
169        }
170    }
171}
172