1 /*
2  * Copyright (C) 2017 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 
17 package com.android.incallui.videotech.duo;
18 
19 import android.content.Context;
20 import android.support.annotation.NonNull;
21 import android.support.annotation.Nullable;
22 import android.telecom.Call;
23 import android.telecom.PhoneAccountHandle;
24 import com.android.dialer.common.Assert;
25 import com.android.dialer.common.LogUtil;
26 import com.android.dialer.common.concurrent.DefaultFutureCallback;
27 import com.android.dialer.configprovider.ConfigProviderComponent;
28 import com.android.dialer.duo.Duo;
29 import com.android.dialer.duo.DuoListener;
30 import com.android.dialer.logging.DialerImpression;
31 import com.android.incallui.video.protocol.VideoCallScreen;
32 import com.android.incallui.video.protocol.VideoCallScreenDelegate;
33 import com.android.incallui.videotech.VideoTech;
34 import com.android.incallui.videotech.utils.SessionModificationState;
35 import com.google.common.base.Optional;
36 import com.google.common.collect.ImmutableList;
37 import com.google.common.util.concurrent.Futures;
38 import com.google.common.util.concurrent.MoreExecutors;
39 
40 public class DuoVideoTech implements VideoTech, DuoListener {
41   private final Duo duo;
42   private final VideoTechListener listener;
43   private final Call call;
44   private final String callingNumber;
45   private int callState = Call.STATE_NEW;
46   private boolean isRemoteUpgradeAvailabilityQueried;
47 
DuoVideoTech( @onNull Duo duo, @NonNull VideoTechListener listener, @NonNull Call call, @NonNull String callingNumber)48   public DuoVideoTech(
49       @NonNull Duo duo,
50       @NonNull VideoTechListener listener,
51       @NonNull Call call,
52       @NonNull String callingNumber) {
53     this.duo = Assert.isNotNull(duo);
54     this.listener = Assert.isNotNull(listener);
55     this.call = Assert.isNotNull(call);
56     this.callingNumber = Assert.isNotNull(callingNumber);
57 
58     duo.registerListener(this);
59   }
60 
61   @Override
isAvailable(Context context, PhoneAccountHandle phoneAccountHandle)62   public boolean isAvailable(Context context, PhoneAccountHandle phoneAccountHandle) {
63     if (!ConfigProviderComponent.get(context)
64         .getConfigProvider()
65         .getBoolean("enable_lightbringer_video_upgrade", true)) {
66       LogUtil.v("DuoVideoTech.isAvailable", "upgrade disabled by flag");
67       return false;
68     }
69 
70     if (callState != Call.STATE_ACTIVE) {
71       LogUtil.v("DuoVideoTech.isAvailable", "upgrade unavailable, call must be active");
72       return false;
73     }
74     Optional<Boolean> localResult = duo.supportsUpgrade(context, callingNumber, phoneAccountHandle);
75     if (localResult.isPresent()) {
76       LogUtil.v(
77           "DuoVideoTech.isAvailable", "upgrade supported in local cache: " + localResult.get());
78       return localResult.get();
79     }
80 
81     if (!isRemoteUpgradeAvailabilityQueried) {
82       LogUtil.v("DuoVideoTech.isAvailable", "reachability unknown, starting remote query");
83       isRemoteUpgradeAvailabilityQueried = true;
84       Futures.addCallback(
85           duo.updateReachability(context, ImmutableList.of(callingNumber)),
86           new DefaultFutureCallback<>(),
87           MoreExecutors.directExecutor());
88     }
89 
90     return false;
91   }
92 
93   @Override
isTransmittingOrReceiving()94   public boolean isTransmittingOrReceiving() {
95     return false;
96   }
97 
98   @Override
isSelfManagedCamera()99   public boolean isSelfManagedCamera() {
100     return false;
101   }
102 
103   @Override
shouldUseSurfaceView()104   public boolean shouldUseSurfaceView() {
105     return false;
106   }
107 
108   @Override
isPaused()109   public boolean isPaused() {
110     return false;
111   }
112 
113   @Override
createVideoCallScreenDelegate( Context context, VideoCallScreen videoCallScreen)114   public VideoCallScreenDelegate createVideoCallScreenDelegate(
115       Context context, VideoCallScreen videoCallScreen) {
116     throw Assert.createUnsupportedOperationFailException();
117   }
118 
119   @Override
onCallStateChanged( Context context, int newState, PhoneAccountHandle phoneAccountHandle)120   public void onCallStateChanged(
121       Context context, int newState, PhoneAccountHandle phoneAccountHandle) {
122     if (newState == Call.STATE_DISCONNECTING) {
123       duo.unregisterListener(this);
124     }
125 
126     callState = newState;
127   }
128 
129   @Override
onRemovedFromCallList()130   public void onRemovedFromCallList() {
131     duo.unregisterListener(this);
132   }
133 
134   @Override
getSessionModificationState()135   public int getSessionModificationState() {
136     return SessionModificationState.NO_REQUEST;
137   }
138 
139   @Override
upgradeToVideo(@onNull Context context)140   public void upgradeToVideo(@NonNull Context context) {
141     listener.onImpressionLoggingNeeded(DialerImpression.Type.LIGHTBRINGER_UPGRADE_REQUESTED);
142     duo.requestUpgrade(context, call);
143   }
144 
145   @Override
acceptVideoRequest(@onNull Context context)146   public void acceptVideoRequest(@NonNull Context context) {
147     throw Assert.createUnsupportedOperationFailException();
148   }
149 
150   @Override
acceptVideoRequestAsAudio()151   public void acceptVideoRequestAsAudio() {
152     throw Assert.createUnsupportedOperationFailException();
153   }
154 
155   @Override
declineVideoRequest()156   public void declineVideoRequest() {
157     throw Assert.createUnsupportedOperationFailException();
158   }
159 
160   @Override
isTransmitting()161   public boolean isTransmitting() {
162     return false;
163   }
164 
165   @Override
stopTransmission()166   public void stopTransmission() {
167     throw Assert.createUnsupportedOperationFailException();
168   }
169 
170   @Override
resumeTransmission(@onNull Context context)171   public void resumeTransmission(@NonNull Context context) {
172     throw Assert.createUnsupportedOperationFailException();
173   }
174 
175   @Override
pause()176   public void pause() {}
177 
178   @Override
unpause()179   public void unpause() {}
180 
181   @Override
setCamera(@ullable String cameraId)182   public void setCamera(@Nullable String cameraId) {
183     throw Assert.createUnsupportedOperationFailException();
184   }
185 
186   @Override
becomePrimary()187   public void becomePrimary() {
188     listener.onImpressionLoggingNeeded(
189         DialerImpression.Type.UPGRADE_TO_VIDEO_CALL_BUTTON_SHOWN_FOR_LIGHTBRINGER);
190   }
191 
192   @Override
setDeviceOrientation(int rotation)193   public void setDeviceOrientation(int rotation) {}
194 
195   @Override
onDuoStateChanged()196   public void onDuoStateChanged() {
197     listener.onVideoTechStateChanged();
198   }
199 
200   @Override
getVideoTechType()201   public com.android.dialer.logging.VideoTech.Type getVideoTechType() {
202     return com.android.dialer.logging.VideoTech.Type.LIGHTBRINGER_VIDEO_TECH;
203   }
204 }
205