summaryrefslogtreecommitdiffstats
path: root/java/com/android/incallui/InCallActivity.java
diff options
context:
space:
mode:
authorlinyuh <linyuh@google.com>2017-11-20 17:40:50 -0800
committerCopybara-Service <copybara-piper@google.com>2017-11-21 12:13:50 -0800
commitc3968e62c44530369eb2ca73bc0f7290e53bd613 (patch)
tree6319f60128a5eef914e5650cfbe3d659861b105b /java/com/android/incallui/InCallActivity.java
parenta3990fc2f6450cbd8c2376d0533a4120c239b38b (diff)
downloadandroid_packages_apps_Dialer-c3968e62c44530369eb2ca73bc0f7290e53bd613.tar.gz
android_packages_apps_Dialer-c3968e62c44530369eb2ca73bc0f7290e53bd613.tar.bz2
android_packages_apps_Dialer-c3968e62c44530369eb2ca73bc0f7290e53bd613.zip
Merge what's left in InCallActivityCommon into InCallActivity.
Bug: 69272096 Test: None PiperOrigin-RevId: 176443652 Change-Id: I90da4789deb4b6337a38cfe010b8aee5090d35e0
Diffstat (limited to 'java/com/android/incallui/InCallActivity.java')
-rw-r--r--java/com/android/incallui/InCallActivity.java614
1 files changed, 513 insertions, 101 deletions
diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java
index 1e5a5fc02..28ff7da60 100644
--- a/java/com/android/incallui/InCallActivity.java
+++ b/java/com/android/incallui/InCallActivity.java
@@ -16,42 +16,56 @@
package com.android.incallui;
+import android.app.ActivityManager;
+import android.app.ActivityManager.AppTask;
import android.app.ActivityManager.TaskDescription;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.os.Bundle;
import android.os.Trace;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
+import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.ColorUtils;
+import android.telecom.CallAudioState;
+import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import android.widget.CheckBox;
import android.widget.Toast;
import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment;
+import com.android.dialer.animation.AnimUtils;
+import com.android.dialer.animation.AnimationListenerAdapter;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.compat.ActivityCompat;
+import com.android.dialer.compat.CompatUtils;
import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.logging.LoggingBindings;
import com.android.dialer.logging.ScreenEvent;
+import com.android.dialer.util.ViewUtil;
import com.android.incallui.answer.bindings.AnswerBindings;
import com.android.incallui.answer.protocol.AnswerScreen;
import com.android.incallui.answer.protocol.AnswerScreenDelegate;
@@ -76,6 +90,11 @@ import com.android.incallui.video.bindings.VideoBindings;
import com.android.incallui.video.protocol.VideoCallScreen;
import com.android.incallui.video.protocol.VideoCallScreenDelegate;
import com.android.incallui.video.protocol.VideoCallScreenDelegateFactory;
+import com.google.common.base.Optional;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
/** Version of {@link InCallActivity} that shows the new UI */
public class InCallActivity extends TransactionSafeFragmentActivity
@@ -85,51 +104,60 @@ public class InCallActivity extends TransactionSafeFragmentActivity
VideoCallScreenDelegateFactory,
PseudoScreenState.StateChangedListener {
- public static final int PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN = 0;
- public static final int PENDING_INTENT_REQUEST_CODE_FULL_SCREEN = 1;
- public static final int PENDING_INTENT_REQUEST_CODE_BUBBLE = 2;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ DIALPAD_REQUEST_NONE,
+ DIALPAD_REQUEST_SHOW,
+ DIALPAD_REQUEST_HIDE,
+ })
+ @interface DialpadRequestType {}
- private static final String DIALPAD_TEXT_KEY = "InCallActivity.dialpad_text";
+ private static final int DIALPAD_REQUEST_NONE = 1;
+ private static final int DIALPAD_REQUEST_SHOW = 2;
+ private static final int DIALPAD_REQUEST_HIDE = 3;
- private static final String INTENT_EXTRA_SHOW_DIALPAD = "InCallActivity.show_dialpad";
+ private static Optional<Integer> audioRouteForTesting = Optional.absent();
- private static final String TAG_ANSWER_SCREEN = "tag_answer_screen";
- private static final String TAG_DIALPAD_FRAGMENT = "tag_dialpad_fragment";
- private static final String TAG_INTERNATIONAL_CALL_ON_WIFI = "tag_international_call_on_wifi";
- private static final String TAG_IN_CALL_SCREEN = "tag_in_call_screen";
- private static final String TAG_VIDEO_CALL_SCREEN = "tag_video_call_screen";
+ private final InternationalCallOnWifiCallback internationalCallOnWifiCallback =
+ new InternationalCallOnWifiCallback();
+ private final SelectPhoneAccountListener selectPhoneAccountListener =
+ new SelectPhoneAccountListener();
- private static final String DID_SHOW_ANSWER_SCREEN_KEY = "did_show_answer_screen";
- private static final String DID_SHOW_IN_CALL_SCREEN_KEY = "did_show_in_call_screen";
- private static final String DID_SHOW_VIDEO_CALL_SCREEN_KEY = "did_show_video_call_screen";
-
- private static final String CONFIG_ANSWER_AND_RELEASE_ENABLED = "answer_and_release_enabled";
-
- private final InCallActivityCommon common;
+ private Animation dialpadSlideInAnimation;
+ private Animation dialpadSlideOutAnimation;
+ private Dialog errorDialog;
+ private GradientDrawable backgroundDrawable;
private InCallOrientationEventListener inCallOrientationEventListener;
+ private View pseudoBlackScreenOverlay;
+ private SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment;
+ private String dtmfTextToPrepopulate;
+ private String showPostCharWaitDialogCallId;
+ private String showPostCharWaitDialogChars;
+ private boolean allowOrientationChange;
+ private boolean animateDialpadOnShow;
private boolean didShowAnswerScreen;
private boolean didShowInCallScreen;
private boolean didShowVideoCallScreen;
private boolean dismissKeyguard;
- private int[] backgroundDrawableColors;
- private GradientDrawable backgroundDrawable;
- private boolean isVisible;
- private View pseudoBlackScreenOverlay;
- private boolean touchDownWhenPseudoScreenOff;
private boolean isInShowMainInCallFragment;
+ private boolean isRecreating; // whether the activity is going to be recreated
+ private boolean isVisible;
private boolean needDismissPendingDialogs;
- private boolean allowOrientationChange;
-
- public InCallActivity() {
- common = new InCallActivityCommon(this);
- }
+ private boolean showPostCharWaitDialogOnResume;
+ private boolean touchDownWhenPseudoScreenOff;
+ private int[] backgroundDrawableColors;
+ @DialpadRequestType private int showDialpadRequest = DIALPAD_REQUEST_NONE;
public static Intent getIntent(
Context context, boolean showDialpad, boolean newOutgoingCall, boolean isForFullScreen) {
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(context, InCallActivity.class);
- InCallActivityCommon.setIntentExtras(intent, showDialpad, newOutgoingCall, isForFullScreen);
+ if (showDialpad) {
+ intent.putExtra(IntentExtraNames.SHOW_DIALPAD, true);
+ }
+ intent.putExtra(IntentExtraNames.NEW_OUTGOING_CALL, newOutgoingCall);
+ intent.putExtra(IntentExtraNames.FOR_FULL_SCREEN, isForFullScreen);
return intent;
}
@@ -142,23 +170,75 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
@Override
- protected void onCreate(Bundle icicle) {
+ protected void onCreate(Bundle bundle) {
Trace.beginSection("InCallActivity.onCreate");
- LogUtil.i("InCallActivity.onCreate", "");
- super.onCreate(icicle);
+ super.onCreate(bundle);
if (getIntent().getBooleanExtra(ReturnToCallController.RETURN_TO_CALL_EXTRA_KEY, false)) {
Logger.get(this).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_RETURN_TO_CALL);
getIntent().removeExtra(ReturnToCallController.RETURN_TO_CALL_EXTRA_KEY);
}
- if (icicle != null) {
- didShowAnswerScreen = icicle.getBoolean(DID_SHOW_ANSWER_SCREEN_KEY);
- didShowInCallScreen = icicle.getBoolean(DID_SHOW_IN_CALL_SCREEN_KEY);
- didShowVideoCallScreen = icicle.getBoolean(DID_SHOW_VIDEO_CALL_SCREEN_KEY);
+ if (bundle != null) {
+ didShowAnswerScreen = bundle.getBoolean(KeysForSavedInstance.DID_SHOW_ANSWER_SCREEN);
+ didShowInCallScreen = bundle.getBoolean(KeysForSavedInstance.DID_SHOW_IN_CALL_SCREEN);
+ didShowVideoCallScreen = bundle.getBoolean(KeysForSavedInstance.DID_SHOW_VIDEO_CALL_SCREEN);
+ }
+
+ setWindowFlags();
+ setContentView(R.layout.incall_screen);
+ internalResolveIntent(getIntent());
+
+ boolean isLandscape =
+ getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
+ boolean isRtl = ViewUtil.isRtl();
+ if (isLandscape) {
+ dialpadSlideInAnimation =
+ AnimationUtils.loadAnimation(
+ this, isRtl ? R.anim.dialpad_slide_in_left : R.anim.dialpad_slide_in_right);
+ dialpadSlideOutAnimation =
+ AnimationUtils.loadAnimation(
+ this, isRtl ? R.anim.dialpad_slide_out_left : R.anim.dialpad_slide_out_right);
+ } else {
+ dialpadSlideInAnimation = AnimationUtils.loadAnimation(this, R.anim.dialpad_slide_in_bottom);
+ dialpadSlideOutAnimation =
+ AnimationUtils.loadAnimation(this, R.anim.dialpad_slide_out_bottom);
+ }
+ dialpadSlideInAnimation.setInterpolator(AnimUtils.EASE_IN);
+ dialpadSlideOutAnimation.setInterpolator(AnimUtils.EASE_OUT);
+ dialpadSlideOutAnimation.setAnimationListener(
+ new AnimationListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ hideDialpadFragment();
+ }
+ });
+
+ if (bundle != null && showDialpadRequest == DIALPAD_REQUEST_NONE) {
+ // If the dialpad was shown before, set related variables so that it can be shown and
+ // populated with the previous DTMF text during onResume().
+ if (bundle.containsKey(IntentExtraNames.SHOW_DIALPAD)) {
+ boolean showDialpad = bundle.getBoolean(IntentExtraNames.SHOW_DIALPAD);
+ showDialpadRequest = showDialpad ? DIALPAD_REQUEST_SHOW : DIALPAD_REQUEST_HIDE;
+ animateDialpadOnShow = false;
+ }
+ dtmfTextToPrepopulate = bundle.getString(KeysForSavedInstance.DIALPAD_TEXT);
+
+ SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment =
+ (SelectPhoneAccountDialogFragment)
+ getFragmentManager().findFragmentByTag(Tags.SELECT_ACCOUNT_FRAGMENT);
+ if (selectPhoneAccountDialogFragment != null) {
+ selectPhoneAccountDialogFragment.setListener(selectPhoneAccountListener);
+ }
+ }
+
+ InternationalCallOnWifiDialogFragment existingInternationalCallOnWifiDialogFragment =
+ (InternationalCallOnWifiDialogFragment)
+ getSupportFragmentManager().findFragmentByTag(Tags.INTERNATIONAL_CALL_ON_WIFI);
+ if (existingInternationalCallOnWifiDialogFragment != null) {
+ existingInternationalCallOnWifiDialogFragment.setCallback(internationalCallOnWifiCallback);
}
- common.onCreate(icicle);
inCallOrientationEventListener = new InCallOrientationEventListener(this);
getWindow()
@@ -175,20 +255,138 @@ public class InCallActivity extends TransactionSafeFragmentActivity
.logStopLatencyTimer(LoggingBindings.ON_CALL_ADDED_TO_ON_INCALL_UI_SHOWN_OUTGOING);
}
+ private void setWindowFlags() {
+ // Allow the activity to be shown when the screen is locked and filter out touch events that are
+ // "too fat".
+ int flags =
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ | WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
+
+ // When the audio stream is not directed through Bluetooth, turn the screen on once the
+ // activity is shown.
+ final int audioRoute = getAudioRoute();
+ if (audioRoute != CallAudioState.ROUTE_BLUETOOTH) {
+ flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+ }
+
+ getWindow().addFlags(flags);
+ }
+
+ private static int getAudioRoute() {
+ if (audioRouteForTesting.isPresent()) {
+ return audioRouteForTesting.get();
+ }
+
+ return AudioModeProvider.getInstance().getAudioState().getRoute();
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ public static void setAudioRouteForTesting(int audioRoute) {
+ audioRouteForTesting = Optional.of(audioRoute);
+ }
+
+ private void internalResolveIntent(Intent intent) {
+ if (!intent.getAction().equals(Intent.ACTION_MAIN)) {
+ return;
+ }
+
+ if (intent.hasExtra(IntentExtraNames.SHOW_DIALPAD)) {
+ // IntentExtraNames.SHOW_DIALPAD can be used to specify whether the DTMF dialpad should be
+ // initially visible. If the extra is absent, leave the dialpad in its previous state.
+ boolean showDialpad = intent.getBooleanExtra(IntentExtraNames.SHOW_DIALPAD, false);
+ relaunchedFromDialer(showDialpad);
+ }
+
+ DialerCall outgoingCall = CallList.getInstance().getOutgoingCall();
+ if (outgoingCall == null) {
+ outgoingCall = CallList.getInstance().getPendingOutgoingCall();
+ }
+ if (intent.getBooleanExtra(IntentExtraNames.NEW_OUTGOING_CALL, false)) {
+ intent.removeExtra(IntentExtraNames.NEW_OUTGOING_CALL);
+
+ // InCallActivity is responsible for disconnecting a new outgoing call if there is no way of
+ // making it (i.e. no valid call capable accounts).
+ // If the version is not MSIM compatible, ignore this code.
+ if (CompatUtils.isMSIMCompatible()
+ && InCallPresenter.isCallWithNoValidAccounts(outgoingCall)) {
+ LogUtil.i(
+ "InCallActivity.internalResolveIntent", "Call with no valid accounts, disconnecting");
+ outgoingCall.disconnect();
+ }
+
+ dismissKeyguard(true);
+ }
+
+ if (showPhoneAccountSelectionDialog()) {
+ hideMainInCallFragment();
+ }
+ }
+
+ /**
+ * When relaunching from the dialer app, {@code showDialpad} indicates whether the dialpad should
+ * be shown on launch.
+ *
+ * @param showDialpad {@code true} to indicate the dialpad should be shown on launch, and {@code
+ * false} to indicate no change should be made to the dialpad visibility.
+ */
+ private void relaunchedFromDialer(boolean showDialpad) {
+ showDialpadRequest = showDialpad ? DIALPAD_REQUEST_SHOW : DIALPAD_REQUEST_NONE;
+ animateDialpadOnShow = true;
+
+ if (showDialpadRequest == DIALPAD_REQUEST_SHOW) {
+ // If there's only one line in use, AND it's on hold, then we're sure the user
+ // wants to use the dialpad toward the exact line, so un-hold the holding line.
+ DialerCall call = CallList.getInstance().getActiveOrBackgroundCall();
+ if (call != null && call.getState() == State.ONHOLD) {
+ call.unhold();
+ }
+ }
+ }
+
+ /**
+ * Show a phone account selection dialog if there is a call waiting for phone account selection.
+ *
+ * @return true if the dialog was shown.
+ */
+ private boolean showPhoneAccountSelectionDialog() {
+ DialerCall waitingForAccountCall = CallList.getInstance().getWaitingForAccountCall();
+ if (waitingForAccountCall == null) {
+ return false;
+ }
+
+ Bundle extras = waitingForAccountCall.getIntentExtras();
+ List<PhoneAccountHandle> phoneAccountHandles =
+ extras == null
+ ? new ArrayList<>()
+ : extras.getParcelableArrayList(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS);
+
+ selectPhoneAccountDialogFragment =
+ SelectPhoneAccountDialogFragment.newInstance(
+ R.string.select_phone_account_for_calls,
+ true /* canSetDefault */,
+ 0 /* setDefaultResId */,
+ phoneAccountHandles,
+ selectPhoneAccountListener,
+ waitingForAccountCall.getId(),
+ null /* hints */);
+ selectPhoneAccountDialogFragment.show(getFragmentManager(), Tags.SELECT_ACCOUNT_FRAGMENT);
+ return true;
+ }
+
@Override
protected void onSaveInstanceState(Bundle out) {
LogUtil.enterBlock("InCallActivity.onSaveInstanceState");
// TODO: DialpadFragment should handle this as part of its own state
- out.putBoolean(INTENT_EXTRA_SHOW_DIALPAD, isDialpadVisible());
+ out.putBoolean(IntentExtraNames.SHOW_DIALPAD, isDialpadVisible());
DialpadFragment dialpadFragment = getDialpadFragment();
if (dialpadFragment != null) {
- out.putString(DIALPAD_TEXT_KEY, dialpadFragment.getDtmfText());
+ out.putString(KeysForSavedInstance.DIALPAD_TEXT, dialpadFragment.getDtmfText());
}
- out.putBoolean(DID_SHOW_ANSWER_SCREEN_KEY, didShowAnswerScreen);
- out.putBoolean(DID_SHOW_IN_CALL_SCREEN_KEY, didShowInCallScreen);
- out.putBoolean(DID_SHOW_VIDEO_CALL_SCREEN_KEY, didShowVideoCallScreen);
+ out.putBoolean(KeysForSavedInstance.DID_SHOW_ANSWER_SCREEN, didShowAnswerScreen);
+ out.putBoolean(KeysForSavedInstance.DID_SHOW_IN_CALL_SCREEN, didShowInCallScreen);
+ out.putBoolean(KeysForSavedInstance.DID_SHOW_VIDEO_CALL_SCREEN, didShowVideoCallScreen);
super.onSaveInstanceState(out);
isVisible = false;
@@ -220,9 +418,45 @@ public class InCallActivity extends TransactionSafeFragmentActivity
@Override
protected void onResume() {
Trace.beginSection("InCallActivity.onResume");
- LogUtil.i("InCallActivity.onResume", "");
super.onResume();
- common.onResume();
+
+ if (!InCallPresenter.getInstance().isReadyForTearDown()) {
+ updateTaskDescription();
+ InCallPresenter.getInstance().onUiShowing(true);
+ }
+
+ // If there is a pending request to show or hide the dialpad, handle that now.
+ if (showDialpadRequest != DIALPAD_REQUEST_NONE) {
+ if (showDialpadRequest == DIALPAD_REQUEST_SHOW) {
+ // Exit fullscreen so that the user has access to the dialpad hide/show button.
+ // This is important when showing the dialpad from within dialer.
+ InCallPresenter.getInstance().setFullScreen(false /* isFullScreen */, true /* force */);
+
+ showDialpadFragment(true /* show */, animateDialpadOnShow /* animate */);
+ animateDialpadOnShow = false;
+
+ DialpadFragment dialpadFragment = getDialpadFragment();
+ if (dialpadFragment != null) {
+ dialpadFragment.setDtmfText(dtmfTextToPrepopulate);
+ dtmfTextToPrepopulate = null;
+ }
+ } else {
+ LogUtil.i("InCallActivity.onResume", "Force-hide the dialpad");
+ if (getDialpadFragment() != null) {
+ showDialpadFragment(false /* show */, false /* animate */);
+ }
+ }
+ showDialpadRequest = DIALPAD_REQUEST_NONE;
+ }
+ updateNavigationBar(isDialpadVisible());
+
+ if (showPostCharWaitDialogOnResume) {
+ showDialogForPostCharWait(showPostCharWaitDialogCallId, showPostCharWaitDialogChars);
+ }
+
+ CallList.getInstance()
+ .onInCallUiShown(getIntent().getBooleanExtra(IntentExtraNames.FOR_FULL_SCREEN, false));
+
PseudoScreenState pseudoScreenState = InCallPresenter.getInstance().getPseudoScreenState();
pseudoScreenState.addListener(this);
onPseudoScreenStateChanged(pseudoScreenState.isOn());
@@ -266,7 +500,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
// be created.
// Skip this when the screen is locked since the activity may complete its current life cycle
// and restart.
- if (!common.getIsRecreating() && !getSystemService(KeyguardManager.class).isKeyguardLocked()) {
+ if (!isRecreating && !getSystemService(KeyguardManager.class).isKeyguardLocked()) {
DialerCall waitingForAccountCall = CallList.getInstance().getWaitingForAccountCall();
if (waitingForAccountCall != null) {
waitingForAccountCall.disconnect();
@@ -276,8 +510,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
enableInCallOrientationEventListener(false);
InCallPresenter.getInstance().updateIsChangingConfigurations();
InCallPresenter.getInstance().onActivityStopped();
- if (!common.getIsRecreating()) {
- Dialog errorDialog = common.getErrorDialog();
+ if (!isRecreating) {
if (errorDialog != null) {
errorDialog.dismiss();
}
@@ -319,7 +552,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
private boolean shouldCloseActivityOnFinish() {
- if (!isVisible()) {
+ if (!isVisible) {
LogUtil.i(
"InCallActivity.shouldCloseActivityOnFinish",
"allowing activity to be closed because it's not visible");
@@ -341,19 +574,40 @@ public class InCallActivity extends TransactionSafeFragmentActivity
@Override
protected void onNewIntent(Intent intent) {
- LogUtil.i("InCallActivity.onNewIntent", "");
+ LogUtil.enterBlock("InCallActivity.onNewIntent");
// If the screen is off, we need to make sure it gets turned on for incoming calls.
// This normally works just fine thanks to FLAG_TURN_SCREEN_ON but that only works
// when the activity is first created. Therefore, to ensure the screen is turned on
// for the call waiting case, we recreate() the current activity. There should be no jank from
// this since the screen is already off and will remain so until our new activity is up.
- if (!isVisible()) {
- common.onNewIntent(intent, true /* isRecreating */);
+ if (!isVisible) {
+ onNewIntent(intent, true /* isRecreating */);
LogUtil.i("InCallActivity.onNewIntent", "Restarting InCallActivity to force screen on.");
recreate();
} else {
- common.onNewIntent(intent, false /* isRecreating */);
+ onNewIntent(intent, false /* isRecreating */);
+ }
+ }
+
+ private void onNewIntent(Intent intent, boolean isRecreating) {
+ this.isRecreating = isRecreating;
+
+ // We're being re-launched with a new Intent. Since it's possible for a single InCallActivity
+ // instance to persist indefinitely (even if we finish() ourselves), this sequence can
+ // happen any time the InCallActivity needs to be displayed.
+
+ // Stash away the new intent so that we can get it in the future by calling getIntent().
+ // Otherwise getIntent() will return the original Intent from when we first got created.
+ setIntent(intent);
+
+ // Activities are always paused before receiving a new intent, so we can count on our onResume()
+ // method being called next.
+
+ // Just like in onCreate(), handle the intent.
+ // Skip if InCallActivity is going to be recreated since this will be called in onCreate().
+ if (!isRecreating) {
+ internalResolveIntent(intent);
}
}
@@ -361,7 +615,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
public void onBackPressed() {
LogUtil.enterBlock("InCallActivity.onBackPressed");
- if (!isVisible()) {
+ if (!isVisible) {
return;
}
@@ -483,14 +737,78 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
}
- public boolean showDialpadFragment(boolean show, boolean animate) {
- boolean didChange = common.showDialpadFragment(show, animate);
- if (didChange) {
- // Note: onInCallScreenDialpadVisibilityChange is called here to ensure that the dialpad FAB
- // repositions itself.
- getInCallScreen().onInCallScreenDialpadVisibilityChange(show);
+ public void showDialpadFragment(boolean show, boolean animate) {
+ if (show == isDialpadVisible()) {
+ return;
+ }
+
+ FragmentManager dialpadFragmentManager = getDialpadFragmentManager();
+ if (dialpadFragmentManager == null) {
+ LogUtil.i("InCallActivity.showDialpadFragment", "Unable to obtain a FragmentManager");
+ return;
+ }
+
+ if (!animate) {
+ if (show) {
+ showDialpadFragment();
+ } else {
+ hideDialpadFragment();
+ }
+ } else {
+ if (show) {
+ showDialpadFragment();
+ getDialpadFragment().animateShowDialpad();
+ }
+ getDialpadFragment()
+ .getView()
+ .startAnimation(show ? dialpadSlideInAnimation : dialpadSlideOutAnimation);
+ }
+
+ ProximitySensor sensor = InCallPresenter.getInstance().getProximitySensor();
+ if (sensor != null) {
+ sensor.onDialpadVisible(show);
+ }
+ showDialpadRequest = DIALPAD_REQUEST_NONE;
+
+ // Note: onInCallScreenDialpadVisibilityChange is called here to ensure that the dialpad FAB
+ // repositions itself.
+ getInCallScreen().onInCallScreenDialpadVisibilityChange(show);
+ }
+
+ private void showDialpadFragment() {
+ FragmentManager dialpadFragmentManager = getDialpadFragmentManager();
+ if (dialpadFragmentManager == null) {
+ return;
}
- return didChange;
+
+ FragmentTransaction transaction = dialpadFragmentManager.beginTransaction();
+ DialpadFragment dialpadFragment = getDialpadFragment();
+ if (dialpadFragment == null) {
+ transaction.add(getDialpadContainerId(), new DialpadFragment(), Tags.DIALPAD_FRAGMENT);
+ } else {
+ transaction.show(dialpadFragment);
+ }
+ transaction.commitAllowingStateLoss();
+ dialpadFragmentManager.executePendingTransactions();
+
+ Logger.get(this).logScreenView(ScreenEvent.Type.INCALL_DIALPAD, this);
+ updateNavigationBar(true /* isDialpadVisible */);
+ }
+
+ private void hideDialpadFragment() {
+ FragmentManager dialpadFragmentManager = getDialpadFragmentManager();
+ if (dialpadFragmentManager == null) {
+ return;
+ }
+
+ Fragment dialpadFragment = dialpadFragmentManager.findFragmentByTag(Tags.DIALPAD_FRAGMENT);
+ if (dialpadFragment != null) {
+ FragmentTransaction transaction = dialpadFragmentManager.beginTransaction();
+ transaction.hide(dialpadFragment);
+ transaction.commitAllowingStateLoss();
+ dialpadFragmentManager.executePendingTransactions();
+ }
+ updateNavigationBar(false /* isDialpadVisible */);
}
public boolean isDialpadVisible() {
@@ -498,17 +816,14 @@ public class InCallActivity extends TransactionSafeFragmentActivity
return dialpadFragment != null && dialpadFragment.isVisible();
}
- /**
- * Returns the {@link DialpadFragment} that's shown by this activity, or {@code null}
- * TODO(a bug): Make this method private after InCallActivityCommon is deleted.
- */
+ /** Returns the {@link DialpadFragment} that's shown by this activity, or {@code null} */
@Nullable
- DialpadFragment getDialpadFragment() {
+ private DialpadFragment getDialpadFragment() {
FragmentManager fragmentManager = getDialpadFragmentManager();
if (fragmentManager == null) {
return null;
}
- return (DialpadFragment) fragmentManager.findFragmentByTag(TAG_DIALPAD_FRAGMENT);
+ return (DialpadFragment) fragmentManager.findFragmentByTag(Tags.DIALPAD_FRAGMENT);
}
public void onForegroundCallChanged(DialerCall newForegroundCall) {
@@ -520,8 +835,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
}
- // TODO(a bug): Make this method private after InCallActivityCommon is deleted.
- void updateTaskDescription() {
+ private void updateTaskDescription() {
int color =
getResources().getBoolean(R.bool.is_layout_landscape)
? ResourcesCompat.getColor(
@@ -605,8 +919,19 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
}
- public void showPostCharWaitDialog(String callId, String chars) {
- common.showPostCharWaitDialog(callId, chars);
+ public void showDialogForPostCharWait(String callId, String chars) {
+ if (isVisible) {
+ PostCharDialogFragment fragment = new PostCharDialogFragment(callId, chars);
+ fragment.show(getSupportFragmentManager(), Tags.POST_CHAR_DIALOG_FRAGMENT);
+
+ showPostCharWaitDialogOnResume = false;
+ showPostCharWaitDialogCallId = null;
+ showPostCharWaitDialogChars = null;
+ } else {
+ showPostCharWaitDialogOnResume = true;
+ showPostCharWaitDialogCallId = callId;
+ showPostCharWaitDialogChars = chars;
+ }
}
public void showDialogOrToastForDisconnectedCall(DisconnectMessage disconnectMessage) {
@@ -629,7 +954,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
// Show the dialog.
- common.setErrorDialog(disconnectMessage.dialog);
+ errorDialog = disconnectMessage.dialog;
InCallUiLock lock = InCallPresenter.getInstance().acquireInCallUiLock("showErrorDialog");
disconnectMessage.dialog.setOnDismissListener(
dialogInterface -> {
@@ -641,12 +966,12 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
private void onDialogDismissed() {
- common.setErrorDialog(null);
+ errorDialog = null;
CallList.getInstance().onErrorDialogDismissed();
}
public void dismissPendingDialogs() {
- LogUtil.i("InCallActivity.dismissPendingDialogs", "");
+ LogUtil.enterBlock("InCallActivity.dismissPendingDialogs");
if (!isVisible) {
// Defer the dismissing action as the activity is not visible and onSaveInstanceState may have
@@ -658,24 +983,21 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
// Dismiss the error dialog
- Dialog errorDialog = common.getErrorDialog();
if (errorDialog != null) {
errorDialog.dismiss();
- common.setErrorDialog(null);
+ errorDialog = null;
}
// Dismiss the phone account selection dialog
- SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment =
- common.getSelectPhoneAccountDialogFragment();
if (selectPhoneAccountDialogFragment != null) {
selectPhoneAccountDialogFragment.dismiss();
- common.setSelectPhoneAccountDialogFragment(null);
+ selectPhoneAccountDialogFragment = null;
}
// Dismiss the dialog for international call on WiFi
InternationalCallOnWifiDialogFragment internationalCallOnWifiFragment =
(InternationalCallOnWifiDialogFragment)
- getSupportFragmentManager().findFragmentByTag(TAG_INTERNATIONAL_CALL_ON_WIFI);
+ getSupportFragmentManager().findFragmentByTag(Tags.INTERNATIONAL_CALL_ON_WIFI);
if (internationalCallOnWifiFragment != null) {
internationalCallOnWifiFragment.dismiss();
}
@@ -689,8 +1011,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
needDismissPendingDialogs = false;
}
- // TODO(a bug): Make this method private after InCallActivityCommon is deleted.
- void enableInCallOrientationEventListener(boolean enable) {
+ private void enableInCallOrientationEventListener(boolean enable) {
if (enable) {
inCallOrientationEventListener.enable(true /* notifyDeviceOrientationChange */);
} else {
@@ -699,7 +1020,18 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
public void setExcludeFromRecents(boolean exclude) {
- common.setExcludeFromRecents(exclude);
+ int taskId = getTaskId();
+
+ List<AppTask> tasks = getSystemService(ActivityManager.class).getAppTasks();
+ for (AppTask task : tasks) {
+ try {
+ if (task.getTaskInfo().id == taskId) {
+ task.setExcludeFromRecents(exclude);
+ }
+ } catch (RuntimeException e) {
+ LogUtil.e("InCallActivity.setExcludeFromRecents", "RuntimeException:\n%s", e);
+ }
+ }
}
@Nullable
@@ -756,7 +1088,6 @@ public class InCallActivity extends TransactionSafeFragmentActivity
public void onPrimaryCallStateChanged() {
Trace.beginSection("InCallActivity.onPrimaryCallStateChanged");
- LogUtil.i("InCallActivity.onPrimaryCallStateChanged", "");
showMainInCallFragment();
Trace.endSection();
}
@@ -790,7 +1121,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
wifiHandoverFailureCheckbox.setChecked(false);
InCallUiLock lock = InCallPresenter.getInstance().acquireInCallUiLock("WifiFailedDialog");
- Dialog errorDialog =
+ errorDialog =
builder
.setView(dialogCheckBoxView)
.setMessage(R.string.video_call_lte_to_wifi_failed_message)
@@ -805,8 +1136,6 @@ public class InCallActivity extends TransactionSafeFragmentActivity
})
.setOnDismissListener(dialogInterface -> lock.release())
.create();
-
- common.setErrorDialog(errorDialog);
errorDialog.show();
}
@@ -820,8 +1149,8 @@ public class InCallActivity extends TransactionSafeFragmentActivity
InternationalCallOnWifiDialogFragment fragment =
InternationalCallOnWifiDialogFragment.newInstance(
- call.getId(), common.getCallbackForInternationalCallOnWifiDialog());
- fragment.show(getSupportFragmentManager(), TAG_INTERNATIONAL_CALL_ON_WIFI);
+ call.getId(), internationalCallOnWifiCallback);
+ fragment.show(getSupportFragmentManager(), Tags.INTERNATIONAL_CALL_ON_WIFI);
}
@Override
@@ -830,8 +1159,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
updateNavigationBar(isDialpadVisible());
}
- // TODO(a bug): Make this method private after InCallActivityCommon is deleted.
- void updateNavigationBar(boolean isDialpadVisible) {
+ private void updateNavigationBar(boolean isDialpadVisible) {
if (ActivityCompat.isInMultiWindowMode(this)) {
return;
}
@@ -856,8 +1184,8 @@ public class InCallActivity extends TransactionSafeFragmentActivity
}
public void hideMainInCallFragment() {
- LogUtil.i("InCallActivity.hideMainInCallFragment", "");
- if (didShowInCallScreen || didShowVideoCallScreen) {
+ LogUtil.enterBlock("InCallActivity.hideMainInCallFragment");
+ if (getCallCardFragmentVisible()) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
hideInCallScreenFragment(transaction);
hideVideoCallScreenFragment(transaction);
@@ -1017,7 +1345,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
call.getVideoTech().isSelfManagedCamera(),
shouldAllowAnswerAndRelease(call),
CallList.getInstance().getBackgroundCall() != null);
- transaction.add(R.id.main, answerScreen.getAnswerScreenFragment(), TAG_ANSWER_SCREEN);
+ transaction.add(R.id.main, answerScreen.getAnswerScreenFragment(), Tags.ANSWER_SCREEN);
Logger.get(this).logScreenView(ScreenEvent.Type.INCOMING_CALL, this);
didShowAnswerScreen = true;
@@ -1038,7 +1366,8 @@ public class InCallActivity extends TransactionSafeFragmentActivity
LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "video call");
return false;
}
- if (!ConfigProviderBindings.get(this).getBoolean(CONFIG_ANSWER_AND_RELEASE_ENABLED, true)) {
+ if (!ConfigProviderBindings.get(this)
+ .getBoolean(ConfigNames.ANSWER_AND_RELEASE_ENABLED, true)) {
LogUtil.i("InCallActivity.shouldAllowAnswerAndRelease", "disabled by config");
return false;
}
@@ -1064,7 +1393,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity
return false;
}
InCallScreen inCallScreen = InCallBindings.createInCallScreen();
- transaction.add(R.id.main, inCallScreen.getInCallScreenFragment(), TAG_IN_CALL_SCREEN);
+ transaction.add(R.id.main, inCallScreen.getInCallScreenFragment(), Tags.IN_CALL_SCREEN);
Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
didShowInCallScreen = true;
return true;
@@ -1099,7 +1428,8 @@ public class InCallActivity extends TransactionSafeFragmentActivity
VideoCallScreen videoCallScreen =
VideoBindings.createVideoCallScreen(
call.getId(), call.getVideoTech().shouldUseSurfaceView());
- transaction.add(R.id.main, videoCallScreen.getVideoCallScreenFragment(), TAG_VIDEO_CALL_SCREEN);
+ transaction.add(
+ R.id.main, videoCallScreen.getVideoCallScreenFragment(), Tags.VIDEO_CALL_SCREEN);
Logger.get(this).logScreenView(ScreenEvent.Type.INCALL, this);
didShowVideoCallScreen = true;
@@ -1118,16 +1448,16 @@ public class InCallActivity extends TransactionSafeFragmentActivity
return true;
}
- AnswerScreen getAnswerScreen() {
- return (AnswerScreen) getSupportFragmentManager().findFragmentByTag(TAG_ANSWER_SCREEN);
+ private AnswerScreen getAnswerScreen() {
+ return (AnswerScreen) getSupportFragmentManager().findFragmentByTag(Tags.ANSWER_SCREEN);
}
- InCallScreen getInCallScreen() {
- return (InCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_IN_CALL_SCREEN);
+ private InCallScreen getInCallScreen() {
+ return (InCallScreen) getSupportFragmentManager().findFragmentByTag(Tags.IN_CALL_SCREEN);
}
- VideoCallScreen getVideoCallScreen() {
- return (VideoCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_VIDEO_CALL_SCREEN);
+ private VideoCallScreen getVideoCallScreen() {
+ return (VideoCallScreen) getSupportFragmentManager().findFragmentByTag(Tags.VIDEO_CALL_SCREEN);
}
@Override
@@ -1171,4 +1501,86 @@ public class InCallActivity extends TransactionSafeFragmentActivity
this.call = call;
}
}
+
+ private static final class IntentExtraNames {
+ static final String FOR_FULL_SCREEN = "InCallActivity.for_full_screen_intent";
+ static final String NEW_OUTGOING_CALL = "InCallActivity.new_outgoing_call";
+ static final String SHOW_DIALPAD = "InCallActivity.show_dialpad";
+ }
+
+ private static final class KeysForSavedInstance {
+ static final String DIALPAD_TEXT = "InCallActivity.dialpad_text";
+ static final String DID_SHOW_ANSWER_SCREEN = "did_show_answer_screen";
+ static final String DID_SHOW_IN_CALL_SCREEN = "did_show_in_call_screen";
+ static final String DID_SHOW_VIDEO_CALL_SCREEN = "did_show_video_call_screen";
+ }
+
+ /** Request codes for pending intents. */
+ public static final class PendingIntentRequestCodes {
+ static final int NON_FULL_SCREEN = 0;
+ static final int FULL_SCREEN = 1;
+ static final int BUBBLE = 2;
+ }
+
+ private static final class Tags {
+ static final String ANSWER_SCREEN = "tag_answer_screen";
+ static final String DIALPAD_FRAGMENT = "tag_dialpad_fragment";
+ static final String IN_CALL_SCREEN = "tag_in_call_screen";
+ static final String INTERNATIONAL_CALL_ON_WIFI = "tag_international_call_on_wifi";
+ static final String SELECT_ACCOUNT_FRAGMENT = "tag_select_account_fragment";
+ static final String VIDEO_CALL_SCREEN = "tag_video_call_screen";
+ static final String POST_CHAR_DIALOG_FRAGMENT = "tag_post_char_dialog_fragment";
+ }
+
+ private static final class ConfigNames {
+ static final String ANSWER_AND_RELEASE_ENABLED = "answer_and_release_enabled";
+ }
+
+ private static final class InternationalCallOnWifiCallback
+ implements InternationalCallOnWifiDialogFragment.Callback {
+ private static final String TAG = InternationalCallOnWifiCallback.class.getCanonicalName();
+
+ @Override
+ public void continueCall(@NonNull String callId) {
+ LogUtil.i(TAG, "Continuing call with ID: %s", callId);
+ }
+
+ @Override
+ public void cancelCall(@NonNull String callId) {
+ DialerCall call = CallList.getInstance().getCallById(callId);
+ if (call == null) {
+ LogUtil.i(TAG, "Call destroyed before the dialog is closed");
+ return;
+ }
+
+ LogUtil.i(TAG, "Disconnecting international call on WiFi");
+ call.disconnect();
+ }
+ }
+
+ private static final class SelectPhoneAccountListener
+ extends SelectPhoneAccountDialogFragment.SelectPhoneAccountListener {
+ private static final String TAG = SelectPhoneAccountListener.class.getCanonicalName();
+
+ @Override
+ public void onPhoneAccountSelected(
+ PhoneAccountHandle selectedAccountHandle, boolean setDefault, String callId) {
+ DialerCall call = CallList.getInstance().getCallById(callId);
+ LogUtil.i(TAG, "Phone account select with call:\n%s", call);
+
+ if (call != null) {
+ call.phoneAccountSelected(selectedAccountHandle, setDefault);
+ }
+ }
+
+ @Override
+ public void onDialogDismissed(String callId) {
+ DialerCall call = CallList.getInstance().getCallById(callId);
+ LogUtil.i(TAG, "Disconnecting call:\n%s" + call);
+
+ if (call != null) {
+ call.disconnect();
+ }
+ }
+ }
}