From c3968e62c44530369eb2ca73bc0f7290e53bd613 Mon Sep 17 00:00:00 2001 From: linyuh Date: Mon, 20 Nov 2017 17:40:50 -0800 Subject: Merge what's left in InCallActivityCommon into InCallActivity. Bug: 69272096 Test: None PiperOrigin-RevId: 176443652 Change-Id: I90da4789deb4b6337a38cfe010b8aee5090d35e0 --- java/com/android/incallui/InCallActivity.java | 614 +++++++++++++++++---- .../com/android/incallui/InCallActivityCommon.java | 575 ------------------- java/com/android/incallui/InCallPresenter.java | 2 +- .../incallui/NewReturnToCallController.java | 2 +- .../android/incallui/ReturnToCallController.java | 2 +- java/com/android/incallui/StatusBarNotifier.java | 4 +- 6 files changed, 518 insertions(+), 681 deletions(-) delete mode 100644 java/com/android/incallui/InCallActivityCommon.java 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 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 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 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(); + } + } + } } diff --git a/java/com/android/incallui/InCallActivityCommon.java b/java/com/android/incallui/InCallActivityCommon.java deleted file mode 100644 index d2aae485d..000000000 --- a/java/com/android/incallui/InCallActivityCommon.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.app.ActivityManager; -import android.app.ActivityManager.AppTask; -import android.app.Dialog; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Bundle; -import android.os.Trace; -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.telecom.CallAudioState; -import android.telecom.PhoneAccountHandle; -import android.view.WindowManager; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; -import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener; -import com.android.dialer.animation.AnimUtils; -import com.android.dialer.animation.AnimationListenerAdapter; -import com.android.dialer.common.LogUtil; -import com.android.dialer.compat.CompatUtils; -import com.android.dialer.logging.Logger; -import com.android.dialer.logging.ScreenEvent; -import com.android.dialer.util.ViewUtil; -import com.android.incallui.audiomode.AudioModeProvider; -import com.android.incallui.call.CallList; -import com.android.incallui.call.DialerCall; -import com.android.incallui.call.DialerCall.State; -import com.android.incallui.telecomeventui.InternationalCallOnWifiDialogFragment; -import com.android.incallui.telecomeventui.InternationalCallOnWifiDialogFragment.Callback; -import com.google.common.base.Optional; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.List; - -/** Shared functionality between the new and old in call activity. */ -public class InCallActivityCommon { - - private static final String INTENT_EXTRA_SHOW_DIALPAD = "InCallActivity.show_dialpad"; - private static final String INTENT_EXTRA_NEW_OUTGOING_CALL = "InCallActivity.new_outgoing_call"; - private static final String INTENT_EXTRA_FOR_FULL_SCREEN = - "InCallActivity.for_full_screen_intent"; - - private static final String DIALPAD_TEXT_KEY = "InCallActivity.dialpad_text"; - - private static final String TAG_SELECT_ACCOUNT_FRAGMENT = "tag_select_account_fragment"; - private static final String TAG_DIALPAD_FRAGMENT = "tag_dialpad_fragment"; - private static final String TAG_INTERNATIONAL_CALL_ON_WIFI = "tag_international_call_on_wifi"; - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - DIALPAD_REQUEST_NONE, - DIALPAD_REQUEST_SHOW, - DIALPAD_REQUEST_HIDE, - }) - @interface DialpadRequestType {} - - 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 Optional audioRouteForTesting = Optional.absent(); - - private final InCallActivity inCallActivity; - private boolean showPostCharWaitDialogOnResume; - private String showPostCharWaitDialogCallId; - private String showPostCharWaitDialogChars; - private Dialog errorDialog; - private SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment; - private Animation dialpadSlideInAnimation; - private Animation dialpadSlideOutAnimation; - private boolean animateDialpadOnShow; - private String dtmfTextToPreopulate; - @DialpadRequestType private int showDialpadRequest = DIALPAD_REQUEST_NONE; - // If activity is going to be recreated. This is usually happening in {@link onNewIntent}. - private boolean isRecreating; - - private final SelectPhoneAccountListener selectAccountListener = - new SelectPhoneAccountListener() { - @Override - public void onPhoneAccountSelected( - PhoneAccountHandle selectedAccountHandle, boolean setDefault, String callId) { - DialerCall call = CallList.getInstance().getCallById(callId); - LogUtil.i( - "InCallActivityCommon.SelectPhoneAccountListener.onPhoneAccountSelected", - "call: " + call); - if (call != null) { - call.phoneAccountSelected(selectedAccountHandle, setDefault); - } - } - - @Override - public void onDialogDismissed(String callId) { - DialerCall call = CallList.getInstance().getCallById(callId); - LogUtil.i( - "InCallActivityCommon.SelectPhoneAccountListener.onDialogDismissed", - "disconnecting call: " + call); - if (call != null) { - call.disconnect(); - } - } - }; - - private InternationalCallOnWifiDialogFragment.Callback internationalCallOnWifiCallback = - new Callback() { - @Override - public void continueCall(@NonNull String callId) { - LogUtil.i("InCallActivityCommon.continueCall", "continuing call with id: %s", callId); - } - - @Override - public void cancelCall(@NonNull String callId) { - DialerCall call = CallList.getInstance().getCallById(callId); - if (call == null) { - LogUtil.i("InCallActivityCommon.cancelCall", "call destroyed before dialog closed"); - return; - } - LogUtil.i("InCallActivityCommon.cancelCall", "disconnecting international call on wifi"); - call.disconnect(); - } - }; - - public static void setIntentExtras( - Intent intent, boolean showDialpad, boolean newOutgoingCall, boolean isForFullScreen) { - if (showDialpad) { - intent.putExtra(INTENT_EXTRA_SHOW_DIALPAD, true); - } - intent.putExtra(INTENT_EXTRA_NEW_OUTGOING_CALL, newOutgoingCall); - intent.putExtra(INTENT_EXTRA_FOR_FULL_SCREEN, isForFullScreen); - } - - public InCallActivityCommon(InCallActivity inCallActivity) { - this.inCallActivity = inCallActivity; - } - - public void onCreate(Bundle icicle) { - setWindowFlags(); - - inCallActivity.setContentView(R.layout.incall_screen); - - internalResolveIntent(inCallActivity.getIntent()); - - boolean isLandscape = - inCallActivity.getResources().getConfiguration().orientation - == Configuration.ORIENTATION_LANDSCAPE; - boolean isRtl = ViewUtil.isRtl(); - - if (isLandscape) { - dialpadSlideInAnimation = - AnimationUtils.loadAnimation( - inCallActivity, isRtl ? R.anim.dialpad_slide_in_left : R.anim.dialpad_slide_in_right); - dialpadSlideOutAnimation = - AnimationUtils.loadAnimation( - inCallActivity, - isRtl ? R.anim.dialpad_slide_out_left : R.anim.dialpad_slide_out_right); - } else { - dialpadSlideInAnimation = - AnimationUtils.loadAnimation(inCallActivity, R.anim.dialpad_slide_in_bottom); - dialpadSlideOutAnimation = - AnimationUtils.loadAnimation(inCallActivity, 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) { - performHideDialpadFragment(); - } - }); - - // Don't override the value if show dialpad request is true in intent extras. - if (icicle != null && showDialpadRequest == DIALPAD_REQUEST_NONE) { - // If the dialpad was shown before, set variables indicating it should be shown and - // populated with the previous DTMF text. The dialpad is actually shown and populated - // in onResume() to ensure the hosting fragment has been inflated and is ready to receive it. - if (icicle.containsKey(INTENT_EXTRA_SHOW_DIALPAD)) { - boolean showDialpad = icicle.getBoolean(INTENT_EXTRA_SHOW_DIALPAD); - showDialpadRequest = showDialpad ? DIALPAD_REQUEST_SHOW : DIALPAD_REQUEST_HIDE; - animateDialpadOnShow = false; - } - dtmfTextToPreopulate = icicle.getString(DIALPAD_TEXT_KEY); - - SelectPhoneAccountDialogFragment dialogFragment = - (SelectPhoneAccountDialogFragment) - inCallActivity.getFragmentManager().findFragmentByTag(TAG_SELECT_ACCOUNT_FRAGMENT); - if (dialogFragment != null) { - dialogFragment.setListener(selectAccountListener); - } - } - - InternationalCallOnWifiDialogFragment existingInternationalFragment = - (InternationalCallOnWifiDialogFragment) - inCallActivity - .getSupportFragmentManager() - .findFragmentByTag(TAG_INTERNATIONAL_CALL_ON_WIFI); - if (existingInternationalFragment != null) { - LogUtil.i( - "InCallActivityCommon.onCreate", "international fragment exists attaching callback"); - existingInternationalFragment.setCallback(internationalCallOnWifiCallback); - } - } - - public void onResume() { - Trace.beginSection("InCallActivityCommon.onResume"); - if (InCallPresenter.getInstance().isReadyForTearDown()) { - LogUtil.i( - "InCallActivityCommon.onResume", - "InCallPresenter is ready for tear down, not sending updates"); - } else { - inCallActivity.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 and - // can hide the dialpad. Important when showing the dialpad from within dialer. - InCallPresenter.getInstance().setFullScreen(false, true /* force */); - - inCallActivity.showDialpadFragment(true /* show */, animateDialpadOnShow /* animate */); - animateDialpadOnShow = false; - - DialpadFragment dialpadFragment = inCallActivity.getDialpadFragment(); - if (dialpadFragment != null) { - dialpadFragment.setDtmfText(dtmfTextToPreopulate); - dtmfTextToPreopulate = null; - } - } else { - LogUtil.i("InCallActivityCommon.onResume", "force hide dialpad"); - if (inCallActivity.getDialpadFragment() != null) { - inCallActivity.showDialpadFragment(false /* show */, false /* animate */); - } - } - showDialpadRequest = DIALPAD_REQUEST_NONE; - } - inCallActivity.updateNavigationBar(inCallActivity.isDialpadVisible()); - - if (showPostCharWaitDialogOnResume) { - showPostCharWaitDialog(showPostCharWaitDialogCallId, showPostCharWaitDialogChars); - } - - CallList.getInstance() - .onInCallUiShown( - inCallActivity.getIntent().getBooleanExtra(INTENT_EXTRA_FOR_FULL_SCREEN, false)); - Trace.endSection(); - } - - void onNewIntent(Intent intent, boolean isRecreating) { - LogUtil.i("InCallActivityCommon.onNewIntent", ""); - 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 potentially 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!) - inCallActivity.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 recreate since this will be called in onCreate(). - if (!isRecreating) { - internalResolveIntent(intent); - } - } - - 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; - } - - inCallActivity.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); - } - - public void showPostCharWaitDialog(String callId, String chars) { - if (inCallActivity.isVisible()) { - PostCharDialogFragment fragment = new PostCharDialogFragment(callId, chars); - fragment.show(inCallActivity.getSupportFragmentManager(), "postCharWait"); - - showPostCharWaitDialogOnResume = false; - showPostCharWaitDialogCallId = null; - showPostCharWaitDialogChars = null; - } else { - showPostCharWaitDialogOnResume = true; - showPostCharWaitDialogCallId = callId; - showPostCharWaitDialogChars = chars; - } - } - - /** - * 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(); - } - } - } - - public void setExcludeFromRecents(boolean exclude) { - List tasks = inCallActivity.getSystemService(ActivityManager.class).getAppTasks(); - int taskId = inCallActivity.getTaskId(); - for (int i = 0; i < tasks.size(); i++) { - ActivityManager.AppTask task = tasks.get(i); - try { - if (task.getTaskInfo().id == taskId) { - task.setExcludeFromRecents(exclude); - } - } catch (RuntimeException e) { - LogUtil.e( - "InCallActivityCommon.setExcludeFromRecents", - "RuntimeException when excluding task from recents.", - e); - } - } - } - - public boolean showDialpadFragment(boolean show, boolean animate) { - // If the dialpad is already visible, don't animate in. If it's gone, don't animate out. - boolean isDialpadVisible = inCallActivity.isDialpadVisible(); - LogUtil.i( - "InCallActivityCommon.showDialpadFragment", - "show: %b, animate: %b, " + "isDialpadVisible: %b", - show, - animate, - isDialpadVisible); - if (show == isDialpadVisible) { - return false; - } - - FragmentManager dialpadFragmentManager = inCallActivity.getDialpadFragmentManager(); - if (dialpadFragmentManager == null) { - LogUtil.i( - "InCallActivityCommon.showDialpadFragment", "unable to show or hide dialpad fragment"); - return false; - } - - // We don't do a FragmentTransaction on the hide case because it will be dealt with when - // the listener is fired after an animation finishes. - if (!animate) { - if (show) { - performShowDialpadFragment(dialpadFragmentManager); - } else { - performHideDialpadFragment(); - } - } else { - if (show) { - performShowDialpadFragment(dialpadFragmentManager); - inCallActivity.getDialpadFragment().animateShowDialpad(); - } - inCallActivity - .getDialpadFragment() - .getView() - .startAnimation(show ? dialpadSlideInAnimation : dialpadSlideOutAnimation); - } - - ProximitySensor sensor = InCallPresenter.getInstance().getProximitySensor(); - if (sensor != null) { - sensor.onDialpadVisible(show); - } - showDialpadRequest = DIALPAD_REQUEST_NONE; - return true; - } - - private void performShowDialpadFragment(@NonNull FragmentManager dialpadFragmentManager) { - FragmentTransaction transaction = dialpadFragmentManager.beginTransaction(); - DialpadFragment dialpadFragment = inCallActivity.getDialpadFragment(); - if (dialpadFragment == null) { - transaction.add( - inCallActivity.getDialpadContainerId(), new DialpadFragment(), TAG_DIALPAD_FRAGMENT); - } else { - transaction.show(dialpadFragment); - } - - transaction.commitAllowingStateLoss(); - dialpadFragmentManager.executePendingTransactions(); - - Logger.get(inCallActivity).logScreenView(ScreenEvent.Type.INCALL_DIALPAD, inCallActivity); - inCallActivity.updateNavigationBar(true /* isDialpadVisible */); - } - - private void performHideDialpadFragment() { - FragmentManager fragmentManager = inCallActivity.getDialpadFragmentManager(); - if (fragmentManager == null) { - LogUtil.e( - "InCallActivityCommon.performHideDialpadFragment", "child fragment manager is null"); - return; - } - - Fragment fragment = fragmentManager.findFragmentByTag(TAG_DIALPAD_FRAGMENT); - if (fragment != null) { - FragmentTransaction transaction = fragmentManager.beginTransaction(); - transaction.hide(fragment); - transaction.commitAllowingStateLoss(); - fragmentManager.executePendingTransactions(); - } - inCallActivity.updateNavigationBar(false /* isDialpadVisible */); - } - - private void internalResolveIntent(Intent intent) { - if (!intent.getAction().equals(Intent.ACTION_MAIN)) { - return; - } - - if (intent.hasExtra(INTENT_EXTRA_SHOW_DIALPAD)) { - // SHOW_DIALPAD_EXTRA can be used here to specify whether the DTMF - // dialpad should be initially visible. If the extra isn't - // present at all, we just leave the dialpad in its previous state. - boolean showDialpad = intent.getBooleanExtra(INTENT_EXTRA_SHOW_DIALPAD, false); - LogUtil.i("InCallActivityCommon.internalResolveIntent", "SHOW_DIALPAD_EXTRA: " + showDialpad); - - relaunchedFromDialer(showDialpad); - } - - DialerCall outgoingCall = CallList.getInstance().getOutgoingCall(); - if (outgoingCall == null) { - outgoingCall = CallList.getInstance().getPendingOutgoingCall(); - } - - if (intent.getBooleanExtra(INTENT_EXTRA_NEW_OUTGOING_CALL, false)) { - intent.removeExtra(INTENT_EXTRA_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, then ignore this code. - if (CompatUtils.isMSIMCompatible() - && InCallPresenter.isCallWithNoValidAccounts(outgoingCall)) { - LogUtil.i( - "InCallActivityCommon.internalResolveIntent", - "call with no valid accounts, disconnecting"); - outgoingCall.disconnect(); - } - - inCallActivity.dismissKeyguard(true); - } - - boolean didShowAccountSelectionDialog = maybeShowAccountSelectionDialog(); - if (didShowAccountSelectionDialog) { - inCallActivity.hideMainInCallFragment(); - } - } - - private boolean maybeShowAccountSelectionDialog() { - DialerCall waitingForAccountCall = CallList.getInstance().getWaitingForAccountCall(); - if (waitingForAccountCall == null) { - return false; - } - - Bundle extras = waitingForAccountCall.getIntentExtras(); - List phoneAccountHandles; - if (extras != null) { - phoneAccountHandles = - extras.getParcelableArrayList(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS); - } else { - phoneAccountHandles = new ArrayList<>(); - } - - selectPhoneAccountDialogFragment = - SelectPhoneAccountDialogFragment.newInstance( - R.string.select_phone_account_for_calls, - true, - 0, - phoneAccountHandles, - selectAccountListener, - waitingForAccountCall.getId(), - null); - selectPhoneAccountDialogFragment.show( - inCallActivity.getFragmentManager(), TAG_SELECT_ACCOUNT_FRAGMENT); - return true; - } - - /** @deprecated Only for temporary use during the deprecation of {@link InCallActivityCommon} */ - @Deprecated - @Nullable - Dialog getErrorDialog() { - return errorDialog; - } - - /** @deprecated Only for temporary use during the deprecation of {@link InCallActivityCommon} */ - @Deprecated - void setErrorDialog(@Nullable Dialog errorDialog) { - this.errorDialog = errorDialog; - } - - /** @deprecated Only for temporary use during the deprecation of {@link InCallActivityCommon} */ - @Deprecated - boolean getIsRecreating() { - return isRecreating; - } - - /** @deprecated Only for temporary use during the deprecation of {@link InCallActivityCommon} */ - @Deprecated - @Nullable - SelectPhoneAccountDialogFragment getSelectPhoneAccountDialogFragment() { - return selectPhoneAccountDialogFragment; - } - - /** @deprecated Only for temporary use during the deprecation of {@link InCallActivityCommon} */ - @Deprecated - void setSelectPhoneAccountDialogFragment( - @Nullable SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment) { - this.selectPhoneAccountDialogFragment = selectPhoneAccountDialogFragment; - } - - /** @deprecated Only for temporary use during the deprecation of {@link InCallActivityCommon} */ - @Deprecated - InternationalCallOnWifiDialogFragment.Callback getCallbackForInternationalCallOnWifiDialog() { - return internationalCallOnWifiCallback; - } -} diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 3ba2ccff6..c5310b969 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -1110,7 +1110,7 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud public void onPostDialCharWait(String callId, String chars) { if (isActivityStarted()) { - mInCallActivity.showPostCharWaitDialog(callId, chars); + mInCallActivity.showDialogForPostCharWait(callId, chars); } } diff --git a/java/com/android/incallui/NewReturnToCallController.java b/java/com/android/incallui/NewReturnToCallController.java index 97bf7ad50..8f2463e8b 100644 --- a/java/com/android/incallui/NewReturnToCallController.java +++ b/java/com/android/incallui/NewReturnToCallController.java @@ -93,7 +93,7 @@ public class NewReturnToCallController implements InCallUiListener, Listener, Au activityIntent.putExtra(RETURN_TO_CALL_EXTRA_KEY, true); fullScreen = PendingIntent.getActivity( - context, InCallActivity.PENDING_INTENT_REQUEST_CODE_BUBBLE, activityIntent, 0); + context, InCallActivity.PendingIntentRequestCodes.BUBBLE, activityIntent, 0); InCallPresenter.getInstance().addInCallUiListener(this); CallList.getInstance().addListener(this); diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java index 89731bc0d..5f4cc5f84 100644 --- a/java/com/android/incallui/ReturnToCallController.java +++ b/java/com/android/incallui/ReturnToCallController.java @@ -236,7 +236,7 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio context.getResources().getDimensionPixelOffset(R.dimen.return_to_call_initial_offset_y)) .setPrimaryIntent( PendingIntent.getActivity( - context, InCallActivity.PENDING_INTENT_REQUEST_CODE_BUBBLE, activityIntent, 0)) + context, InCallActivity.PendingIntentRequestCodes.BUBBLE, activityIntent, 0)) .setActions(generateActions()) .build(); } diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java index 0a0aa5e61..4da858fff 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -1007,11 +1007,11 @@ public class StatusBarNotifier InCallActivity.getIntent( mContext, false /* showDialpad */, false /* newOutgoingCall */, isFullScreen); - int requestCode = InCallActivity.PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN; + int requestCode = InCallActivity.PendingIntentRequestCodes.NON_FULL_SCREEN; if (isFullScreen) { // Use a unique request code so that the pending intent isn't clobbered by the // non-full screen pending intent. - requestCode = InCallActivity.PENDING_INTENT_REQUEST_CODE_FULL_SCREEN; + requestCode = InCallActivity.PendingIntentRequestCodes.FULL_SCREEN; } // PendingIntent that can be used to launch the InCallActivity. The -- cgit v1.2.3 From 6d67975290cae16971dd30779ed60dba44962ecc Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Tue, 21 Nov 2017 10:53:53 -0800 Subject: Nearby places location permission request is now in a card view. Bug: 68272141 Test: n/a PiperOrigin-RevId: 176531675 Change-Id: Ia6cc29c4285ebe280d23a81f91007a02a65855b3 --- .../res/layout/location_permission_row.xml | 100 ++++++++++++--------- .../nearbyplaces/res/values/strings.xml | 2 +- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/layout/location_permission_row.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/layout/location_permission_row.xml index 66a3e0c49..4373252bd 100644 --- a/java/com/android/dialer/searchfragment/nearbyplaces/res/layout/location_permission_row.xml +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/layout/location_permission_row.xml @@ -14,53 +14,65 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> - + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_marginTop="8dp" + app:cardElevation="2dp"> - - - + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:paddingTop="16dp" + android:paddingBottom="12dp"> + + + + -