summaryrefslogtreecommitdiff
path: root/InCallUI/src/com/android
diff options
context:
space:
mode:
authorYorke Lee <yorkelee@google.com>2015-02-19 18:03:00 -0800
committerYorke Lee <yorkelee@google.com>2015-03-04 15:59:10 -0800
commit6596e1be9d3e15e2cbe4a5e9c3824ee47a0e2744 (patch)
tree6c0d966c46d74faa69dc237455218e10c00436e6 /InCallUI/src/com/android
parentc4bb1c74483332ecdb11f1c50eee3433001b5cd8 (diff)
Remove CircularRevealActivity
Replace CircularRevealActivity with a fragment that is tied to the lifecycle of InCallActivity so that InCallActivity is the only activity that is involved in the outgoing call process. Simplify some of the intent creation logic that is used to launch InCallActivity since we no longer need some of the flags that were currently provided via various method overloads in InCallPresenter.getAnimationIntent and getInCallIntent. To further simplify this CL, a very rudimentary approach is taken to track the state where we are starting up the UI but haven't received a call from Telecom yet. This is done by a boolean flag set on the InCallPresenter: mBoundAndWaitingForOutgoingCall. Further changes will build upon and improve this. Also set most elements inside primary_call_info.xml to visibility: GONE by default to fix some animation jank where a empty but not GONE view would continue to take up space. Change-Id: Ic70857685680af6868d4b2153d942d73eef3ca56
Diffstat (limited to 'InCallUI/src/com/android')
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java69
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java4
-rw-r--r--InCallUI/src/com/android/incallui/CircularRevealActivity.java179
-rw-r--r--InCallUI/src/com/android/incallui/CircularRevealFragment.java159
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java10
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java146
-rw-r--r--InCallUI/src/com/android/incallui/StatusBarNotifier.java3
7 files changed, 244 insertions, 326 deletions
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 649176ce9..00e619609 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -24,7 +24,6 @@ import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
-import android.graphics.Point;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -33,11 +32,9 @@ import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.text.format.DateUtils;
-import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
-import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver;
@@ -51,7 +48,6 @@ import android.widget.TextView;
import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
import com.android.contacts.common.widget.FloatingActionButtonController;
-import com.android.incallui.service.PhoneNumberService;
import com.android.phone.common.animation.AnimUtils;
import java.util.List;
@@ -63,7 +59,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
implements CallCardPresenter.CallCardUi {
private AnimatorSet mAnimatorSet;
- private int mRevealAnimationDuration;
private int mShrinkAnimationDuration;
private int mFabNormalDiameter;
private int mFabSmallDiameter;
@@ -108,9 +103,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
private ImageButton mFloatingActionButton;
private int mFloatingActionButtonVerticalOffset;
- // Cached DisplayMetrics density.
- private float mDensity;
-
private float mTranslationOffset;
private Animation mPulseAnimation;
@@ -132,7 +124,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mRevealAnimationDuration = getResources().getInteger(R.integer.reveal_animation_duration);
mShrinkAnimationDuration = getResources().getInteger(R.integer.shrink_animation_duration);
mVideoAnimationDuration = getResources().getInteger(R.integer.video_animation_duration);
mFloatingActionButtonVerticalOffset = getResources().getDimensionPixelOffset(
@@ -156,9 +147,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- super.onCreateView(inflater, container, savedInstanceState);
-
- mDensity = getResources().getDisplayMetrics().density;
mTranslationOffset =
getResources().getDimensionPixelSize(R.dimen.call_card_anim_translate_y_offset);
@@ -230,6 +218,9 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mPrimaryName.setElegantTextHeight(false);
mCallStateLabel.setElegantTextHeight(false);
+
+ final LayoutTransition transition = mPrimaryCallInfo.getLayoutTransition();
+ transition.enableTransitionType(LayoutTransition.CHANGING);
}
@Override
@@ -425,7 +416,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
public void setPrimary(String number, String name, boolean nameIsNumber, String label,
Drawable photo, boolean isSipCall) {
Log.d(this, "Setting primary call");
-
// set the name field.
setPrimaryName(name, nameIsNumber);
@@ -842,13 +832,14 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
}
}
- public void animateForNewOutgoingCall(final Point touchPoint,
- final boolean showCircularReveal) {
+ @Override
+ public void animateForNewOutgoingCall() {
final ViewGroup parent = (ViewGroup) mPrimaryCallCardContainer.getParent();
final ViewTreeObserver observer = getView().getViewTreeObserver();
- mPrimaryCallInfo.getLayoutTransition().disableTransitionType(LayoutTransition.CHANGING);
+ final LayoutTransition transition = mPrimaryCallInfo.getLayoutTransition();
+ transition.disableTransitionType(LayoutTransition.CHANGING);
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
@@ -862,21 +853,21 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
final LayoutIgnoringListener listener = new LayoutIgnoringListener();
mPrimaryCallCardContainer.addOnLayoutChangeListener(listener);
- // Prepare the state of views before the circular reveal animation
+ // Prepare the state of views before the slide animation
final int originalHeight = mPrimaryCallCardContainer.getHeight();
mPrimaryCallCardContainer.setBottom(parent.getHeight());
// Set up FAB.
mFloatingActionButtonContainer.setVisibility(View.GONE);
mFloatingActionButtonController.setScreenWidth(parent.getWidth());
+
mCallButtonsContainer.setAlpha(0);
mCallStateLabel.setAlpha(0);
mPrimaryName.setAlpha(0);
mCallTypeLabel.setAlpha(0);
mCallNumberAndLabel.setAlpha(0);
- final Animator animator = getOutgoingCallAnimator(touchPoint,
- parent.getHeight(), originalHeight, showCircularReveal);
+ final Animator animator = getShrinkAnimator(parent.getHeight(), originalHeight);
animator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -990,41 +981,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
return shrinkAnimator;
}
- private Animator getRevealAnimator(Point touchPoint) {
- final Activity activity = getActivity();
- final View view = activity.getWindow().getDecorView();
- final Display display = activity.getWindowManager().getDefaultDisplay();
- final Point size = new Point();
- display.getSize(size);
-
- int startX = size.x / 2;
- int startY = size.y / 2;
- if (touchPoint != null) {
- startX = touchPoint.x;
- startY = touchPoint.y;
- }
-
- final Animator valueAnimator = ViewAnimationUtils.createCircularReveal(view,
- startX, startY, 0, Math.max(size.x, size.y));
- valueAnimator.setDuration(mRevealAnimationDuration);
- return valueAnimator;
- }
-
- private Animator getOutgoingCallAnimator(Point touchPoint, int startHeight, int endHeight,
- boolean showCircularReveal) {
-
- final Animator shrinkAnimator = getShrinkAnimator(startHeight, endHeight);
-
- if (!showCircularReveal) {
- return shrinkAnimator;
- }
-
- final Animator revealAnimator = getRevealAnimator(touchPoint);
- final AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playSequentially(revealAnimator, shrinkAnimator);
- return animatorSet;
- }
-
private void assignTranslateAnimation(View view, int offset) {
view.setTranslationY(mTranslationOffset * offset);
view.animate().translationY(0).alpha(1).withLayer()
@@ -1045,7 +1001,10 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
setViewStatePostAnimation(mCallStateIcon);
mPrimaryCallCardContainer.removeOnLayoutChangeListener(layoutChangeListener);
- mPrimaryCallInfo.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
+
+ final LayoutTransition transition = mPrimaryCallInfo.getLayoutTransition();
+ transition.enableTransitionType(LayoutTransition.CHANGING);
+
mFloatingActionButtonController.scaleIn(AnimUtils.NO_DELAY);
}
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index cb378a687..ab93c2d8e 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -17,6 +17,8 @@
package com.android.incallui;
import android.Manifest;
+import android.app.Activity;
+import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -34,6 +36,7 @@ import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import com.android.incallui.CircularRevealFragment.OnCircularRevealCompleteListener;
import com.android.incallui.ContactInfoCache.ContactCacheEntry;
import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
import com.android.incallui.InCallPresenter.InCallDetailsListener;
@@ -743,5 +746,6 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
void setProgressSpinnerVisible(boolean visible);
void showManageConferenceCallButton(boolean visible);
boolean isManageConferenceVisible();
+ void animateForNewOutgoingCall();
}
}
diff --git a/InCallUI/src/com/android/incallui/CircularRevealActivity.java b/InCallUI/src/com/android/incallui/CircularRevealActivity.java
deleted file mode 100644
index 4dc58baa8..000000000
--- a/InCallUI/src/com/android/incallui/CircularRevealActivity.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2014 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.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.Outline;
-import android.graphics.Point;
-import android.os.Bundle;
-import android.support.v4.content.LocalBroadcastManager;
-import android.view.Display;
-import android.view.View;
-import android.view.ViewAnimationUtils;
-import android.view.ViewOutlineProvider;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
-
-import com.android.contacts.common.interactions.TouchPointManager;
-import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
-
-/**
- * Lightweight activity used to display a circular reveal while InCallActivity is starting up.
- * A BroadcastReceiver is used to listen to broadcasts from a LocalBroadcastManager to finish
- * the activity at suitable times.
- */
-public class CircularRevealActivity extends Activity {
- private static final int REVEAL_DURATION = 333;
- public static final String EXTRA_THEME_COLORS = "extra_theme_colors";
- public static final String ACTION_CLEAR_DISPLAY = "action_clear_display";
-
- final BroadcastReceiver mClearDisplayReceiver = new BroadcastReceiver( ) {
- @Override
- public void onReceive(Context context, Intent intent) {
- clearDisplay();
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- overridePendingTransition(0, 0);
- setContentView(R.layout.outgoing_call_animation);
- prepareDecorViewFromIntent(getIntent());
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- if (!InCallPresenter.getInstance().isServiceBound()) {
- clearDisplay();
- }
- final IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_CLEAR_DISPLAY);
- LocalBroadcastManager.getInstance(this).registerReceiver(mClearDisplayReceiver, filter);
- }
-
- @Override
- protected void onStop() {
- LocalBroadcastManager.getInstance(this).unregisterReceiver(mClearDisplayReceiver);
- super.onStop();
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- setIntent(intent);
- prepareDecorViewFromIntent(intent);
- }
-
- private void prepareDecorViewFromIntent(Intent intent) {
- final Point touchPoint = intent.getParcelableExtra(TouchPointManager.TOUCH_POINT);
- final MaterialPalette palette = intent.getParcelableExtra(EXTRA_THEME_COLORS);
- setupDecorView(touchPoint, palette);
- }
-
- private void setupDecorView(final Point touchPoint, MaterialPalette palette) {
- final View view = getWindow().getDecorView();
-
- // The circle starts from an initial size of 0 so clip it such that it is invisible. When
- // the animation later starts, this clip will be clobbered by the circular reveal clip.
- // See ViewAnimationUtils.createCircularReveal.
- view.setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- // Using (0, 0, 0, 0) will not work since the outline will simply be treated as
- // an empty outline.
- outline.setOval(-1, -1, 0, 0);
- }
- });
- view.setClipToOutline(true);
-
- if (palette != null) {
- view.findViewById(R.id.outgoing_call_animation_circle).setBackgroundColor(
- palette.mPrimaryColor);
- getWindow().setStatusBarColor(palette.mSecondaryColor);
- }
-
- view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- final ViewTreeObserver vto = view.getViewTreeObserver();
- if (vto.isAlive()) {
- vto.removeOnPreDrawListener(this);
- }
- final Animator animator = getRevealAnimator(touchPoint);
- // Since this animator is a RenderNodeAnimator (native animator), add an arbitary
- // start delay to force the onAnimationStart callback to happen later on the UI
- // thread. Otherwise it would happen right away inside animator.start()
- animator.setStartDelay(5);
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- InCallPresenter.getInstance().onCircularRevealStarted(
- CircularRevealActivity.this);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- view.setClipToOutline(false);
- super.onAnimationEnd(animation);
- }
- });
- animator.start();
- return false;
- }
- });
- }
-
- private void clearDisplay() {
- getWindow().getDecorView().setVisibility(View.INVISIBLE);
- finish();
- }
-
- @Override
- public void onBackPressed() {
- return;
- }
-
- public static void sendClearDisplayBroadcast(Context context) {
- LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ACTION_CLEAR_DISPLAY));
- }
-
- private Animator getRevealAnimator(Point touchPoint) {
- final View view = getWindow().getDecorView();
- final Display display = getWindowManager().getDefaultDisplay();
- final Point size = new Point();
- display.getSize(size);
-
- int startX = size.x / 2;
- int startY = size.y / 2;
- if (touchPoint != null) {
- startX = touchPoint.x;
- startY = touchPoint.y;
- }
-
- final Animator valueAnimator = ViewAnimationUtils.createCircularReveal(view,
- startX, startY, 0, Math.max(size.x, size.y));
- valueAnimator.setDuration(REVEAL_DURATION);
- return valueAnimator;
- }
-}
diff --git a/InCallUI/src/com/android/incallui/CircularRevealFragment.java b/InCallUI/src/com/android/incallui/CircularRevealFragment.java
new file mode 100644
index 000000000..c2821792b
--- /dev/null
+++ b/InCallUI/src/com/android/incallui/CircularRevealFragment.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014 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.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.graphics.Outline;
+import android.graphics.Point;
+import android.os.Bundle;
+import android.view.Display;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnPreDrawListener;
+
+import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
+
+public class CircularRevealFragment extends Fragment {
+ static final String TAG = "CircularRevealFragment";
+
+ private Point mTouchPoint;
+ private OnCircularRevealCompleteListener mListener;
+ private boolean mAnimationStarted;
+
+ interface OnCircularRevealCompleteListener {
+ public void onCircularRevealComplete(FragmentManager fm);
+ }
+
+ public static void startCircularReveal(FragmentManager fm, Point touchPoint,
+ OnCircularRevealCompleteListener listener) {
+ fm.beginTransaction().add(R.id.main, new CircularRevealFragment(touchPoint, listener), TAG)
+ .commitAllowingStateLoss();
+ }
+
+ public static void endCircularReveal(FragmentManager fm) {
+ final Fragment fragment = fm.findFragmentByTag(TAG);
+ if (fragment != null) {
+ fm.beginTransaction().remove(fragment).commitAllowingStateLoss();
+ }
+ }
+
+ /**
+ * Empty constructor used only by the {@link FragmentManager}.
+ */
+ public CircularRevealFragment() {}
+
+ public CircularRevealFragment(Point touchPoint, OnCircularRevealCompleteListener listener) {
+ mTouchPoint = touchPoint;
+ mListener = listener;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (!mAnimationStarted) {
+ // Only run the animation once for each instance of the fragment
+ startOutgoingAnimation(InCallPresenter.getInstance().getThemeColors());
+ }
+ mAnimationStarted = true;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.outgoing_call_animation, container, false);
+ }
+
+ public void startOutgoingAnimation(MaterialPalette palette) {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ Log.w(this, "Asked to do outgoing call animation when not attached");
+ return;
+ }
+
+ final View view = activity.getWindow().getDecorView();
+
+ // The circle starts from an initial size of 0 so clip it such that it is invisible.
+ // Otherwise the first frame is drawn with a fully opaque screen which causes jank. When
+ // the animation later starts, this clip will be clobbered by the circular reveal clip.
+ // See ViewAnimationUtils.createCircularReveal.
+ view.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ // Using (0, 0, 0, 0) will not work since the outline will simply be treated as
+ // an empty outline.
+ outline.setOval(-1, -1, 0, 0);
+ }
+ });
+ view.setClipToOutline(true);
+
+ if (palette != null) {
+ view.findViewById(R.id.outgoing_call_animation_circle).setBackgroundColor(
+ palette.mPrimaryColor);
+ activity.getWindow().setStatusBarColor(palette.mSecondaryColor);
+ }
+
+ view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ final ViewTreeObserver vto = view.getViewTreeObserver();
+ if (vto.isAlive()) {
+ vto.removeOnPreDrawListener(this);
+ }
+ final Animator animator = getRevealAnimator(mTouchPoint);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setClipToOutline(false);
+ if (mListener != null) {
+ mListener.onCircularRevealComplete(getFragmentManager());
+ }
+ }
+ });
+ animator.start();
+ return false;
+ }
+ });
+ }
+
+ private Animator getRevealAnimator(Point touchPoint) {
+ final Activity activity = getActivity();
+ final View view = activity.getWindow().getDecorView();
+ final Display display = activity.getWindowManager().getDefaultDisplay();
+ final Point size = new Point();
+ display.getSize(size);
+
+ int startX = size.x / 2;
+ int startY = size.y / 2;
+ if (touchPoint != null) {
+ startX = touchPoint.x;
+ startY = touchPoint.y;
+ }
+
+ final Animator valueAnimator = ViewAnimationUtils.createCircularReveal(view,
+ startX, startY, 0, Math.max(size.x, size.y));
+ valueAnimator.setDuration(getResources().getInteger(R.integer.reveal_animation_duration));
+ return valueAnimator;
+ }
+}
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index 32bee93a7..f692627a1 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -66,7 +66,6 @@ public class InCallActivity extends Activity {
public static final String SHOW_DIALPAD_EXTRA = "InCallActivity.show_dialpad";
public static final String DIALPAD_TEXT_EXTRA = "InCallActivity.dialpad_text";
public static final String NEW_OUTGOING_CALL_EXTRA = "InCallActivity.new_outgoing_call";
- public static final String SHOW_CIRCULAR_REVEAL_EXTRA = "InCallActivity.show_circular_reveal";
private CallButtonFragment mCallButtonFragment;
private CallCardFragment mCallCardFragment;
@@ -489,12 +488,9 @@ public class InCallActivity extends Activity {
}
}
- // This is only true in the case where an outgoing call is initiated by tapping
- // on the "Select account dialog", in which case we skip the initial animation. In
- // most other cases the circular reveal is done by OutgoingCallAnimationActivity.
- final boolean showCircularReveal =
- intent.getBooleanExtra(SHOW_CIRCULAR_REVEAL_EXTRA, false);
- mCallCardFragment.animateForNewOutgoingCall(touchPoint, showCircularReveal);
+ // Start animation for new outgoing call
+ CircularRevealFragment.startCircularReveal(getFragmentManager(), touchPoint,
+ InCallPresenter.getInstance());
// InCallActivity is responsible for disconnecting a new outgoing call if there
// is no way of making it (i.e. no valid call capable accounts)
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index ce6d439d1..82ce58c11 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -16,14 +16,13 @@
package com.android.incallui;
-import android.app.Activity;
+import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccount;
import android.telecom.Phone;
@@ -57,7 +56,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
* that want to listen in on the in-call state changes.
* TODO: This class has become more of a state machine at this point. Consider renaming.
*/
-public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
+public class InCallPresenter implements CallList.Listener, InCallPhoneListener,
+ CircularRevealFragment.OnCircularRevealCompleteListener {
private static final String EXTRA_FIRST_TIME_SHOWN =
"com.android.incallui.intent.extra.FIRST_TIME_SHOWN";
@@ -97,6 +97,16 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
private boolean mAccountSelectionCancelled = false;
private InCallCameraManager mInCallCameraManager = null;
+ /**
+ * Whether or not we are currently bound and waiting for Telecom to send us a new call.
+ */
+ private boolean mBoundAndWaitingForOutgoingCall;
+ /**
+ * If there is no actual call currently in the call list, this will be used as a fallback
+ * to determine the theme color for InCallUI.
+ */
+ private PhoneAccountHandle mPendingPhoneAccountHandle;
+
private final Phone.Listener mPhoneListener = new Phone.Listener() {
@Override
public void onBringToForeground(Phone phone, boolean showDialpad) {
@@ -105,6 +115,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
@Override
public void onCallAdded(Phone phone, android.telecom.Call call) {
+ // Since a call has been added we are no longer waiting for Telecom to send us a
+ // call.
+ setBoundAndWaitingForOutgoingCall(false, null);
call.addListener(mCallListener);
}
@Override
@@ -156,20 +169,6 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
*/
private boolean mIsActivityPreviouslyStarted = false;
-
- /**
- * Whether or not to wait for the circular reveal animation to be started, to avoid stopping
- * the circular reveal animation activity before the animation is initiated.
- */
- private boolean mWaitForRevealAnimationStart = false;
-
- /**
- * Whether or not the CircularRevealAnimationActivity has started.
- */
- private boolean mCircularRevealActivityStarted = false;
-
- private boolean mShowDialpadOnStart = false;
-
/**
* Whether or not InCallService is bound to Telecom.
*/
@@ -177,8 +176,6 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
private Phone mPhone;
- private Handler mHandler = new Handler();
-
/** Display colors for the UI. Consists of a primary color and secondary (darker) color */
private MaterialPalette mThemeColors;
@@ -261,13 +258,6 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
private void attemptFinishActivity() {
- mWaitForRevealAnimationStart = false;
-
- Context context = mContext != null ? mContext : mInCallActivity;
- if (context != null) {
- CircularRevealActivity.sendClearDisplayBroadcast(context);
- }
-
final boolean doFinish = (mInCallActivity != null && isActivityStarted());
Log.i(this, "Hide in call UI: " + doFinish);
if (doFinish) {
@@ -457,7 +447,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
/**
* Given the call list, return the state in which the in-call screen should be.
*/
- public static InCallState getPotentialStateFromCallList(CallList callList) {
+ public InCallState getPotentialStateFromCallList(CallList callList) {
InCallState newState = InCallState.NO_CALLS;
@@ -479,9 +469,40 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
newState = InCallState.INCALL;
}
+ if (newState == InCallState.NO_CALLS) {
+ if (mBoundAndWaitingForOutgoingCall) {
+ return InCallState.OUTGOING;
+ }
+ }
+
return newState;
}
+ public boolean isBoundAndWaitingForOutgoingCall() {
+ return mBoundAndWaitingForOutgoingCall;
+ }
+
+ public void setBoundAndWaitingForOutgoingCall(boolean isBound, PhoneAccountHandle handle) {
+ // NOTE: It is possible for there to be a race and have handle become null before
+ // the circular reveal starts. This should not cause any problems because CallCardFragment
+ // should fallback to the actual call in the CallList at that point in time to determine
+ // the theme color.
+ Log.i(this, "setBoundAndWaitingForOutgoingCall: " + isBound);
+ mBoundAndWaitingForOutgoingCall = isBound;
+ mPendingPhoneAccountHandle = handle;
+ if (isBound && mInCallState == InCallState.NO_CALLS) {
+ mInCallState = InCallState.OUTGOING;
+ }
+ }
+
+ @Override
+ public void onCircularRevealComplete(FragmentManager fm) {
+ if (mInCallActivity != null) {
+ mInCallActivity.getCallCardFragment().animateForNewOutgoingCall();
+ CircularRevealFragment.endCircularReveal(mInCallActivity.getFragmentManager());
+ }
+ }
+
public void addIncomingCallListener(IncomingCallListener listener) {
Preconditions.checkNotNull(listener);
mIncomingCallListeners.add(listener);
@@ -714,8 +735,6 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
if (showing) {
mIsActivityPreviouslyStarted = true;
- } else {
- CircularRevealActivity.sendClearDisplayBroadcast(mContext);
}
for (InCallUiListener listener : mInCallUiListeners) {
@@ -1125,35 +1144,8 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) {
- if (mCircularRevealActivityStarted) {
- mWaitForRevealAnimationStart = true;
- mShowDialpadOnStart = showDialpad;
- Log.i(this, "Waiting for circular reveal completion to show InCallActivity");
- } else {
- Log.i(this, "Showing InCallActivity immediately");
- mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall,
- newOutgoingCall /* showCircularReveal */));
- }
- }
-
- public void onCircularRevealStarted(final Activity activity) {
- mCircularRevealActivityStarted = false;
- if (mWaitForRevealAnimationStart) {
- mWaitForRevealAnimationStart = false;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Log.i(this, "Showing InCallActivity after circular reveal");
- final Intent intent =
- getInCallIntent(mShowDialpadOnStart, true, false, false);
- activity.startActivity(intent);
- mShowDialpadOnStart = false;
- }
- });
- } else if (!mServiceBound) {
- CircularRevealActivity.sendClearDisplayBroadcast(mContext);
- return;
- }
+ Log.i(this, "Showing InCallActivity");
+ mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall));
}
public void onServiceBind() {
@@ -1161,6 +1153,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
public void onServiceUnbind() {
+ InCallPresenter.getInstance().setBoundAndWaitingForOutgoingCall(false, null);
mServiceBound = false;
}
@@ -1185,43 +1178,26 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
final PhoneAccountHandle accountHandle =
intent.getParcelableExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
- final MaterialPalette colors = getColorsFromPhoneAccountHandle(accountHandle);
final Point touchPoint = extras.getParcelable(TouchPointManager.TOUCH_POINT);
- mCircularRevealActivityStarted = true;
- mContext.startActivity(getAnimationIntent(touchPoint, colors));
- }
-
- private Intent getAnimationIntent(Point touchPoint, MaterialPalette palette) {
- final Intent intent = new Intent(mContext, CircularRevealActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
- intent.putExtra(TouchPointManager.TOUCH_POINT, touchPoint);
- intent.putExtra(CircularRevealActivity.EXTRA_THEME_COLORS, palette);
- return intent;
- }
+ InCallPresenter.getInstance().setBoundAndWaitingForOutgoingCall(true, accountHandle);
- public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall,
- boolean showCircularReveal) {
- return getInCallIntent(showDialpad, newOutgoingCall, showCircularReveal, true);
+ final Intent incallIntent = getInCallIntent(false, true);
+ incallIntent.putExtra(TouchPointManager.TOUCH_POINT, touchPoint);
+ mContext.startActivity(incallIntent);
}
- public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall,
- boolean showCircularReveal, boolean newTask) {
+ public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall) {
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
- if (newTask) {
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
+ | Intent.FLAG_ACTIVITY_NO_USER_ACTION
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(mContext, InCallActivity.class);
if (showDialpad) {
intent.putExtra(InCallActivity.SHOW_DIALPAD_EXTRA, true);
}
intent.putExtra(InCallActivity.NEW_OUTGOING_CALL_EXTRA, newOutgoingCall);
- intent.putExtra(InCallActivity.SHOW_CIRCULAR_REVEAL_EXTRA, showCircularReveal);
return intent;
}
@@ -1359,7 +1335,11 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
private MaterialPalette getColorsFromCall(Call call) {
- return getColorsFromPhoneAccountHandle(call == null ? null : call.getAccountHandle());
+ if (call == null) {
+ return getColorsFromPhoneAccountHandle(mPendingPhoneAccountHandle);
+ } else {
+ return getColorsFromPhoneAccountHandle(call.getAccountHandle());
+ }
}
private MaterialPalette getColorsFromPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) {
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 99392d9fd..89192f882 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -627,8 +627,7 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
private PendingIntent createLaunchPendingIntent() {
final Intent intent = InCallPresenter.getInstance().getInCallIntent(
- false /* showDialpad */, false /* newOutgoingCall */,
- false /* showCircularReveal */);
+ false /* showDialpad */, false /* newOutgoingCall */);
// PendingIntent that can be used to launch the InCallActivity. The
// system fires off this intent if the user pulls down the windowshade