diff options
author | Yorke Lee <yorkelee@google.com> | 2014-11-24 09:25:08 -0800 |
---|---|---|
committer | Yorke Lee <yorkelee@google.com> | 2014-12-04 12:51:10 -0800 |
commit | 609c0d0d02c8b45369095ae69951fa687ee25673 (patch) | |
tree | 60cfff611557da485071777de48763b73454cf4b | |
parent | 67ca197575874cb39e14d1acfe2140ece3e86625 (diff) |
Improve outgoing call UI responsiveness
* Start InCallUI immediately once Telecom binds
* This CL is a bandaid for improving outgoing call responsiveness
in the MR1 timeframe. Refactoring InCallActivity into dynamically
added fragments and modifying its lifecycle with respect to
the call list is too risky.
* Add a lightweight activity (CircularRevealAnimationActivity)
that is used to display the circular reveal animation while
the significantly heavier InCallActivity is starting up
* Inside InCallServiceImpl.bind, start the reveal animation once
bind is called to avoid being blocked by any synchronous work in
Telecom.
* Refactor CallCardFragment.animateForNewOutgoingCall to
conditionally display the reveal animation, depending on
whether or not it was already displayed by the
CircularRevealAnimationActivity.
* Refactor the calculation of theme colors in InCallPresenter so that
the CircularRevealAnimationActivity can use those colors as well.
* Remove PENDING_OUTGOING from the list of call states that bring up
InCallUI.
Bug: 18373617
Bug: 18611753
Change-Id: I44c593373864ffc0ba9edebb88887177112d8b27
-rw-r--r-- | InCallUI/res/layout/outgoing_call_animation.xml | 22 | ||||
-rw-r--r-- | InCallUI/res/values/styles.xml | 23 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/CallCardFragment.java | 31 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/CircularRevealActivity.java | 165 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/InCallActivity.java | 16 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/InCallPresenter.java | 157 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/InCallServiceImpl.java | 18 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/StatusBarNotifier.java | 3 |
8 files changed, 380 insertions, 55 deletions
diff --git a/InCallUI/res/layout/outgoing_call_animation.xml b/InCallUI/res/layout/outgoing_call_animation.xml new file mode 100644 index 000000000..69ba3d3c6 --- /dev/null +++ b/InCallUI/res/layout/outgoing_call_animation.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ 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 + --> +<View xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/outgoing_call_animation_circle" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/incall_background_color" />
\ No newline at end of file diff --git a/InCallUI/res/values/styles.xml b/InCallUI/res/values/styles.xml index 17edfafc5..d99c66847 100644 --- a/InCallUI/res/values/styles.xml +++ b/InCallUI/res/values/styles.xml @@ -84,12 +84,23 @@ (Note that InCallActivity won't be destroyed once it is created) TODO: try removing the flag instead --> - <item name="android:taskOpenEnterAnimation">@anim/activity_open_enter</item> + <item name="android:taskOpenEnterAnimation">@null</item> <item name="android:taskOpenExitAnimation">@anim/activity_open_exit</item> <item name="android:taskToFrontEnterAnimation">@anim/activity_open_enter</item> <item name="android:taskToFrontExitAnimation">@anim/activity_open_exit</item> </style> + <style name="OutgoingCallAnimationStyle" parent="@android:style/Animation.Activity"> + <item name="android:taskOpenEnterAnimation">@null</item> + <item name="android:taskOpenExitAnimation">@null</item> + <item name="android:activityOpenEnterAnimation">@null</item> + <item name="android:activityOpenExitAnimation">@null</item> + <item name="android:activityCloseEnterAnimation">@null</item> + <item name="android:activityCloseExitAnimation">@null</item> + <item name="android:taskToFrontEnterAnimation">@null</item> + <item name="android:taskToFrontExitAnimation">@null</item> + </style> + <!-- Theme for the InCallActivity activity. Should have a transparent background for the circular reveal animation for a new outgoing call to work correctly. We don't just use Theme.Black.NoTitleBar directly, since we want any popups or dialogs from the @@ -99,6 +110,7 @@ <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> + <item name="android:windowNoTitle">true</item> <item name="dialpad_key_button_touch_tint">@color/incall_dialpad_touch_tint</item> <item name="android:textColorPrimary">@color/incall_call_banner_text_color</item> <item name="android:colorPrimaryDark">@color/dialer_theme_color_dark</item> @@ -106,6 +118,15 @@ <item name="android:actionBarStyle">@style/InCallActionBarStyle</item> </style> + <style name="Theme.CircularRevealAnimation" parent="@android:style/Theme.Material.Light"> + <item name="android:windowIsTranslucent">true</item> + <item name="android:windowContentOverlay">@null</item> + <item name="android:windowNoTitle">true</item> + <item name="android:colorPrimaryDark">@color/dialer_theme_color_dark</item> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:windowAnimationStyle">@null</item> + </style> + <style name="InCallPopupMenuStyle" parent="@android:style/Theme.Material.Light"> <item name="android:textColorPrimary">@color/popup_menu_color</item> </style> diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java index d3a229c9f..8648eee3f 100644 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ b/InCallUI/src/com/android/incallui/CallCardFragment.java @@ -112,8 +112,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr private int mVideoAnimationDuration; - private Drawable mDefaultContactPhoto; - private MaterialPalette mCurrentThemeColors; @Override @@ -817,7 +815,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr } } - public void animateForNewOutgoingCall(final Point touchPoint) { + public void animateForNewOutgoingCall(final Point touchPoint, + final boolean showCircularReveal) { final ViewGroup parent = (ViewGroup) mPrimaryCallCardContainer.getParent(); final ViewTreeObserver observer = getView().getViewTreeObserver(); @@ -849,19 +848,16 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr mCallTypeLabel.setAlpha(0); mCallNumberAndLabel.setAlpha(0); - final Animator revealAnimator = getRevealAnimator(touchPoint); - final Animator shrinkAnimator = - getShrinkAnimator(parent.getHeight(), originalHeight); + final Animator animator = getOutgoingCallAnimator(touchPoint, + parent.getHeight(), originalHeight, showCircularReveal); - mAnimatorSet = new AnimatorSet(); - mAnimatorSet.playSequentially(revealAnimator, shrinkAnimator); - mAnimatorSet.addListener(new AnimatorListenerAdapter() { + animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { setViewStatePostAnimation(listener); } }); - mAnimatorSet.start(); + animator.start(); } }); } @@ -987,6 +983,21 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr 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() diff --git a/InCallUI/src/com/android/incallui/CircularRevealActivity.java b/InCallUI/src/com/android/incallui/CircularRevealActivity.java new file mode 100644 index 000000000..ce6b33d31 --- /dev/null +++ b/InCallUI/src/com/android/incallui/CircularRevealActivity.java @@ -0,0 +1,165 @@ +/* + * 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(); + finish(); + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.outgoing_call_animation); + final Point touchPoint = getIntent().getParcelableExtra(TouchPointManager.TOUCH_POINT); + final MaterialPalette palette = getIntent().getParcelableExtra(EXTRA_THEME_COLORS); + setupDecorView(touchPoint, palette); + } + + @Override + protected void onStart() { + super.onStart(); + 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(); + } + + 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); + } + + @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/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java index e94a2dcad..f34f65fb3 100644 --- a/InCallUI/src/com/android/incallui/InCallActivity.java +++ b/InCallUI/src/com/android/incallui/InCallActivity.java @@ -65,7 +65,8 @@ 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 = "InCallActivity.new_outgoing_call"; + 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; @@ -202,7 +203,6 @@ public class InCallActivity extends Activity { mIsForegroundActivity = true; InCallPresenter.getInstance().setThemeColors(); - InCallPresenter.getInstance().onUiShowing(true); if (mShowDialpadRequested) { @@ -236,7 +236,6 @@ public class InCallActivity extends Activity { } InCallPresenter.getInstance().onUiShowing(false); - if (isFinishing()) { InCallPresenter.getInstance().unsetActivity(this); } @@ -479,8 +478,8 @@ public class InCallActivity extends Activity { relaunchedFromDialer(showDialpad); } - if (intent.getBooleanExtra(NEW_OUTGOING_CALL, false)) { - intent.removeExtra(NEW_OUTGOING_CALL); + if (intent.getBooleanExtra(NEW_OUTGOING_CALL_EXTRA, false)) { + intent.removeExtra(NEW_OUTGOING_CALL_EXTRA); Call call = CallList.getInstance().getOutgoingCall(); if (call == null) { call = CallList.getInstance().getPendingOutgoingCall(); @@ -506,7 +505,12 @@ public class InCallActivity extends Activity { } } - mCallCardFragment.animateForNewOutgoingCall(touchPoint); + // 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); /* * If both a phone account handle and a list of phone accounts to choose from are diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java index 72d45893c..1c1dc9616 100644 --- a/InCallUI/src/com/android/incallui/InCallPresenter.java +++ b/InCallUI/src/com/android/incallui/InCallPresenter.java @@ -16,10 +16,13 @@ package com.android.incallui; +import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.graphics.Point; import android.os.Bundle; +import android.os.Handler; import android.telecom.DisconnectCause; import android.telecom.PhoneAccount; import android.telecom.Phone; @@ -32,7 +35,7 @@ import android.view.View; import com.google.common.base.Preconditions; -import com.android.contacts.common.util.MaterialColorMapUtils; +import com.android.contacts.common.interactions.TouchPointManager; import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; import com.android.incalluibind.ObjectFactory; @@ -149,8 +152,24 @@ 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; + 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; @@ -233,9 +252,10 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } private void attemptFinishActivity() { + mWaitForRevealAnimationStart = false; + CircularRevealActivity.sendClearDisplayBroadcast(mContext); final boolean doFinish = (mInCallActivity != null && isActivityStarted()); Log.i(this, "Hide in call UI: " + doFinish); - if (doFinish) { mInCallActivity.finish(); @@ -680,6 +700,8 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { if (showing) { mIsActivityPreviouslyStarted = true; + } else { + CircularRevealActivity.sendClearDisplayBroadcast(mContext); } for (InCallUiListener listener : mInCallUiListeners) { @@ -845,12 +867,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { // TODO: Consider a proper state machine implementation - // If the state isn't changing or if we're transitioning from pending outgoing to actual - // outgoing, we have already done any starting/stopping of activities in a previous pass - // ...so lets cut out early - boolean alreadyOutgoing = mInCallState == InCallState.PENDING_OUTGOING && - newState == InCallState.OUTGOING; - if (newState == mInCallState || alreadyOutgoing) { + // If the state isn't changing we have already done any starting/stopping of activities in + // a previous pass...so lets cut out early + if (newState == mInCallState) { return newState; } @@ -895,8 +914,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { // This is different from the incoming call sequence because we do not need to shock the // user with a top-level notification. Just show the call UI normally. final boolean mainUiNotVisible = !isShowingInCallUi() || !getCallCardFragmentVisible(); - final boolean showCallUi = ((InCallState.PENDING_OUTGOING == newState || - InCallState.OUTGOING == newState) && mainUiNotVisible); + final boolean showCallUi = InCallState.OUTGOING == newState && mainUiNotVisible; // TODO: Can we be suddenly in a call without it having been in the outgoing or incoming // state? I havent seen that but if it can happen, the code below should be enabled. @@ -1043,21 +1061,87 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } } - private void showInCall(boolean showDialpad, boolean newOutgoingCall) { - mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall)); + public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) { + if (mCircularRevealActivityStarted) { + mWaitForRevealAnimationStart = true; + mShowDialpadOnStart = showDialpad; + } else { + mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall, + newOutgoingCall /* showCircularReveal */)); + } } - public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall) { - final Intent intent = new Intent(Intent.ACTION_MAIN, null); + public void onCircularRevealStarted(final Activity activity) { + mCircularRevealActivityStarted = false; + if (mWaitForRevealAnimationStart) { + mWaitForRevealAnimationStart = false; + mHandler.post(new Runnable() { + @Override + public void run() { + final Intent intent = + getInCallIntent(mShowDialpadOnStart, true, false, false); + activity.startActivity(intent); + mShowDialpadOnStart = false; + } + }); + + } + } + + public void maybeStartRevealAnimation(Intent intent) { + if (intent == null || mInCallActivity != null) { + return; + } + final Bundle extras = intent.getBundleExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS); + if (extras == null) { + // Incoming call, just show the in-call UI directly. + return; + } + + if (extras.containsKey(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS)) { + // Account selection dialog will show up so don't show the animation. + return; + } + + 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; + } + + public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall, + boolean showCircularReveal) { + return getInCallIntent(showDialpad, newOutgoingCall, showCircularReveal, true); + } + + public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall, + boolean showCircularReveal, boolean newTask) { + 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.setClass(mContext, InCallActivity.class); if (showDialpad) { intent.putExtra(InCallActivity.SHOW_DIALPAD_EXTRA, true); } - - intent.putExtra(InCallActivity.NEW_OUTGOING_CALL, newOutgoingCall); + intent.putExtra(InCallActivity.NEW_OUTGOING_CALL_EXTRA, newOutgoingCall); + intent.putExtra(InCallActivity.SHOW_CIRCULAR_REVEAL_EXTRA, showCircularReveal); return intent; } @@ -1163,26 +1247,13 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { * and a secondary color. */ public void setThemeColors() { + // This method will set the background to default if the color is PhoneAccount.NO_COLOR. + mThemeColors = getColorsFromCall(CallList.getInstance().getFirstCall()); + if (mInCallActivity == null) { return; } - Call call = CallList.getInstance().getFirstCall(); - TelecomManager tm = getTelecomManager(); - - int highlightColor = PhoneAccount.NO_HIGHLIGHT_COLOR; - - if (call != null && tm != null && tm.hasMultipleCallCapableAccounts()) { - PhoneAccount account = tm.getPhoneAccount(call.getAccountHandle()); - if (account != null) { - highlightColor = account.getHighlightColor(); - } - } - - // This method will set the background to default if the color is PhoneAccount.NO_COLOR. - mThemeColors = new InCallUIMaterialColorMapUtils(mContext.getResources()). - calculatePrimaryAndSecondaryColor(highlightColor); - mInCallActivity.getWindow().setStatusBarColor(mThemeColors.mSecondaryColor); } @@ -1193,13 +1264,33 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { return mThemeColors; } + private MaterialPalette getColorsFromCall(Call call) { + return getColorsFromPhoneAccountHandle(call == null ? null : call.getAccountHandle()); + } + + private MaterialPalette getColorsFromPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) { + int highlightColor = PhoneAccount.NO_HIGHLIGHT_COLOR; + if (phoneAccountHandle != null) { + final TelecomManager tm = getTelecomManager(); + + if (tm != null && tm.hasMultipleCallCapableAccounts()) { + final PhoneAccount account = tm.getPhoneAccount(phoneAccountHandle); + if (account != null) { + highlightColor = account.getHighlightColor(); + } + } + } + return new InCallUIMaterialColorMapUtils( + mContext.getResources()).calculatePrimaryAndSecondaryColor(highlightColor); + } + /** * @return An instance of TelecomManager. */ public TelecomManager getTelecomManager() { if (mTelecomManager == null) { mTelecomManager = (TelecomManager) - mInCallActivity.getSystemService(Context.TELECOM_SERVICE); + mContext.getSystemService(Context.TELECOM_SERVICE); } return mTelecomManager; } diff --git a/InCallUI/src/com/android/incallui/InCallServiceImpl.java b/InCallUI/src/com/android/incallui/InCallServiceImpl.java index 37e16a3bf..d413370e6 100644 --- a/InCallUI/src/com/android/incallui/InCallServiceImpl.java +++ b/InCallUI/src/com/android/incallui/InCallServiceImpl.java @@ -16,6 +16,8 @@ package com.android.incallui; +import android.content.Intent; +import android.os.IBinder; import android.telecom.InCallService; import android.telecom.Phone; @@ -34,10 +36,6 @@ public class InCallServiceImpl extends InCallService { AudioModeProvider.getInstance().setPhone(phone); TelecomAdapter.getInstance().setPhone(phone); InCallPresenter.getInstance().setPhone(phone); - InCallPresenter.getInstance().setUp( - getApplicationContext(), - CallList.getInstance(), - AudioModeProvider.getInstance()); TelecomAdapter.getInstance().setContext(InCallServiceImpl.this); } @@ -52,4 +50,16 @@ public class InCallServiceImpl extends InCallService { CallList.getInstance().clearOnDisconnect(); InCallPresenter.getInstance().tearDown(); } + + @Override + public IBinder onBind(Intent intent) { + InCallPresenter.getInstance().setUp( + getApplicationContext(), + CallList.getInstance(), + AudioModeProvider.getInstance()); + + InCallPresenter.getInstance().maybeStartRevealAnimation(intent); + + return super.onBind(intent); + } } diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java index 89192f882..99392d9fd 100644 --- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java +++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java @@ -627,7 +627,8 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener { private PendingIntent createLaunchPendingIntent() { final Intent intent = InCallPresenter.getInstance().getInCallIntent( - false /* showDialpad */, false /* newOutgoingCall */); + false /* showDialpad */, false /* newOutgoingCall */, + false /* showCircularReveal */); // PendingIntent that can be used to launch the InCallActivity. The // system fires off this intent if the user pulls down the windowshade |