19050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian/*
29050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * Copyright (C) 2016 The Android Open Source Project
39050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian *
49050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
59050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * you may not use this file except in compliance with the License.
69050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * You may obtain a copy of the License at
79050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian *
89050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
99050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian *
109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * Unless required by applicable law or agreed to in writing, software
119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * See the License for the specific language governing permissions and
149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * limitations under the License
159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian */
169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianpackage com.android.incallui.video.impl;
189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.Manifest.permission;
209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.content.Context;
219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.content.pm.PackageManager;
229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.graphics.Point;
239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.graphics.drawable.Animatable;
249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.os.Bundle;
258d662cae2c05b5e256e7bb826abf05fb9ace133dwangqiimport android.support.annotation.ColorInt;
269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.annotation.NonNull;
279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.annotation.Nullable;
289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.annotation.VisibleForTesting;
299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.v4.app.Fragment;
309050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.v4.app.FragmentTransaction;
319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.v4.view.animation.FastOutLinearInInterpolator;
329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.support.v4.view.animation.LinearOutSlowInInterpolator;
339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.telecom.CallAudioState;
349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.text.TextUtils;
359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.LayoutInflater;
369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.Surface;
379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.SurfaceView;
389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.View;
399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.View.OnClickListener;
409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.View.OnSystemUiVisibilityChangeListener;
419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.ViewGroup;
429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.ViewGroup.MarginLayoutParams;
439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.ViewTreeObserver;
449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.accessibility.AccessibilityEvent;
459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.animation.AccelerateDecelerateInterpolator;
469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.view.animation.Interpolator;
47d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport android.widget.FrameLayout;
489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.widget.ImageButton;
499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport android.widget.TextView;
509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.dialer.common.Assert;
519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.dialer.common.FragmentUtils;
529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.dialer.common.LogUtil;
539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.dialer.compat.ActivityCompat;
54ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanianimport com.android.dialer.util.PermissionsUtil;
559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.audioroute.AudioRouteSelectorDialogFragment;
569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter;
579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.contactgrid.ContactGridManager;
589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.hold.OnHoldFragment;
599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonIds;
609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonIdsExtension;
619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonUi;
629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonUiDelegate;
639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonUiDelegateFactory;
649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreen;
659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreenDelegate;
669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreenDelegateFactory;
679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.PrimaryCallState;
689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.PrimaryInfo;
699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.incall.protocol.SecondaryInfo;
709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.video.impl.CheckableImageButton.OnCheckedChangeListener;
719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.video.protocol.VideoCallScreen;
729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.video.protocol.VideoCallScreenDelegate;
739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.video.protocol.VideoCallScreenDelegateFactory;
749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.videotech.utils.VideoUtils;
759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian/**
779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * Contains UI elements for a video call.
789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian *
799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * <p>This version is used by RCS Video Share since Dreamchip requires a SurfaceView instead of the
809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian * TextureView, which is present in {@link VideoCallFragment} and used by IMS.
819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian */
829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianpublic class SurfaceViewVideoCallFragment extends Fragment
839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    implements InCallScreen,
849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        InCallButtonUi,
859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        VideoCallScreen,
869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        OnClickListener,
879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        OnCheckedChangeListener,
889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        AudioRouteSelectorPresenter,
89ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanian        OnSystemUiVisibilityChangeListener {
909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  static final String ARG_CALL_ID = "call_id";
939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private static final int CAMERA_PERMISSION_REQUEST_CODE = 1;
959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private static final long CAMERA_PERMISSION_DIALOG_DELAY_IN_MILLIS = 2000L;
969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private static final long VIDEO_OFF_VIEW_FADE_OUT_DELAY_IN_MILLIS = 2000L;
979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private InCallScreenDelegate inCallScreenDelegate;
999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private VideoCallScreenDelegate videoCallScreenDelegate;
1009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private InCallButtonUiDelegate inCallButtonUiDelegate;
1019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View endCallButton;
1029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private CheckableImageButton speakerButton;
1039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private SpeakerButtonController speakerButtonController;
1049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private CheckableImageButton muteButton;
1059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private CheckableImageButton cameraOffButton;
1069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private ImageButton swapCameraButton;
1079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View switchOnHoldButton;
1089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View onHoldContainer;
1099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private SwitchOnHoldCallController switchOnHoldCallController;
1109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private TextView remoteVideoOff;
1119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View mutePreviewOverlay;
1129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View previewOffOverlay;
1139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View controls;
1149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View controlsContainer;
1159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private SurfaceView previewSurfaceView;
1169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private SurfaceView remoteSurfaceView;
1179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View greenScreenBackgroundView;
1189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View fullscreenBackgroundView;
119d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  private FrameLayout previewRoot;
1209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean shouldShowRemote;
1219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean shouldShowPreview;
1229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean isInFullscreenMode;
1239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean isInGreenScreenMode;
1249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean hasInitializedScreenModes;
1259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean isRemotelyHeld;
1269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private ContactGridManager contactGridManager;
1279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private SecondaryInfo savedSecondaryInfo;
1289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private final Runnable cameraPermissionDialogRunnable =
1299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      new Runnable() {
1309050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        @Override
1319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        public void run() {
132ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanian          if (videoCallScreenDelegate.shouldShowCameraPermissionToast()) {
133d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            LogUtil.i(
134d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian                "SurfaceViewVideoCallFragment.cameraPermissionDialogRunnable", "showing dialog");
1359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            checkCameraPermission();
1369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          }
1379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        }
1389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      };
1399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public static SurfaceViewVideoCallFragment newInstance(String callId) {
1419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    Bundle bundle = new Bundle();
1429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    bundle.putString(ARG_CALL_ID, Assert.isNotNull(callId));
1439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    SurfaceViewVideoCallFragment instance = new SurfaceViewVideoCallFragment();
1459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    instance.setArguments(bundle);
1469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return instance;
1479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
1489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
1509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onCreate(@Nullable Bundle savedInstanceState) {
1519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onCreate(savedInstanceState);
152d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onCreate", null);
1539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallButtonUiDelegate =
1559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        FragmentUtils.getParent(this, InCallButtonUiDelegateFactory.class)
1569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .newInCallButtonUiDelegate();
1579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (savedInstanceState != null) {
1589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      inCallButtonUiDelegate.onRestoreInstanceState(savedInstanceState);
1599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
1609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
1619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
1639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onRequestPermissionsResult(
1649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
1659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
1669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
167d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        LogUtil.i(
168d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            "SurfaceViewVideoCallFragment.onRequestPermissionsResult",
169d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            "Camera permission granted.");
1709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        videoCallScreenDelegate.onCameraPermissionGranted();
1719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      } else {
172d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        LogUtil.i(
173d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            "SurfaceViewVideoCallFragment.onRequestPermissionsResult", "Camera permission denied.");
1749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
1759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
1769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
1779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
1789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Nullable
1809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
1819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public View onCreateView(
1829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) {
183d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onCreateView", null);
1849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1858369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    View view = layoutInflater.inflate(R.layout.frag_videocall_surfaceview, viewGroup, false);
1869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridManager =
1879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        new ContactGridManager(view, null /* no avatar */, 0, false /* showAnonymousAvatar */);
1889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
1899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    controls = view.findViewById(R.id.videocall_video_controls);
1909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    controls.setVisibility(
1919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        ActivityCompat.isInMultiWindowMode(getActivity()) ? View.GONE : View.VISIBLE);
1929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    controlsContainer = view.findViewById(R.id.videocall_video_controls_container);
1939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    speakerButton = (CheckableImageButton) view.findViewById(R.id.videocall_speaker_button);
1949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    muteButton = (CheckableImageButton) view.findViewById(R.id.videocall_mute_button);
1959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    muteButton.setOnCheckedChangeListener(this);
1969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    mutePreviewOverlay = view.findViewById(R.id.videocall_video_preview_mute_overlay);
1979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    cameraOffButton = (CheckableImageButton) view.findViewById(R.id.videocall_mute_video);
1989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    cameraOffButton.setOnCheckedChangeListener(this);
1999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    previewOffOverlay = view.findViewById(R.id.videocall_video_preview_off_overlay);
2009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    swapCameraButton = (ImageButton) view.findViewById(R.id.videocall_switch_video);
2019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    swapCameraButton.setOnClickListener(this);
2029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    view.findViewById(R.id.videocall_switch_controls)
2039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setVisibility(
2049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            ActivityCompat.isInMultiWindowMode(getActivity()) ? View.GONE : View.VISIBLE);
2059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldButton = view.findViewById(R.id.videocall_switch_on_hold);
2069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    onHoldContainer = view.findViewById(R.id.videocall_on_hold_banner);
2079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    remoteVideoOff = (TextView) view.findViewById(R.id.videocall_remote_video_off);
2089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    remoteVideoOff.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
2099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    endCallButton = view.findViewById(R.id.videocall_end_call);
2109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    endCallButton.setOnClickListener(this);
2119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    previewSurfaceView = (SurfaceView) view.findViewById(R.id.videocall_video_preview);
212d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    previewSurfaceView.setZOrderMediaOverlay(true);
2139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    previewOffOverlay.setOnClickListener(
2149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        new OnClickListener() {
2159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          @Override
2169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          public void onClick(View v) {
2179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            checkCameraPermission();
2189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          }
2199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        });
2209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    remoteSurfaceView = (SurfaceView) view.findViewById(R.id.videocall_video_remote);
221d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    remoteSurfaceView.setOnClickListener(
222d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        surfaceView -> {
223d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          videoCallScreenDelegate.resetAutoFullscreenTimer();
224d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          if (isInFullscreenMode) {
225d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            updateFullscreenAndGreenScreenMode(
226d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian                false /* shouldShowFullscreen */, false /* shouldShowGreenScreen */);
227d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          } else {
228d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            updateFullscreenAndGreenScreenMode(
229d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian                true /* shouldShowFullscreen */, false /* shouldShowGreenScreen */);
230d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          }
231d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        });
2329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    greenScreenBackgroundView = view.findViewById(R.id.videocall_green_screen_background);
2339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    fullscreenBackgroundView = view.findViewById(R.id.videocall_fullscreen_background);
234d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    previewRoot = (FrameLayout) view.findViewById(R.id.videocall_preview_root);
2359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // We need the texture view size to be able to scale the remote video. At this point the view
2379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // layout won't be complete so add a layout listener.
2389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    ViewTreeObserver observer = remoteSurfaceView.getViewTreeObserver();
2399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    observer.addOnGlobalLayoutListener(
2409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        new ViewTreeObserver.OnGlobalLayoutListener() {
2419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          @Override
2429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          public void onGlobalLayout() {
243d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            LogUtil.i("SurfaceViewVideoCallFragment.onGlobalLayout", null);
2449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            updateVideoOffViews();
2459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            // Remove the listener so we don't continually re-layout.
2469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            ViewTreeObserver observer = remoteSurfaceView.getViewTreeObserver();
2479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            if (observer.isAlive()) {
2489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              observer.removeOnGlobalLayoutListener(this);
2499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            }
2509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          }
2519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        });
2529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return view;
2549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
2559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
2579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onViewCreated(View view, @Nullable Bundle bundle) {
2589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onViewCreated(view, bundle);
259d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onViewCreated", null);
2609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallScreenDelegate =
2629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        FragmentUtils.getParentUnsafe(this, InCallScreenDelegateFactory.class)
2639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .newInCallScreenDelegate();
2649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    videoCallScreenDelegate =
2659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        FragmentUtils.getParentUnsafe(this, VideoCallScreenDelegateFactory.class)
2669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .newVideoCallScreenDelegate(this);
2679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    speakerButtonController =
2699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        new SpeakerButtonController(speakerButton, inCallButtonUiDelegate, videoCallScreenDelegate);
2709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldCallController =
2719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        new SwitchOnHoldCallController(
2729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            switchOnHoldButton, onHoldContainer, inCallScreenDelegate, videoCallScreenDelegate);
2739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    videoCallScreenDelegate.initVideoCallScreenDelegate(getContext(), this);
2759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallScreenDelegate.onInCallScreenDelegateInit(this);
2779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallScreenDelegate.onInCallScreenReady();
2789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallButtonUiDelegate.onInCallButtonUiReady(this);
2799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    view.setOnSystemUiVisibilityChangeListener(this);
2819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
2829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
2849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onSaveInstanceState(Bundle outState) {
2859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onSaveInstanceState(outState);
2869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallButtonUiDelegate.onSaveInstanceState(outState);
2879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
2889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
2909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onDestroyView() {
2919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onDestroyView();
292d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onDestroyView", null);
2939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallButtonUiDelegate.onInCallButtonUiUnready();
2949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallScreenDelegate.onInCallScreenUnready();
2959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
2969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
2979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
2989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onAttach(Context context) {
2999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onAttach(context);
3009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (savedSecondaryInfo != null) {
3019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      setSecondary(savedSecondaryInfo);
3029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
3039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
3069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onStart() {
3079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onStart();
308d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onStart", null);
3099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    onVideoScreenStart();
3109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
3139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onVideoScreenStart() {
3149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallButtonUiDelegate.refreshMuteState();
3159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    videoCallScreenDelegate.onVideoCallScreenUiReady();
3169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    getView().postDelayed(cameraPermissionDialogRunnable, CAMERA_PERMISSION_DIALOG_DELAY_IN_MILLIS);
3179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
3209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onResume() {
3219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onResume();
322d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onResume", null);
3239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallScreenDelegate.onInCallScreenResumed();
3249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
3279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onPause() {
3289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onPause();
329d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onPause", null);
33010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian    inCallScreenDelegate.onInCallScreenPaused();
3319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
3349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onStop() {
3359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    super.onStop();
336d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onStop", null);
3379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    onVideoScreenStop();
3389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
3419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onVideoScreenStop() {
3429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    getView().removeCallbacks(cameraPermissionDialogRunnable);
3439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    videoCallScreenDelegate.onVideoCallScreenUiUnready();
3449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
3459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void exitFullscreenMode() {
347d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.exitFullscreenMode", null);
3489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (!getView().isAttachedToWindow()) {
350d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      LogUtil.i("SurfaceViewVideoCallFragment.exitFullscreenMode", "not attached");
3519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return;
3529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
3539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    showSystemUI();
3559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    LinearOutSlowInInterpolator linearOutSlowInInterpolator = new LinearOutSlowInInterpolator();
3579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate the controls to the shown state.
3599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    controls
3609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
3619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(0)
3629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(0)
3639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(linearOutSlowInInterpolator)
3649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(1)
3659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .start();
3669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate onHold to the shown state.
3689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldButton
3699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
3709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(0)
3719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(0)
3729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(linearOutSlowInInterpolator)
3739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(1)
3749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .withStartAction(
3759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            new Runnable() {
3769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              @Override
3779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              public void run() {
3789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian                switchOnHoldCallController.setOnScreen();
3799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              }
3809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            });
3819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    View contactGridView = contactGridManager.getContainerView();
3839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate contact grid to the shown state.
3849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridView
3859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
3869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(0)
3879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(0)
3889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(linearOutSlowInInterpolator)
3899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(1)
3909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .withStartAction(
3919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            new Runnable() {
3929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              @Override
3939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              public void run() {
3949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian                contactGridManager.show();
3959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              }
3969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            });
3979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
3989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    endCallButton
3999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
4009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(0)
4019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(0)
4029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(linearOutSlowInInterpolator)
4039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(1)
4049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .withStartAction(
4059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            new Runnable() {
4069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              @Override
4079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              public void run() {
4089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian                endCallButton.setVisibility(View.VISIBLE);
4099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              }
4109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            })
4119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .start();
4129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate all the preview controls up to make room for the navigation bar.
4149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // In green screen mode we don't need this because the preview takes up the whole screen and has
4159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // a fixed position.
4169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (!isInGreenScreenMode) {
4179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      Point previewOffsetStartShown = getPreviewOffsetStartShown();
4189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      for (View view : getAllPreviewRelatedViews()) {
4199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        // Animate up with the preview offset above the navigation bar.
4209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        view.animate()
4219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .translationX(previewOffsetStartShown.x)
4229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .translationY(previewOffsetStartShown.y)
4239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .setInterpolator(new AccelerateDecelerateInterpolator())
4249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .start();
4259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
4269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateOverlayBackground();
4299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4309050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void showSystemUI() {
4329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    View view = getView();
4339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (view != null) {
4349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // Code is more expressive with all flags present, even though some may be combined
4359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      //noinspection PointlessBitwiseExpression
4369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
4379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  /** Set view flags to hide the system UI. System UI will return on any touch event */
4419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void hideSystemUI() {
4429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    View view = getView();
4439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (view != null) {
4449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      view.setSystemUiVisibility(
4459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          View.SYSTEM_UI_FLAG_FULLSCREEN
4469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
4479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
4489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private Point getControlsOffsetEndHidden(View controls) {
4529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (isLandscape()) {
4539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(0, getOffsetBottom(controls));
4549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
4559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(getOffsetStart(controls), 0);
4569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private Point getSwitchOnHoldOffsetEndHidden(View swapCallButton) {
4609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (isLandscape()) {
4619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(0, getOffsetTop(swapCallButton));
4629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
4639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(getOffsetEnd(swapCallButton), 0);
4649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private Point getContactGridOffsetEndHidden(View view) {
4689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return new Point(0, getOffsetTop(view));
4699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private Point getEndCallOffsetEndHidden(View endCallButton) {
4729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (isLandscape()) {
4739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(getOffsetEnd(endCallButton), 0);
4749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
4759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(0, ((MarginLayoutParams) endCallButton.getLayoutParams()).bottomMargin);
4769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private Point getPreviewOffsetStartShown() {
4809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // No insets in multiwindow mode, and rootWindowInsets will get the display's insets.
4819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (ActivityCompat.isInMultiWindowMode(getActivity())) {
4829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point();
4839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (isLandscape()) {
4859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      int stableInsetEnd =
4869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          getView().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
4879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              ? getView().getRootWindowInsets().getStableInsetLeft()
4889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              : -getView().getRootWindowInsets().getStableInsetRight();
4899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(stableInsetEnd, 0);
4909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
4919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return new Point(0, -getView().getRootWindowInsets().getStableInsetBottom());
4929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
4939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private View[] getAllPreviewRelatedViews() {
49691ce7d2a476bd04fe525049a37a2f8b2824e9724Eric Erfanian    return new View[] {previewRoot, mutePreviewOverlay};
4979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
4989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
4999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private int getOffsetTop(View view) {
5009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return -(view.getHeight() + ((MarginLayoutParams) view.getLayoutParams()).topMargin);
5019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
5029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private int getOffsetBottom(View view) {
5049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return view.getHeight() + ((MarginLayoutParams) view.getLayoutParams()).bottomMargin;
5059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
5069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private int getOffsetStart(View view) {
5089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    int offset = view.getWidth() + ((MarginLayoutParams) view.getLayoutParams()).getMarginStart();
5099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
5109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      offset = -offset;
5119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
5129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return -offset;
5139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
5149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private int getOffsetEnd(View view) {
5169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    int offset = view.getWidth() + ((MarginLayoutParams) view.getLayoutParams()).getMarginEnd();
5179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
5189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      offset = -offset;
5199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
5209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return offset;
5219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
5229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void enterFullscreenMode() {
524d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.enterFullscreenMode", null);
5259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    hideSystemUI();
5279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    Interpolator fastOutLinearInInterpolator = new FastOutLinearInInterpolator();
5299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5309050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate controls to the hidden state.
5319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    Point offset = getControlsOffsetEndHidden(controls);
5329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    controls
5339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
5349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(offset.x)
5359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(offset.y)
5369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(fastOutLinearInInterpolator)
5379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(0)
5389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .start();
5399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate onHold to the hidden state.
5419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    offset = getSwitchOnHoldOffsetEndHidden(switchOnHoldButton);
5429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldButton
5439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
5449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(offset.x)
5459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(offset.y)
5469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(fastOutLinearInInterpolator)
5479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(0);
5489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    View contactGridView = contactGridManager.getContainerView();
5509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate contact grid to the hidden state.
5519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    offset = getContactGridOffsetEndHidden(contactGridView);
5529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridView
5539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
5549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(offset.x)
5559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(offset.y)
5569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(fastOutLinearInInterpolator)
5579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(0);
5589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    offset = getEndCallOffsetEndHidden(endCallButton);
5609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Use a fast out interpolator to quickly fade out the button. This is important because the
5619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // button can't draw under the navigation bar which means that it'll look weird if it just
5629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // abruptly disappears when it reaches the edge of the naivgation bar.
5639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    endCallButton
5649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .animate()
5659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationX(offset.x)
5669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .translationY(offset.y)
5679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(fastOutLinearInInterpolator)
5689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(0)
5699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .withEndAction(
5709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            new Runnable() {
5719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              @Override
5729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              public void run() {
5739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian                endCallButton.setVisibility(View.INVISIBLE);
5749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              }
5759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            })
5769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .setInterpolator(new FastOutLinearInInterpolator())
5779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .start();
5789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Animate all the preview controls down now that the navigation bar is hidden.
5809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // In green screen mode we don't need this because the preview takes up the whole screen and has
5819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // a fixed position.
5829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (!isInGreenScreenMode) {
5839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      for (View view : getAllPreviewRelatedViews()) {
5849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        // Animate down with the navigation bar hidden.
5859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        view.animate()
5869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .translationX(0)
5879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .translationY(0)
5889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .setInterpolator(new AccelerateDecelerateInterpolator())
5899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            .start();
5909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
5919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
5929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateOverlayBackground();
5939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
5949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
5959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
5969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onClick(View v) {
5979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (v == endCallButton) {
598d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      LogUtil.i("SurfaceViewVideoCallFragment.onClick", "end call button clicked");
5999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      inCallButtonUiDelegate.onEndCallClicked();
6009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      videoCallScreenDelegate.resetAutoFullscreenTimer();
6019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (v == swapCameraButton) {
6029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      if (swapCameraButton.getDrawable() instanceof Animatable) {
6039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        ((Animatable) swapCameraButton.getDrawable()).start();
6049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
6059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      inCallButtonUiDelegate.toggleCameraClicked();
6069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      videoCallScreenDelegate.resetAutoFullscreenTimer();
6079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
6089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
6099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
6119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onCheckedChanged(CheckableImageButton button, boolean isChecked) {
6129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (button == cameraOffButton) {
613ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanian      if (!isChecked && !VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
614d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        LogUtil.i("SurfaceViewVideoCallFragment.onCheckedChanged", "show camera permission dialog");
6159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        checkCameraPermission();
6169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      } else {
6179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        inCallButtonUiDelegate.pauseVideoClicked(isChecked);
6189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        videoCallScreenDelegate.resetAutoFullscreenTimer();
6199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
6209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (button == muteButton) {
6219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      inCallButtonUiDelegate.muteClicked(isChecked, true /* clickedByUser */);
6229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      videoCallScreenDelegate.resetAutoFullscreenTimer();
6239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
6249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
6259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
6279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void showVideoViews(
6289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      boolean shouldShowPreview, boolean shouldShowRemote, boolean isRemotelyHeld) {
6299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    LogUtil.i(
630d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "SurfaceViewVideoCallFragment.showVideoViews",
6319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        "showPreview: %b, shouldShowRemote: %b",
6329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        shouldShowPreview,
6339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        shouldShowRemote);
634d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
6359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    this.shouldShowPreview = shouldShowPreview;
6369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    this.shouldShowRemote = shouldShowRemote;
6379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    this.isRemotelyHeld = isRemotelyHeld;
6389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
639d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    previewSurfaceView.setVisibility(shouldShowPreview ? View.VISIBLE : View.INVISIBLE);
640d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
6419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    videoCallScreenDelegate.setSurfaceViews(previewSurfaceView, remoteSurfaceView);
6429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateVideoOffViews();
6439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
6449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
6469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onLocalVideoDimensionsChanged() {
647d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onLocalVideoDimensionsChanged", null);
6489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
6499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
6519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onLocalVideoOrientationChanged() {
652d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onLocalVideoOrientationChanged", null);
6539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
6549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  /** Called when the remote video's dimensions change. */
6569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
6579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onRemoteVideoDimensionsChanged() {
658d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onRemoteVideoDimensionsChanged", null);
6599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
6609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
6629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void updateFullscreenAndGreenScreenMode(
6639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      boolean shouldShowFullscreen, boolean shouldShowGreenScreen) {
6649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    LogUtil.i(
665d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "SurfaceViewVideoCallFragment.updateFullscreenAndGreenScreenMode",
6669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        "shouldShowFullscreen: %b, shouldShowGreenScreen: %b",
6679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        shouldShowFullscreen,
6689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        shouldShowGreenScreen);
6699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (getActivity() == null) {
671d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      LogUtil.i(
672d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          "SurfaceViewVideoCallFragment.updateFullscreenAndGreenScreenMode",
673d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          "not attached to activity");
6749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return;
6759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
6769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Check if anything is actually going to change. The first time this function is called we
6789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // force a change by checking the hasInitializedScreenModes flag. We also force both fullscreen
6799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // and green screen modes to update even if only one has changed. That's because they both
6809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // depend on each other.
6819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (hasInitializedScreenModes
6829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        && shouldShowGreenScreen == isInGreenScreenMode
6839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        && shouldShowFullscreen == isInFullscreenMode) {
6849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      LogUtil.i(
685d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          "SurfaceViewVideoCallFragment.updateFullscreenAndGreenScreenMode",
686d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          "no change to screen modes");
6879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return;
6889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
6899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    hasInitializedScreenModes = true;
6909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    isInGreenScreenMode = shouldShowGreenScreen;
6919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    isInFullscreenMode = shouldShowFullscreen;
6929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
6939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (getView().isAttachedToWindow() && !ActivityCompat.isInMultiWindowMode(getActivity())) {
6949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      controlsContainer.onApplyWindowInsets(getView().getRootWindowInsets());
6959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
6969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (shouldShowGreenScreen) {
6979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      enterGreenScreenMode();
6989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
6999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      exitGreenScreenMode();
7009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
7019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (shouldShowFullscreen) {
7029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      enterFullscreenMode();
7039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
7049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      exitFullscreenMode();
7059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
7069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateVideoOffViews();
7079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    OnHoldFragment onHoldFragment =
7099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        ((OnHoldFragment)
7109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            getChildFragmentManager().findFragmentById(R.id.videocall_on_hold_banner));
7119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (onHoldFragment != null) {
7129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      onHoldFragment.setPadTopInset(!isInFullscreenMode);
7139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
7149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public Fragment getVideoCallScreenFragment() {
7189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return this;
7199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @NonNull
7239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public String getCallId() {
7249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return Assert.isNotNull(getArguments().getString(ARG_CALL_ID));
7259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void showButton(@InCallButtonIds int buttonId, boolean show) {
7299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    LogUtil.v(
730d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "SurfaceViewVideoCallFragment.showButton",
7319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        "buttonId: %s, show: %b",
7329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        InCallButtonIdsExtension.toString(buttonId),
7339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        show);
7349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (buttonId == InCallButtonIds.BUTTON_AUDIO) {
7359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      speakerButtonController.setEnabled(show);
7369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_MUTE) {
7379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      muteButton.setEnabled(show);
7389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_PAUSE_VIDEO) {
7399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      cameraOffButton.setEnabled(show);
7409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_SWITCH_TO_SECONDARY) {
7419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      switchOnHoldCallController.setVisible(show);
7429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_SWITCH_CAMERA) {
7439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      swapCameraButton.setEnabled(show);
7449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
7459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void enableButton(@InCallButtonIds int buttonId, boolean enable) {
7499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    LogUtil.v(
750d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "SurfaceViewVideoCallFragment.setEnabled",
7519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        "buttonId: %s, enable: %b",
7529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        InCallButtonIdsExtension.toString(buttonId),
7539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        enable);
7549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (buttonId == InCallButtonIds.BUTTON_AUDIO) {
7559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      speakerButtonController.setEnabled(enable);
7569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_MUTE) {
7579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      muteButton.setEnabled(enable);
7589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_PAUSE_VIDEO) {
7599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      cameraOffButton.setEnabled(enable);
7609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (buttonId == InCallButtonIds.BUTTON_SWITCH_TO_SECONDARY) {
7619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      switchOnHoldCallController.setEnabled(enable);
7629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
7639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setEnabled(boolean enabled) {
767d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.v("SurfaceViewVideoCallFragment.setEnabled", "enabled: " + enabled);
7689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    speakerButtonController.setEnabled(enabled);
7699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    muteButton.setEnabled(enabled);
7709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    cameraOffButton.setEnabled(enabled);
7719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldCallController.setEnabled(enabled);
7729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setHold(boolean value) {
776d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setHold", "value: " + value);
7779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setCameraSwitched(boolean isBackFacingCamera) {
781d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i(
782d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "SurfaceViewVideoCallFragment.setCameraSwitched",
783d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "isBackFacingCamera: " + isBackFacingCamera);
7849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setVideoPaused(boolean isPaused) {
788d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setVideoPaused", "isPaused: " + isPaused);
7899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    cameraOffButton.setChecked(isPaused);
7909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
7929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
7939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setAudioState(CallAudioState audioState) {
794d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setAudioState", "audioState: " + audioState);
7959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    speakerButtonController.setAudioState(audioState);
7969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    muteButton.setChecked(audioState.isMuted());
7979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateMutePreviewOverlayVisibility();
7989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
7999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void updateButtonStates() {
802d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.updateButtonState", null);
8039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    speakerButtonController.updateButtonState();
8049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldCallController.updateButtonState();
8059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8088d662cae2c05b5e256e7bb826abf05fb9ace133dwangqi  public void updateInCallButtonUiColors(@ColorInt int color) {}
8099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public Fragment getInCallButtonUiFragment() {
8129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return this;
8139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void showAudioRouteSelector() {
817d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.showAudioRouteSelector", null);
8189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    AudioRouteSelectorDialogFragment.newInstance(inCallButtonUiDelegate.getCurrentAudioState())
8199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .show(getChildFragmentManager(), null);
8209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onAudioRouteSelected(int audioRoute) {
824d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onAudioRouteSelected", "audioRoute: " + audioRoute);
8259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    inCallButtonUiDelegate.setAudioRoute(audioRoute);
8269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
82991ce7d2a476bd04fe525049a37a2f8b2824e9724Eric Erfanian  public void onAudioRouteSelectorDismiss() {}
83091ce7d2a476bd04fe525049a37a2f8b2824e9724Eric Erfanian
83191ce7d2a476bd04fe525049a37a2f8b2824e9724Eric Erfanian  @Override
8329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setPrimary(@NonNull PrimaryInfo primaryInfo) {
833d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setPrimary", primaryInfo.toString());
8349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridManager.setPrimary(primaryInfo);
8359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setSecondary(@NonNull SecondaryInfo secondaryInfo) {
839d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setSecondary", secondaryInfo.toString());
8409050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (!isAdded()) {
8419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      savedSecondaryInfo = secondaryInfo;
8429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return;
8439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
8449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    savedSecondaryInfo = null;
8459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    switchOnHoldCallController.setSecondaryInfo(secondaryInfo);
8469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateButtonStates();
8479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
8489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    Fragment oldBanner = getChildFragmentManager().findFragmentById(R.id.videocall_on_hold_banner);
8499e335e2d4fb43b22c7f95b2e9d4e048798e8e239Android Dialer    if (secondaryInfo.shouldShow()) {
8509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      OnHoldFragment onHoldFragment = OnHoldFragment.newInstance(secondaryInfo);
8519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      onHoldFragment.setPadTopInset(!isInFullscreenMode);
8529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      transaction.replace(R.id.videocall_on_hold_banner, onHoldFragment);
8539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
8549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      if (oldBanner != null) {
8559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        transaction.remove(oldBanner);
8569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
8579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
8589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    transaction.setCustomAnimations(R.anim.abc_slide_in_top, R.anim.abc_slide_out_top);
8599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    transaction.commitAllowingStateLoss();
8609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setCallState(@NonNull PrimaryCallState primaryCallState) {
864d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setCallState", primaryCallState.toString());
8659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridManager.setCallState(primaryCallState);
8669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void setEndCallButtonEnabled(boolean enabled, boolean animate) {
870d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.setEndCallButtonEnabled", "enabled: " + enabled);
8719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void showManageConferenceCallButton(boolean visible) {
875d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.showManageConferenceCallButton", "visible: " + visible);
8769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public boolean isManageConferenceVisible() {
880d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.isManageConferenceVisible", null);
8819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return false;
8829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
8869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridManager.dispatchPopulateAccessibilityEvent(event);
8879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void showNoteSentToast() {
891d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.showNoteSentToast", null);
8929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
8959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void updateInCallScreenColors() {
896d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.updateColors", null);
8979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
8989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
8999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
9009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onInCallScreenDialpadVisibilityChange(boolean isShowing) {
901d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.onInCallScreenDialpadVisibilityChange", null);
9029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
9059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public int getAnswerAndDialpadContainerResourceId() {
9069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return 0;
9079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
9109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public Fragment getInCallScreenFragment() {
9119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return this;
9129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
9159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public boolean isShowingLocationUi() {
9169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return false;
9179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
9209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void showLocationUi(Fragment locationUi) {
921d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.e(
922d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        "SurfaceViewVideoCallFragment.showLocationUi", "Emergency video calling not supported");
9239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Do nothing
9249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private boolean isLandscape() {
9279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Choose orientation based on display orientation, not window orientation
9289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
9299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    return rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270;
9309050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void enterGreenScreenMode() {
933d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.enterGreenScreenMode", null);
9349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateOverlayBackground();
9359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridManager.setIsMiddleRowVisible(true);
9369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateMutePreviewOverlayVisibility();
9379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void exitGreenScreenMode() {
940d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    LogUtil.i("SurfaceViewVideoCallFragment.exitGreenScreenMode", null);
9419050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateOverlayBackground();
9429050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    contactGridManager.setIsMiddleRowVisible(false);
9439050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    updateMutePreviewOverlayVisibility();
9449050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9459050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9469050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void updateVideoOffViews() {
9479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Always hide the preview off and remote off views in green screen mode.
9489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    boolean previewEnabled = isInGreenScreenMode || shouldShowPreview;
9499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    previewOffOverlay.setVisibility(previewEnabled ? View.GONE : View.VISIBLE);
9509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    boolean remoteEnabled = isInGreenScreenMode || shouldShowRemote;
9529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    boolean isResumed = remoteEnabled && !isRemotelyHeld;
9539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (isResumed) {
9549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      boolean wasRemoteVideoOff =
9559050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          TextUtils.equals(
9569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              remoteVideoOff.getText(),
9579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              remoteVideoOff.getResources().getString(R.string.videocall_remote_video_off));
9589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // The text needs to be updated and hidden after enough delay in order to be announced by
9599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // talkback.
9609050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      remoteVideoOff.setText(
9619050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          wasRemoteVideoOff
9629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              ? R.string.videocall_remote_video_on
9639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              : R.string.videocall_remotely_resumed);
9649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      remoteVideoOff.postDelayed(
9659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          new Runnable() {
9669050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            @Override
9679050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            public void run() {
9689050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              remoteVideoOff.setVisibility(View.GONE);
9699050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            }
9709050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          },
9719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          VIDEO_OFF_VIEW_FADE_OUT_DELAY_IN_MILLIS);
9729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
9739050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      remoteVideoOff.setText(
9749050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          isRemotelyHeld ? R.string.videocall_remotely_held : R.string.videocall_remote_video_off);
9759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      remoteVideoOff.setVisibility(View.VISIBLE);
9769050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
9779050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9789050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9799050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void updateOverlayBackground() {
9809050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (isInGreenScreenMode) {
9819050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // We want to darken the preview view to make text and buttons readable. The fullscreen
9829050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // background is below the preview view so use the green screen background instead.
9839050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      animateSetVisibility(greenScreenBackgroundView, View.VISIBLE);
9849050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      animateSetVisibility(fullscreenBackgroundView, View.GONE);
9859050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (!isInFullscreenMode) {
9869050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // We want to darken the remote view to make text and buttons readable. The green screen
9879050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // background is above the preview view so it would darken the preview too. Use the fullscreen
9889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      // background instead.
9899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      animateSetVisibility(greenScreenBackgroundView, View.GONE);
9909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      animateSetVisibility(fullscreenBackgroundView, View.VISIBLE);
9919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
9929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      animateSetVisibility(greenScreenBackgroundView, View.GONE);
9939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      animateSetVisibility(fullscreenBackgroundView, View.GONE);
9949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
9959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
9969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
9979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void updateMutePreviewOverlayVisibility() {
9989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Normally the mute overlay shows on the bottom right of the preview bubble. In green screen
9999050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // mode the preview is fullscreen so there's no where to anchor it.
10009050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    mutePreviewOverlay.setVisibility(
10019050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        muteButton.isChecked() && !isInGreenScreenMode ? View.VISIBLE : View.GONE);
10029050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
10039050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
10049050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private static void animateSetVisibility(final View view, final int visibility) {
10059050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (view.getVisibility() == visibility) {
10069050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return;
10079050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
10089050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
10099050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    int startAlpha;
10109050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    int endAlpha;
10119050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    if (visibility == View.GONE) {
10129050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      startAlpha = 1;
10139050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      endAlpha = 0;
10149050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else if (visibility == View.VISIBLE) {
10159050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      startAlpha = 0;
10169050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      endAlpha = 1;
10179050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    } else {
10189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      Assert.fail();
10199050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      return;
10209050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
10219050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
10229050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    view.setAlpha(startAlpha);
10239050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    view.setVisibility(View.VISIBLE);
10249050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    view.animate()
10259050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .alpha(endAlpha)
10269050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .withEndAction(
10279050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            new Runnable() {
10289050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              @Override
10299050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              public void run() {
10309050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian                view.setVisibility(visibility);
10319050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian              }
10329050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            })
10339050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        .start();
10349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
10359050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
10369050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  @Override
10379050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  public void onSystemUiVisibilityChange(int visibility) {
10389050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    boolean navBarVisible = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
10399050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    videoCallScreenDelegate.onSystemUiVisibilityChange(navBarVisible);
1040d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (navBarVisible) {
1041d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      updateFullscreenAndGreenScreenMode(
1042d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          false /* shouldShowFullscreen */, false /* shouldShowGreenScreen */);
1043d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    } else {
1044d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      updateFullscreenAndGreenScreenMode(
1045d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian          true /* shouldShowFullscreen */, false /* shouldShowGreenScreen */);
1046d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
10479050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
10489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
10499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private void checkCameraPermission() {
10509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // Checks if user has consent of camera permission and the permission is granted.
10519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // If camera permission is revoked, shows system permission dialog.
10529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // If camera permission is granted but user doesn't have consent of camera permission
10539050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // (which means it's first time making video call), shows custom dialog instead. This
10549050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    // will only be shown to user once.
1055ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanian    if (!VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
10569050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      videoCallScreenDelegate.onCameraPermissionDialogShown();
10579050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      if (!VideoUtils.hasCameraPermission(getContext())) {
10589050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        requestPermissions(new String[] {permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
10599050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      } else {
1060ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanian        PermissionsUtil.showCameraPermissionToast(getContext());
1061ff2ad7ffdba7c74077eae3016b32174f0f2dad30Eric Erfanian        videoCallScreenDelegate.onCameraPermissionGranted();
10629050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      }
10639050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    }
10649050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  }
10659050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian}
1066