summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/drawable/ic_chevron_left.xml28
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml6
-rw-r--r--packages/SystemUI/res/values/dimens.xml12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java429
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java)389
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java133
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java97
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java70
11 files changed, 885 insertions, 312 deletions
diff --git a/packages/SystemUI/res/drawable/ic_chevron_left.xml b/packages/SystemUI/res/drawable/ic_chevron_left.xml
new file mode 100644
index 0000000..27c2034
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_chevron_left.xml
@@ -0,0 +1,28 @@
+<!--
+ ~ 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
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="24dp"
+ android:height="24dp"/>
+
+ <viewport
+ android:viewportWidth="36.0"
+ android:viewportHeight="36.0"/>
+
+ <path
+ android:fill="#ffffffff"
+ android:pathData="M23.1,11.1l-2.1000004,-2.1000004 -9.0,9.0 9.0,9.0 2.1000004,-2.1000004 -6.8999996,-6.8999996z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index db5983b..42fb740 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
>
- <com.android.systemui.statusbar.AlphaImageView
+ <com.android.systemui.statusbar.KeyguardAffordanceView
android:id="@+id/camera_button"
android:layout_height="64dp"
android:layout_width="64dp"
@@ -32,7 +32,7 @@
android:scaleType="center"
android:contentDescription="@string/accessibility_camera_button" />
- <com.android.systemui.statusbar.AlphaImageView
+ <com.android.systemui.statusbar.KeyguardAffordanceView
android:id="@+id/phone_button"
android:layout_height="64dp"
android:layout_width="64dp"
@@ -52,7 +52,7 @@
android:textColor="#ffffff"
android:textAppearance="?android:attr/textAppearanceSmall"/>
- <com.android.systemui.statusbar.AlphaImageView
+ <com.android.systemui.statusbar.KeyguardAffordanceView
android:id="@+id/lock_icon"
android:layout_width="64dp"
android:layout_height="64dp"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9bc2b0d..4e536e4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -295,6 +295,15 @@
<!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
<dimen name="keyguard_min_swipe_amount">75dp</dimen>
+ <!-- The minimum background radius when swiping to a side for the camera / phone affordances. -->
+ <dimen name="keyguard_affordance_min_background_radius">30dp</dimen>
+
+ <!-- The grow amount for the camera and phone circles when hinting -->
+ <dimen name="hint_grow_amount_sideways">60dp</dimen>
+
+ <!-- The chevron padding to the circle when hinting -->
+ <dimen name="hint_chevron_circle_padding">16dp</dimen>
+
<!-- Volume panel dialog y offset -->
<dimen name="volume_panel_top">0dp</dimen>
@@ -317,9 +326,6 @@
<!-- Move distance for the unlock hint animation on the lockscreen -->
<dimen name="hint_move_distance">75dp</dimen>
- <!-- Move distance for the other hint animations on the lockscreen (phone, camera)-->
- <dimen name="hint_move_distance_sideways">60dp</dimen>
-
<!-- The width of the region on the left/right edge of the screen for performing the camera/
phone hints. -->
<dimen name="edge_tap_area_width">48dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 0a288d9..225b6af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -244,9 +244,6 @@ public abstract class BaseStatusBar extends SystemUI implements
// the user switches to home. We know it is safe to do at this
// point, so make sure new activity switches are now allowed.
ActivityManagerNative.getDefault().resumeAppSwitches();
- // Also, notifications can be launched from the lock screen,
- // so dismiss the lock screen when the activity starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
} catch (RemoteException e) {
}
@@ -1153,9 +1150,6 @@ public abstract class BaseStatusBar extends SystemUI implements
// the user switches to home. We know it is safe to do at this
// point, so make sure new activity switches are now allowed.
ActivityManagerNative.getDefault().resumeAppSwitches();
- // Also, notifications can be launched from the lock screen,
- // so dismiss the lock screen when the activity starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
} catch (RemoteException e) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
new file mode 100644
index 0000000..845e0ae
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -0,0 +1,429 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ArgbEvaluator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.widget.ImageView;
+import com.android.systemui.R;
+
+/**
+ * An ImageView which does not have overlapping renderings commands and therefore does not need a
+ * layer when alpha is changed.
+ */
+public class KeyguardAffordanceView extends ImageView {
+
+ private static final long CIRCLE_APPEAR_DURATION = 80;
+ private static final long CIRCLE_DISAPPEAR_MAX_DURATION = 200;
+ private static final long NORMAL_ANIMATION_DURATION = 200;
+ public static final float MAX_ICON_SCALE_AMOUNT = 1.5f;
+ public static final float MIN_ICON_SCALE_AMOUNT = 0.8f;
+
+ private final int mMinBackgroundRadius;
+ private final Paint mCirclePaint;
+ private final Interpolator mAppearInterpolator;
+ private final Interpolator mDisappearInterpolator;
+ private final int mInverseColor;
+ private final int mNormalColor;
+ private final ArgbEvaluator mColorInterpolator;
+ private final FlingAnimationUtils mFlingAnimationUtils;
+ private final Drawable mArrowDrawable;
+ private final int mHintChevronPadding;
+ private float mCircleRadius;
+ private int mCenterX;
+ private int mCenterY;
+ private ValueAnimator mCircleAnimator;
+ private ValueAnimator mAlphaAnimator;
+ private ValueAnimator mScaleAnimator;
+ private ValueAnimator mArrowAnimator;
+ private float mCircleStartValue;
+ private boolean mCircleWillBeHidden;
+ private int[] mTempPoint = new int[2];
+ private float mImageScale;
+ private int mCircleColor;
+ private boolean mIsLeft;
+ private float mArrowAlpha = 0.0f;
+ private AnimatorListenerAdapter mCircleEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCircleAnimator = null;
+ }
+ };
+ private AnimatorListenerAdapter mScaleEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mScaleAnimator = null;
+ }
+ };
+ private AnimatorListenerAdapter mAlphaEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAlphaAnimator = null;
+ }
+ };
+ private AnimatorListenerAdapter mArrowEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mArrowAnimator = null;
+ }
+ };
+
+ public KeyguardAffordanceView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardAffordanceView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardAffordanceView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public KeyguardAffordanceView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mCirclePaint = new Paint();
+ mCirclePaint.setAntiAlias(true);
+ mCircleColor = 0xffffffff;
+ mCirclePaint.setColor(mCircleColor);
+
+ mNormalColor = 0xffffffff;
+ mInverseColor = 0xff000000;
+ mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_affordance_min_background_radius);
+ mHintChevronPadding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.hint_chevron_circle_padding);
+ mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.linear_out_slow_in);
+ mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_linear_in);
+ mColorInterpolator = new ArgbEvaluator();
+ mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.3f);
+ mArrowDrawable = context.getDrawable(R.drawable.ic_chevron_left);
+ mArrowDrawable.setBounds(0, 0, mArrowDrawable.getIntrinsicWidth(),
+ mArrowDrawable.getIntrinsicHeight());
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ mCenterX = getWidth() / 2;
+ mCenterY = getHeight() / 2;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ drawBackgroundCircle(canvas);
+ drawArrow(canvas);
+ canvas.save();
+ updateIconColor();
+ canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2);
+ super.onDraw(canvas);
+ canvas.restore();
+ }
+
+ private void drawArrow(Canvas canvas) {
+ if (mArrowAlpha > 0) {
+ canvas.save();
+ canvas.translate(mCenterX, mCenterY);
+ if (mIsLeft) {
+ canvas.scale(-1.0f, 1.0f);
+ }
+ canvas.translate(- mCircleRadius - mHintChevronPadding
+ - mArrowDrawable.getIntrinsicWidth() / 2,
+ - mArrowDrawable.getIntrinsicHeight() / 2);
+ mArrowDrawable.setAlpha((int) (mArrowAlpha * 255));
+ mArrowDrawable.draw(canvas);
+ canvas.restore();
+ }
+ }
+
+ private void updateIconColor() {
+ Drawable drawable = getDrawable().mutate();
+ float alpha = mCircleRadius / mMinBackgroundRadius;
+ alpha = Math.min(1.0f, alpha);
+ int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mInverseColor);
+ drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+ }
+
+ private void drawBackgroundCircle(Canvas canvas) {
+ if (mCircleRadius > 0) {
+ updateCircleColor();
+ canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mCirclePaint);
+ }
+ }
+
+ private void updateCircleColor() {
+ float fraction = 0.5f + 0.5f * Math.max(0.0f, Math.min(1.0f,
+ (mCircleRadius - mMinBackgroundRadius) / (0.5f * mMinBackgroundRadius)));
+ int color = Color.argb((int) (Color.alpha(mCircleColor) * fraction),
+ Color.red(mCircleColor),
+ Color.green(mCircleColor), Color.blue(mCircleColor));
+ mCirclePaint.setColor(color);
+ }
+
+ public void finishAnimation(float velocity, final Runnable mAnimationEndRunnable) {
+ cancelAnimator(mCircleAnimator);
+ float maxCircleSize = getMaxCircleSize();
+ ValueAnimator animatorToRadius = getAnimatorToRadius(maxCircleSize);
+ mFlingAnimationUtils.applyDismissing(animatorToRadius, mCircleRadius, maxCircleSize,
+ velocity, maxCircleSize);
+ animatorToRadius.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimationEndRunnable.run();
+ }
+ });
+ animatorToRadius.start();
+ setImageAlpha(0, true);
+ }
+
+ private float getMaxCircleSize() {
+ getLocationInWindow(mTempPoint);
+ float rootWidth = getRootView().getWidth();
+ float width = mTempPoint[0] + mCenterX;
+ width = Math.max(rootWidth - width, width);
+ float height = mTempPoint[1] + mCenterY;
+ return (float) Math.hypot(width, height);
+ }
+
+ public void setCircleRadius(float circleRadius) {
+ setCircleRadius(circleRadius, false);
+ }
+
+ public void setCircleRadiusWithoutAnimation(float circleRadius) {
+ cancelAnimator(mCircleAnimator);
+ setCircleRadius(circleRadius, true);
+ }
+
+ private void setCircleRadius(float circleRadius, boolean noAnimation) {
+
+ // Check if we need a new animation
+ boolean radiusHidden = (mCircleAnimator != null && mCircleWillBeHidden)
+ || (mCircleAnimator == null && mCircleRadius == 0.0f);
+ boolean nowHidden = circleRadius == 0.0f;
+ boolean radiusNeedsAnimation = (radiusHidden != nowHidden) && !noAnimation;
+ if (!radiusNeedsAnimation) {
+ if (mCircleAnimator == null) {
+ mCircleRadius = circleRadius;
+ invalidate();
+ } else if (!mCircleWillBeHidden) {
+
+ // We just update the end value
+ float diff = circleRadius - mMinBackgroundRadius;
+ PropertyValuesHolder[] values = mCircleAnimator.getValues();
+ values[0].setFloatValues(mCircleStartValue + diff, circleRadius);
+ mCircleAnimator.setCurrentPlayTime(mCircleAnimator.getCurrentPlayTime());
+ }
+ } else {
+ cancelAnimator(mCircleAnimator);
+ ValueAnimator animator = getAnimatorToRadius(circleRadius);
+ Interpolator interpolator = circleRadius == 0.0f
+ ? mDisappearInterpolator
+ : mAppearInterpolator;
+ animator.setInterpolator(interpolator);
+ float durationFactor = Math.abs(mCircleRadius - circleRadius)
+ / (float) mMinBackgroundRadius;
+ long duration = (long) (CIRCLE_APPEAR_DURATION * durationFactor);
+ duration = Math.min(duration, CIRCLE_DISAPPEAR_MAX_DURATION);
+ animator.setDuration(duration);
+ animator.start();
+ }
+ }
+
+ private ValueAnimator getAnimatorToRadius(float circleRadius) {
+ ValueAnimator animator = ValueAnimator.ofFloat(mCircleRadius, circleRadius);
+ mCircleAnimator = animator;
+ mCircleStartValue = mCircleRadius;
+ mCircleWillBeHidden = circleRadius == 0.0f;
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mCircleRadius = (float) animation.getAnimatedValue();
+ invalidate();
+ }
+ });
+ animator.addListener(mCircleEndListener);
+ return animator;
+ }
+
+ private void cancelAnimator(Animator animator) {
+ if (animator != null) {
+ animator.cancel();
+ }
+ }
+
+ public void setImageScale(float imageScale, boolean animate) {
+ setImageScale(imageScale, animate, -1, null);
+ }
+
+ /**
+ * Sets the scale of the containing image
+ *
+ * @param imageScale The new Scale.
+ * @param animate Should an animation be performed
+ * @param duration If animate, whats the duration? When -1 we take the default duration
+ * @param interpolator If animate, whats the interpolator? When null we take the default
+ * interpolator.
+ */
+ public void setImageScale(float imageScale, boolean animate, long duration,
+ Interpolator interpolator) {
+ cancelAnimator(mScaleAnimator);
+ if (!animate) {
+ mImageScale = imageScale;
+ invalidate();
+ } else {
+ ValueAnimator animator = ValueAnimator.ofFloat(mImageScale, imageScale);
+ mScaleAnimator = animator;
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mImageScale = (float) animation.getAnimatedValue();
+ invalidate();
+ }
+ });
+ animator.addListener(mScaleEndListener);
+ if (interpolator == null) {
+ interpolator = imageScale == 0.0f
+ ? mDisappearInterpolator
+ : mAppearInterpolator;
+ }
+ animator.setInterpolator(interpolator);
+ if (duration == -1) {
+ float durationFactor = Math.abs(mImageScale - imageScale)
+ / (1.0f - MIN_ICON_SCALE_AMOUNT);
+ durationFactor = Math.min(1.0f, durationFactor);
+ duration = (long) (NORMAL_ANIMATION_DURATION * durationFactor);
+ }
+ animator.setDuration(duration);
+ animator.start();
+ }
+ }
+
+ public void setImageAlpha(float alpha, boolean animate) {
+ setImageAlpha(alpha, animate, -1, null, null);
+ }
+
+ /**
+ * Sets the alpha of the containing image
+ *
+ * @param alpha The new alpha.
+ * @param animate Should an animation be performed
+ * @param duration If animate, whats the duration? When -1 we take the default duration
+ * @param interpolator If animate, whats the interpolator? When null we take the default
+ * interpolator.
+ */
+ public void setImageAlpha(float alpha, boolean animate, long duration,
+ Interpolator interpolator, Runnable runnable) {
+ cancelAnimator(mAlphaAnimator);
+ int endAlpha = (int) (alpha * 255);
+ if (!animate) {
+ setImageAlpha(endAlpha);
+ } else {
+ int currentAlpha = getImageAlpha();
+ ValueAnimator animator = ValueAnimator.ofInt(currentAlpha, endAlpha);
+ mAlphaAnimator = animator;
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ setImageAlpha((int) animation.getAnimatedValue());
+ }
+ });
+ animator.addListener(mAlphaEndListener);
+ if (interpolator == null) {
+ interpolator = alpha == 0.0f
+ ? mDisappearInterpolator
+ : mAppearInterpolator;
+ }
+ animator.setInterpolator(interpolator);
+ if (duration == -1) {
+ float durationFactor = Math.abs(currentAlpha - endAlpha) / 255f;
+ durationFactor = Math.min(1.0f, durationFactor);
+ duration = (long) (NORMAL_ANIMATION_DURATION * durationFactor);
+ }
+ animator.setDuration(duration);
+ if (runnable != null) {
+ animator.addListener(getEndListener(runnable));
+ }
+ animator.start();
+ }
+ }
+
+ private Animator.AnimatorListener getEndListener(final Runnable runnable) {
+ return new AnimatorListenerAdapter() {
+ boolean mCancelled;
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCancelled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mCancelled) {
+ runnable.run();
+ }
+ }
+ };
+ }
+
+ public float getCircleRadius() {
+ return mCircleRadius;
+ }
+
+ public void showArrow(boolean show) {
+ cancelAnimator(mArrowAnimator);
+ float targetAlpha = show ? 1.0f : 0.0f;
+ if (mArrowAlpha == targetAlpha) {
+ return;
+ }
+ ValueAnimator animator = ValueAnimator.ofFloat(mArrowAlpha, targetAlpha);
+ mArrowAnimator = animator;
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mArrowAlpha = (float) animation.getAnimatedValue();
+ invalidate();
+ }
+ });
+ animator.addListener(mArrowEndListener);
+ Interpolator interpolator = show
+ ? mAppearInterpolator
+ : mDisappearInterpolator;
+ animator.setInterpolator(interpolator);
+ float durationFactor = Math.abs(mArrowAlpha - targetAlpha);
+ long duration = (long) (NORMAL_ANIMATION_DURATION * durationFactor);
+ animator.setDuration(duration);
+ animator.start();
+ }
+
+ public void setIsLeft(boolean left) {
+ mIsLeft = left;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index d5f9619..a8a0cb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -21,28 +21,28 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.os.PowerManager;
+import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import com.android.systemui.R;
import com.android.systemui.statusbar.FlingAnimationUtils;
-
-import java.util.ArrayList;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
/**
- * A touch handler of the Keyguard which is responsible for swiping the content left or right.
+ * A touch handler of the keyguard which is responsible for launching phone and camera affordances.
*/
-public class KeyguardPageSwipeHelper {
+public class KeyguardAffordanceHelper {
- private static final float SWIPE_MAX_ICON_SCALE_AMOUNT = 2.0f;
public static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.5f;
- public static final long HINT_PHASE1_DURATION = 250;
- private static final long HINT_PHASE2_DURATION = 450;
+ public static final long HINT_PHASE1_DURATION = 200;
+ private static final long HINT_PHASE2_DURATION = 350;
+ private static final float BACKGROUND_RADIUS_SCALE_FACTOR = 0.15f;
+ private static final int HINT_CIRCLE_OPEN_DURATION = 500;
private final Context mContext;
@@ -58,25 +58,42 @@ public class KeyguardPageSwipeHelper {
private int mTouchSlop;
private int mMinTranslationAmount;
private int mMinFlingVelocity;
- private int mHintDistance;
- private final View mLeftIcon;
- private final View mCenterIcon;
- private final View mRightIcon;
- private Interpolator mFastOutSlowIn;
- private Interpolator mBounceInterpolator;
+ private int mHintGrowAmount;
+ private final KeyguardAffordanceView mLeftIcon;
+ private final KeyguardAffordanceView mCenterIcon;
+ private final KeyguardAffordanceView mRightIcon;
+ private Interpolator mAppearInterpolator;
+ private Interpolator mDisappearInterpolator;
private Animator mSwipeAnimator;
- private boolean mCallbackCalled;
+ private int mMinBackgroundRadius;
+ private boolean mMotionPerformedByUser;
+ private PowerManager mPM;
+ private AnimatorListenerAdapter mFlingEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mSwipeAnimator = null;
+ setSwipingInProgress(false);
+ }
+ };
+ private Runnable mAnimationEndRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onAnimationToSideEnded();
+ }
+ };
- KeyguardPageSwipeHelper(Callback callback, Context context) {
+ KeyguardAffordanceHelper(Callback callback, Context context) {
mContext = context;
mCallback = callback;
mLeftIcon = mCallback.getLeftIcon();
+ mLeftIcon.setIsLeft(true);
mCenterIcon = mCallback.getCenterIcon();
mRightIcon = mCallback.getRightIcon();
- updateIcon(mLeftIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
- updateIcon(mCenterIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
- updateIcon(mRightIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mLeftIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mCenterIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mRightIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
initDimens();
+ mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
private void initDimens() {
@@ -85,12 +102,15 @@ public class KeyguardPageSwipeHelper {
mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
R.dimen.keyguard_min_swipe_amount);
- mHintDistance =
- mContext.getResources().getDimensionPixelSize(R.dimen.hint_move_distance_sideways);
+ mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_affordance_min_background_radius);
+ mHintGrowAmount =
+ mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways);
mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
- mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext,
- android.R.interpolator.fast_out_slow_in);
- mBounceInterpolator = new BounceInterpolator();
+ mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.linear_out_slow_in);
+ mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_linear_in);
}
public boolean onTouchEvent(MotionEvent event) {
@@ -102,16 +122,18 @@ public class KeyguardPageSwipeHelper {
final float y = event.getY(pointerIndex);
final float x = event.getX(pointerIndex);
+ boolean isUp = false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
if (mSwipingInProgress) {
- cancelAnimations();
+ cancelAnimation();
}
mInitialTouchY = y;
mInitialTouchX = x;
mTranslationOnDown = mTranslation;
initVelocityTracker();
trackMovement(event);
+ mMotionPerformedByUser = false;
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -135,23 +157,24 @@ public class KeyguardPageSwipeHelper {
|| (rightSwipePossible() && w < -mTouchSlop))
&& Math.abs(w) > Math.abs(y - mInitialTouchY)
&& !mSwipingInProgress) {
- cancelAnimations();
+ cancelAnimation();
mInitialTouchY = y;
mInitialTouchX = x;
mTranslationOnDown = mTranslation;
- mSwipingInProgress = true;
+ setSwipingInProgress(true);
}
if (mSwipingInProgress) {
- setTranslation(mTranslationOnDown + x - mInitialTouchX, false);
+ setTranslation(mTranslationOnDown + x - mInitialTouchX, false, false);
}
break;
case MotionEvent.ACTION_UP:
+ isUp = true;
case MotionEvent.ACTION_CANCEL:
mTrackingPointer = -1;
trackMovement(event);
if (mSwipingInProgress) {
- flingWithCurrentVelocity();
+ flingWithCurrentVelocity(!isUp);
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
@@ -162,6 +185,13 @@ public class KeyguardPageSwipeHelper {
return true;
}
+ private void setSwipingInProgress(boolean inProgress) {
+ mSwipingInProgress = inProgress;
+ if (inProgress) {
+ mCallback.onSwipingStarted();
+ }
+ }
+
private boolean rightSwipePossible() {
return mRightIcon.getVisibility() == View.VISIBLE;
}
@@ -175,22 +205,14 @@ public class KeyguardPageSwipeHelper {
}
public void startHintAnimation(boolean right, Runnable onFinishedListener) {
+
startHintAnimationPhase1(right, onFinishedListener);
}
- /**
- * Phase 1: Move everything sidewards.
- */
- private void startHintAnimationPhase1(boolean right, final Runnable onFinishedListener) {
- float target = right ? -mHintDistance : mHintDistance;
- startHintTranslationAnimations(target, HINT_PHASE1_DURATION, mFastOutSlowIn);
- ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
- animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mTranslation = (float) animation.getAnimatedValue();
- }
- });
+ private void startHintAnimationPhase1(final boolean right, final Runnable onFinishedListener) {
+ final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
+ targetView.showArrow(true);
+ ValueAnimator animator = getAnimatorToRadius(right, mHintGrowAmount);
animator.addListener(new AnimatorListenerAdapter() {
private boolean mCancelled;
@@ -204,12 +226,13 @@ public class KeyguardPageSwipeHelper {
if (mCancelled) {
mSwipeAnimator = null;
onFinishedListener.run();
+ targetView.showArrow(false);
} else {
- startUnlockHintAnimationPhase2(onFinishedListener);
+ startUnlockHintAnimationPhase2(right, onFinishedListener);
}
}
});
- animator.setInterpolator(mFastOutSlowIn);
+ animator.setInterpolator(mAppearInterpolator);
animator.setDuration(HINT_PHASE1_DURATION);
animator.start();
mSwipeAnimator = animator;
@@ -218,75 +241,69 @@ public class KeyguardPageSwipeHelper {
/**
* Phase 2: Move back.
*/
- private void startUnlockHintAnimationPhase2(final Runnable onFinishedListener) {
- startHintTranslationAnimations(0f /* target */, HINT_PHASE2_DURATION, mBounceInterpolator);
- ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, 0f);
- animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mTranslation = (float) animation.getAnimatedValue();
- }
- });
+ private void startUnlockHintAnimationPhase2(boolean right, final Runnable onFinishedListener) {
+ final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
+ ValueAnimator animator = getAnimatorToRadius(right, 0);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mSwipeAnimator = null;
+ targetView.showArrow(false);
onFinishedListener.run();
}
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ targetView.showArrow(false);
+ }
});
- animator.setInterpolator(mBounceInterpolator);
+ animator.setInterpolator(mDisappearInterpolator);
animator.setDuration(HINT_PHASE2_DURATION);
+ animator.setStartDelay(HINT_CIRCLE_OPEN_DURATION);
animator.start();
mSwipeAnimator = animator;
}
- private void startHintTranslationAnimations(float target, long duration,
- Interpolator interpolator) {
- ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View targetView : targetViews) {
- targetView.animate()
- .setDuration(duration)
- .setInterpolator(interpolator)
- .translationX(target);
- }
+ private ValueAnimator getAnimatorToRadius(final boolean right, int radius) {
+ final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
+ ValueAnimator animator = ValueAnimator.ofFloat(targetView.getCircleRadius(), radius);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float newRadius = (float) animation.getAnimatedValue();
+ targetView.setCircleRadiusWithoutAnimation(newRadius);
+ float translation = getTranslationFromRadius(newRadius);
+ mTranslation = right ? -translation : translation;
+ updateIconsFromRadius(targetView, newRadius);
+ }
+ });
+ return animator;
}
- private void cancelAnimations() {
- ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View target : targetViews) {
- target.animate().cancel();
- }
- View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
- targetView.animate().cancel();
+ private void cancelAnimation() {
if (mSwipeAnimator != null) {
mSwipeAnimator.cancel();
- hideInactiveIcons(true);
}
}
- private void flingWithCurrentVelocity() {
+ private void flingWithCurrentVelocity(boolean forceSnapBack) {
float vel = getCurrentVelocity();
// We snap back if the current translation is not far enough
- boolean snapBack = Math.abs(mTranslation) < mMinTranslationAmount;
+ boolean snapBack = Math.abs(mTranslation) < Math.abs(mTranslationOnDown)
+ + mMinTranslationAmount;
// or if the velocity is in the opposite direction.
boolean velIsInWrongDirection = vel * mTranslation < 0;
snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection;
vel = snapBack ^ velIsInWrongDirection ? 0 : vel;
- fling(vel, snapBack);
+ fling(vel, snapBack || forceSnapBack);
}
private void fling(float vel, final boolean snapBack) {
float target = mTranslation < 0 ? -mCallback.getPageWidth() : mCallback.getPageWidth();
target = snapBack ? 0 : target;
- // translation Animation
- startTranslationAnimations(vel, target);
-
- // animate left / right icon
- startIconAnimation(vel, snapBack, target);
-
ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -295,109 +312,84 @@ public class KeyguardPageSwipeHelper {
mTranslation = (float) animation.getAnimatedValue();
}
});
- animator.addListener(new AnimatorListenerAdapter() {
- private boolean mCancelled;
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCancelled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mSwipeAnimator = null;
- mSwipingInProgress = false;
- if (!snapBack && !mCallbackCalled && !mCancelled) {
-
- // ensure that the callback is called eventually
- mCallback.onAnimationToSideStarted(mTranslation < 0);
- mCallbackCalled = true;
- }
- }
- });
+ animator.addListener(mFlingEndListener);
if (!snapBack) {
- mCallbackCalled = false;
- animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- int frameNumber;
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- if (frameNumber == 2 && !mCallbackCalled) {
-
- // we have to wait for the second frame for this call,
- // until the render thread has definitely kicked in, to avoid a lag.
- mCallback.onAnimationToSideStarted(mTranslation < 0);
- mCallbackCalled = true;
- }
- frameNumber++;
- }
- });
+ startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable);
+ mCallback.onAnimationToSideStarted(mTranslation < 0);
} else {
- showAllIcons(true);
+ reset(true);
}
animator.start();
mSwipeAnimator = animator;
}
- private void startTranslationAnimations(float vel, float target) {
- ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View targetView : targetViews) {
- ViewPropertyAnimator animator = targetView.animate();
- mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
- animator.translationX(target);
- }
- }
-
- private void startIconAnimation(float vel, boolean snapBack, float target) {
- float scale = snapBack ? 1.0f : SWIPE_MAX_ICON_SCALE_AMOUNT;
- float alpha = snapBack ? SWIPE_RESTING_ALPHA_AMOUNT : 1.0f;
- View targetView = mTranslation > 0
- ? mLeftIcon
- : mRightIcon;
- if (targetView.getVisibility() == View.VISIBLE) {
- ViewPropertyAnimator iconAnimator = targetView.animate();
- mFlingAnimationUtils.apply(iconAnimator, mTranslation, target, vel);
- iconAnimator.scaleX(scale);
- iconAnimator.scaleY(scale);
- iconAnimator.alpha(alpha);
- }
+ private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable) {
+ KeyguardAffordanceView targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
+ targetView.finishAnimation(velocity, mAnimationEndRunnable);
}
- private void setTranslation(float translation, boolean isReset) {
+ private void setTranslation(float translation, boolean isReset, boolean animateReset) {
translation = rightSwipePossible() ? translation : Math.max(0, translation);
translation = leftSwipePossible() ? translation : Math.min(0, translation);
+ float absTranslation = Math.abs(translation);
+ if (absTranslation > Math.abs(mTranslationOnDown) + mMinTranslationAmount ||
+ mMotionPerformedByUser) {
+ userActivity();
+ mMotionPerformedByUser = true;
+ }
if (translation != mTranslation || isReset) {
- ArrayList<View> translatedViews = mCallback.getTranslationViews();
- for (View view : translatedViews) {
- view.setTranslationX(translation);
- }
- if (translation == 0.0f) {
- boolean animate = !isReset;
- showAllIcons(animate);
+ KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
+ KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
+ float alpha = absTranslation / mMinTranslationAmount;
+
+ // We interpolate the alpha of the other icons to 0
+ float fadeOutAlpha = SWIPE_RESTING_ALPHA_AMOUNT * (1.0f - alpha);
+ fadeOutAlpha = Math.max(0.0f, fadeOutAlpha);
+
+ // We interpolate the alpha of the targetView to 1
+ alpha = fadeOutAlpha + alpha;
+
+ boolean animateIcons = isReset && animateReset;
+ float radius = getRadiusFromTranslation(absTranslation);
+ if (!isReset) {
+ updateIcon(targetView, radius, alpha, false);
} else {
- View targetView = translation > 0 ? mLeftIcon : mRightIcon;
- float progress = Math.abs(translation) / mCallback.getPageWidth();
- progress = Math.min(progress, 1.0f);
- float alpha = SWIPE_RESTING_ALPHA_AMOUNT * (1.0f - progress) + progress;
- float scale = (1.0f - progress) + progress * SWIPE_MAX_ICON_SCALE_AMOUNT;
- updateIcon(targetView, scale, alpha, false);
- View otherView = translation < 0 ? mLeftIcon : mRightIcon;
- if (mTranslation * translation <= 0) {
- // The sign of the translation has changed so we need to hide the other icons
- updateIcon(otherView, 0, 0, true);
- updateIcon(mCenterIcon, 0, 0, true);
- }
+ updateIcon(targetView, 0.0f, fadeOutAlpha, animateIcons);
}
+ updateIcon(otherView, 0.0f, fadeOutAlpha, animateIcons);
+ updateIcon(mCenterIcon, 0.0f, fadeOutAlpha, animateIcons);
+
mTranslation = translation;
}
}
- public void showAllIcons(boolean animate) {
- float scale = 1.0f;
- float alpha = SWIPE_RESTING_ALPHA_AMOUNT;
- updateIcon(mRightIcon, scale, alpha, animate);
- updateIcon(mCenterIcon, scale, alpha, animate);
- updateIcon(mLeftIcon, scale, alpha, animate);
+ private void updateIconsFromRadius(KeyguardAffordanceView targetView, float newRadius) {
+ float alpha = newRadius / mMinBackgroundRadius;
+
+ // We interpolate the alpha of the other icons to 0
+ float fadeOutAlpha = SWIPE_RESTING_ALPHA_AMOUNT * (1.0f - alpha);
+ fadeOutAlpha = Math.max(0.0f, fadeOutAlpha);
+
+ // We interpolate the alpha of the targetView to 1
+ alpha = fadeOutAlpha + alpha;
+ KeyguardAffordanceView otherView = targetView == mRightIcon ? mLeftIcon : mRightIcon;
+ updateIconAlpha(targetView, alpha, false);
+ updateIconAlpha(otherView, fadeOutAlpha, false);
+ updateIconAlpha(mCenterIcon, fadeOutAlpha, false);
+ }
+
+ private float getTranslationFromRadius(float circleSize) {
+ float translation = (circleSize - mMinBackgroundRadius) / BACKGROUND_RADIUS_SCALE_FACTOR;
+ return Math.max(0, translation);
+ }
+
+ private float getRadiusFromTranslation(float translation) {
+ return translation * BACKGROUND_RADIUS_SCALE_FACTOR + mMinBackgroundRadius;
+ }
+
+
+ private void userActivity() {
+ mPM.userActivity(SystemClock.uptimeMillis(), false);
}
public void animateHideLeftRightIcon() {
@@ -405,32 +397,26 @@ public class KeyguardPageSwipeHelper {
updateIcon(mLeftIcon, 0f, 0f, true);
}
- private void hideInactiveIcons(boolean animate){
- View otherView = mTranslation < 0 ? mLeftIcon : mRightIcon;
- updateIcon(otherView, 0, 0, animate);
- updateIcon(mCenterIcon, 0, 0, animate);
- }
-
- private void updateIcon(View view, float scale, float alpha, boolean animate) {
+ private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha,
+ boolean animate) {
if (view.getVisibility() != View.VISIBLE) {
return;
}
- if (!animate) {
- view.animate().cancel();
- view.setAlpha(alpha);
- view.setScaleX(scale);
- view.setScaleY(scale);
- // TODO: remove this invalidate once the property setters invalidate it properly
- view.invalidate();
- } else {
- if (view.getAlpha() != alpha || view.getScaleX() != scale) {
- view.animate()
- .setInterpolator(mFastOutSlowIn)
- .alpha(alpha)
- .scaleX(scale)
- .scaleY(scale);
- }
- }
+ view.setCircleRadius(circleRadius);
+ updateIconAlpha(view, alpha, animate);
+ }
+
+ private void updateIconAlpha(KeyguardAffordanceView view, float alpha, boolean animate) {
+ float scale = getScale(alpha);
+ alpha = Math.min(1.0f, alpha);
+ view.setImageAlpha(alpha, animate);
+ view.setImageScale(scale, animate);
+ }
+
+ private float getScale(float alpha) {
+ float scale = alpha / SWIPE_RESTING_ALPHA_AMOUNT * 0.2f +
+ KeyguardAffordanceView.MIN_ICON_SCALE_AMOUNT;
+ return Math.min(scale, KeyguardAffordanceView.MAX_ICON_SCALE_AMOUNT);
}
private void trackMovement(MotionEvent event) {
@@ -458,20 +444,12 @@ public class KeyguardPageSwipeHelper {
initDimens();
}
- public void reset() {
+ public void reset(boolean animate) {
if (mSwipeAnimator != null) {
mSwipeAnimator.cancel();
}
- ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View view : targetViews) {
- view.animate().cancel();
- }
- setTranslation(0.0f, true);
- mSwipingInProgress = false;
- }
-
- public boolean isSwipingInProgress() {
- return mSwipingInProgress;
+ setTranslation(0.0f, true, animate);
+ setSwipingInProgress(false);
}
public interface Callback {
@@ -483,14 +461,19 @@ public class KeyguardPageSwipeHelper {
*/
void onAnimationToSideStarted(boolean rightPage);
+ /**
+ * Notifies the callback the animation to a side page has ended.
+ */
+ void onAnimationToSideEnded();
+
float getPageWidth();
- ArrayList<View> getTranslationViews();
+ void onSwipingStarted();
- View getLeftIcon();
+ KeyguardAffordanceView getLeftIcon();
- View getCenterIcon();
+ KeyguardAffordanceView getCenterIcon();
- View getRightIcon();
+ KeyguardAffordanceView getRightIcon();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 74bc698..b9f012c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -39,6 +39,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.FlashlightController;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
@@ -56,9 +57,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
- private ImageView mCameraImageView;
- private ImageView mPhoneImageView;
- private ImageView mLockIcon;
+ private KeyguardAffordanceView mCameraImageView;
+ private KeyguardAffordanceView mPhoneImageView;
+ private KeyguardAffordanceView mLockIcon;
private View mIndicationText;
private ActivityStarter mActivityStarter;
@@ -87,9 +88,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
protected void onFinishInflate() {
super.onFinishInflate();
mLockPatternUtils = new LockPatternUtils(mContext);
- mCameraImageView = (ImageView) findViewById(R.id.camera_button);
- mPhoneImageView = (ImageView) findViewById(R.id.phone_button);
- mLockIcon = (ImageView) findViewById(R.id.lock_icon);
+ mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
+ mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button);
+ mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon);
mIndicationText = findViewById(R.id.keyguard_indication_text);
watchForCameraPolicyChanges();
watchForAccessibilityChanges();
@@ -98,6 +99,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
updateTrust();
+ setClipChildren(false);
+ setClipToPadding(false);
}
public void setActivityStarter(ActivityStarter activityStarter) {
@@ -228,15 +231,15 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mLockIcon.setImageResource(iconRes);
}
- public ImageView getPhoneImageView() {
+ public KeyguardAffordanceView getPhoneView() {
return mPhoneImageView;
}
- public ImageView getCameraImageView() {
+ public KeyguardAffordanceView getCameraView() {
return mCameraImageView;
}
- public ImageView getLockIcon() {
+ public KeyguardAffordanceView getLockIcon() {
return mLockIcon;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index fc0f2d5..11a38b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -39,6 +39,7 @@ import com.android.systemui.qs.QSPanel;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.GestureRecorder;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.MirrorView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -49,7 +50,7 @@ import java.util.ArrayList;
public class NotificationPanelView extends PanelView implements
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
- KeyguardPageSwipeHelper.Callback {
+ KeyguardAffordanceHelper.Callback {
// Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is
// changed.
@@ -59,7 +60,7 @@ public class NotificationPanelView extends PanelView implements
private static final float HEADER_RUBBERBAND_FACTOR = 2.15f;
private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
- private KeyguardPageSwipeHelper mPageSwiper;
+ private KeyguardAffordanceHelper mAfforanceHelper;
private StatusBarHeaderView mHeader;
private View mQsContainer;
private QSPanel mQsPanel;
@@ -124,7 +125,6 @@ public class NotificationPanelView extends PanelView implements
private boolean mIsExpanding;
private boolean mBlockTouches;
- private ArrayList<View> mSwipeTranslationViews = new ArrayList<>();
private int mNotificationScrimWaitDistance;
private boolean mTwoFingerQsExpand;
private boolean mTwoFingerQsExpandPossible;
@@ -135,6 +135,10 @@ public class NotificationPanelView extends PanelView implements
*/
private int mScrollYOverride = -1;
private boolean mQsAnimatorExpand;
+ private boolean mIsLaunchTransitionFinished;
+ private boolean mIsLaunchTransitionRunning;
+ private Runnable mLaunchAnimationEndRunnable;
+ private boolean mOnlyAffordanceInThisMotion;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -167,9 +171,7 @@ public class NotificationPanelView extends PanelView implements
mFastOutLinearInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_linear_in);
mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
- mSwipeTranslationViews.add(mNotificationStackScroller);
- mSwipeTranslationViews.add(mKeyguardStatusView);
- mPageSwiper = new KeyguardPageSwipeHelper(this, getContext());
+ mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
}
@Override
@@ -297,9 +299,10 @@ public class NotificationPanelView extends PanelView implements
@Override
public void resetViews() {
+ mIsLaunchTransitionFinished = false;
mBlockTouches = false;
mUnlockIconActive = false;
- mPageSwiper.reset();
+ mAfforanceHelper.reset(true);
closeQs();
mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */,
true /* cancelAnimators */);
@@ -354,6 +357,7 @@ public class NotificationPanelView extends PanelView implements
if (mBlockTouches) {
return false;
}
+ resetDownStates(event);
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
@@ -430,6 +434,12 @@ public class NotificationPanelView extends PanelView implements
return !mQsExpanded && super.onInterceptTouchEvent(event);
}
+ private void resetDownStates(MotionEvent event) {
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mOnlyAffordanceInThisMotion = false;
+ }
+ }
+
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
@@ -464,15 +474,14 @@ public class NotificationPanelView extends PanelView implements
if (mBlockTouches) {
return false;
}
- // TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
- // implementation.
+ resetDownStates(event);
if ((!mIsExpanding || mHintAnimationRunning)
&& !mQsExpanded
&& mStatusBar.getBarState() != StatusBarState.SHADE) {
- mPageSwiper.onTouchEvent(event);
- if (mPageSwiper.isSwipingInProgress()) {
- return true;
- }
+ mAfforanceHelper.onTouchEvent(event);
+ }
+ if (mOnlyAffordanceInThisMotion) {
+ return true;
}
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
&& mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
@@ -951,20 +960,16 @@ public class NotificationPanelView extends PanelView implements
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
boolean active = getMaxPanelHeight() - getExpandedHeight() > mUnlockMoveDistance;
+ KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
if (active && !mUnlockIconActive && mTracking) {
- mKeyguardBottomArea.getLockIcon().animate()
- .alpha(1f)
- .scaleY(LOCK_ICON_ACTIVE_SCALE)
- .scaleX(LOCK_ICON_ACTIVE_SCALE)
- .setInterpolator(mFastOutLinearInterpolator)
- .setDuration(150);
+ lockIcon.setImageAlpha(1.0f, true, 150, mFastOutLinearInterpolator, null);
+ lockIcon.setImageScale(LOCK_ICON_ACTIVE_SCALE, true, 150,
+ mFastOutLinearInterpolator);
} else if (!active && mUnlockIconActive && mTracking) {
- mKeyguardBottomArea.getLockIcon().animate()
- .alpha(KeyguardPageSwipeHelper.SWIPE_RESTING_ALPHA_AMOUNT)
- .scaleY(1f)
- .scaleX(1f)
- .setInterpolator(mFastOutLinearInterpolator)
- .setDuration(150);
+ lockIcon.setImageAlpha(KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT, true,
+ 150, mFastOutLinearInterpolator, null);
+ lockIcon.setImageScale(1.0f, true, 150,
+ mFastOutLinearInterpolator);
}
mUnlockIconActive = active;
}
@@ -1093,7 +1098,7 @@ public class NotificationPanelView extends PanelView implements
super.onTrackingStarted();
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
- mPageSwiper.animateHideLeftRightIcon();
+ mAfforanceHelper.animateHideLeftRightIcon();
}
}
@@ -1106,16 +1111,15 @@ public class NotificationPanelView extends PanelView implements
}
if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
- mPageSwiper.showAllIcons(true);
+ if (!mHintAnimationRunning) {
+ mAfforanceHelper.reset(true);
+ }
}
if (!expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
- mKeyguardBottomArea.getLockIcon().animate()
- .alpha(0f)
- .scaleX(2f)
- .scaleY(2f)
- .setInterpolator(mFastOutLinearInterpolator)
- .setDuration(100);
+ KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
+ lockIcon.setImageAlpha(0.0f, true, 100, mFastOutLinearInterpolator, null);
+ lockIcon.setImageScale(2.0f, true, 100, mFastOutLinearInterpolator);
}
}
@@ -1141,7 +1145,7 @@ public class NotificationPanelView extends PanelView implements
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- mPageSwiper.onConfigurationChanged();
+ mAfforanceHelper.onConfigurationChanged();
}
@Override
@@ -1159,6 +1163,8 @@ public class NotificationPanelView extends PanelView implements
@Override
public void onAnimationToSideStarted(boolean rightPage) {
boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? rightPage : !rightPage;
+ mIsLaunchTransitionRunning = true;
+ mLaunchAnimationEndRunnable = null;
if (start) {
mKeyguardBottomArea.launchPhone();
} else {
@@ -1168,20 +1174,29 @@ public class NotificationPanelView extends PanelView implements
}
@Override
+ public void onAnimationToSideEnded() {
+ mIsLaunchTransitionRunning = false;
+ mIsLaunchTransitionFinished = true;
+ if (mLaunchAnimationEndRunnable != null) {
+ mLaunchAnimationEndRunnable.run();
+ mLaunchAnimationEndRunnable = null;
+ }
+ }
+
+ @Override
protected void onEdgeClicked(boolean right) {
if ((right && getRightIcon().getVisibility() != View.VISIBLE)
|| (!right && getLeftIcon().getVisibility() != View.VISIBLE)) {
return;
}
mHintAnimationRunning = true;
- mPageSwiper.startHintAnimation(right, new Runnable() {
+ mAfforanceHelper.startHintAnimation(right, new Runnable() {
@Override
public void run() {
mHintAnimationRunning = false;
mStatusBar.onHintFinished();
}
});
- startHighlightIconAnimation(right ? getRightIcon() : getLeftIcon());
boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? right : !right;
if (start) {
mStatusBar.onPhoneHintStarted();
@@ -1199,17 +1214,14 @@ public class NotificationPanelView extends PanelView implements
/**
* Starts the highlight (making it fully opaque) animation on an icon.
*/
- private void startHighlightIconAnimation(final View icon) {
- icon.animate()
- .alpha(1.0f)
- .setDuration(KeyguardPageSwipeHelper.HINT_PHASE1_DURATION)
- .setInterpolator(mFastOutSlowInInterpolator)
- .withEndAction(new Runnable() {
+ private void startHighlightIconAnimation(final KeyguardAffordanceView icon) {
+ icon.setImageAlpha(1.0f, true, KeyguardAffordanceHelper.HINT_PHASE1_DURATION,
+ mFastOutSlowInInterpolator, new Runnable() {
@Override
public void run() {
- icon.animate().alpha(KeyguardPageSwipeHelper.SWIPE_RESTING_ALPHA_AMOUNT)
- .setDuration(KeyguardPageSwipeHelper.HINT_PHASE1_DURATION)
- .setInterpolator(mFastOutSlowInInterpolator);
+ icon.setImageAlpha(KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT,
+ true, KeyguardAffordanceHelper.HINT_PHASE1_DURATION,
+ mFastOutSlowInInterpolator, null);
}
});
}
@@ -1220,27 +1232,28 @@ public class NotificationPanelView extends PanelView implements
}
@Override
- public ArrayList<View> getTranslationViews() {
- return mSwipeTranslationViews;
+ public void onSwipingStarted() {
+ requestDisallowInterceptTouchEvent(true);
+ mOnlyAffordanceInThisMotion = true;
}
@Override
- public View getLeftIcon() {
+ public KeyguardAffordanceView getLeftIcon() {
return getLayoutDirection() == LAYOUT_DIRECTION_RTL
- ? mKeyguardBottomArea.getCameraImageView()
- : mKeyguardBottomArea.getPhoneImageView();
+ ? mKeyguardBottomArea.getCameraView()
+ : mKeyguardBottomArea.getPhoneView();
}
@Override
- public View getCenterIcon() {
+ public KeyguardAffordanceView getCenterIcon() {
return mKeyguardBottomArea.getLockIcon();
}
@Override
- public View getRightIcon() {
+ public KeyguardAffordanceView getRightIcon() {
return getLayoutDirection() == LAYOUT_DIRECTION_RTL
- ? mKeyguardBottomArea.getPhoneImageView()
- : mKeyguardBottomArea.getCameraImageView();
+ ? mKeyguardBottomArea.getPhoneView()
+ : mKeyguardBottomArea.getCameraView();
}
@Override
@@ -1282,4 +1295,16 @@ public class NotificationPanelView extends PanelView implements
public boolean shouldDelayChildPressedState() {
return true;
}
+
+ public boolean isLaunchTransitionFinished() {
+ return mIsLaunchTransitionFinished;
+ }
+
+ public boolean isLaunchTransitionRunning() {
+ return mIsLaunchTransitionRunning;
+ }
+
+ public void setLaunchTransitionEndRunnable(Runnable r) {
+ mLaunchAnimationEndRunnable = r;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e4e67c9..46a32da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -53,7 +53,6 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
@@ -63,6 +62,7 @@ import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -70,6 +70,7 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -201,6 +202,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.build();
+ public static final int FADE_KEYGUARD_START_DELAY = 100;
+ public static final int FADE_KEYGUARD_DURATION = 300;
+
PhoneStatusBarPolicy mIconPolicy;
// These are no longer handled by the policy, because we need custom strategies for them
@@ -441,6 +445,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
private int mDrawCount;
+ private Runnable mLaunchTransitionEndRunnable;
+ private boolean mLaunchTransitionFadingAway;
private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD
| ViewState.LOCATION_TOP_STACK_PEEKING
@@ -1728,7 +1734,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
private int adjustDisableFlags(int state) {
- if (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit) {
+ if (!mLaunchTransitionFadingAway
+ && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
state |= StatusBarManager.DISABLE_SYSTEM_INFO;
}
@@ -2725,13 +2732,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
dismissKeyguardThenExecute(new OnDismissAction() {
@Override
public boolean onDismiss() {
- try {
- // Dismiss the lock screen when Settings starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- }
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ try {
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mContext.startActivityAsUser(
+ intent, new UserHandle(UserHandle.USER_CURRENT));
+ mWindowManagerService.overridePendingAppTransition(null, 0, 0, null);
+ } catch (RemoteException e) {
+ }
+ }
+ });
animateCollapsePanels();
return DELAY_DISMISS_TO_ACTIVITY_LAUNCH;
@@ -2795,9 +2807,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
};
@Override
- protected void dismissKeyguardThenExecute(OnDismissAction action) {
+ protected void dismissKeyguardThenExecute(final OnDismissAction action) {
if (mStatusBarKeyguardViewManager.isShowing()) {
- mStatusBarKeyguardViewManager.dismissWithAction(action);
+ if (UnlockMethodCache.getInstance(mContext).isMethodInsecure()
+ && mNotificationPanel.isLaunchTransitionRunning()) {
+ action.onDismiss();
+ mNotificationPanel.setLaunchTransitionEndRunnable(new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarKeyguardViewManager.dismiss();
+ }
+ });
+ } else {
+ mStatusBarKeyguardViewManager.dismissWithAction(action);
+ }
} else {
action.onDismiss();
}
@@ -3170,6 +3193,52 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mLeaveOpenOnKeyguardHide = false;
}
+ public boolean isInLaunchTransition() {
+ return mNotificationPanel.isLaunchTransitionRunning()
+ || mNotificationPanel.isLaunchTransitionFinished();
+ }
+
+ /**
+ * Fades the content of the keyguard away after the launch transition is done.
+ *
+ * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
+ * starts
+ * @param endRunnable the runnable to be run when the transition is done
+ */
+ public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
+ final Runnable endRunnable) {
+ Runnable hideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mLaunchTransitionFadingAway = true;
+ if (beforeFading != null) {
+ beforeFading.run();
+ }
+ mNotificationPanel.setAlpha(1);
+ mNotificationPanel.animate()
+ .alpha(0)
+ .setStartDelay(FADE_KEYGUARD_START_DELAY)
+ .setDuration(FADE_KEYGUARD_DURATION)
+ .withLayer()
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mNotificationPanel.setAlpha(1);
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ mLaunchTransitionFadingAway = false;
+ }
+ });
+ }
+ };
+ if (mNotificationPanel.isLaunchTransitionRunning()) {
+ mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
+ } else {
+ hideRunnable.run();
+ }
+ }
+
public void hideKeyguard() {
setBarState(StatusBarState.SHADE);
if (mLeaveOpenOnKeyguardHide) {
@@ -3204,8 +3273,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void updatePublicMode() {
setLockscreenPublicMode(
- (mStatusBarKeyguardViewManager.isShowing() ||
- mStatusBarKeyguardViewManager.isOccluded())
+ (mStatusBarKeyguardViewManager.isShowing() ||
+ mStatusBarKeyguardViewManager.isOccluded())
&& mStatusBarKeyguardViewManager.isSecure());
}
@@ -3315,7 +3384,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void showBouncer() {
if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
- mWaitingForKeyguardExit = true;
+ mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
mStatusBarKeyguardViewManager.dismiss();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index cf930bd..eb42401 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -71,7 +71,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
private boolean mAnimationStarted;
private boolean mDozing;
private int mTeasesRemaining;
-
private final Interpolator mInterpolator = new DecelerateInterpolator();
public ScrimController(View scrimBehind, View scrimInFront) {
@@ -149,7 +148,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
}
private void updateScrims() {
- if ((!mKeyguardShowing && !mBouncerShowing) || mAnimateKeyguardFadingOut) {
+ if (mAnimateKeyguardFadingOut) {
+ setScrimInFrontColor(0f);
+ setScrimBehindColor(0f);
+ }else if (!mKeyguardShowing && !mBouncerShowing) {
updateScrimNormal();
setScrimInFrontColor(0);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 93dcf90..af21f25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -176,6 +176,19 @@ public class StatusBarKeyguardViewManager {
}
public void setOccluded(boolean occluded) {
+ if (occluded && !mOccluded && mShowing) {
+ if (mPhoneStatusBar.isInLaunchTransition()) {
+ mOccluded = true;
+ mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
+ new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setKeyguardOccluded(true);
+ }
+ });
+ return;
+ }
+ }
mOccluded = occluded;
mStatusBarWindowManager.setKeyguardOccluded(occluded);
reset();
@@ -188,29 +201,50 @@ public class StatusBarKeyguardViewManager {
/**
* Hides the keyguard view
*/
- public void hide(long startTime, long fadeoutDuration) {
+ public void hide(long startTime, final long fadeoutDuration) {
mShowing = false;
long uptimeMillis = SystemClock.uptimeMillis();
- long delay = startTime - uptimeMillis;
- if (delay < 0) {
- delay = 0;
+ long delay = Math.max(0, startTime - uptimeMillis);
+
+ if (mPhoneStatusBar.isInLaunchTransition() ) {
+ mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setKeyguardShowing(false);
+ mStatusBarWindowManager.setKeyguardFadingAway(true);
+ mBouncer.animateHide(PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
+ PhoneStatusBar.FADE_KEYGUARD_DURATION);
+ updateStates();
+ mScrimController.animateKeyguardFadingOut(
+ PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
+ PhoneStatusBar.FADE_KEYGUARD_DURATION, null);
+ }
+ }, new Runnable() {
+ @Override
+ public void run() {
+ mPhoneStatusBar.hideKeyguard();
+ mStatusBarWindowManager.setKeyguardFadingAway(false);
+ mViewMediatorCallback.keyguardGone();
+ }
+ });
+ } else {
+ mPhoneStatusBar.setKeyguardFadingAway(delay, fadeoutDuration);
+ mPhoneStatusBar.hideKeyguard();
+ mStatusBarWindowManager.setKeyguardFadingAway(true);
+ mStatusBarWindowManager.setKeyguardShowing(false);
+ mBouncer.animateHide(delay, fadeoutDuration);
+ mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setKeyguardFadingAway(false);
+ mPhoneStatusBar.finishKeyguardFadingAway();
+ }
+ });
+ mViewMediatorCallback.keyguardGone();
+ updateStates();
}
- mPhoneStatusBar.setKeyguardFadingAway(delay, fadeoutDuration);
- mPhoneStatusBar.hideKeyguard();
- mStatusBarWindowManager.setKeyguardFadingAway(true);
- mStatusBarWindowManager.setKeyguardShowing(false);
- mBouncer.animateHide(delay, fadeoutDuration);
- mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
- @Override
- public void run() {
- mStatusBarWindowManager.setKeyguardFadingAway(false);
- mPhoneStatusBar.finishKeyguardFadingAway();
- }
- });
- mViewMediatorCallback.keyguardGone();
- updateStates();
}
/**