blob: a55770c410cd9d5e03f5f3ff585bc97c35c68732 [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";
linyuh69a25062017-11-15 16:18:51 -080084 private static final String TAG_DIALPAD_FRAGMENT = "tag_dialpad_fragment";
linyuhf99f6302017-11-15 11:23:51 -080085 private static final String TAG_INTERNATIONAL_CALL_ON_WIFI = "tag_international_call_on_wifi";
86 private static final String TAG_IN_CALL_SCREEN = "tag_in_call_screen";
Eric Erfanianccca3152017-02-22 16:32:36 -080087 private static final String TAG_VIDEO_CALL_SCREEN = "tag_video_call_screen";
88
89 private static final String DID_SHOW_ANSWER_SCREEN_KEY = "did_show_answer_screen";
90 private static final String DID_SHOW_IN_CALL_SCREEN_KEY = "did_show_in_call_screen";
91 private static final String DID_SHOW_VIDEO_CALL_SCREEN_KEY = "did_show_video_call_screen";
92
Eric Erfanian90508232017-03-24 09:31:16 -070093 private static final String CONFIG_ANSWER_AND_RELEASE_ENABLED = "answer_and_release_enabled";
94
Eric Erfanianccca3152017-02-22 16:32:36 -080095 private final InCallActivityCommon common;
linyuh69a25062017-11-15 16:18:51 -080096 private InCallOrientationEventListener inCallOrientationEventListener;
Eric Erfanianccca3152017-02-22 16:32:36 -080097 private boolean didShowAnswerScreen;
98 private boolean didShowInCallScreen;
99 private boolean didShowVideoCallScreen;
linyuh9c327da2017-11-14 12:33:48 -0800100 private boolean dismissKeyguard;
Eric Erfanianccca3152017-02-22 16:32:36 -0800101 private int[] backgroundDrawableColors;
102 private GradientDrawable backgroundDrawable;
103 private boolean isVisible;
104 private View pseudoBlackScreenOverlay;
105 private boolean touchDownWhenPseudoScreenOff;
106 private boolean isInShowMainInCallFragment;
107 private boolean needDismissPendingDialogs;
wangqi9982f0d2017-10-11 17:46:07 -0700108 private boolean allowOrientationChange;
Eric Erfanianccca3152017-02-22 16:32:36 -0800109
110 public InCallActivity() {
111 common = new InCallActivityCommon(this);
112 }
113
114 public static Intent getIntent(
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700115 Context context, boolean showDialpad, boolean newOutgoingCall, boolean isForFullScreen) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800116 Intent intent = new Intent(Intent.ACTION_MAIN, null);
117 intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
118 intent.setClass(context, InCallActivity.class);
119 InCallActivityCommon.setIntentExtras(intent, showDialpad, newOutgoingCall, isForFullScreen);
120 return intent;
121 }
122
123 @Override
124 protected void onResumeFragments() {
125 super.onResumeFragments();
126 if (needDismissPendingDialogs) {
127 dismissPendingDialogs();
128 }
129 }
130
131 @Override
132 protected void onCreate(Bundle icicle) {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700133 Trace.beginSection("InCallActivity.onCreate");
Eric Erfanianccca3152017-02-22 16:32:36 -0800134 LogUtil.i("InCallActivity.onCreate", "");
135 super.onCreate(icicle);
136
Eric Erfanian2ca43182017-08-31 06:57:16 -0700137 if (getIntent().getBooleanExtra(ReturnToCallController.RETURN_TO_CALL_EXTRA_KEY, false)) {
138 Logger.get(this).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_RETURN_TO_CALL);
139 getIntent().removeExtra(ReturnToCallController.RETURN_TO_CALL_EXTRA_KEY);
140 }
141
Eric Erfanianccca3152017-02-22 16:32:36 -0800142 if (icicle != null) {
143 didShowAnswerScreen = icicle.getBoolean(DID_SHOW_ANSWER_SCREEN_KEY);
144 didShowInCallScreen = icicle.getBoolean(DID_SHOW_IN_CALL_SCREEN_KEY);
145 didShowVideoCallScreen = icicle.getBoolean(DID_SHOW_VIDEO_CALL_SCREEN_KEY);
146 }
147
148 common.onCreate(icicle);
linyuh69a25062017-11-15 16:18:51 -0800149 inCallOrientationEventListener = new InCallOrientationEventListener(this);
Eric Erfanianccca3152017-02-22 16:32:36 -0800150
151 getWindow()
152 .getDecorView()
153 .setSystemUiVisibility(
154 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
155
156 pseudoBlackScreenOverlay = findViewById(R.id.psuedo_black_screen_overlay);
Eric Erfanian2ca43182017-08-31 06:57:16 -0700157 sendBroadcast(CallPendingActivity.getFinishBroadcast());
158 Trace.endSection();
weijiaxuc950a9b2017-11-06 16:39:04 -0800159 Logger.get(this)
160 .logStopLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_INCOMING);
161 Logger.get(this)
162 .logStopLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_OUTGOING);
Eric Erfanianccca3152017-02-22 16:32:36 -0800163 }
164
165 @Override
166 protected void onSaveInstanceState(Bundle out) {
167 LogUtil.i("InCallActivity.onSaveInstanceState", "");
168 common.onSaveInstanceState(out);
169 out.putBoolean(DID_SHOW_ANSWER_SCREEN_KEY, didShowAnswerScreen);
170 out.putBoolean(DID_SHOW_IN_CALL_SCREEN_KEY, didShowInCallScreen);
171 out.putBoolean(DID_SHOW_VIDEO_CALL_SCREEN_KEY, didShowVideoCallScreen);
172 super.onSaveInstanceState(out);
173 isVisible = false;
174 }
175
176 @Override
177 protected void onStart() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700178 Trace.beginSection("InCallActivity.onStart");
Eric Erfanianccca3152017-02-22 16:32:36 -0800179 LogUtil.i("InCallActivity.onStart", "");
wangqi9982f0d2017-10-11 17:46:07 -0700180 Trace.beginSection("call super");
Eric Erfanianccca3152017-02-22 16:32:36 -0800181 super.onStart();
wangqi9982f0d2017-10-11 17:46:07 -0700182 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800183 isVisible = true;
184 showMainInCallFragment();
185 common.onStart();
186 if (ActivityCompat.isInMultiWindowMode(this)
187 && !getResources().getBoolean(R.bool.incall_dialpad_allowed)) {
188 // Hide the dialpad because there may not be enough room
189 showDialpadFragment(false, false);
190 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700191 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800192 }
193
194 @Override
195 protected void onResume() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700196 Trace.beginSection("InCallActivity.onResume");
Eric Erfanianccca3152017-02-22 16:32:36 -0800197 LogUtil.i("InCallActivity.onResume", "");
198 super.onResume();
199 common.onResume();
200 PseudoScreenState pseudoScreenState = InCallPresenter.getInstance().getPseudoScreenState();
201 pseudoScreenState.addListener(this);
202 onPseudoScreenStateChanged(pseudoScreenState.isOn());
Eric Erfanian2ca43182017-08-31 06:57:16 -0700203 Trace.endSection();
weijiaxu650e7cc2017-10-31 12:38:54 -0700204 // add 1 sec delay to get memory snapshot so that dialer wont react slowly on resume.
205 ThreadUtil.postDelayedOnUiThread(
weijiaxuc950a9b2017-11-06 16:39:04 -0800206 () ->
207 Logger.get(this)
208 .logRecordMemory(LoggingBindings.INCALL_ACTIVITY_ON_RESUME_MEMORY_EVENT_NAME),
weijiaxu650e7cc2017-10-31 12:38:54 -0700209 1000);
Eric Erfanianccca3152017-02-22 16:32:36 -0800210 }
211
212 /** onPause is guaranteed to be called when the InCallActivity goes in the background. */
213 @Override
214 protected void onPause() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700215 Trace.beginSection("InCallActivity.onPause");
Eric Erfanianccca3152017-02-22 16:32:36 -0800216 LogUtil.i("InCallActivity.onPause", "");
217 super.onPause();
218 common.onPause();
219 InCallPresenter.getInstance().getPseudoScreenState().removeListener(this);
Eric Erfanian2ca43182017-08-31 06:57:16 -0700220 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800221 }
222
223 @Override
224 protected void onStop() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700225 Trace.beginSection("InCallActivity.onStop");
Eric Erfanianccca3152017-02-22 16:32:36 -0800226 LogUtil.i("InCallActivity.onStop", "");
wangqi4d705e52017-09-28 12:23:35 -0700227 isVisible = false;
Eric Erfanianccca3152017-02-22 16:32:36 -0800228 super.onStop();
229 common.onStop();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700230 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800231 }
232
233 @Override
234 protected void onDestroy() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700235 Trace.beginSection("InCallActivity.onDestroy");
Eric Erfanianccca3152017-02-22 16:32:36 -0800236 LogUtil.i("InCallActivity.onDestroy", "");
237 super.onDestroy();
238 common.onDestroy();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700239 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800240 }
241
242 @Override
243 public void finish() {
244 if (shouldCloseActivityOnFinish()) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700245 // When user select incall ui from recents after the call is disconnected, it tries to launch
246 // a new InCallActivity but InCallPresenter is already teared down at this point, which causes
247 // crash.
248 // By calling finishAndRemoveTask() instead of finish() the task associated with
249 // InCallActivity is cleared completely. So system won't try to create a new InCallActivity in
250 // this case.
251 //
252 // Calling finish won't clear the task and normally when an activity finishes it shouldn't
253 // clear the task since there could be parent activity in the same task that's still alive.
254 // But InCallActivity is special since it's singleInstance which means it's root activity and
255 // only instance of activity in the task. So it should be safe to also remove task when
256 // finishing.
257 // It's also necessary in the sense of it's excluded from recents. So whenever the activity
258 // finishes, the task should also be removed since it doesn't make sense to go back to it in
259 // anyway anymore.
260 super.finishAndRemoveTask();
Eric Erfanianccca3152017-02-22 16:32:36 -0800261 }
262 }
263
264 private boolean shouldCloseActivityOnFinish() {
265 if (!isVisible()) {
266 LogUtil.i(
267 "InCallActivity.shouldCloseActivityOnFinish",
268 "allowing activity to be closed because it's not visible");
269 return true;
270 }
271
twyen8efb4952017-10-06 16:35:54 -0700272 if (InCallPresenter.getInstance().isInCallUiLocked()) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800273 LogUtil.i(
274 "InCallActivity.shouldCloseActivityOnFinish",
twyen8efb4952017-10-06 16:35:54 -0700275 "in call ui is locked, not closing activity");
Eric Erfanianccca3152017-02-22 16:32:36 -0800276 return false;
277 }
278
279 LogUtil.i(
280 "InCallActivity.shouldCloseActivityOnFinish",
twyen8efb4952017-10-06 16:35:54 -0700281 "activity is visible and has no locks, allowing activity to close");
Eric Erfanianccca3152017-02-22 16:32:36 -0800282 return true;
283 }
284
285 @Override
286 protected void onNewIntent(Intent intent) {
287 LogUtil.i("InCallActivity.onNewIntent", "");
Eric Erfanianccca3152017-02-22 16:32:36 -0800288
289 // If the screen is off, we need to make sure it gets turned on for incoming calls.
290 // This normally works just fine thanks to FLAG_TURN_SCREEN_ON but that only works
291 // when the activity is first created. Therefore, to ensure the screen is turned on
292 // for the call waiting case, we recreate() the current activity. There should be no jank from
293 // this since the screen is already off and will remain so until our new activity is up.
294 if (!isVisible()) {
Eric Erfanian10b34a52017-05-04 08:23:17 -0700295 common.onNewIntent(intent, true /* isRecreating */);
Eric Erfanianccca3152017-02-22 16:32:36 -0800296 LogUtil.i("InCallActivity.onNewIntent", "Restarting InCallActivity to force screen on.");
297 recreate();
Eric Erfanian10b34a52017-05-04 08:23:17 -0700298 } else {
299 common.onNewIntent(intent, false /* isRecreating */);
Eric Erfanianccca3152017-02-22 16:32:36 -0800300 }
301 }
302
303 @Override
304 public void onBackPressed() {
305 LogUtil.i("InCallActivity.onBackPressed", "");
306 if (!common.onBackPressed(didShowInCallScreen || didShowVideoCallScreen)) {
307 super.onBackPressed();
308 }
309 }
310
311 @Override
312 public boolean onOptionsItemSelected(MenuItem item) {
313 LogUtil.i("InCallActivity.onOptionsItemSelected", "item: " + item);
314 if (item.getItemId() == android.R.id.home) {
315 onBackPressed();
316 return true;
317 }
318 return super.onOptionsItemSelected(item);
319 }
320
321 @Override
322 public boolean onKeyUp(int keyCode, KeyEvent event) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700323 return common.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
Eric Erfanianccca3152017-02-22 16:32:36 -0800324 }
325
326 @Override
327 public boolean onKeyDown(int keyCode, KeyEvent event) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700328 return common.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
Eric Erfanianccca3152017-02-22 16:32:36 -0800329 }
330
331 public boolean isInCallScreenAnimating() {
332 return false;
333 }
334
335 public void showConferenceFragment(boolean show) {
336 if (show) {
337 startActivity(new Intent(this, ManageConferenceActivity.class));
338 }
339 }
340
341 public boolean showDialpadFragment(boolean show, boolean animate) {
342 boolean didChange = common.showDialpadFragment(show, animate);
343 if (didChange) {
344 // Note: onInCallScreenDialpadVisibilityChange is called here to ensure that the dialpad FAB
345 // repositions itself.
346 getInCallScreen().onInCallScreenDialpadVisibilityChange(show);
347 }
348 return didChange;
349 }
350
351 public boolean isDialpadVisible() {
linyuh69a25062017-11-15 16:18:51 -0800352 DialpadFragment dialpadFragment = getDialpadFragment();
353 return dialpadFragment != null && dialpadFragment.isVisible();
354 }
355
356 /**
357 * Returns the {@link DialpadFragment} that's shown by this activity, or {@code null}
358 * TODO(a bug): Make this method private after InCallActivityCommon is deleted.
359 */
360 @Nullable
361 DialpadFragment getDialpadFragment() {
362 FragmentManager fragmentManager = getDialpadFragmentManager();
363 if (fragmentManager == null) {
364 return null;
365 }
366 return (DialpadFragment) fragmentManager.findFragmentByTag(TAG_DIALPAD_FRAGMENT);
Eric Erfanianccca3152017-02-22 16:32:36 -0800367 }
368
369 public void onForegroundCallChanged(DialerCall newForegroundCall) {
370 common.updateTaskDescription();
371 if (didShowAnswerScreen && newForegroundCall != null) {
372 if (newForegroundCall.getState() == State.DISCONNECTED
373 || newForegroundCall.getState() == State.IDLE) {
374 LogUtil.i(
375 "InCallActivity.onForegroundCallChanged",
376 "rejecting incoming call, not updating " + "window background color");
377 }
378 } else {
379 LogUtil.v("InCallActivity.onForegroundCallChanged", "resetting background color");
380 updateWindowBackgroundColor(0);
381 }
382 }
383
384 public void updateWindowBackgroundColor(@FloatRange(from = -1f, to = 1.0f) float progress) {
385 ThemeColorManager themeColorManager = InCallPresenter.getInstance().getThemeColorManager();
386 @ColorInt int top;
387 @ColorInt int middle;
388 @ColorInt int bottom;
389 @ColorInt int gray = 0x66000000;
390
391 if (ActivityCompat.isInMultiWindowMode(this)) {
392 top = themeColorManager.getBackgroundColorSolid();
393 middle = themeColorManager.getBackgroundColorSolid();
394 bottom = themeColorManager.getBackgroundColorSolid();
395 } else {
396 top = themeColorManager.getBackgroundColorTop();
397 middle = themeColorManager.getBackgroundColorMiddle();
398 bottom = themeColorManager.getBackgroundColorBottom();
399 }
400
401 if (progress < 0) {
402 float correctedProgress = Math.abs(progress);
403 top = ColorUtils.blendARGB(top, gray, correctedProgress);
404 middle = ColorUtils.blendARGB(middle, gray, correctedProgress);
405 bottom = ColorUtils.blendARGB(bottom, gray, correctedProgress);
406 }
407
408 boolean backgroundDirty = false;
409 if (backgroundDrawable == null) {
410 backgroundDrawableColors = new int[] {top, middle, bottom};
411 backgroundDrawable = new GradientDrawable(Orientation.TOP_BOTTOM, backgroundDrawableColors);
412 backgroundDirty = true;
413 } else {
414 if (backgroundDrawableColors[0] != top) {
415 backgroundDrawableColors[0] = top;
416 backgroundDirty = true;
417 }
418 if (backgroundDrawableColors[1] != middle) {
419 backgroundDrawableColors[1] = middle;
420 backgroundDirty = true;
421 }
422 if (backgroundDrawableColors[2] != bottom) {
423 backgroundDrawableColors[2] = bottom;
424 backgroundDirty = true;
425 }
426 if (backgroundDirty) {
427 backgroundDrawable.setColors(backgroundDrawableColors);
428 }
429 }
430
431 if (backgroundDirty) {
432 getWindow().setBackgroundDrawable(backgroundDrawable);
433 }
434 }
435
436 public boolean isVisible() {
437 return isVisible;
438 }
439
440 public boolean getCallCardFragmentVisible() {
441 return didShowInCallScreen || didShowVideoCallScreen;
442 }
443
444 public void dismissKeyguard(boolean dismiss) {
linyuh9c327da2017-11-14 12:33:48 -0800445 if (dismissKeyguard == dismiss) {
446 return;
447 }
448
449 dismissKeyguard = dismiss;
450 if (dismiss) {
451 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
452 } else {
453 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
454 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800455 }
456
457 public void showPostCharWaitDialog(String callId, String chars) {
458 common.showPostCharWaitDialog(callId, chars);
459 }
460
Eric Erfanian2ca43182017-08-31 06:57:16 -0700461 public void maybeShowErrorDialogOnDisconnect(DisconnectMessage disconnectMessage) {
462 common.maybeShowErrorDialogOnDisconnect(disconnectMessage);
Eric Erfanianccca3152017-02-22 16:32:36 -0800463 }
464
465 public void dismissPendingDialogs() {
linyuhf99f6302017-11-15 11:23:51 -0800466 LogUtil.i("InCallActivity.dismissPendingDialogs", "");
467
468 if (!isVisible) {
469 // Defer the dismissing action as the activity is not visible and onSaveInstanceState may have
470 // been called.
Eric Erfanianccca3152017-02-22 16:32:36 -0800471 LogUtil.i(
472 "InCallActivity.dismissPendingDialogs", "defer actions since activity is not visible");
473 needDismissPendingDialogs = true;
linyuhf99f6302017-11-15 11:23:51 -0800474 return;
Eric Erfanianccca3152017-02-22 16:32:36 -0800475 }
linyuhf99f6302017-11-15 11:23:51 -0800476
477 // Dismiss the error dialog
478 Dialog errorDialog = common.getErrorDialog();
479 if (errorDialog != null) {
480 errorDialog.dismiss();
481 common.setErrorDialog(null);
482 }
483
484 // Dismiss the phone account selection dialog
485 SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment =
486 common.getSelectPhoneAccountDialogFragment();
487 if (selectPhoneAccountDialogFragment != null) {
488 selectPhoneAccountDialogFragment.dismiss();
489 common.setSelectPhoneAccountDialogFragment(null);
490 }
491
492 // Dismiss the dialog for international call on WiFi
493 InternationalCallOnWifiDialogFragment internationalCallOnWifiFragment =
494 (InternationalCallOnWifiDialogFragment)
495 getSupportFragmentManager().findFragmentByTag(TAG_INTERNATIONAL_CALL_ON_WIFI);
496 if (internationalCallOnWifiFragment != null) {
497 internationalCallOnWifiFragment.dismiss();
498 }
499
500 // Dismiss the answer screen
501 AnswerScreen answerScreen = getAnswerScreen();
502 if (answerScreen != null) {
503 answerScreen.dismissPendingDialogs();
504 }
505
506 needDismissPendingDialogs = false;
Eric Erfanianccca3152017-02-22 16:32:36 -0800507 }
508
linyuh69a25062017-11-15 16:18:51 -0800509 // TODO(a bug): Make this method private after InCallActivityCommon is deleted.
510 void enableInCallOrientationEventListener(boolean enable) {
511 if (enable) {
512 inCallOrientationEventListener.enable(true /* notifyDeviceOrientationChange */);
513 } else {
514 inCallOrientationEventListener.disable();
515 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800516 }
517
518 public void setExcludeFromRecents(boolean exclude) {
519 common.setExcludeFromRecents(exclude);
520 }
521
Eric Erfanianccca3152017-02-22 16:32:36 -0800522 @Nullable
523 public FragmentManager getDialpadFragmentManager() {
524 InCallScreen inCallScreen = getInCallScreen();
525 if (inCallScreen != null) {
526 return inCallScreen.getInCallScreenFragment().getChildFragmentManager();
527 }
528 return null;
529 }
530
531 public int getDialpadContainerId() {
532 return getInCallScreen().getAnswerAndDialpadContainerResourceId();
533 }
534
535 @Override
536 public AnswerScreenDelegate newAnswerScreenDelegate(AnswerScreen answerScreen) {
537 DialerCall call = CallList.getInstance().getCallById(answerScreen.getCallId());
538 if (call == null) {
539 // This is a work around for a bug where we attempt to create a new delegate after the call
540 // has already been removed. An example of when this can happen is:
541 // 1. incoming video call in landscape mode
542 // 2. remote party hangs up
543 // 3. activity switches from landscape to portrait
544 // At step #3 the answer fragment will try to create a new answer delegate but the call won't
545 // exist. In this case we'll simply return a stub delegate that does nothing. This is ok
546 // because this new state is transient and the activity will be destroyed soon.
547 LogUtil.i("InCallActivity.onPrimaryCallStateChanged", "call doesn't exist, using stub");
548 return new AnswerScreenPresenterStub();
549 } else {
550 return new AnswerScreenPresenter(
551 this, answerScreen, CallList.getInstance().getCallById(answerScreen.getCallId()));
552 }
553 }
554
555 @Override
556 public InCallScreenDelegate newInCallScreenDelegate() {
557 return new CallCardPresenter(this);
558 }
559
560 @Override
561 public InCallButtonUiDelegate newInCallButtonUiDelegate() {
562 return new CallButtonPresenter(this);
563 }
564
565 @Override
Eric Erfanian90508232017-03-24 09:31:16 -0700566 public VideoCallScreenDelegate newVideoCallScreenDelegate(VideoCallScreen videoCallScreen) {
567 DialerCall dialerCall = CallList.getInstance().getCallById(videoCallScreen.getCallId());
568 if (dialerCall != null && dialerCall.getVideoTech().shouldUseSurfaceView()) {
569 return dialerCall.getVideoTech().createVideoCallScreenDelegate(this, videoCallScreen);
570 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800571 return new VideoCallPresenter();
572 }
573
574 public void onPrimaryCallStateChanged() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700575 Trace.beginSection("InCallActivity.onPrimaryCallStateChanged");
Eric Erfanianccca3152017-02-22 16:32:36 -0800576 LogUtil.i("InCallActivity.onPrimaryCallStateChanged", "");
577 showMainInCallFragment();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700578 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800579 }
580
581 public void onWiFiToLteHandover(DialerCall call) {
582 common.showWifiToLteHandoverToast(call);
583 }
584
585 public void onHandoverToWifiFailed(DialerCall call) {
586 common.showWifiFailedDialog(call);
587 }
588
Eric Erfanianc857f902017-05-15 14:05:33 -0700589 public void onInternationalCallOnWifi(@NonNull DialerCall call) {
590 LogUtil.enterBlock("InCallActivity.onInternationalCallOnWifi");
591 common.showInternationalCallOnWifiDialog(call);
592 }
593
Eric Erfanian938468d2017-10-24 14:05:52 -0700594 @Override
595 public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
596 super.onMultiWindowModeChanged(isInMultiWindowMode);
597 if (!isInMultiWindowMode) {
598 common.updateNavigationBar(isDialpadVisible());
599 }
600 }
601
Eric Erfanianccca3152017-02-22 16:32:36 -0800602 public void setAllowOrientationChange(boolean allowOrientationChange) {
wangqi9982f0d2017-10-11 17:46:07 -0700603 if (this.allowOrientationChange == allowOrientationChange) {
604 return;
605 }
606 this.allowOrientationChange = allowOrientationChange;
Eric Erfanianccca3152017-02-22 16:32:36 -0800607 if (!allowOrientationChange) {
608 setRequestedOrientation(InCallOrientationEventListener.ACTIVITY_PREFERENCE_DISALLOW_ROTATION);
609 } else {
610 setRequestedOrientation(InCallOrientationEventListener.ACTIVITY_PREFERENCE_ALLOW_ROTATION);
611 }
612 enableInCallOrientationEventListener(allowOrientationChange);
613 }
614
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700615 public void hideMainInCallFragment() {
Eric Erfanianccca3152017-02-22 16:32:36 -0800616 LogUtil.i("InCallActivity.hideMainInCallFragment", "");
617 if (didShowInCallScreen || didShowVideoCallScreen) {
618 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
619 hideInCallScreenFragment(transaction);
620 hideVideoCallScreenFragment(transaction);
621 transaction.commitAllowingStateLoss();
622 getSupportFragmentManager().executePendingTransactions();
623 }
624 }
625
626 private void showMainInCallFragment() {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700627 Trace.beginSection("InCallActivity.showMainInCallFragment");
Eric Erfanianccca3152017-02-22 16:32:36 -0800628 // If the activity's onStart method hasn't been called yet then defer doing any work.
629 if (!isVisible) {
630 LogUtil.i("InCallActivity.showMainInCallFragment", "not visible yet/anymore");
Eric Erfanian2ca43182017-08-31 06:57:16 -0700631 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800632 return;
633 }
634
635 // Don't let this be reentrant.
636 if (isInShowMainInCallFragment) {
637 LogUtil.i("InCallActivity.showMainInCallFragment", "already in method, bailing");
Eric Erfanian2ca43182017-08-31 06:57:16 -0700638 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800639 return;
640 }
641
642 isInShowMainInCallFragment = true;
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700643 ShouldShowUiResult shouldShowAnswerUi = getShouldShowAnswerUi();
644 ShouldShowUiResult shouldShowVideoUi = getShouldShowVideoUi();
Eric Erfanianccca3152017-02-22 16:32:36 -0800645 LogUtil.i(
646 "InCallActivity.showMainInCallFragment",
647 "shouldShowAnswerUi: %b, shouldShowVideoUi: %b, "
648 + "didShowAnswerScreen: %b, didShowInCallScreen: %b, didShowVideoCallScreen: %b",
649 shouldShowAnswerUi.shouldShow,
Eric Erfanian10b34a52017-05-04 08:23:17 -0700650 shouldShowVideoUi.shouldShow,
Eric Erfanianccca3152017-02-22 16:32:36 -0800651 didShowAnswerScreen,
652 didShowInCallScreen,
653 didShowVideoCallScreen);
654 // Only video call ui allows orientation change.
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700655 setAllowOrientationChange(shouldShowVideoUi.shouldShow);
Eric Erfanianccca3152017-02-22 16:32:36 -0800656
657 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
658 boolean didChangeInCall;
659 boolean didChangeVideo;
660 boolean didChangeAnswer;
661 if (shouldShowAnswerUi.shouldShow) {
662 didChangeInCall = hideInCallScreenFragment(transaction);
663 didChangeVideo = hideVideoCallScreenFragment(transaction);
664 didChangeAnswer = showAnswerScreenFragment(transaction, shouldShowAnswerUi.call);
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700665 } else if (shouldShowVideoUi.shouldShow) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800666 didChangeInCall = hideInCallScreenFragment(transaction);
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700667 didChangeVideo = showVideoCallScreenFragment(transaction, shouldShowVideoUi.call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800668 didChangeAnswer = hideAnswerScreenFragment(transaction);
669 } else {
670 didChangeInCall = showInCallScreenFragment(transaction);
671 didChangeVideo = hideVideoCallScreenFragment(transaction);
672 didChangeAnswer = hideAnswerScreenFragment(transaction);
673 }
674
675 if (didChangeInCall || didChangeVideo || didChangeAnswer) {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700676 Trace.beginSection("InCallActivity.commitTransaction");
Eric Erfanianccca3152017-02-22 16:32:36 -0800677 transaction.commitNow();
Eric Erfanian2ca43182017-08-31 06:57:16 -0700678 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800679 Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
680 }
681 isInShowMainInCallFragment = false;
Eric Erfanian2ca43182017-08-31 06:57:16 -0700682 Trace.endSection();
Eric Erfanianccca3152017-02-22 16:32:36 -0800683 }
684
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700685 private ShouldShowUiResult getShouldShowAnswerUi() {
Eric Erfanianccca3152017-02-22 16:32:36 -0800686 DialerCall call = CallList.getInstance().getIncomingCall();
687 if (call != null) {
688 LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found incoming call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700689 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800690 }
691
692 call = CallList.getInstance().getVideoUpgradeRequestCall();
693 if (call != null) {
694 LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found video upgrade request");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700695 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800696 }
697
698 // Check if we're showing the answer screen and the call is disconnected. If this condition is
699 // true then we won't switch from the answer UI to the in call UI. This prevents flicker when
700 // the user rejects an incoming call.
701 call = CallList.getInstance().getFirstCall();
702 if (call == null) {
703 call = CallList.getInstance().getBackgroundCall();
704 }
705 if (didShowAnswerScreen && (call == null || call.getState() == State.DISCONNECTED)) {
706 LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found disconnecting incoming call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700707 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800708 }
709
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700710 return new ShouldShowUiResult(false, null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800711 }
712
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700713 private static ShouldShowUiResult getShouldShowVideoUi() {
Eric Erfanianccca3152017-02-22 16:32:36 -0800714 DialerCall call = CallList.getInstance().getFirstCall();
715 if (call == null) {
716 LogUtil.i("InCallActivity.getShouldShowVideoUi", "null call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700717 return new ShouldShowUiResult(false, null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800718 }
719
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700720 if (call.isVideoCall()) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800721 LogUtil.i("InCallActivity.getShouldShowVideoUi", "found video call");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700722 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800723 }
724
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700725 if (call.hasSentVideoUpgradeRequest()) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800726 LogUtil.i("InCallActivity.getShouldShowVideoUi", "upgrading to video");
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700727 return new ShouldShowUiResult(true, call);
Eric Erfanianccca3152017-02-22 16:32:36 -0800728 }
729
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700730 return new ShouldShowUiResult(false, null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800731 }
732
733 private boolean showAnswerScreenFragment(FragmentTransaction transaction, DialerCall call) {
734 // When rejecting a call the active call can become null in which case we should continue
735 // showing the answer screen.
736 if (didShowAnswerScreen && call == null) {
737 return false;
738 }
739
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700740 Assert.checkArgument(call != null, "didShowAnswerScreen was false but call was still null");
741
742 boolean isVideoUpgradeRequest = call.hasReceivedVideoUpgradeRequest();
Eric Erfanianccca3152017-02-22 16:32:36 -0800743
744 // Check if we're already showing an answer screen for this call.
745 if (didShowAnswerScreen) {
746 AnswerScreen answerScreen = getAnswerScreen();
747 if (answerScreen.getCallId().equals(call.getId())
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700748 && answerScreen.isVideoCall() == call.isVideoCall()
Eric Erfanian2ca43182017-08-31 06:57:16 -0700749 && answerScreen.isVideoUpgradeRequest() == isVideoUpgradeRequest
750 && !answerScreen.isActionTimeout()) {
751 LogUtil.d(
752 "InCallActivity.showAnswerScreenFragment",
753 "answer fragment exists for same call and has NOT been accepted/rejected/timed out");
Eric Erfanianccca3152017-02-22 16:32:36 -0800754 return false;
755 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700756 if (answerScreen.isActionTimeout()) {
757 LogUtil.i(
758 "InCallActivity.showAnswerScreenFragment",
759 "answer fragment exists but has been accepted/rejected and timed out");
760 } else {
761 LogUtil.i(
762 "InCallActivity.showAnswerScreenFragment",
763 "answer fragment exists but arguments do not match");
764 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800765 hideAnswerScreenFragment(transaction);
766 }
767
768 // Show a new answer screen.
769 AnswerScreen answerScreen =
Eric Erfanianfc37b022017-03-21 10:11:17 -0700770 AnswerBindings.createAnswerScreen(
771 call.getId(),
772 call.isVideoCall(),
773 isVideoUpgradeRequest,
Eric Erfanian90508232017-03-24 09:31:16 -0700774 call.getVideoTech().isSelfManagedCamera(),
775 shouldAllowAnswerAndRelease(call),
776 CallList.getInstance().getBackgroundCall() != null);
Eric Erfanianccca3152017-02-22 16:32:36 -0800777 transaction.add(R.id.main, answerScreen.getAnswerScreenFragment(), TAG_ANSWER_SCREEN);
778
779 Logger.get(this).logScreenView(ScreenEvent.Type.INCOMING_CALL, this);
780 didShowAnswerScreen = true;
781 return true;
782 }
783
Eric Erfanian90508232017-03-24 09:31:16 -0700784 private boolean shouldAllowAnswerAndRelease(DialerCall call) {
785 if (CallList.getInstance().getActiveCall() == null) {
786 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "no active call");
787 return false;
788 }
789 if (getSystemService(TelephonyManager.class).getPhoneType()
790 == TelephonyManager.PHONE_TYPE_CDMA) {
791 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "PHONE_TYPE_CDMA not supported");
792 return false;
793 }
794 if (call.isVideoCall() || call.hasReceivedVideoUpgradeRequest()) {
795 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "video call");
796 return false;
797 }
798 if (!ConfigProviderBindings.get(this).getBoolean(CONFIG_ANSWER_AND_RELEASE_ENABLED, true)) {
799 LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "disabled by config");
800 return false;
801 }
802
803 return true;
804 }
805
Eric Erfanianccca3152017-02-22 16:32:36 -0800806 private boolean hideAnswerScreenFragment(FragmentTransaction transaction) {
807 if (!didShowAnswerScreen) {
808 return false;
809 }
810 AnswerScreen answerScreen = getAnswerScreen();
811 if (answerScreen != null) {
812 transaction.remove(answerScreen.getAnswerScreenFragment());
813 }
814
815 didShowAnswerScreen = false;
816 return true;
817 }
818
819 private boolean showInCallScreenFragment(FragmentTransaction transaction) {
820 if (didShowInCallScreen) {
821 return false;
822 }
Eric Erfanian2ca43182017-08-31 06:57:16 -0700823 InCallScreen inCallScreen = InCallBindings.createInCallScreen();
824 transaction.add(R.id.main, inCallScreen.getInCallScreenFragment(), TAG_IN_CALL_SCREEN);
Eric Erfanianccca3152017-02-22 16:32:36 -0800825 Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
826 didShowInCallScreen = true;
827 return true;
828 }
829
830 private boolean hideInCallScreenFragment(FragmentTransaction transaction) {
831 if (!didShowInCallScreen) {
832 return false;
833 }
834 InCallScreen inCallScreen = getInCallScreen();
835 if (inCallScreen != null) {
Eric Erfanian2ca43182017-08-31 06:57:16 -0700836 transaction.remove(inCallScreen.getInCallScreenFragment());
Eric Erfanianccca3152017-02-22 16:32:36 -0800837 }
838 didShowInCallScreen = false;
839 return true;
840 }
841
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700842 private boolean showVideoCallScreenFragment(FragmentTransaction transaction, DialerCall call) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800843 if (didShowVideoCallScreen) {
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700844 VideoCallScreen videoCallScreen = getVideoCallScreen();
845 if (videoCallScreen.getCallId().equals(call.getId())) {
846 return false;
847 }
848 LogUtil.i(
849 "InCallActivity.showVideoCallScreenFragment",
850 "video call fragment exists but arguments do not match");
851 hideVideoCallScreenFragment(transaction);
Eric Erfanianccca3152017-02-22 16:32:36 -0800852 }
853
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700854 LogUtil.i("InCallActivity.showVideoCallScreenFragment", "call: %s", call);
855
Eric Erfanian90508232017-03-24 09:31:16 -0700856 VideoCallScreen videoCallScreen =
857 VideoBindings.createVideoCallScreen(
858 call.getId(), call.getVideoTech().shouldUseSurfaceView());
Eric Erfanianccca3152017-02-22 16:32:36 -0800859 transaction.add(R.id.main, videoCallScreen.getVideoCallScreenFragment(), TAG_VIDEO_CALL_SCREEN);
860
861 Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
862 didShowVideoCallScreen = true;
863 return true;
864 }
865
866 private boolean hideVideoCallScreenFragment(FragmentTransaction transaction) {
867 if (!didShowVideoCallScreen) {
868 return false;
869 }
870 VideoCallScreen videoCallScreen = getVideoCallScreen();
871 if (videoCallScreen != null) {
872 transaction.remove(videoCallScreen.getVideoCallScreenFragment());
873 }
874 didShowVideoCallScreen = false;
875 return true;
876 }
877
878 AnswerScreen getAnswerScreen() {
879 return (AnswerScreen) getSupportFragmentManager().findFragmentByTag(TAG_ANSWER_SCREEN);
880 }
881
882 InCallScreen getInCallScreen() {
883 return (InCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_IN_CALL_SCREEN);
884 }
885
886 VideoCallScreen getVideoCallScreen() {
887 return (VideoCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_VIDEO_CALL_SCREEN);
888 }
889
890 @Override
891 public void onPseudoScreenStateChanged(boolean isOn) {
892 LogUtil.i("InCallActivity.onPseudoScreenStateChanged", "isOn: " + isOn);
893 pseudoBlackScreenOverlay.setVisibility(isOn ? View.GONE : View.VISIBLE);
894 }
895
896 /**
897 * For some touch related issue, turning off the screen can be faked by drawing a black view over
898 * the activity. All touch events started when the screen is "off" is rejected.
899 *
900 * @see PseudoScreenState
901 */
902 @Override
903 public boolean dispatchTouchEvent(MotionEvent event) {
904 // Reject any gesture that started when the screen is in the fake off state.
905 if (touchDownWhenPseudoScreenOff) {
906 if (event.getAction() == MotionEvent.ACTION_UP) {
907 touchDownWhenPseudoScreenOff = false;
908 }
909 return true;
910 }
911 // Reject all touch event when the screen is in the fake off state.
912 if (!InCallPresenter.getInstance().getPseudoScreenState().isOn()) {
913 if (event.getAction() == MotionEvent.ACTION_DOWN) {
914 touchDownWhenPseudoScreenOff = true;
915 LogUtil.i("InCallActivity.dispatchTouchEvent", "touchDownWhenPseudoScreenOff");
916 }
917 return true;
918 }
919 return super.dispatchTouchEvent(event);
920 }
921
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700922 private static class ShouldShowUiResult {
Eric Erfanianccca3152017-02-22 16:32:36 -0800923 public final boolean shouldShow;
924 public final DialerCall call;
925
Eric Erfaniand5e47f62017-03-15 14:41:07 -0700926 ShouldShowUiResult(boolean shouldShow, DialerCall call) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800927 this.shouldShow = shouldShow;
928 this.call = call;
929 }
930 }
931}