blob: f9311f8d3c2644dc688b1e572519c22c1a42c084 [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
linyuhf99f6302017-11-15 11:23:51 -080019import android.app.Dialog;
Eric Erfanianccca3152017-02-22 16:32:36 -080020import android.content.Context;
21import android.content.Intent;
22import android.graphics.drawable.GradientDrawable;
23import android.graphics.drawable.GradientDrawable.Orientation;
24import android.os.Bundle;
Eric Erfanian2ca43182017-08-31 06:57:16 -070025import android.os.Trace;
Eric Erfanianccca3152017-02-22 16:32:36 -080026import android.support.annotation.ColorInt;
27import android.support.annotation.FloatRange;
Eric Erfanianc857f902017-05-15 14:05:33 -070028import android.support.annotation.NonNull;
Eric Erfanianccca3152017-02-22 16:32:36 -080029import android.support.annotation.Nullable;
30import android.support.v4.app.FragmentManager;
31import android.support.v4.app.FragmentTransaction;
32import android.support.v4.graphics.ColorUtils;
Eric Erfanian90508232017-03-24 09:31:16 -070033import android.telephony.TelephonyManager;
Eric Erfanianccca3152017-02-22 16:32:36 -080034import android.view.KeyEvent;
35import android.view.MenuItem;
36import android.view.MotionEvent;
37import android.view.View;
linyuh9c327da2017-11-14 12:33:48 -080038import android.view.WindowManager;
linyuhf99f6302017-11-15 11:23:51 -080039import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment;
Eric Erfaniand5e47f62017-03-15 14:41:07 -070040import com.android.dialer.common.Assert;
Eric Erfanianccca3152017-02-22 16:32:36 -080041import com.android.dialer.common.LogUtil;
weijiaxu650e7cc2017-10-31 12:38:54 -070042import com.android.dialer.common.concurrent.ThreadUtil;
Eric Erfanianccca3152017-02-22 16:32:36 -080043import com.android.dialer.compat.ActivityCompat;
Eric Erfanian2ca43182017-08-31 06:57:16 -070044import com.android.dialer.configprovider.ConfigProviderBindings;
45import com.android.dialer.logging.DialerImpression;
Eric Erfanianccca3152017-02-22 16:32:36 -080046import com.android.dialer.logging.Logger;
weijiaxu94df7202017-10-25 18:21:41 -070047import com.android.dialer.logging.LoggingBindings;
Eric Erfanian8369df02017-05-03 10:27:13 -070048import com.android.dialer.logging.ScreenEvent;
Eric Erfanianccca3152017-02-22 16:32:36 -080049import com.android.incallui.answer.bindings.AnswerBindings;
50import com.android.incallui.answer.protocol.AnswerScreen;
51import com.android.incallui.answer.protocol.AnswerScreenDelegate;
52import com.android.incallui.answer.protocol.AnswerScreenDelegateFactory;
53import com.android.incallui.answerproximitysensor.PseudoScreenState;
54import com.android.incallui.call.CallList;
55import com.android.incallui.call.DialerCall;
56import com.android.incallui.call.DialerCall.State;
Eric Erfanian2ca43182017-08-31 06:57:16 -070057import com.android.incallui.callpending.CallPendingActivity;
58import com.android.incallui.disconnectdialog.DisconnectMessage;
Eric Erfanianccca3152017-02-22 16:32:36 -080059import com.android.incallui.incall.bindings.InCallBindings;
60import com.android.incallui.incall.protocol.InCallButtonUiDelegate;
61import com.android.incallui.incall.protocol.InCallButtonUiDelegateFactory;
62import com.android.incallui.incall.protocol.InCallScreen;
63import com.android.incallui.incall.protocol.InCallScreenDelegate;
64import com.android.incallui.incall.protocol.InCallScreenDelegateFactory;
linyuhf99f6302017-11-15 11:23:51 -080065import com.android.incallui.telecomeventui.InternationalCallOnWifiDialogFragment;
Eric Erfanianccca3152017-02-22 16:32:36 -080066import com.android.incallui.video.bindings.VideoBindings;
67import com.android.incallui.video.protocol.VideoCallScreen;
68import com.android.incallui.video.protocol.VideoCallScreenDelegate;
69import com.android.incallui.video.protocol.VideoCallScreenDelegateFactory;
70
71/** Version of {@link InCallActivity} that shows the new UI */
72public class InCallActivity extends TransactionSafeFragmentActivity
73 implements AnswerScreenDelegateFactory,
74 InCallScreenDelegateFactory,
75 InCallButtonUiDelegateFactory,
76 VideoCallScreenDelegateFactory,
77 PseudoScreenState.StateChangedListener {
78
Eric Erfanian2ca43182017-08-31 06:57:16 -070079 public static final int PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN = 0;
80 public static final int PENDING_INTENT_REQUEST_CODE_FULL_SCREEN = 1;
81 public static final int PENDING_INTENT_REQUEST_CODE_BUBBLE = 2;
82
Eric Erfanianccca3152017-02-22 16:32:36 -080083 private static final String TAG_ANSWER_SCREEN = "tag_answer_screen";
linyuhf99f6302017-11-15 11:23:51 -080084 private static final String TAG_INTERNATIONAL_CALL_ON_WIFI = "tag_international_call_on_wifi";
85 private static final String TAG_IN_CALL_SCREEN = "tag_in_call_screen";
Eric Erfanianccca3152017-02-22 16:32:36 -080086 private static final String TAG_VIDEO_CALL_SCREEN = "tag_video_call_screen";
87
88 private static final String DID_SHOW_ANSWER_SCREEN_KEY = "did_show_answer_screen";
89 private static final String DID_SHOW_IN_CALL_SCREEN_KEY = "did_show_in_call_screen";
90 private static final String DID_SHOW_VIDEO_CALL_SCREEN_KEY = "did_show_video_call_screen";
91
Eric Erfanian90508232017-03-24 09:31:16 -070092 private static final String CONFIG_ANSWER_AND_RELEASE_ENABLED = "answer_and_release_enabled";
93
Eric Erfanianccca3152017-02-22 16:32:36 -080094 private final InCallActivityCommon common;
95 private boolean didShowAnswerScreen;
96 private boolean didShowInCallScreen;
97 private boolean didShowVideoCallScreen;
linyuh9c327da2017-11-14 12:33:48 -080098 private boolean dismissKeyguard;
Eric Erfanianccca3152017-02-22 16:32:36 -080099 private int[] backgroundDrawableColors;
100 private GradientDrawable backgroundDrawable;
101 private boolean isVisible;
102 private View pseudoBlackScreenOverlay;
103 private boolean touchDownWhenPseudoScreenOff;
104 private boolean isInShowMainInCallFragment;
105 private boolean needDismissPendingDialogs;
wangqi9982f0d2017-10-11 17:46:07 -0700106 private boolean allowOrientationChange;
Eric Erfanianccca3152017-02-22 16:32:36 -0800107
108 public InCallActivity() {
109 common = new InCallActivityCommon(this);
110 }
111
112 public static Intent getIntent(
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700113 Context context, boolean showDialpad, boolean newOutgoingCall, boolean isForFullScreen) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800114 Intent intent = new Intent(Intent.ACTION_MAIN, null);
115 intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
116 intent.setClass(context, InCallActivity.class);
117 InCallActivityCommon.setIntentExtras(intent, showDialpad, newOutgoingCall, isForFullScreen);
118 return intent;
119 }
120
121 @Override
122 protected void onResumeFragments() {
123 super.onResumeFragments();
124 if (needDismissPendingDialogs) {
125 dismissPendingDialogs();
126 }
127 }
128
129 @Override
130 protected void onCreate(Bundle icicle) {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700131 Trace.beginSection("InCallActivity.onCreate");
Eric Erfanianccca3152017-02-22 16:32:36 -0800132 LogUtil.i("InCallActivity.onCreate", "");
133 super.onCreate(icicle);
134
Eric Erfanian2ca43182017-08-31 06:57:16 -0700135 if (getIntent().getBooleanExtra(ReturnToCallController.RETURN_TO_CALL_EXTRA_KEY, false)) {
136 Logger.get(this).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_RETURN_TO_CALL);
137 getIntent().removeExtra(ReturnToCallController.RETURN_TO_CALL_EXTRA_KEY);
138 }
139
Eric Erfanianccca3152017-02-22 16:32:36 -0800140 if (icicle != null) {
141 didShowAnswerScreen = icicle.getBoolean(DID_SHOW_ANSWER_SCREEN_KEY);
142 didShowInCallScreen = icicle.getBoolean(DID_SHOW_IN_CALL_SCREEN_KEY);
143 didShowVideoCallScreen = icicle.getBoolean(DID_SHOW_VIDEO_CALL_SCREEN_KEY);
144 }
145
146 common.onCreate(icicle);
147
148 getWindow()
149 .getDecorView()
150 .setSystemUiVisibility(
151 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
152
153 pseudoBlackScreenOverlay = findViewById(R.id.psuedo_black_screen_overlay);
Eric Erfanian2ca43182017-08-31 06:57:16 -0700154 sendBroadcast(CallPendingActivity.getFinishBroadcast());
155 Trace.endSection();
weijiaxuc950a9b2017-11-06 16:39:04 -0800156 Logger.get(this)
157 .logStopLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_INCOMING);
158 Logger.get(this)
159 .logStopLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_OUTGOING);
Eric Erfanianccca3152017-02-22 16:32:36 -0800160 }
161
162 @Override
163 protected void onSaveInstanceState(Bundle out) {
164 LogUtil.i("InCallActivity.onSaveInstanceState", "");
165 common.onSaveInstanceState(out);
166 out.putBoolean(DID_SHOW_ANSWER_SCREEN_KEY, didShowAnswerScreen);
167 out.putBoolean(DID_SHOW_IN_CALL_SCREEN_KEY, didShowInCallScreen);
168 out.putBoolean(DID_SHOW_VIDEO_CALL_SCREEN_KEY, didShowVideoCallScreen);
169 super.onSaveInstanceState(out);
170 isVisible = false;
171 }
172
173 @Override
174 protected void onStart() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700175 Trace.beginSection("InCallActivity.onStart");
Eric Erfanianccca3152017-02-22 16:32:36 -0800176 LogUtil.i("InCallActivity.onStart", "");
wangqi9982f0d2017-10-11 17:46:07 -0700177 Trace.beginSection("call super");
Eric Erfanianccca3152017-02-22 16:32:36 -0800178 super.onStart();
wangqi9982f0d2017-10-11 17:46:07 -0700179 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800180 isVisible = true;
181 showMainInCallFragment();
182 common.onStart();
183 if (ActivityCompat.isInMultiWindowMode(this)
184 && !getResources().getBoolean(R.bool.incall_dialpad_allowed)) {
185 // Hide the dialpad because there may not be enough room
186 showDialpadFragment(false, false);
187 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700188 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800189 }
190
191 @Override
192 protected void onResume() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700193 Trace.beginSection("InCallActivity.onResume");
Eric Erfanianccca3152017-02-22 16:32:36 -0800194 LogUtil.i("InCallActivity.onResume", "");
195 super.onResume();
196 common.onResume();
197 PseudoScreenState pseudoScreenState = InCallPresenter.getInstance().getPseudoScreenState();
198 pseudoScreenState.addListener(this);
199 onPseudoScreenStateChanged(pseudoScreenState.isOn());
Eric Erfanian2ca43182017-08-31 06:57:16 -0700200 Trace.endSection();
weijiaxu650e7cc2017-10-31 12:38:54 -0700201 // add 1 sec delay to get memory snapshot so that dialer wont react slowly on resume.
202 ThreadUtil.postDelayedOnUiThread(
weijiaxuc950a9b2017-11-06 16:39:04 -0800203 () ->
204 Logger.get(this)
205 .logRecordMemory(LoggingBindings.INCALL_ACTIVITY_ON_RESUME_MEMORY_EVENT_NAME),
weijiaxu650e7cc2017-10-31 12:38:54 -0700206 1000);
Eric Erfanianccca3152017-02-22 16:32:36 -0800207 }
208
209 /** onPause is guaranteed to be called when the InCallActivity goes in the background. */
210 @Override
211 protected void onPause() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700212 Trace.beginSection("InCallActivity.onPause");
Eric Erfanianccca3152017-02-22 16:32:36 -0800213 LogUtil.i("InCallActivity.onPause", "");
214 super.onPause();
215 common.onPause();
216 InCallPresenter.getInstance().getPseudoScreenState().removeListener(this);
Eric Erfanian2ca43182017-08-31 06:57:16 -0700217 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800218 }
219
220 @Override
221 protected void onStop() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700222 Trace.beginSection("InCallActivity.onStop");
Eric Erfanianccca3152017-02-22 16:32:36 -0800223 LogUtil.i("InCallActivity.onStop", "");
wangqi4d705e52017-09-28 12:23:35 -0700224 isVisible = false;
Eric Erfanianccca3152017-02-22 16:32:36 -0800225 super.onStop();
226 common.onStop();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700227 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800228 }
229
230 @Override
231 protected void onDestroy() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700232 Trace.beginSection("InCallActivity.onDestroy");
Eric Erfanianccca3152017-02-22 16:32:36 -0800233 LogUtil.i("InCallActivity.onDestroy", "");
234 super.onDestroy();
235 common.onDestroy();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700236 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800237 }
238
239 @Override
240 public void finish() {
241 if (shouldCloseActivityOnFinish()) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700242 // When user select incall ui from recents after the call is disconnected, it tries to launch
243 // a new InCallActivity but InCallPresenter is already teared down at this point, which causes
244 // crash.
245 // By calling finishAndRemoveTask() instead of finish() the task associated with
246 // InCallActivity is cleared completely. So system won't try to create a new InCallActivity in
247 // this case.
248 //
249 // Calling finish won't clear the task and normally when an activity finishes it shouldn't
250 // clear the task since there could be parent activity in the same task that's still alive.
251 // But InCallActivity is special since it's singleInstance which means it's root activity and
252 // only instance of activity in the task. So it should be safe to also remove task when
253 // finishing.
254 // It's also necessary in the sense of it's excluded from recents. So whenever the activity
255 // finishes, the task should also be removed since it doesn't make sense to go back to it in
256 // anyway anymore.
257 super.finishAndRemoveTask();
Eric Erfanianccca3152017-02-22 16:32:36 -0800258 }
259 }
260
261 private boolean shouldCloseActivityOnFinish() {
262 if (!isVisible()) {
263 LogUtil.i(
264 "InCallActivity.shouldCloseActivityOnFinish",
265 "allowing activity to be closed because it's not visible");
266 return true;
267 }
268
twyen8efb4952017-10-06 16:35:54 -0700269 if (InCallPresenter.getInstance().isInCallUiLocked()) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800270 LogUtil.i(
271 "InCallActivity.shouldCloseActivityOnFinish",
twyen8efb4952017-10-06 16:35:54 -0700272 "in call ui is locked, not closing activity");
Eric Erfanianccca3152017-02-22 16:32:36 -0800273 return false;
274 }
275
276 LogUtil.i(
277 "InCallActivity.shouldCloseActivityOnFinish",
twyen8efb4952017-10-06 16:35:54 -0700278 "activity is visible and has no locks, allowing activity to close");
Eric Erfanianccca3152017-02-22 16:32:36 -0800279 return true;
280 }
281
282 @Override
283 protected void onNewIntent(Intent intent) {
284 LogUtil.i("InCallActivity.onNewIntent", "");
Eric Erfanianccca3152017-02-22 16:32:36 -0800285
286 // If the screen is off, we need to make sure it gets turned on for incoming calls.
287 // This normally works just fine thanks to FLAG_TURN_SCREEN_ON but that only works
288 // when the activity is first created. Therefore, to ensure the screen is turned on
289 // for the call waiting case, we recreate() the current activity. There should be no jank from
290 // this since the screen is already off and will remain so until our new activity is up.
291 if (!isVisible()) {
Eric Erfanian10b34a52017-05-04 08:23:17 -0700292 common.onNewIntent(intent, true /* isRecreating */);
Eric Erfanianccca3152017-02-22 16:32:36 -0800293 LogUtil.i("InCallActivity.onNewIntent", "Restarting InCallActivity to force screen on.");
294 recreate();
Eric Erfanian10b34a52017-05-04 08:23:17 -0700295 } else {
296 common.onNewIntent(intent, false /* isRecreating */);
Eric Erfanianccca3152017-02-22 16:32:36 -0800297 }
298 }
299
300 @Override
301 public void onBackPressed() {
302 LogUtil.i("InCallActivity.onBackPressed", "");
303 if (!common.onBackPressed(didShowInCallScreen || didShowVideoCallScreen)) {
304 super.onBackPressed();
305 }
306 }
307
308 @Override
309 public boolean onOptionsItemSelected(MenuItem item) {
310 LogUtil.i("InCallActivity.onOptionsItemSelected", "item: " + item);
311 if (item.getItemId() == android.R.id.home) {
312 onBackPressed();
313 return true;
314 }
315 return super.onOptionsItemSelected(item);
316 }
317
318 @Override
319 public boolean onKeyUp(int keyCode, KeyEvent event) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700320 return common.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
Eric Erfanianccca3152017-02-22 16:32:36 -0800321 }
322
323 @Override
324 public boolean onKeyDown(int keyCode, KeyEvent event) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700325 return common.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
Eric Erfanianccca3152017-02-22 16:32:36 -0800326 }
327
328 public boolean isInCallScreenAnimating() {
329 return false;
330 }
331
332 public void showConferenceFragment(boolean show) {
333 if (show) {
334 startActivity(new Intent(this, ManageConferenceActivity.class));
335 }
336 }
337
338 public boolean showDialpadFragment(boolean show, boolean animate) {
339 boolean didChange = common.showDialpadFragment(show, animate);
340 if (didChange) {
341 // Note: onInCallScreenDialpadVisibilityChange is called here to ensure that the dialpad FAB
342 // repositions itself.
343 getInCallScreen().onInCallScreenDialpadVisibilityChange(show);
344 }
345 return didChange;
346 }
347
348 public boolean isDialpadVisible() {
349 return common.isDialpadVisible();
350 }
351
352 public void onForegroundCallChanged(DialerCall newForegroundCall) {
353 common.updateTaskDescription();
354 if (didShowAnswerScreen && newForegroundCall != null) {
355 if (newForegroundCall.getState() == State.DISCONNECTED
356 || newForegroundCall.getState() == State.IDLE) {
357 LogUtil.i(
358 "InCallActivity.onForegroundCallChanged",
359 "rejecting incoming call, not updating " + "window background color");
360 }
361 } else {
362 LogUtil.v("InCallActivity.onForegroundCallChanged", "resetting background color");
363 updateWindowBackgroundColor(0);
364 }
365 }
366
367 public void updateWindowBackgroundColor(@FloatRange(from = -1f, to = 1.0f) float progress) {
368 ThemeColorManager themeColorManager = InCallPresenter.getInstance().getThemeColorManager();
369 @ColorInt int top;
370 @ColorInt int middle;
371 @ColorInt int bottom;
372 @ColorInt int gray = 0x66000000;
373
374 if (ActivityCompat.isInMultiWindowMode(this)) {
375 top = themeColorManager.getBackgroundColorSolid();
376 middle = themeColorManager.getBackgroundColorSolid();
377 bottom = themeColorManager.getBackgroundColorSolid();
378 } else {
379 top = themeColorManager.getBackgroundColorTop();
380 middle = themeColorManager.getBackgroundColorMiddle();
381 bottom = themeColorManager.getBackgroundColorBottom();
382 }
383
384 if (progress < 0) {
385 float correctedProgress = Math.abs(progress);
386 top = ColorUtils.blendARGB(top, gray, correctedProgress);
387 middle = ColorUtils.blendARGB(middle, gray, correctedProgress);
388 bottom = ColorUtils.blendARGB(bottom, gray, correctedProgress);
389 }
390
391 boolean backgroundDirty = false;
392 if (backgroundDrawable == null) {
393 backgroundDrawableColors = new int[] {top, middle, bottom};
394 backgroundDrawable = new GradientDrawable(Orientation.TOP_BOTTOM, backgroundDrawableColors);
395 backgroundDirty = true;
396 } else {
397 if (backgroundDrawableColors[0] != top) {
398 backgroundDrawableColors[0] = top;
399 backgroundDirty = true;
400 }
401 if (backgroundDrawableColors[1] != middle) {
402 backgroundDrawableColors[1] = middle;
403 backgroundDirty = true;
404 }
405 if (backgroundDrawableColors[2] != bottom) {
406 backgroundDrawableColors[2] = bottom;
407 backgroundDirty = true;
408 }
409 if (backgroundDirty) {
410 backgroundDrawable.setColors(backgroundDrawableColors);
411 }
412 }
413
414 if (backgroundDirty) {
415 getWindow().setBackgroundDrawable(backgroundDrawable);
416 }
417 }
418
419 public boolean isVisible() {
420 return isVisible;
421 }
422
423 public boolean getCallCardFragmentVisible() {
424 return didShowInCallScreen || didShowVideoCallScreen;
425 }
426
427 public void dismissKeyguard(boolean dismiss) {
linyuh9c327da2017-11-14 12:33:48 -0800428 if (dismissKeyguard == dismiss) {
429 return;
430 }
431
432 dismissKeyguard = dismiss;
433 if (dismiss) {
434 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
435 } else {
436 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
437 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800438 }
439
440 public void showPostCharWaitDialog(String callId, String chars) {
441 common.showPostCharWaitDialog(callId, chars);
442 }
443
Eric Erfanian2ca43182017-08-31 06:57:16 -0700444 public void maybeShowErrorDialogOnDisconnect(DisconnectMessage disconnectMessage) {
445 common.maybeShowErrorDialogOnDisconnect(disconnectMessage);
Eric Erfanianccca3152017-02-22 16:32:36 -0800446 }
447
448 public void dismissPendingDialogs() {
linyuhf99f6302017-11-15 11:23:51 -0800449 LogUtil.i("InCallActivity.dismissPendingDialogs", "");
450
451 if (!isVisible) {
452 // Defer the dismissing action as the activity is not visible and onSaveInstanceState may have
453 // been called.
Eric Erfanianccca3152017-02-22 16:32:36 -0800454 LogUtil.i(
455 "InCallActivity.dismissPendingDialogs", "defer actions since activity is not visible");
456 needDismissPendingDialogs = true;
linyuhf99f6302017-11-15 11:23:51 -0800457 return;
Eric Erfanianccca3152017-02-22 16:32:36 -0800458 }
linyuhf99f6302017-11-15 11:23:51 -0800459
460 // Dismiss the error dialog
461 Dialog errorDialog = common.getErrorDialog();
462 if (errorDialog != null) {
463 errorDialog.dismiss();
464 common.setErrorDialog(null);
465 }
466
467 // Dismiss the phone account selection dialog
468 SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment =
469 common.getSelectPhoneAccountDialogFragment();
470 if (selectPhoneAccountDialogFragment != null) {
471 selectPhoneAccountDialogFragment.dismiss();
472 common.setSelectPhoneAccountDialogFragment(null);
473 }
474
475 // Dismiss the dialog for international call on WiFi
476 InternationalCallOnWifiDialogFragment internationalCallOnWifiFragment =
477 (InternationalCallOnWifiDialogFragment)
478 getSupportFragmentManager().findFragmentByTag(TAG_INTERNATIONAL_CALL_ON_WIFI);
479 if (internationalCallOnWifiFragment != null) {
480 internationalCallOnWifiFragment.dismiss();
481 }
482
483 // Dismiss the answer screen
484 AnswerScreen answerScreen = getAnswerScreen();
485 if (answerScreen != null) {
486 answerScreen.dismissPendingDialogs();
487 }
488
489 needDismissPendingDialogs = false;
Eric Erfanianccca3152017-02-22 16:32:36 -0800490 }
491
492 private void enableInCallOrientationEventListener(boolean enable) {
493 common.enableInCallOrientationEventListener(enable);
494 }
495
496 public void setExcludeFromRecents(boolean exclude) {
497 common.setExcludeFromRecents(exclude);
498 }
499
Eric Erfanianccca3152017-02-22 16:32:36 -0800500 @Nullable
501 public FragmentManager getDialpadFragmentManager() {
502 InCallScreen inCallScreen = getInCallScreen();
503 if (inCallScreen != null) {
504 return inCallScreen.getInCallScreenFragment().getChildFragmentManager();
505 }
506 return null;
507 }
508
509 public int getDialpadContainerId() {
510 return getInCallScreen().getAnswerAndDialpadContainerResourceId();
511 }
512
513 @Override
514 public AnswerScreenDelegate newAnswerScreenDelegate(AnswerScreen answerScreen) {
515 DialerCall call = CallList.getInstance().getCallById(answerScreen.getCallId());
516 if (call == null) {
517 // This is a work around for a bug where we attempt to create a new delegate after the call
518 // has already been removed. An example of when this can happen is:
519 // 1. incoming video call in landscape mode
520 // 2. remote party hangs up
521 // 3. activity switches from landscape to portrait
522 // At step #3 the answer fragment will try to create a new answer delegate but the call won't
523 // exist. In this case we'll simply return a stub delegate that does nothing. This is ok
524 // because this new state is transient and the activity will be destroyed soon.
525 LogUtil.i("InCallActivity.onPrimaryCallStateChanged", "call doesn't exist, using stub");
526 return new AnswerScreenPresenterStub();
527 } else {
528 return new AnswerScreenPresenter(
529 this, answerScreen, CallList.getInstance().getCallById(answerScreen.getCallId()));
530 }
531 }
532
533 @Override
534 public InCallScreenDelegate newInCallScreenDelegate() {
535 return new CallCardPresenter(this);
536 }
537
538 @Override
539 public InCallButtonUiDelegate newInCallButtonUiDelegate() {
540 return new CallButtonPresenter(this);
541 }
542
543 @Override
Eric Erfanian90508232017-03-24 09:31:16 -0700544 public VideoCallScreenDelegate newVideoCallScreenDelegate(VideoCallScreen videoCallScreen) {
545 DialerCall dialerCall = CallList.getInstance().getCallById(videoCallScreen.getCallId());
546 if (dialerCall != null && dialerCall.getVideoTech().shouldUseSurfaceView()) {
547 return dialerCall.getVideoTech().createVideoCallScreenDelegate(this, videoCallScreen);
548 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800549 return new VideoCallPresenter();
550 }
551
552 public void onPrimaryCallStateChanged() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700553 Trace.beginSection("InCallActivity.onPrimaryCallStateChanged");
Eric Erfanianccca3152017-02-22 16:32:36 -0800554 LogUtil.i("InCallActivity.onPrimaryCallStateChanged", "");
555 showMainInCallFragment();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700556 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800557 }
558
559 public void onWiFiToLteHandover(DialerCall call) {
560 common.showWifiToLteHandoverToast(call);
561 }
562
563 public void onHandoverToWifiFailed(DialerCall call) {
564 common.showWifiFailedDialog(call);
565 }
566
Eric Erfanianc857f902017-05-15 14:05:33 -0700567 public void onInternationalCallOnWifi(@NonNull DialerCall call) {
568 LogUtil.enterBlock("InCallActivity.onInternationalCallOnWifi");
569 common.showInternationalCallOnWifiDialog(call);
570 }
571
Eric Erfanian938468d2017-10-24 14:05:52 -0700572 @Override
573 public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
574 super.onMultiWindowModeChanged(isInMultiWindowMode);
575 if (!isInMultiWindowMode) {
576 common.updateNavigationBar(isDialpadVisible());
577 }
578 }
579
Eric Erfanianccca3152017-02-22 16:32:36 -0800580 public void setAllowOrientationChange(boolean allowOrientationChange) {
wangqi9982f0d2017-10-11 17:46:07 -0700581 if (this.allowOrientationChange == allowOrientationChange) {
582 return;
583 }
584 this.allowOrientationChange = allowOrientationChange;
Eric Erfanianccca3152017-02-22 16:32:36 -0800585 if (!allowOrientationChange) {
586 setRequestedOrientation(InCallOrientationEventListener.ACTIVITY_PREFERENCE_DISALLOW_ROTATION);
587 } else {
588 setRequestedOrientation(InCallOrientationEventListener.ACTIVITY_PREFERENCE_ALLOW_ROTATION);
589 }
590 enableInCallOrientationEventListener(allowOrientationChange);
591 }
592
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700593 public void hideMainInCallFragment() {
Eric Erfanianccca3152017-02-22 16:32:36 -0800594 LogUtil.i("InCallActivity.hideMainInCallFragment", "");
595 if (didShowInCallScreen || didShowVideoCallScreen) {
596 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
597 hideInCallScreenFragment(transaction);
598 hideVideoCallScreenFragment(transaction);
599 transaction.commitAllowingStateLoss();
600 getSupportFragmentManager().executePendingTransactions();
601 }
602 }
603
604 private void showMainInCallFragment() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700605 Trace.beginSection("InCallActivity.showMainInCallFragment");
Eric Erfanianccca3152017-02-22 16:32:36 -0800606 // If the activity's onStart method hasn't been called yet then defer doing any work.
607 if (!isVisible) {
608 LogUtil.i("InCallActivity.showMainInCallFragment", "not visible yet/anymore");
Eric Erfanian2ca43182017-08-31 06:57:16 -0700609 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800610 return;
611 }
612
613 // Don't let this be reentrant.
614 if (isInShowMainInCallFragment) {
615 LogUtil.i("InCallActivity.showMainInCallFragment", "already in method, bailing");
Eric Erfanian2ca43182017-08-31 06:57:16 -0700616 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800617 return;
618 }
619
620 isInShowMainInCallFragment = true;
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700621 ShouldShowUiResult shouldShowAnswerUi = getShouldShowAnswerUi();
622 ShouldShowUiResult shouldShowVideoUi = getShouldShowVideoUi();
Eric Erfanianccca3152017-02-22 16:32:36 -0800623 LogUtil.i(
624 "InCallActivity.showMainInCallFragment",
625 "shouldShowAnswerUi: %b, shouldShowVideoUi: %b, "
626 + "didShowAnswerScreen: %b, didShowInCallScreen: %b, didShowVideoCallScreen: %b",
627 shouldShowAnswerUi.shouldShow,
Eric Erfanian10b34a52017-05-04 08:23:17 -0700628 shouldShowVideoUi.shouldShow,
Eric Erfanianccca3152017-02-22 16:32:36 -0800629 didShowAnswerScreen,
630 didShowInCallScreen,
631 didShowVideoCallScreen);
632 // Only video call ui allows orientation change.
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700633 setAllowOrientationChange(shouldShowVideoUi.shouldShow);
Eric Erfanianccca3152017-02-22 16:32:36 -0800634
635 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
636 boolean didChangeInCall;
637 boolean didChangeVideo;
638 boolean didChangeAnswer;
639 if (shouldShowAnswerUi.shouldShow) {
640 didChangeInCall = hideInCallScreenFragment(transaction);
641 didChangeVideo = hideVideoCallScreenFragment(transaction);
642 didChangeAnswer = showAnswerScreenFragment(transaction, shouldShowAnswerUi.call);
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700643 } else if (shouldShowVideoUi.shouldShow) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800644 didChangeInCall = hideInCallScreenFragment(transaction);
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700645 didChangeVideo = showVideoCallScreenFragment(transaction, shouldShowVideoUi.call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800646 didChangeAnswer = hideAnswerScreenFragment(transaction);
647 } else {
648 didChangeInCall = showInCallScreenFragment(transaction);
649 didChangeVideo = hideVideoCallScreenFragment(transaction);
650 didChangeAnswer = hideAnswerScreenFragment(transaction);
651 }
652
653 if (didChangeInCall || didChangeVideo || didChangeAnswer) {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700654 Trace.beginSection("InCallActivity.commitTransaction");
Eric Erfanianccca3152017-02-22 16:32:36 -0800655 transaction.commitNow();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700656 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800657 Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
658 }
659 isInShowMainInCallFragment = false;
Eric Erfanian2ca43182017-08-31 06:57:16 -0700660 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800661 }
662
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700663 private ShouldShowUiResult getShouldShowAnswerUi() {
Eric Erfanianccca3152017-02-22 16:32:36 -0800664 DialerCall call = CallList.getInstance().getIncomingCall();
665 if (call != null) {
666 LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found incoming call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700667 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800668 }
669
670 call = CallList.getInstance().getVideoUpgradeRequestCall();
671 if (call != null) {
672 LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found video upgrade request");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700673 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800674 }
675
676 // Check if we're showing the answer screen and the call is disconnected. If this condition is
677 // true then we won't switch from the answer UI to the in call UI. This prevents flicker when
678 // the user rejects an incoming call.
679 call = CallList.getInstance().getFirstCall();
680 if (call == null) {
681 call = CallList.getInstance().getBackgroundCall();
682 }
683 if (didShowAnswerScreen && (call == null || call.getState() == State.DISCONNECTED)) {
684 LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found disconnecting incoming call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700685 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800686 }
687
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700688 return new ShouldShowUiResult(false, null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800689 }
690
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700691 private static ShouldShowUiResult getShouldShowVideoUi() {
Eric Erfanianccca3152017-02-22 16:32:36 -0800692 DialerCall call = CallList.getInstance().getFirstCall();
693 if (call == null) {
694 LogUtil.i("InCallActivity.getShouldShowVideoUi", "null call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700695 return new ShouldShowUiResult(false, null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800696 }
697
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700698 if (call.isVideoCall()) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800699 LogUtil.i("InCallActivity.getShouldShowVideoUi", "found video call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700700 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800701 }
702
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700703 if (call.hasSentVideoUpgradeRequest()) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800704 LogUtil.i("InCallActivity.getShouldShowVideoUi", "upgrading to video");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700705 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800706 }
707
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700708 return new ShouldShowUiResult(false, null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800709 }
710
711 private boolean showAnswerScreenFragment(FragmentTransaction transaction, DialerCall call) {
712 // When rejecting a call the active call can become null in which case we should continue
713 // showing the answer screen.
714 if (didShowAnswerScreen && call == null) {
715 return false;
716 }
717
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700718 Assert.checkArgument(call != null, "didShowAnswerScreen was false but call was still null");
719
720 boolean isVideoUpgradeRequest = call.hasReceivedVideoUpgradeRequest();
Eric Erfanianccca3152017-02-22 16:32:36 -0800721
722 // Check if we're already showing an answer screen for this call.
723 if (didShowAnswerScreen) {
724 AnswerScreen answerScreen = getAnswerScreen();
725 if (answerScreen.getCallId().equals(call.getId())
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700726 && answerScreen.isVideoCall() == call.isVideoCall()
Eric Erfanian2ca43182017-08-31 06:57:16 -0700727 && answerScreen.isVideoUpgradeRequest() == isVideoUpgradeRequest
728 && !answerScreen.isActionTimeout()) {
729 LogUtil.d(
730 "InCallActivity.showAnswerScreenFragment",
731 "answer fragment exists for same call and has NOT been accepted/rejected/timed out");
Eric Erfanianccca3152017-02-22 16:32:36 -0800732 return false;
733 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700734 if (answerScreen.isActionTimeout()) {
735 LogUtil.i(
736 "InCallActivity.showAnswerScreenFragment",
737 "answer fragment exists but has been accepted/rejected and timed out");
738 } else {
739 LogUtil.i(
740 "InCallActivity.showAnswerScreenFragment",
741 "answer fragment exists but arguments do not match");
742 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800743 hideAnswerScreenFragment(transaction);
744 }
745
746 // Show a new answer screen.
747 AnswerScreen answerScreen =
Eric Erfanianfc37b022017-03-21 10:11:17 -0700748 AnswerBindings.createAnswerScreen(
749 call.getId(),
750 call.isVideoCall(),
751 isVideoUpgradeRequest,
Eric Erfanian90508232017-03-24 09:31:16 -0700752 call.getVideoTech().isSelfManagedCamera(),
753 shouldAllowAnswerAndRelease(call),
754 CallList.getInstance().getBackgroundCall() != null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800755 transaction.add(R.id.main, answerScreen.getAnswerScreenFragment(), TAG_ANSWER_SCREEN);
756
757 Logger.get(this).logScreenView(ScreenEvent.Type.INCOMING_CALL, this);
758 didShowAnswerScreen = true;
759 return true;
760 }
761
Eric Erfanian90508232017-03-24 09:31:16 -0700762 private boolean shouldAllowAnswerAndRelease(DialerCall call) {
763 if (CallList.getInstance().getActiveCall() == null) {
764 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "no active call");
765 return false;
766 }
767 if (getSystemService(TelephonyManager.class).getPhoneType()
768 == TelephonyManager.PHONE_TYPE_CDMA) {
769 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "PHONE_TYPE_CDMA not supported");
770 return false;
771 }
772 if (call.isVideoCall() || call.hasReceivedVideoUpgradeRequest()) {
773 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "video call");
774 return false;
775 }
776 if (!ConfigProviderBindings.get(this).getBoolean(CONFIG_ANSWER_AND_RELEASE_ENABLED, true)) {
777 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "disabled by config");
778 return false;
779 }
780
781 return true;
782 }
783
Eric Erfanianccca3152017-02-22 16:32:36 -0800784 private boolean hideAnswerScreenFragment(FragmentTransaction transaction) {
785 if (!didShowAnswerScreen) {
786 return false;
787 }
788 AnswerScreen answerScreen = getAnswerScreen();
789 if (answerScreen != null) {
790 transaction.remove(answerScreen.getAnswerScreenFragment());
791 }
792
793 didShowAnswerScreen = false;
794 return true;
795 }
796
797 private boolean showInCallScreenFragment(FragmentTransaction transaction) {
798 if (didShowInCallScreen) {
799 return false;
800 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700801 InCallScreen inCallScreen = InCallBindings.createInCallScreen();
802 transaction.add(R.id.main, inCallScreen.getInCallScreenFragment(), TAG_IN_CALL_SCREEN);
Eric Erfanianccca3152017-02-22 16:32:36 -0800803 Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
804 didShowInCallScreen = true;
805 return true;
806 }
807
808 private boolean hideInCallScreenFragment(FragmentTransaction transaction) {
809 if (!didShowInCallScreen) {
810 return false;
811 }
812 InCallScreen inCallScreen = getInCallScreen();
813 if (inCallScreen != null) {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700814 transaction.remove(inCallScreen.getInCallScreenFragment());
Eric Erfanianccca3152017-02-22 16:32:36 -0800815 }
816 didShowInCallScreen = false;
817 return true;
818 }
819
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700820 private boolean showVideoCallScreenFragment(FragmentTransaction transaction, DialerCall call) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800821 if (didShowVideoCallScreen) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700822 VideoCallScreen videoCallScreen = getVideoCallScreen();
823 if (videoCallScreen.getCallId().equals(call.getId())) {
824 return false;
825 }
826 LogUtil.i(
827 "InCallActivity.showVideoCallScreenFragment",
828 "video call fragment exists but arguments do not match");
829 hideVideoCallScreenFragment(transaction);
Eric Erfanianccca3152017-02-22 16:32:36 -0800830 }
831
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700832 LogUtil.i("InCallActivity.showVideoCallScreenFragment", "call: %s", call);
833
Eric Erfanian90508232017-03-24 09:31:16 -0700834 VideoCallScreen videoCallScreen =
835 VideoBindings.createVideoCallScreen(
836 call.getId(), call.getVideoTech().shouldUseSurfaceView());
Eric Erfanianccca3152017-02-22 16:32:36 -0800837 transaction.add(R.id.main, videoCallScreen.getVideoCallScreenFragment(), TAG_VIDEO_CALL_SCREEN);
838
839 Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
840 didShowVideoCallScreen = true;
841 return true;
842 }
843
844 private boolean hideVideoCallScreenFragment(FragmentTransaction transaction) {
845 if (!didShowVideoCallScreen) {
846 return false;
847 }
848 VideoCallScreen videoCallScreen = getVideoCallScreen();
849 if (videoCallScreen != null) {
850 transaction.remove(videoCallScreen.getVideoCallScreenFragment());
851 }
852 didShowVideoCallScreen = false;
853 return true;
854 }
855
856 AnswerScreen getAnswerScreen() {
857 return (AnswerScreen) getSupportFragmentManager().findFragmentByTag(TAG_ANSWER_SCREEN);
858 }
859
860 InCallScreen getInCallScreen() {
861 return (InCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_IN_CALL_SCREEN);
862 }
863
864 VideoCallScreen getVideoCallScreen() {
865 return (VideoCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_VIDEO_CALL_SCREEN);
866 }
867
868 @Override
869 public void onPseudoScreenStateChanged(boolean isOn) {
870 LogUtil.i("InCallActivity.onPseudoScreenStateChanged", "isOn: " + isOn);
871 pseudoBlackScreenOverlay.setVisibility(isOn ? View.GONE : View.VISIBLE);
872 }
873
874 /**
875 * For some touch related issue, turning off the screen can be faked by drawing a black view over
876 * the activity. All touch events started when the screen is "off" is rejected.
877 *
878 * @see PseudoScreenState
879 */
880 @Override
881 public boolean dispatchTouchEvent(MotionEvent event) {
882 // Reject any gesture that started when the screen is in the fake off state.
883 if (touchDownWhenPseudoScreenOff) {
884 if (event.getAction() == MotionEvent.ACTION_UP) {
885 touchDownWhenPseudoScreenOff = false;
886 }
887 return true;
888 }
889 // Reject all touch event when the screen is in the fake off state.
890 if (!InCallPresenter.getInstance().getPseudoScreenState().isOn()) {
891 if (event.getAction() == MotionEvent.ACTION_DOWN) {
892 touchDownWhenPseudoScreenOff = true;
893 LogUtil.i("InCallActivity.dispatchTouchEvent", "touchDownWhenPseudoScreenOff");
894 }
895 return true;
896 }
897 return super.dispatchTouchEvent(event);
898 }
899
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700900 private static class ShouldShowUiResult {
Eric Erfanianccca3152017-02-22 16:32:36 -0800901 public final boolean shouldShow;
902 public final DialerCall call;
903
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700904 ShouldShowUiResult(boolean shouldShow, DialerCall call) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800905 this.shouldShow = shouldShow;
906 this.call = call;
907 }
908 }
909}