1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2016 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License.
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.incallui.incall.impl;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.Manifest.permission;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.pm.PackageManager;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION_CODES;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Bundle;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Handler;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.NonNull;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.Nullable;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.app.Fragment;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.app.FragmentTransaction;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.content.ContextCompat;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.CallAudioState;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telephony.TelephonyManager;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.LayoutInflater;
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View;
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View.OnClickListener;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.ViewGroup;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.accessibility.AccessibilityEvent;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.ImageView;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.RelativeLayout;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.Toast;
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.Assert;
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.FragmentUtils;
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.LogUtil;
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.multimedia.MultimediaData;
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.audioroute.AudioRouteSelectorDialogFragment;
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter;
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.contactgrid.ContactGridManager;
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.hold.OnHoldFragment;
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.impl.ButtonController.SpeakerButtonController;
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.impl.InCallButtonGridFragment.OnButtonGridCreatedListener;
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonIds;
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonIdsExtension;
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonUi;
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonUiDelegate;
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallButtonUiDelegateFactory;
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreen;
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreenDelegate;
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreenDelegateFactory;
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.PrimaryCallState;
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.PrimaryInfo;
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.SecondaryInfo;
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList;
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.List;
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Fragment that shows UI for an ongoing voice call. */
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class InCallFragment extends Fragment
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    implements InCallScreen,
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        InCallButtonUi,
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        OnClickListener,
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        AudioRouteSelectorPresenter,
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        OnButtonGridCreatedListener {
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private List<ButtonController> buttonControllers = new ArrayList<>();
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private View endCallButton;
75fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian  private InCallPaginator paginator;
76fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian  private LockableViewPager pager;
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private InCallPagerAdapter adapter;
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactGridManager contactGridManager;
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private InCallScreenDelegate inCallScreenDelegate;
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private InCallButtonUiDelegate inCallButtonUiDelegate;
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private InCallButtonGridFragment inCallButtonGridFragment;
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Nullable private ButtonChooser buttonChooser;
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private SecondaryInfo savedSecondaryInfo;
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int voiceNetworkType;
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int phoneType;
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean stateRestored;
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
889050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  // Add animation to educate users. If a call has enriched calling attachments then we'll
899050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  // initially show the attachment page. After a delay seconds we'll animate to the button grid.
909050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private final Handler handler = new Handler();
919050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian  private final Runnable pagerRunnable =
929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      new Runnable() {
939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        @Override
949050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        public void run() {
959050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          pager.setCurrentItem(adapter.getButtonGridPosition());
969050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        }
979050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian      };
989050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean isSupportedButton(@InCallButtonIds int id) {
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return id == InCallButtonIds.BUTTON_AUDIO
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_MUTE
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_DIALPAD
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_HOLD
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_SWAP
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_ADD_CALL
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_MERGE
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || id == InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE;
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onAttach(Context context) {
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super.onAttach(context);
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (savedSecondaryInfo != null) {
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      setSecondary(savedSecondaryInfo);
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onCreate(Bundle savedInstanceState) {
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super.onCreate(savedInstanceState);
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallButtonUiDelegate =
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        FragmentUtils.getParent(this, InCallButtonUiDelegateFactory.class)
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .newInCallButtonUiDelegate();
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (savedInstanceState != null) {
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      inCallButtonUiDelegate.onRestoreInstanceState(savedInstanceState);
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      stateRestored = true;
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Nullable
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public View onCreateView(
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @NonNull LayoutInflater layoutInflater,
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Nullable ViewGroup viewGroup,
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Nullable Bundle bundle) {
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.onCreateView", null);
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final View view = layoutInflater.inflate(R.layout.frag_incall_voice, viewGroup, false);
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactGridManager =
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        new ContactGridManager(
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            view,
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            (ImageView) view.findViewById(R.id.contactgrid_avatar),
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            getResources().getDimensionPixelSize(R.dimen.incall_avatar_size),
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            true /* showAnonymousAvatar */);
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
146fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian    paginator = (InCallPaginator) view.findViewById(R.id.incall_paginator);
147fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian    pager = (LockableViewPager) view.findViewById(R.id.incall_pager);
1489050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    pager.setOnTouchListener(
1499050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        (v, event) -> {
1509050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          handler.removeCallbacks(pagerRunnable);
1519050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian          return false;
1529050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        });
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    endCallButton = view.findViewById(R.id.incall_end_call);
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    endCallButton.setOnClickListener(this);
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (ContextCompat.checkSelfPermission(getContext(), permission.READ_PHONE_STATE)
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        != PackageManager.PERMISSION_GRANTED) {
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      voiceNetworkType =
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          VERSION.SDK_INT >= VERSION_CODES.N
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              ? getContext().getSystemService(TelephonyManager.class).getVoiceNetworkType()
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              : TelephonyManager.NETWORK_TYPE_UNKNOWN;
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    phoneType = getContext().getSystemService(TelephonyManager.class).getPhoneType();
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return view;
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onResume() {
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super.onResume();
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallButtonUiDelegate.refreshMuteState();
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallScreenDelegate.onInCallScreenResumed();
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onViewCreated(@NonNull View view, @Nullable Bundle bundle) {
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.onViewCreated", null);
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super.onViewCreated(view, bundle);
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallScreenDelegate =
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        FragmentUtils.getParent(this, InCallScreenDelegateFactory.class).newInCallScreenDelegate();
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.isNotNull(inCallScreenDelegate);
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.MuteButtonController(inCallButtonUiDelegate));
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.SpeakerButtonController(inCallButtonUiDelegate));
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.DialpadButtonController(inCallButtonUiDelegate));
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.HoldButtonController(inCallButtonUiDelegate));
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.AddCallButtonController(inCallButtonUiDelegate));
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.SwapButtonController(inCallButtonUiDelegate));
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(new ButtonController.MergeButtonController(inCallButtonUiDelegate));
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(
194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        new ButtonController.UpgradeToVideoButtonController(inCallButtonUiDelegate));
195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(
196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        new ButtonController.ManageConferenceButtonController(inCallScreenDelegate));
197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonControllers.add(
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        new ButtonController.SwitchToSecondaryButtonController(inCallScreenDelegate));
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallScreenDelegate.onInCallScreenDelegateInit(this);
201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallScreenDelegate.onInCallScreenReady();
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
205d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  public void onPause() {
206d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    super.onPause();
207d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    inCallScreenDelegate.onInCallScreenPaused();
208d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  }
209d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
210d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  @Override
21110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian  public void onDestroyView() {
21210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian    super.onDestroyView();
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallScreenDelegate.onInCallScreenUnready();
214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onSaveInstanceState(Bundle outState) {
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super.onSaveInstanceState(outState);
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallButtonUiDelegate.onSaveInstanceState(outState);
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onClick(View view) {
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (view == endCallButton) {
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("InCallFragment.onClick", "end call button clicked");
226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      inCallScreenDelegate.onEndCallClicked();
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.e("InCallFragment.onClick", "unknown view: " + view);
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Assert.fail();
230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
233ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
234ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setPrimary(@NonNull PrimaryInfo primaryInfo) {
235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.setPrimary", primaryInfo.toString());
236d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    setAdapterMedia(primaryInfo.multimediaData);
237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactGridManager.setPrimary(primaryInfo);
238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (primaryInfo.shouldShowLocation) {
240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Hide the avatar to make room for location
241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      contactGridManager.setAvatarHidden(true);
242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Need to widen the contact grid to fit location information
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      View contactGridView = getView().findViewById(R.id.incall_contact_grid);
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      ViewGroup.LayoutParams params = contactGridView.getLayoutParams();
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (params instanceof ViewGroup.MarginLayoutParams) {
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ((ViewGroup.MarginLayoutParams) params).setMarginStart(0);
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ((ViewGroup.MarginLayoutParams) params).setMarginEnd(0);
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      contactGridView.setLayoutParams(params);
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Need to let the dialpad move up a little further when location info is being shown
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      View dialpadView = getView().findViewById(R.id.incall_dialpad_container);
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      params = dialpadView.getLayoutParams();
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (params instanceof RelativeLayout.LayoutParams) {
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ((RelativeLayout.LayoutParams) params).removeRule(RelativeLayout.BELOW);
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      dialpadView.setLayoutParams(params);
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
262d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private void setAdapterMedia(MultimediaData multimediaData) {
263d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (adapter == null) {
264d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      adapter = new InCallPagerAdapter(getChildFragmentManager(), multimediaData);
265d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      pager.setAdapter(adapter);
266d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    } else {
267d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      adapter.setAttachments(multimediaData);
268d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
27010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian    if (adapter.getCount() > 1 && getResources().getInteger(R.integer.incall_num_rows) > 1) {
271fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian      paginator.setVisibility(View.VISIBLE);
272fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian      paginator.setupWithViewPager(pager);
27310b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian      pager.setSwipingLocked(false);
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!stateRestored) {
2759050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        handler.postDelayed(pagerRunnable, 4_000);
27610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian      } else {
27710b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian        pager.setCurrentItem(adapter.getButtonGridPosition(), false /* animateScroll */);
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
2798369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    } else {
2808369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      paginator.setVisibility(View.GONE);
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setSecondary(@NonNull SecondaryInfo secondaryInfo) {
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.setSecondary", secondaryInfo.toString());
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_SWITCH_TO_SECONDARY)
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        .setEnabled(secondaryInfo.shouldShow);
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_SWITCH_TO_SECONDARY)
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        .setAllowed(secondaryInfo.shouldShow);
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateButtonStates();
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!isAdded()) {
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      savedSecondaryInfo = secondaryInfo;
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    savedSecondaryInfo = null;
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Fragment oldBanner = getChildFragmentManager().findFragmentById(R.id.incall_on_hold_banner);
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (secondaryInfo.shouldShow) {
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      transaction.replace(R.id.incall_on_hold_banner, OnHoldFragment.newInstance(secondaryInfo));
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (oldBanner != null) {
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        transaction.remove(oldBanner);
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    transaction.setCustomAnimations(R.anim.abc_slide_in_top, R.anim.abc_slide_out_top);
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    transaction.commitAllowingStateLoss();
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setCallState(@NonNull PrimaryCallState primaryCallState) {
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.setCallState", primaryCallState.toString());
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactGridManager.setCallState(primaryCallState);
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    buttonChooser =
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ButtonChooserFactory.newButtonChooser(voiceNetworkType, primaryCallState.isWifi, phoneType);
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateButtonStates();
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setEndCallButtonEnabled(boolean enabled, boolean animate) {
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (endCallButton != null) {
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      endCallButton.setEnabled(enabled);
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void showManageConferenceCallButton(boolean visible) {
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE).setAllowed(visible);
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE).setEnabled(visible);
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateButtonStates();
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public boolean isManageConferenceVisible() {
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return getButtonController(InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE).isAllowed();
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactGridManager.dispatchPopulateAccessibilityEvent(event);
342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void showNoteSentToast() {
346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.showNoteSentToast", null);
347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Toast.makeText(getContext(), R.string.incall_note_sent, Toast.LENGTH_LONG).show();
348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateInCallScreenColors() {}
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onInCallScreenDialpadVisibilityChange(boolean isShowing) {
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.onInCallScreenDialpadVisibilityChange", "isShowing: " + isShowing);
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Take note that the dialpad button isShowing
357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_DIALPAD).setChecked(isShowing);
358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // This check is needed because there is a race condition where we attempt to update
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // ButtonGridFragment before it is ready, so we check whether it is ready first and once it is
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // ready, #onButtonGridCreated will mark the dialpad button as isShowing.
362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (inCallButtonGridFragment != null) {
363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Update the Android Button's state to isShowing.
364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      inCallButtonGridFragment.onInCallScreenDialpadVisibilityChange(isShowing);
365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public int getAnswerAndDialpadContainerResourceId() {
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return R.id.incall_dialpad_container;
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public Fragment getInCallScreenFragment() {
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void showButton(@InCallButtonIds int buttonId, boolean show) {
380ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v(
381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "InCallFragment.showButton",
382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "buttionId: %s, show: %b",
383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        InCallButtonIdsExtension.toString(buttonId),
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        show);
385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (isSupportedButton(buttonId)) {
386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      getButtonController(buttonId).setAllowed(show);
387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
389ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
390ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void enableButton(@InCallButtonIds int buttonId, boolean enable) {
392ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v(
393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "InCallFragment.enableButton",
394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "buttonId: %s, enable: %b",
395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        InCallButtonIdsExtension.toString(buttonId),
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        enable);
397ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (isSupportedButton(buttonId)) {
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      getButtonController(buttonId).setEnabled(enable);
399ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
401ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
402ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
403ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setEnabled(boolean enabled) {
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("InCallFragment.setEnabled", "enabled: " + enabled);
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    for (ButtonController buttonController : buttonControllers) {
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      buttonController.setEnabled(enabled);
407ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
409ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
410ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
411ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setHold(boolean value) {
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_HOLD).setChecked(value);
413ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
414ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
415ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
416ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setCameraSwitched(boolean isBackFacingCamera) {}
417ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
418ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
419ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setVideoPaused(boolean isPaused) {}
420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
422ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setAudioState(CallAudioState audioState) {
423ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.setAudioState", "audioState: " + audioState);
424ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ((SpeakerButtonController) getButtonController(InCallButtonIds.BUTTON_AUDIO))
425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        .setAudioState(audioState);
426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getButtonController(InCallButtonIds.BUTTON_MUTE).setChecked(audioState.isMuted());
427ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
428ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
429ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
430ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateButtonStates() {
431ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // When the incall screen is ready, this method is called from #setSecondary, even though the
432ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // incall button ui is not ready yet. This method is called again once the incall button ui is
433ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // ready though, so this operation is safe and will be executed asap.
434ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (inCallButtonGridFragment == null) {
435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
437ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int numVisibleButtons =
438ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        inCallButtonGridFragment.updateButtonStates(
439ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            buttonControllers, buttonChooser, voiceNetworkType, phoneType);
440ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
441ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int visibility = numVisibleButtons == 0 ? View.GONE : View.VISIBLE;
442ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    pager.setVisibility(visibility);
443fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian    if (adapter != null
444fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian        && adapter.getCount() > 1
445fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian        && getResources().getInteger(R.integer.incall_num_rows) > 1) {
446fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian      paginator.setVisibility(View.VISIBLE);
447fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian      pager.setSwipingLocked(false);
448fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian    } else {
449fc37b02f5d3381a7882770941e461b13b679b6efEric Erfanian      paginator.setVisibility(View.GONE);
450d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      if (adapter != null) {
451d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        pager.setSwipingLocked(true);
452d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        pager.setCurrentItem(adapter.getButtonGridPosition());
453d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      }
454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
455ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
456ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateInCallButtonUiColors() {}
459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public Fragment getInCallButtonUiFragment() {
462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
464ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
465ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
466ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void showAudioRouteSelector() {
467ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    AudioRouteSelectorDialogFragment.newInstance(inCallButtonUiDelegate.getCurrentAudioState())
468ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        .show(getChildFragmentManager(), null);
469ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
470ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
471ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
472ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onAudioRouteSelected(int audioRoute) {
473ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallButtonUiDelegate.setAudioRoute(audioRoute);
474ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
475ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
476ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @NonNull
477ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
478ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ButtonController getButtonController(@InCallButtonIds int id) {
479ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    for (ButtonController buttonController : buttonControllers) {
480ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (buttonController.getInCallButtonId() == id) {
481ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return buttonController;
482ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
483ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
484ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.fail();
485ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return null;
486ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
487ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
488ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
489ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onButtonGridCreated(InCallButtonGridFragment inCallButtonGridFragment) {
490ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.onButtonGridCreated", "InCallUiReady");
491ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    this.inCallButtonGridFragment = inCallButtonGridFragment;
492ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallButtonUiDelegate.onInCallButtonUiReady(this);
493ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateButtonStates();
494ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
495ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
496ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
497ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onButtonGridDestroyed() {
498ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("InCallFragment.onButtonGridCreated", "InCallUiUnready");
499ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallButtonUiDelegate.onInCallButtonUiUnready();
500ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    this.inCallButtonGridFragment = null;
501ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
502ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
503ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
504ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public boolean isShowingLocationUi() {
505d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    Fragment fragment = getLocationFragment();
506ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return fragment != null && fragment.isVisible();
507ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
508ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
509ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
510ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void showLocationUi(@Nullable Fragment locationUi) {
511d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    boolean isVisible = isShowingLocationUi();
512d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (locationUi != null && !isVisible) {
513ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Show the location fragment.
514ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      getChildFragmentManager()
515ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .beginTransaction()
516ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .replace(R.id.incall_location_holder, locationUi)
517ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .commitAllowingStateLoss();
518d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    } else if (locationUi == null && isVisible) {
519ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Hide the location fragment
520d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      getChildFragmentManager()
521d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          .beginTransaction()
522d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          .remove(getLocationFragment())
523d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          .commitAllowingStateLoss();
524ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
525ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
526d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
527d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  @Override
528d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
529d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    super.onMultiWindowModeChanged(isInMultiWindowMode);
530d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (isInMultiWindowMode == isShowingLocationUi()) {
531d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("InCallFragment.onMultiWindowModeChanged", "hide = " + isInMultiWindowMode);
532d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      // Need to show or hide location
533d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      showLocationUi(isInMultiWindowMode ? null : getLocationFragment());
534d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
535d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
536d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
537d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private Fragment getLocationFragment() {
538d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return getChildFragmentManager().findFragmentById(R.id.incall_location_holder);
539d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
540ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
541