blob: b9a84ae5df7a8e87ffce39ea8d381b2578133a9b [file] [log] [blame]
Eric Erfanianccca3152017-02-22 16:32:36 -08001/*
2 * Copyright (C) 2016 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.content.Context;
Eric Erfanian2ca43182017-08-31 06:57:16 -070020import android.os.SystemClock;
Eric Erfanianccca3152017-02-22 16:32:36 -080021import android.support.annotation.FloatRange;
22import android.support.annotation.NonNull;
23import android.support.v4.os.UserManagerCompat;
Eric Erfaniand5e47f62017-03-15 14:41:07 -070024import android.telecom.VideoProfile;
Eric Erfanianccca3152017-02-22 16:32:36 -080025import com.android.dialer.common.Assert;
26import com.android.dialer.common.LogUtil;
Eric Erfanian2ca43182017-08-31 06:57:16 -070027import com.android.dialer.common.concurrent.ThreadUtil;
Eric Erfanian8369df02017-05-03 10:27:13 -070028import com.android.dialer.logging.DialerImpression;
29import com.android.dialer.logging.Logger;
Eric Erfanianccca3152017-02-22 16:32:36 -080030import com.android.incallui.answer.protocol.AnswerScreen;
31import com.android.incallui.answer.protocol.AnswerScreenDelegate;
32import com.android.incallui.answerproximitysensor.AnswerProximitySensor;
33import com.android.incallui.answerproximitysensor.PseudoScreenState;
Eric Erfanian90508232017-03-24 09:31:16 -070034import com.android.incallui.call.CallList;
Eric Erfanianccca3152017-02-22 16:32:36 -080035import com.android.incallui.call.DialerCall;
Eric Erfanian90508232017-03-24 09:31:16 -070036import com.android.incallui.call.DialerCallListener;
twyen8efb4952017-10-06 16:35:54 -070037import com.android.incallui.incalluilock.InCallUiLock;
Eric Erfanianccca3152017-02-22 16:32:36 -080038
39/** Manages changes for an incoming call screen. */
40public class AnswerScreenPresenter
41 implements AnswerScreenDelegate, DialerCall.CannedTextResponsesLoadedListener {
Eric Erfanian2ca43182017-08-31 06:57:16 -070042 private static final int ACCEPT_REJECT_CALL_TIME_OUT_IN_MILLIS = 5000;
43
Eric Erfanianccca3152017-02-22 16:32:36 -080044 @NonNull private final Context context;
45 @NonNull private final AnswerScreen answerScreen;
46 @NonNull private final DialerCall call;
Eric Erfanian2ca43182017-08-31 06:57:16 -070047 private long actionPerformedTimeMillis;
Eric Erfanianccca3152017-02-22 16:32:36 -080048
Eric Erfanian2ca43182017-08-31 06:57:16 -070049 AnswerScreenPresenter(
Eric Erfanianccca3152017-02-22 16:32:36 -080050 @NonNull Context context, @NonNull AnswerScreen answerScreen, @NonNull DialerCall call) {
51 LogUtil.i("AnswerScreenPresenter.constructor", null);
52 this.context = Assert.isNotNull(context);
53 this.answerScreen = Assert.isNotNull(answerScreen);
54 this.call = Assert.isNotNull(call);
55 if (isSmsResponseAllowed(call)) {
56 answerScreen.setTextResponses(call.getCannedSmsResponses());
57 }
58 call.addCannedTextResponsesLoadedListener(this);
59
60 PseudoScreenState pseudoScreenState = InCallPresenter.getInstance().getPseudoScreenState();
61 if (AnswerProximitySensor.shouldUse(context, call)) {
62 new AnswerProximitySensor(context, call, pseudoScreenState);
63 } else {
64 pseudoScreenState.setOn(true);
65 }
66 }
67
68 @Override
Eric Erfanian2ca43182017-08-31 06:57:16 -070069 public boolean isActionTimeout() {
70 return actionPerformedTimeMillis != 0
71 && SystemClock.elapsedRealtime() - actionPerformedTimeMillis
72 >= ACCEPT_REJECT_CALL_TIME_OUT_IN_MILLIS;
73 }
74
75 @Override
twyen8efb4952017-10-06 16:35:54 -070076 public InCallUiLock acquireInCallUiLock(String tag) {
77 return InCallPresenter.getInstance().acquireInCallUiLock(tag);
78 }
79
80 @Override
Eric Erfanianccca3152017-02-22 16:32:36 -080081 public void onAnswerScreenUnready() {
82 call.removeCannedTextResponsesLoadedListener(this);
83 }
84
85 @Override
Eric Erfanianccca3152017-02-22 16:32:36 -080086 public void onRejectCallWithMessage(String message) {
87 call.reject(true /* rejectWithMessage */, message);
Eric Erfanian2ca43182017-08-31 06:57:16 -070088 addTimeoutCheck();
Eric Erfanianccca3152017-02-22 16:32:36 -080089 }
90
91 @Override
Eric Erfaniand5e47f62017-03-15 14:41:07 -070092 public void onAnswer(boolean answerVideoAsAudio) {
Eric Erfanianccca3152017-02-22 16:32:36 -080093 if (answerScreen.isVideoUpgradeRequest()) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -070094 if (answerVideoAsAudio) {
Eric Erfanian8369df02017-05-03 10:27:13 -070095 Logger.get(context)
96 .logCallImpression(
97 DialerImpression.Type.VIDEO_CALL_REQUEST_ACCEPTED_AS_AUDIO,
98 call.getUniqueCallId(),
99 call.getTimeAddedMs());
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700100 call.getVideoTech().acceptVideoRequestAsAudio();
101 } else {
Eric Erfanian8369df02017-05-03 10:27:13 -0700102 Logger.get(context)
103 .logCallImpression(
104 DialerImpression.Type.VIDEO_CALL_REQUEST_ACCEPTED,
105 call.getUniqueCallId(),
106 call.getTimeAddedMs());
twyen59209802017-09-13 10:37:01 -0700107 call.getVideoTech().acceptVideoRequest(context);
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700108 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800109 } else {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700110 if (answerVideoAsAudio) {
111 call.answer(VideoProfile.STATE_AUDIO_ONLY);
112 } else {
113 call.answer();
114 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800115 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700116 addTimeoutCheck();
Eric Erfanianccca3152017-02-22 16:32:36 -0800117 }
118
119 @Override
120 public void onReject() {
121 if (answerScreen.isVideoUpgradeRequest()) {
Eric Erfanian8369df02017-05-03 10:27:13 -0700122 Logger.get(context)
123 .logCallImpression(
124 DialerImpression.Type.VIDEO_CALL_REQUEST_DECLINED,
125 call.getUniqueCallId(),
126 call.getTimeAddedMs());
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700127 call.getVideoTech().declineVideoRequest();
Eric Erfanianccca3152017-02-22 16:32:36 -0800128 } else {
129 call.reject(false /* rejectWithMessage */, null);
130 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700131 addTimeoutCheck();
Eric Erfanianccca3152017-02-22 16:32:36 -0800132 }
133
134 @Override
Eric Erfanian90508232017-03-24 09:31:16 -0700135 public void onAnswerAndReleaseCall() {
Eric Erfaniand8046e52017-04-06 09:41:50 -0700136 LogUtil.enterBlock("AnswerScreenPresenter.onAnswerAndReleaseCall");
Eric Erfanian90508232017-03-24 09:31:16 -0700137 DialerCall activeCall = CallList.getInstance().getActiveCall();
138 if (activeCall == null) {
Eric Erfaniand8046e52017-04-06 09:41:50 -0700139 LogUtil.i("AnswerScreenPresenter.onAnswerAndReleaseCall", "activeCall == null");
Eric Erfanian90508232017-03-24 09:31:16 -0700140 onAnswer(false);
141 } else {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700142 activeCall.setReleasedByAnsweringSecondCall(true);
Eric Erfanian90508232017-03-24 09:31:16 -0700143 activeCall.addListener(new AnswerOnDisconnected(activeCall));
144 activeCall.disconnect();
145 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700146 addTimeoutCheck();
147 }
148
149 @Override
150 public void onAnswerAndReleaseButtonDisabled() {
151 DialerCall activeCall = CallList.getInstance().getActiveCall();
152 if (activeCall != null) {
153 activeCall.increaseSecondCallWithoutAnswerAndReleasedButtonTimes();
154 }
155 }
156
157 @Override
158 public void onAnswerAndReleaseButtonEnabled() {
159 DialerCall activeCall = CallList.getInstance().getActiveCall();
160 if (activeCall != null) {
161 activeCall.increaseAnswerAndReleaseButtonDisplayedTimes();
162 }
Eric Erfanian90508232017-03-24 09:31:16 -0700163 }
164
165 @Override
Eric Erfanianccca3152017-02-22 16:32:36 -0800166 public void onCannedTextResponsesLoaded(DialerCall call) {
167 if (isSmsResponseAllowed(call)) {
168 answerScreen.setTextResponses(call.getCannedSmsResponses());
169 }
170 }
171
172 @Override
173 public void updateWindowBackgroundColor(@FloatRange(from = -1f, to = 1.0f) float progress) {
174 InCallActivity activity = (InCallActivity) answerScreen.getAnswerScreenFragment().getActivity();
175 if (activity != null) {
176 activity.updateWindowBackgroundColor(progress);
177 }
178 }
179
Eric Erfanian90508232017-03-24 09:31:16 -0700180 private class AnswerOnDisconnected implements DialerCallListener {
181
182 private final DialerCall disconnectingCall;
183
Eric Erfanian2ca43182017-08-31 06:57:16 -0700184 AnswerOnDisconnected(DialerCall disconnectingCall) {
Eric Erfanian90508232017-03-24 09:31:16 -0700185 this.disconnectingCall = disconnectingCall;
186 }
187
188 @Override
189 public void onDialerCallDisconnect() {
Eric Erfaniand8046e52017-04-06 09:41:50 -0700190 LogUtil.i(
191 "AnswerScreenPresenter.AnswerOnDisconnected", "call disconnected, answering new call");
Eric Erfanian90508232017-03-24 09:31:16 -0700192 call.answer();
193 disconnectingCall.removeListener(this);
194 }
195
196 @Override
197 public void onDialerCallUpdate() {}
198
199 @Override
200 public void onDialerCallChildNumberChange() {}
201
202 @Override
203 public void onDialerCallLastForwardedNumberChange() {}
204
205 @Override
206 public void onDialerCallUpgradeToVideo() {}
207
208 @Override
209 public void onDialerCallSessionModificationStateChange() {}
210
211 @Override
212 public void onWiFiToLteHandover() {}
213
214 @Override
215 public void onHandoverToWifiFailure() {}
Eric Erfanianc857f902017-05-15 14:05:33 -0700216
217 @Override
218 public void onInternationalCallOnWifi() {}
Eric Erfanian2ca43182017-08-31 06:57:16 -0700219
220 @Override
221 public void onEnrichedCallSessionUpdate() {}
Eric Erfanian90508232017-03-24 09:31:16 -0700222 }
223
Eric Erfanianccca3152017-02-22 16:32:36 -0800224 private boolean isSmsResponseAllowed(DialerCall call) {
225 return UserManagerCompat.isUserUnlocked(context)
226 && call.can(android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT);
227 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700228
229 private void addTimeoutCheck() {
230 actionPerformedTimeMillis = SystemClock.elapsedRealtime();
231 if (answerScreen.getAnswerScreenFragment().isVisible()) {
232 ThreadUtil.postDelayedOnUiThread(
233 () -> {
234 if (!answerScreen.getAnswerScreenFragment().isVisible()) {
235 LogUtil.d(
236 "AnswerScreenPresenter.addTimeoutCheck",
237 "accept/reject call timed out, do nothing");
238 return;
239 }
240 LogUtil.i("AnswerScreenPresenter.addTimeoutCheck", "accept/reject call timed out");
241 // Force re-evaluate which fragment to show.
242 InCallPresenter.getInstance().refreshUi();
243 },
244 ACCEPT_REJECT_CALL_TIME_OUT_IN_MILLIS);
245 }
246 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800247}