1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2013 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;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport static com.android.contacts.common.compat.CallCompat.Details.PROPERTY_ENTERPRISE_CALL;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.Manifest;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Intent;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.IntentFilter;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.pm.ApplicationInfo;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.pm.PackageManager;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.drawable.Drawable;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.display.DisplayManager;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.BatteryManager;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Handler;
31d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport android.support.annotation.NonNull;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.Nullable;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.app.Fragment;
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.content.ContextCompat;
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.Call.Details;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.StatusHints;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.TelecomManager;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.Display;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View;
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.accessibility.AccessibilityEvent;
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.accessibility.AccessibilityManager;
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils;
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.preference.ContactsPreferences;
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.util.ContactDisplayUtils;
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.Assert;
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.LogUtil;
48d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.compat.ActivityCompat;
492f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.dialer.configprovider.ConfigProviderBindings;
508369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport com.android.dialer.logging.DialerImpression;
51d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport com.android.dialer.logging.Logger;
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.multimedia.MultimediaData;
53d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.oem.MotorolaUtils;
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.InCallPresenter.InCallDetailsListener;
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.InCallPresenter.InCallEventListener;
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.InCallPresenter.InCallState;
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.InCallPresenter.InCallStateListener;
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.InCallPresenter.IncomingCallListener;
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.call.CallList;
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.call.DialerCall;
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.call.DialerCallListener;
64d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.incallui.calllocation.CallLocation;
65d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.incallui.calllocation.CallLocationComponent;
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.ContactPhotoType;
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreen;
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.InCallScreenDelegate;
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.PrimaryCallState;
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.PrimaryInfo;
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.incall.protocol.SecondaryInfo;
729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanianimport com.android.incallui.videotech.utils.SessionModificationState;
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.lang.ref.WeakReference;
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/**
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Controller for the Call Card Fragment. This class listens for changes to InCallState and passes
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * it along to the fragment.
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class CallCardPresenter
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    implements InCallStateListener,
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        IncomingCallListener,
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        InCallDetailsListener,
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        InCallEventListener,
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        InCallScreenDelegate,
852f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        DialerCallListener {
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Amount of time to wait before sending an announcement via the accessibility manager. When the
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * call state changes to an outgoing or incoming state for the first time, the UI can often be
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * changing due to call updates or contact lookup. This allows the UI to settle to a stable state
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * to ensure that the correct information is announced.
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final long ACCESSIBILITY_ANNOUNCEMENT_DELAY_MILLIS = 500;
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Flag to allow the user's current location to be shown during emergency calls. */
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String CONFIG_ENABLE_EMERGENCY_LOCATION = "config_enable_emergency_location";
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final boolean CONFIG_ENABLE_EMERGENCY_LOCATION_DEFAULT = true;
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Make it possible to not get location during an emergency call if the battery is too low, since
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * doing so could trigger gps and thus potentially cause the phone to die in the middle of the
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * call.
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String CONFIG_MIN_BATTERY_PERCENT_FOR_EMERGENCY_LOCATION =
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      "min_battery_percent_for_emergency_location";
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final long CONFIG_MIN_BATTERY_PERCENT_FOR_EMERGENCY_LOCATION_DEFAULT = 10;
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Context mContext;
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Handler handler = new Handler();
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private DialerCall mPrimary;
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private DialerCall mSecondary;
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactCacheEntry mPrimaryContactInfo;
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactCacheEntry mSecondaryContactInfo;
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Nullable private ContactsPreferences mContactsPreferences;
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mIsFullscreen = false;
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private InCallScreen mInCallScreen;
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isInCallScreenReady;
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldSendAccessibilityEvent;
122d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
123d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  @NonNull private final CallLocation callLocation;
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Runnable sendAccessibilityEventRunnable =
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      new Runnable() {
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        @Override
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        public void run() {
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          shouldSendAccessibilityEvent = !sendAccessibilityEvent(mContext, getUi());
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          LogUtil.i(
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              "CallCardPresenter.sendAccessibilityEventRunnable",
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              "still should send: %b",
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              shouldSendAccessibilityEvent);
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          if (!shouldSendAccessibilityEvent) {
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            handler.removeCallbacks(this);
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          }
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      };
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public CallCardPresenter(Context context) {
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("CallCardController.constructor", null);
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContext = Assert.isNotNull(context).getApplicationContext();
142d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    callLocation = CallLocationComponent.get(mContext).getCallLocation();
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean hasCallSubject(DialerCall call) {
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return !TextUtils.isEmpty(call.getCallSubject());
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onInCallScreenDelegateInit(InCallScreen inCallScreen) {
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.isNotNull(inCallScreen);
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mInCallScreen = inCallScreen;
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext);
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Call may be null if disconnect happened already.
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DialerCall call = CallList.getInstance().getFirstCall();
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call != null) {
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPrimary = call;
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (shouldShowNoteSentToast(mPrimary)) {
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mInCallScreen.showNoteSentToast();
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      call.addListener(this);
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // start processing lookups right away.
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!call.isConferenceCall()) {
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        startContactInfoSearch(call, true, call.getState() == DialerCall.State.INCOMING);
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updateContactEntry(null, true);
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    onStateChange(null, InCallPresenter.getInstance().getInCallState(), CallList.getInstance());
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onInCallScreenReady() {
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("CallCardController.onInCallScreenReady", null);
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.checkState(!isInCallScreenReady);
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mContactsPreferences != null) {
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Contact search may have completed before ui is ready.
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimaryContactInfo != null) {
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updatePrimaryDisplayInfo();
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Register for call state changes last
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().addListener(this);
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().addIncomingCallListener(this);
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().addDetailsListener(this);
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().addInCallEventListener(this);
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    isInCallScreenReady = true;
194d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
195d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    // Log location impressions
196d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (isOutgoingEmergencyCall(mPrimary)) {
197d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      Logger.get(mContext).logImpression(DialerImpression.Type.EMERGENCY_NEW_EMERGENCY_CALL);
198d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    } else if (isIncomingEmergencyCall(mPrimary) || isIncomingEmergencyCall(mSecondary)) {
199d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      Logger.get(mContext).logImpression(DialerImpression.Type.EMERGENCY_CALLBACK);
200d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
201d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
202d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    // Showing the location may have been skipped if the UI wasn't ready during previous layout.
203d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (shouldShowLocation()) {
204d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      updatePrimaryDisplayInfo();
205d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
206d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      // Log location impressions
207d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      if (!hasLocationPermission()) {
208d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        Logger.get(mContext).logImpression(DialerImpression.Type.EMERGENCY_NO_LOCATION_PERMISSION);
209d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      } else if (isBatteryTooLowForEmergencyLocation()) {
210d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        Logger.get(mContext)
211d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian            .logImpression(DialerImpression.Type.EMERGENCY_BATTERY_TOO_LOW_TO_GET_LOCATION);
212d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      } else if (!callLocation.canGetLocation(mContext)) {
213d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian        Logger.get(mContext).logImpression(DialerImpression.Type.EMERGENCY_CANT_GET_LOCATION);
214d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      }
215d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onInCallScreenUnready() {
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("CallCardController.onInCallScreenUnready", null);
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.checkState(isInCallScreenReady);
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // stop getting call state changes
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().removeListener(this);
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().removeIncomingCallListener(this);
226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().removeDetailsListener(this);
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().removeInCallEventListener(this);
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary != null) {
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPrimary.removeListener(this);
230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
232d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    callLocation.close();
233d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
234ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPrimary = null;
235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPrimaryContactInfo = null;
236ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mSecondaryContactInfo = null;
237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    isInCallScreenReady = false;
238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onIncomingCall(InCallState oldState, InCallState newState, DialerCall call) {
242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // same logic should happen as with onStateChange()
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    onStateChange(oldState, newState, CallList.getInstance());
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
2482f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    LogUtil.v("CallCardPresenter.onStateChange", "oldState: %s, newState: %s", oldState, newState);
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mInCallScreen == null) {
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DialerCall primary = null;
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DialerCall secondary = null;
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (newState == InCallState.INCOMING) {
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      primary = callList.getIncomingCall();
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) {
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      primary = callList.getOutgoingCall();
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (primary == null) {
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        primary = callList.getPendingOutgoingCall();
262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // highest priority call to display as the secondary call.
266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      secondary = getCallToDisplay(callList, null, true);
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (newState == InCallState.INCALL) {
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      primary = getCallToDisplay(callList, null, false);
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      secondary = getCallToDisplay(callList, primary, true);
270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("CallCardPresenter.onStateChange", "primary call: " + primary);
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("CallCardPresenter.onStateChange", "secondary call: " + secondary);
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final boolean primaryChanged =
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        !(DialerCall.areSame(mPrimary, primary) && DialerCall.areSameNumber(mPrimary, primary));
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final boolean secondaryChanged =
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        !(DialerCall.areSame(mSecondary, secondary)
279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            && DialerCall.areSameNumber(mSecondary, secondary));
280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mSecondary = secondary;
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DialerCall previousPrimary = mPrimary;
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPrimary = primary;
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary != null) {
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      InCallPresenter.getInstance().onForegroundCallChanged(mPrimary);
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.updateInCallScreenColors();
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (primaryChanged && shouldShowNoteSentToast(primary)) {
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.showNoteSentToast();
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Refresh primary call information if either:
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // 1. Primary call changed.
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // 2. The call's ability to manage conference has changed.
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (shouldRefreshPrimaryInfo(primaryChanged)) {
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // primary call has changed
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (previousPrimary != null) {
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        previousPrimary.removeListener(this);
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPrimary.addListener(this);
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPrimaryContactInfo =
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          ContactInfoCache.buildCacheEntryFromCall(
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mContext, mPrimary, mPrimary.getState() == DialerCall.State.INCOMING);
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updatePrimaryDisplayInfo();
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      maybeStartSearch(mPrimary, true);
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (previousPrimary != null && mPrimary == null) {
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      previousPrimary.removeListener(this);
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mSecondary == null) {
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Secondary call may have ended.  Update the ui.
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mSecondaryContactInfo = null;
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateSecondaryDisplayInfo();
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (secondaryChanged) {
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // secondary call has changed
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mSecondaryContactInfo =
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          ContactInfoCache.buildCacheEntryFromCall(
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mContext, mSecondary, mSecondary.getState() == DialerCall.State.INCOMING);
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateSecondaryDisplayInfo();
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      maybeStartSearch(mSecondary, false);
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Set the call state
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int callState = DialerCall.State.IDLE;
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary != null) {
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      callState = mPrimary.getState();
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updatePrimaryCallState();
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      getUi().setCallState(PrimaryCallState.createEmptyPrimaryCallState());
335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    maybeShowManageConferenceCallButton();
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Hide the end call button instantly if we're receiving an incoming call.
340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getUi()
341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        .setEndCallButtonEnabled(
342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            shouldShowEndCallButton(mPrimary, callState),
343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            callState != DialerCall.State.INCOMING /* animate */);
344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    maybeSendAccessibilityEvent(oldState, newState, primaryChanged);
346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onDetailsChanged(DialerCall call, Details details) {
350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updatePrimaryCallState();
351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call.can(Details.CAPABILITY_MANAGE_CONFERENCE)
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        != details.can(Details.CAPABILITY_MANAGE_CONFERENCE)) {
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      maybeShowManageConferenceCallButton();
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onDialerCallDisconnect() {}
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onDialerCallUpdate() {
363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // No-op; specific call updates handled elsewhere.
364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onWiFiToLteHandover() {}
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onHandoverToWifiFailure() {}
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
372c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian  @Override
373c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian  public void onInternationalCallOnWifi() {}
374c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian
3752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  @Override
3762f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public void onEnrichedCallSessionUpdate() {
3772f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    LogUtil.enterBlock("CallCardPresenter.onEnrichedCallSessionUpdate");
3782f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    updatePrimaryDisplayInfo();
3792f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
3802f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Handles a change to the child number by refreshing the primary call info. */
382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onDialerCallChildNumberChange() {
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("CallCardPresenter.onDialerCallChildNumberChange", "");
385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
389ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updatePrimaryDisplayInfo();
390ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
392ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Handles a change to the last forwarding number by refreshing the primary call info. */
393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onDialerCallLastForwardedNumberChange() {
395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("CallCardPresenter.onDialerCallLastForwardedNumberChange", "");
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
397ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
399ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updatePrimaryDisplayInfo();
401ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updatePrimaryCallState();
402ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
403ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onDialerCallUpgradeToVideo() {}
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
407d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  /** Handles a change to the session modification state for a call. */
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
409d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public void onDialerCallSessionModificationStateChange() {
410d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.enterBlock("CallCardPresenter.onDialerCallSessionModificationStateChange");
411ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
413ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
414ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
415ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getUi()
416ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        .setEndCallButtonEnabled(
417d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            mPrimary.getVideoTech().getSessionModificationState()
4189050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian                != SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST,
419ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            true /* shouldAnimate */);
420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updatePrimaryCallState();
421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
422ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
423ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldRefreshPrimaryInfo(boolean primaryChanged) {
424ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
427ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return primaryChanged
428ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || mInCallScreen.isManageConferenceVisible() != shouldShowManageConference();
429ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
430ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
431ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void updatePrimaryCallState() {
432ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (getUi() != null && mPrimary != null) {
433ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean isWorkCall =
434ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL)
435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              || (mPrimaryContactInfo != null
436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  && mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK);
437ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean isHdAudioCall =
438ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          isPrimaryCallActive() && mPrimary.hasProperty(Details.PROPERTY_HIGH_DEF_AUDIO);
439d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      boolean isAttemptingHdAudioCall =
440d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          !isHdAudioCall
441d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian              && !mPrimary.hasProperty(DialerCall.PROPERTY_CODEC_KNOWN)
442d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian              && MotorolaUtils.shouldBlinkHdIconWhenConnectingCall(mContext);
443d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
444d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      boolean isBusiness = mPrimaryContactInfo != null && mPrimaryContactInfo.isBusiness;
445d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
446ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Check for video state change and update the visibility of the contact photo.  The contact
447ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // photo is hidden when the incoming video surface is shown.
448ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // The contact photo visibility can also change in setPrimary().
449ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean shouldShowContactPhoto =
450ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          !VideoCallPresenter.showIncomingVideo(mPrimary.getVideoState(), mPrimary.getState());
451ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      getUi()
452ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .setCallState(
453ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              new PrimaryCallState(
454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  mPrimary.getState(),
455d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian                  mPrimary.isVideoCall(),
456d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian                  mPrimary.getVideoTech().getSessionModificationState(),
457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  mPrimary.getDisconnectCause(),
458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  getConnectionLabel(),
459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  getCallStateIcon(),
460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  getGatewayNumber(),
461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  shouldShowCallSubject(mPrimary) ? mPrimary.getCallSubject() : null,
462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  mPrimary.getCallbackNumber(),
463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  mPrimary.hasProperty(Details.PROPERTY_WIFI),
46483b20211c3be04a850de3674977deee8e448d17fEric Erfanian                  mPrimary.isConferenceCall()
46583b20211c3be04a850de3674977deee8e448d17fEric Erfanian                      && !mPrimary.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE),
466ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  isWorkCall,
467d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian                  isAttemptingHdAudioCall,
468ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  isHdAudioCall,
469ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  !TextUtils.isEmpty(mPrimary.getLastForwardedNumber()),
470ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  shouldShowContactPhoto,
471ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  mPrimary.getConnectTimeMillis(),
472ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  CallerInfoUtils.isVoiceMailNumber(mContext, mPrimary),
473d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian                  mPrimary.isRemotelyHeld(),
4742f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian                  isBusiness,
4752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian                  supports2ndCallOnHold()));
476ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
477ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      InCallActivity activity =
478ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          (InCallActivity) (mInCallScreen.getInCallScreenFragment().getActivity());
479ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (activity != null) {
480ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        activity.onPrimaryCallStateChanged();
481ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
482ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
483ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
484ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
485ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Only show the conference call button if we can manage the conference. */
486ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void maybeShowManageConferenceCallButton() {
487ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    getUi().showManageConferenceCallButton(shouldShowManageConference());
488ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
489ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
490ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
491ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Determines if the manage conference button should be visible, based on the current primary
492ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * call.
493ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
494ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return {@code True} if the manage conference button should be visible.
495ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
496ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldShowManageConference() {
497ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
498ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
499ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
500ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
501ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mPrimary.can(android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE)
502ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !mIsFullscreen;
503ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
504ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
5052f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  private boolean supports2ndCallOnHold() {
5062f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    DialerCall firstCall = CallList.getInstance().getActiveOrBackgroundCall();
5072f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    DialerCall incomingCall = CallList.getInstance().getIncomingCall();
5082f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    if (firstCall != null && incomingCall != null && firstCall != incomingCall) {
5092f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return incomingCall.can(Details.CAPABILITY_HOLD);
5102f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    }
5112f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    return true;
5122f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
5132f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
514ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
515ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onCallStateButtonClicked() {
516ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Intent broadcastIntent = Bindings.get(mContext).getCallStateButtonBroadcastIntent(mContext);
517ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (broadcastIntent != null) {
518ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.v(
519ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.onCallStateButtonClicked",
520ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "sending call state button broadcast: " + broadcastIntent);
521ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mContext.sendBroadcast(broadcastIntent, Manifest.permission.READ_PHONE_STATE);
522ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
523ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
524ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
525ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
526ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onManageConferenceClicked() {
527ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallActivity activity =
528ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (InCallActivity) (mInCallScreen.getInCallScreenFragment().getActivity());
529ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    activity.showConferenceFragment(true);
530ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
531ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
532ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
533ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onShrinkAnimationComplete() {
534ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    InCallPresenter.getInstance().onShrinkAnimationComplete();
535ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
536ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
537ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
538ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public Drawable getDefaultContactPhotoDrawable() {
539ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return ContactInfoCache.getInstance(mContext).getDefaultContactPhotoDrawable();
540ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
541ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
542ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void maybeStartSearch(DialerCall call, boolean isPrimary) {
543ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // no need to start search for conference calls which show generic info.
544ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call != null && !call.isConferenceCall()) {
545ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      startContactInfoSearch(call, isPrimary, call.getState() == DialerCall.State.INCOMING);
546ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
547ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
548ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
549ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Starts a query for more contact data for the save primary and secondary calls. */
550ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void startContactInfoSearch(
551ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final DialerCall call, final boolean isPrimary, boolean isIncoming) {
552ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
553ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
554ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary));
555ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
556ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
557ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) {
558ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final boolean entryMatchesExistingCall =
559ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (isPrimary && mPrimary != null && TextUtils.equals(callId, mPrimary.getId()))
560ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            || (!isPrimary && mSecondary != null && TextUtils.equals(callId, mSecondary.getId()));
561ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (entryMatchesExistingCall) {
562ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateContactEntry(entry, isPrimary);
563ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
564ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.e(
565ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.onContactInfoComplete",
566ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "dropping stale contact lookup info for " + callId);
567ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
568ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
569ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final DialerCall call = CallList.getInstance().getCallById(callId);
570ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call != null) {
571ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      call.getLogState().contactLookupResult = entry.contactLookupResult;
572ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
573ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (entry.contactUri != null) {
574ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CallerInfoUtils.sendViewNotification(mContext, entry.contactUri);
575ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
576ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
577ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
578ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void onImageLoadComplete(String callId, ContactCacheEntry entry) {
579ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (getUi() == null) {
580ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
581ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
582ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
583ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (entry.photo != null) {
584ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (mPrimary != null && callId.equals(mPrimary.getId())) {
585ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updateContactEntry(entry, true /* isPrimary */);
586ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else if (mSecondary != null && callId.equals(mSecondary.getId())) {
587ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updateContactEntry(entry, false /* isPrimary */);
588ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
589ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
590ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
591ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
592ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary) {
593ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (isPrimary) {
594ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPrimaryContactInfo = entry;
595ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updatePrimaryDisplayInfo();
596ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
597ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mSecondaryContactInfo = entry;
598ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateSecondaryDisplayInfo();
599ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
600ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
601ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
602ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
603ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Get the highest priority call to display. Goes through the calls and chooses which to return
604ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * based on priority of which type of call to display to the user. Callers can use the "ignore"
605ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * feature to get the second best call by passing a previously found primary call as ignore.
606ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
607ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param ignore A call to ignore if found.
608ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
609ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private DialerCall getCallToDisplay(
610ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CallList callList, DialerCall ignore, boolean skipDisconnected) {
611ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Active calls come second.  An active call always gets precedent.
612ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DialerCall retval = callList.getActiveCall();
613ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (retval != null && retval != ignore) {
614ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return retval;
615ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
616ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
617ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Sometimes there is intemediate state that two calls are in active even one is about
618ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // to be on hold.
619ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    retval = callList.getSecondActiveCall();
620ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (retval != null && retval != ignore) {
621ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return retval;
622ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
623ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
624ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Disconnected calls get primary position if there are no active calls
625ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // to let user know quickly what call has disconnected. Disconnected
626ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // calls are very short lived.
627ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!skipDisconnected) {
628ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      retval = callList.getDisconnectingCall();
629ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (retval != null && retval != ignore) {
630ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return retval;
631ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
632ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      retval = callList.getDisconnectedCall();
633ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (retval != null && retval != ignore) {
634ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return retval;
635ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
636ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
637ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
638ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Then we go to background call (calls on hold)
639ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    retval = callList.getBackgroundCall();
640ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (retval != null && retval != ignore) {
641ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return retval;
642ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
643ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
644ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Lastly, we go to a second background call.
645ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    retval = callList.getSecondBackgroundCall();
646ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
647ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return retval;
648ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
649ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
650ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void updatePrimaryDisplayInfo() {
651ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mInCallScreen == null) {
652ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // TODO: May also occur if search result comes back after ui is destroyed. Look into
653ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // removing that case completely.
654ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.v(
655ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.updatePrimaryDisplayInfo",
656ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "updatePrimaryDisplayInfo called but ui is null!");
657ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
658ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
659ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
660ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
661ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Clear the primary display info.
662ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setPrimary(PrimaryInfo.createEmptyPrimaryInfo());
663ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
664ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
665ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
666ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Hide the contact photo if we are in a video call and the incoming video surface is
667ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // showing.
668ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean showContactPhoto =
669ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        !VideoCallPresenter.showIncomingVideo(mPrimary.getVideoState(), mPrimary.getState());
670ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
671ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // DialerCall placed through a work phone account.
672ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean hasWorkCallProperty = mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL);
673ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
674d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    MultimediaData multimediaData = null;
6752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    if (mPrimary.getEnrichedCallSession() != null) {
6762f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      multimediaData = mPrimary.getEnrichedCallSession().getMultimediaData();
677d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
678ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
679ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary.isConferenceCall()) {
680ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.v(
681ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.updatePrimaryDisplayInfo",
682ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "update primary display info for conference call.");
683ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
684ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setPrimary(
685ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new PrimaryInfo(
686ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              null /* number */,
6872f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian              CallerInfoUtils.getConferenceString(
6882f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian                  mContext, mPrimary.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE)),
689ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              false /* nameIsNumber */,
690ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              null /* location */,
691ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              null /* label */,
69283b20211c3be04a850de3674977deee8e448d17fEric Erfanian              null /* photo */,
693ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              ContactPhotoType.DEFAULT_PLACEHOLDER,
694ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              false /* isSipCall */,
695ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              showContactPhoto,
696ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              hasWorkCallProperty,
697ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              false /* isSpam */,
698ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              false /* answeringDisconnectsOngoingCall */,
699ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              shouldShowLocation(),
700ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              null /* contactInfoLookupKey */,
701d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian              null /* enrichedCallMultimediaData */,
702d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian              mPrimary.getNumberPresentation()));
703ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (mPrimaryContactInfo != null) {
704ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.v(
705ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.updatePrimaryDisplayInfo",
706ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "update primary display info for " + mPrimaryContactInfo);
707ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
708ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String name = getNameForCall(mPrimaryContactInfo);
709ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String number;
710ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
711ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean isChildNumberShown = !TextUtils.isEmpty(mPrimary.getChildNumber());
712ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean isForwardedNumberShown = !TextUtils.isEmpty(mPrimary.getLastForwardedNumber());
713ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean isCallSubjectShown = shouldShowCallSubject(mPrimary);
714ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
715ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (isCallSubjectShown) {
716ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        number = null;
717ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else if (isChildNumberShown) {
718ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        number = mContext.getString(R.string.child_number, mPrimary.getChildNumber());
719ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else if (isForwardedNumberShown) {
720ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // Use last forwarded number instead of second line, if present.
721ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        number = mPrimary.getLastForwardedNumber();
722ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
723ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        number = mPrimaryContactInfo.number;
724ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
725ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
726ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean nameIsNumber = name != null && name.equals(mPrimaryContactInfo.number);
727d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
728ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // DialerCall with caller that is a work contact.
729ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean isWorkContact = (mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK);
730ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setPrimary(
731ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new PrimaryInfo(
732ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              number,
733c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian              mPrimary.updateNameIfRestricted(name),
734ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              nameIsNumber,
735d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian              shouldShowLocationAsLabel(nameIsNumber, mPrimaryContactInfo.shouldShowLocation)
736d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian                  ? mPrimaryContactInfo.location
737d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian                  : null,
738ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              isChildNumberShown || isCallSubjectShown ? null : mPrimaryContactInfo.label,
739ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPrimaryContactInfo.photo,
740ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPrimaryContactInfo.photoType,
741ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPrimaryContactInfo.isSipCall,
742ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              showContactPhoto,
743ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              hasWorkCallProperty || isWorkContact,
744ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPrimary.isSpam(),
745ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPrimary.answeringDisconnectsForegroundVideoCall(),
746ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              shouldShowLocation(),
747ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPrimaryContactInfo.lookupKey,
748d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian              multimediaData,
749d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian              mPrimary.getNumberPresentation()));
750ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
751ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Clear the primary display info.
752ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setPrimary(PrimaryInfo.createEmptyPrimaryInfo());
753ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
754ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
755d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (isInCallScreenReady) {
756d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      mInCallScreen.showLocationUi(getLocationFragment());
757d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    } else {
758d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.updatePrimaryDisplayInfo", "UI not ready, not showing location");
759d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
760d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
761d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
762d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  private static boolean shouldShowLocationAsLabel(
763d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      boolean nameIsNumber, boolean shouldShowLocation) {
764d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (nameIsNumber) {
765d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      return true;
766d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
767d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (shouldShowLocation) {
768d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      return true;
769d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
770d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    return false;
771d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  }
772d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
773d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private Fragment getLocationFragment() {
774d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (!ConfigProviderBindings.get(mContext)
775d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        .getBoolean(CONFIG_ENABLE_EMERGENCY_LOCATION, CONFIG_ENABLE_EMERGENCY_LOCATION_DEFAULT)) {
776d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "disabled by config.");
777d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
778d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
779d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (!shouldShowLocation()) {
780d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "shouldn't show location");
781d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
782d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
783d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (!hasLocationPermission()) {
784d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "no location permission.");
785d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
786d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
787d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (isBatteryTooLowForEmergencyLocation()) {
788d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "low battery.");
789d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
790d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
791d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (ActivityCompat.isInMultiWindowMode(mInCallScreen.getInCallScreenFragment().getActivity())) {
792d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "in multi-window mode");
793d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
794d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
795d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (mPrimary.isVideoCall()) {
796d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "emergency video calls not supported");
797d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
798d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
799d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (!callLocation.canGetLocation(mContext)) {
800d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.i("CallCardPresenter.getLocationFragment", "can't get current location");
801d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return null;
802d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
803d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.i("CallCardPresenter.getLocationFragment", "returning location fragment");
804d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return callLocation.getLocationFragment(mContext);
805ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
806ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
807ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldShowLocation() {
808ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (isOutgoingEmergencyCall(mPrimary)) {
809ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("CallCardPresenter.shouldShowLocation", "new emergency call");
810ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return true;
811ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (isIncomingEmergencyCall(mPrimary)) {
812ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("CallCardPresenter.shouldShowLocation", "potential emergency callback");
813ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return true;
814ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (isIncomingEmergencyCall(mSecondary)) {
815ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("CallCardPresenter.shouldShowLocation", "has potential emergency callback");
816ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return true;
817ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
818ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return false;
819ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
820ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
821ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean isOutgoingEmergencyCall(@Nullable DialerCall call) {
822ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return call != null && !call.isIncoming() && call.isEmergencyCall();
823ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
824ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
825ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean isIncomingEmergencyCall(@Nullable DialerCall call) {
826ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return call != null && call.isIncoming() && call.isPotentialEmergencyCallback();
827ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
828ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
829ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean hasLocationPermission() {
830ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
831ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        == PackageManager.PERMISSION_GRANTED;
832ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
833ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
834ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isBatteryTooLowForEmergencyLocation() {
835ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Intent batteryStatus =
836ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
837ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
838ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (status == BatteryManager.BATTERY_STATUS_CHARGING
839ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || status == BatteryManager.BATTERY_STATUS_FULL) {
840ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Plugged in or full battery
841ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
842ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
843ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
844ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
845ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    float batteryPercent = (100f * level) / scale;
846ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    long threshold =
847ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ConfigProviderBindings.get(mContext)
848ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getLong(
849ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                CONFIG_MIN_BATTERY_PERCENT_FOR_EMERGENCY_LOCATION,
850ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                CONFIG_MIN_BATTERY_PERCENT_FOR_EMERGENCY_LOCATION_DEFAULT);
851ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i(
852ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "CallCardPresenter.isBatteryTooLowForEmergencyLocation",
853ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "percent charged: " + batteryPercent + ", min required charge: " + threshold);
854ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return batteryPercent < threshold;
855ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
856ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
857ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void updateSecondaryDisplayInfo() {
858ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mInCallScreen == null) {
859ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
860ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
861ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
862ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mSecondary == null) {
863ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Clear the secondary display info.
864ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setSecondary(SecondaryInfo.createEmptySecondaryInfo(mIsFullscreen));
865ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
866ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
867ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
8682f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    if (mSecondary.isMergeInProcess()) {
8692f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      LogUtil.i(
8702f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          "CallCardPresenter.updateSecondaryDisplayInfo",
8712f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          "secondary call is merge in process, clearing info");
8722f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      mInCallScreen.setSecondary(SecondaryInfo.createEmptySecondaryInfo(mIsFullscreen));
8732f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return;
8742f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    }
8752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
876ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mSecondary.isConferenceCall()) {
877ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setSecondary(
878ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new SecondaryInfo(
879ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              true /* show */,
8802f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian              CallerInfoUtils.getConferenceString(
8812f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian                  mContext, mSecondary.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE)),
882ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              false /* nameIsNumber */,
883ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              null /* label */,
884ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mSecondary.getCallProviderLabel(),
885ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              true /* isConference */,
886ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mSecondary.isVideoCall(),
887ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mIsFullscreen));
888ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (mSecondaryContactInfo != null) {
889ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.v("CallCardPresenter.updateSecondaryDisplayInfo", "" + mSecondaryContactInfo);
890ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String name = getNameForCall(mSecondaryContactInfo);
891ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      boolean nameIsNumber = name != null && name.equals(mSecondaryContactInfo.number);
892ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setSecondary(
893ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new SecondaryInfo(
894ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              true /* show */,
895c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian              mSecondary.updateNameIfRestricted(name),
896ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              nameIsNumber,
897ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mSecondaryContactInfo.label,
898ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mSecondary.getCallProviderLabel(),
899ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              false /* isConference */,
900ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mSecondary.isVideoCall(),
901ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mIsFullscreen));
902ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
903ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Clear the secondary display info.
904ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInCallScreen.setSecondary(SecondaryInfo.createEmptySecondaryInfo(mIsFullscreen));
905ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
906ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
907ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
908ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Returns the gateway number for any existing outgoing call. */
909ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String getGatewayNumber() {
910ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (hasOutgoingGatewayCall()) {
911ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return DialerCall.getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayAddress());
912ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
913ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return null;
914ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
915ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
916ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
917ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the label (line of text above the number/name) for any given call. For example,
918ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * "calling via [Account/Google Voice]" for outgoing calls.
919ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
920ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String getConnectionLabel() {
921ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)
922ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        != PackageManager.PERMISSION_GRANTED) {
923ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
924ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
925ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    StatusHints statusHints = mPrimary.getStatusHints();
926ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (statusHints != null && !TextUtils.isEmpty(statusHints.getLabel())) {
927ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return statusHints.getLabel().toString();
928ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
929ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
930ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (hasOutgoingGatewayCall() && getUi() != null) {
931ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Return the label for the gateway app on outgoing calls.
932ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final PackageManager pm = mContext.getPackageManager();
933ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      try {
934ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ApplicationInfo info =
935ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            pm.getApplicationInfo(mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
936ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return pm.getApplicationLabel(info).toString();
937ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } catch (PackageManager.NameNotFoundException e) {
938ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        LogUtil.e("CallCardPresenter.getConnectionLabel", "gateway Application Not Found.", e);
939ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return null;
940ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
941ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
942ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mPrimary.getCallProviderLabel();
943ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
944ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
945ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Drawable getCallStateIcon() {
946ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Return connection icon if one exists.
947ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    StatusHints statusHints = mPrimary.getStatusHints();
948ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (statusHints != null && statusHints.getIcon() != null) {
949ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Drawable icon = statusHints.getIcon().loadDrawable(mContext);
950ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (icon != null) {
951ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return icon;
952ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
953ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
954ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
955ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return null;
956ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
957ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
958ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean hasOutgoingGatewayCall() {
959ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // We only display the gateway information while STATE_DIALING so return false for any other
960ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // call state.
961ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
962ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // is also called after a contact search completes (call is not present yet).  Split the
963ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // UI update so it can receive independent updates.
964ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary == null) {
965ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
966ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
967ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return DialerCall.State.isDialing(mPrimary.getState())
968ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && mPrimary.getGatewayInfo() != null
969ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !mPrimary.getGatewayInfo().isEmpty();
970ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
971ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
972ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Gets the name to display for the call. */
9732f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  private String getNameForCall(ContactCacheEntry contactInfo) {
974ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String preferredName =
975ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContactDisplayUtils.getPreferredDisplayName(
976ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            contactInfo.namePrimary, contactInfo.nameAlternative, mContactsPreferences);
977ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(preferredName)) {
978ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return contactInfo.number;
979ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
980ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return preferredName;
981ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
982ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
983ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
984ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onSecondaryInfoClicked() {
985ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mSecondary == null) {
986ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.e(
987ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.onSecondaryInfoClicked",
988ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "secondary info clicked but no secondary call.");
989ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
990ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
991ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
992ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i(
993ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        "CallCardPresenter.onSecondaryInfoClicked", "swapping call to foreground: " + mSecondary);
994ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mSecondary.unhold();
995ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
996ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
997ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
998ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onEndCallClicked() {
999ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("CallCardPresenter.onEndCallClicked", "disconnecting call: " + mPrimary);
1000ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPrimary != null) {
1001ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPrimary.disconnect();
1002ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1003ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1004ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1005ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
1006ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Handles a change to the fullscreen mode of the in-call UI.
1007ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
1008ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param isFullscreenMode {@code True} if the in-call UI is entering full screen mode.
1009ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
1010ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
1011ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onFullscreenModeChanged(boolean isFullscreenMode) {
1012ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mIsFullscreen = isFullscreenMode;
1013ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mInCallScreen == null) {
1014ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
1015ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1016ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    maybeShowManageConferenceCallButton();
1017ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1018ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1019ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isPrimaryCallActive() {
1020ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mPrimary != null && mPrimary.getState() == DialerCall.State.ACTIVE;
1021ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1022ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1023ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldShowEndCallButton(DialerCall primary, int callState) {
1024ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (primary == null) {
1025ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1026ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1027ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if ((!DialerCall.State.isConnectingOrConnected(callState)
1028ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            && callState != DialerCall.State.DISCONNECTING
1029ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            && callState != DialerCall.State.DISCONNECTED)
1030ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || callState == DialerCall.State.INCOMING) {
1031ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1032ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1033d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (mPrimary.getVideoTech().getSessionModificationState()
10349050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
1035ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1036ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1037ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return true;
1038ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1039ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1040ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
1041ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onInCallScreenResumed() {
1042d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    updatePrimaryDisplayInfo();
1043d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
1044ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (shouldSendAccessibilityEvent) {
1045ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      handler.postDelayed(sendAccessibilityEventRunnable, ACCESSIBILITY_ANNOUNCEMENT_DELAY_MILLIS);
1046ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1047ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1048ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1049d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  @Override
10502f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public void onInCallScreenPaused() {}
1051d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
1052ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  static boolean sendAccessibilityEvent(Context context, InCallScreen inCallScreen) {
1053ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    AccessibilityManager am =
1054ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
1055ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!am.isEnabled()) {
1056ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.w("CallCardPresenter.sendAccessibilityEvent", "accessibility is off");
1057ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1058ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1059ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (inCallScreen == null) {
1060ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.w("CallCardPresenter.sendAccessibilityEvent", "incallscreen is null");
1061ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1062ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1063ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Fragment fragment = inCallScreen.getInCallScreenFragment();
1064ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (fragment == null || fragment.getView() == null || fragment.getView().getParent() == null) {
1065ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.w("CallCardPresenter.sendAccessibilityEvent", "fragment/view/parent is null");
1066ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1067ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1068ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1069ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DisplayManager displayManager =
1070ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
1071ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
1072ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean screenIsOn = display.getState() == Display.STATE_ON;
1073ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.d("CallCardPresenter.sendAccessibilityEvent", "screen is on: %b", screenIsOn);
1074ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!screenIsOn) {
1075ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1076ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1077ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1078ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT);
1079ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    inCallScreen.dispatchPopulateAccessibilityEvent(event);
1080ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    View view = inCallScreen.getInCallScreenFragment().getView();
1081ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    view.getParent().requestSendAccessibilityEvent(view, event);
1082ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return true;
1083ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1084ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1085ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void maybeSendAccessibilityEvent(
1086ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      InCallState oldState, final InCallState newState, boolean primaryChanged) {
1087ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    shouldSendAccessibilityEvent = false;
1088ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mContext == null) {
1089ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
1090ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1091ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final AccessibilityManager am =
1092ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
1093ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!am.isEnabled()) {
1094ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
1095ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1096ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Announce the current call if it's new incoming/outgoing call or primary call is changed
1097ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // due to switching calls between two ongoing calls (one is on hold).
1098ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if ((oldState != InCallState.OUTGOING && newState == InCallState.OUTGOING)
1099ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || (oldState != InCallState.INCOMING && newState == InCallState.INCOMING)
1100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        || primaryChanged) {
1101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i(
1102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "CallCardPresenter.maybeSendAccessibilityEvent", "schedule accessibility announcement");
1103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      shouldSendAccessibilityEvent = true;
1104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      handler.postDelayed(sendAccessibilityEventRunnable, ACCESSIBILITY_ANNOUNCEMENT_DELAY_MILLIS);
1105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
1109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Determines whether the call subject should be visible on the UI. For the call subject to be
1110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * visible, the call has to be in an incoming or waiting state, and the subject must not be empty.
1111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
1112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param call The call.
1113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return {@code true} if the subject should be shown, {@code false} otherwise.
1114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
1115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldShowCallSubject(DialerCall call) {
1116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call == null) {
1117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
1118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean isIncomingOrWaiting =
1121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mPrimary.getState() == DialerCall.State.INCOMING
1122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            || mPrimary.getState() == DialerCall.State.CALL_WAITING;
1123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return isIncomingOrWaiting
1124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !TextUtils.isEmpty(call.getCallSubject())
1125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && call.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED
1126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && call.isCallSubjectSupported();
1127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
1130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Determines whether the "note sent" toast should be shown. It should be shown for a new outgoing
1131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * call with a subject.
1132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
1133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param call The call
1134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return {@code true} if the toast should be shown, {@code false} otherwise.
1135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
1136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldShowNoteSentToast(DialerCall call) {
1137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return call != null
1138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && hasCallSubject(call)
1139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && (call.getState() == DialerCall.State.DIALING
1140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            || call.getState() == DialerCall.State.CONNECTING);
1141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private InCallScreen getUi() {
1144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mInCallScreen;
1145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static class ContactLookupCallback implements ContactInfoCacheCallback {
1148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    private final WeakReference<CallCardPresenter> mCallCardPresenter;
1150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    private final boolean mIsPrimary;
1151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) {
1153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mCallCardPresenter = new WeakReference<CallCardPresenter>(callCardPresenter);
1154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mIsPrimary = isPrimary;
1155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Override
1158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
1159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CallCardPresenter presenter = mCallCardPresenter.get();
1160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (presenter != null) {
1161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        presenter.onContactInfoComplete(callId, entry, mIsPrimary);
1162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
1163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Override
1166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
1167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CallCardPresenter presenter = mCallCardPresenter.get();
1168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (presenter != null) {
1169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        presenter.onImageLoadComplete(callId, entry);
1170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
1171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
1172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
1173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
1174