diff options
Diffstat (limited to 'packages/SystemUI')
17 files changed, 359 insertions, 66 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index 2a84362..adc9b36 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -22,6 +22,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.graphics.Typeface; import android.media.projection.MediaProjectionManager; import android.media.projection.IMediaProjectionManager; import android.media.projection.IMediaProjection; @@ -29,7 +30,14 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.text.BidiFormatter; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextPaint; +import android.text.TextUtils; +import android.text.style.StyleSpan; import android.util.Log; +import android.util.TypedValue; import android.view.WindowManager; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -39,6 +47,8 @@ public class MediaProjectionPermissionActivity extends Activity implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener, DialogInterface.OnCancelListener { private static final String TAG = "MediaProjectionPermissionActivity"; + private static final float MAX_APP_NAME_SIZE_PX = 500f; + private static final String ELLIPSIS = "\u2026"; private boolean mPermanentGrant; private String mPackageName; @@ -84,11 +94,49 @@ public class MediaProjectionPermissionActivity extends Activity return; } - String appName = aInfo.loadLabel(packageManager).toString(); + TextPaint paint = new TextPaint(); + paint.setTextSize(42); + + String label = aInfo.loadLabel(packageManager).toString(); + + // If the label contains new line characters it may push the security + // message below the fold of the dialog. Labels shouldn't have new line + // characters anyways, so just truncate the message the first time one + // is seen. + final int labelLength = label.length(); + int offset = 0; + while (offset < labelLength) { + final int codePoint = label.codePointAt(offset); + final int type = Character.getType(codePoint); + if (type == Character.LINE_SEPARATOR + || type == Character.CONTROL + || type == Character.PARAGRAPH_SEPARATOR) { + label = label.substring(0, offset) + ELLIPSIS; + break; + } + offset += Character.charCount(codePoint); + } + + if (label.isEmpty()) { + label = mPackageName; + } + + String unsanitizedAppName = TextUtils.ellipsize(label, + paint, MAX_APP_NAME_SIZE_PX, TextUtils.TruncateAt.END).toString(); + String appName = BidiFormatter.getInstance().unicodeWrap(unsanitizedAppName); + + String actionText = getString(R.string.media_projection_dialog_text, appName); + SpannableString message = new SpannableString(actionText); + + int appNameIndex = actionText.indexOf(appName); + if (appNameIndex >= 0) { + message.setSpan(new StyleSpan(Typeface.BOLD), + appNameIndex, appNameIndex + appName.length(), 0); + } mDialog = new AlertDialog.Builder(this) .setIcon(aInfo.loadIcon(packageManager)) - .setMessage(getString(R.string.media_projection_dialog_text, appName)) + .setMessage(message) .setPositiveButton(R.string.media_projection_action_text, this) .setNegativeButton(android.R.string.cancel, this) .setView(R.layout.remember_permission_checkbox) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index a1b07b5..025451d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -64,6 +64,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT; private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT; private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; + private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; public static final int FLAG_EXCLUDE_NONE = 0; public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; @@ -109,6 +110,7 @@ public class CommandQueue extends IStatusBar.Stub { public void appTransitionStarting(long startTime, long duration); public void showAssistDisclosure(); public void startAssist(Bundle args); + public void onCameraLaunchGestureDetected(); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -293,6 +295,14 @@ public class CommandQueue extends IStatusBar.Stub { } } + @Override + public void onCameraLaunchGestureDetected() { + synchronized (mList) { + mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE); + mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; @@ -391,6 +401,9 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_START_ASSIST: mCallbacks.startAssist((Bundle) msg.obj); break; + case MSG_CAMERA_LAUNCH_GESTURE: + mCallbacks.onCameraLaunchGestureDetected(); + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 0aa4f6c..5f01306 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -24,6 +24,7 @@ import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.RippleDrawable; import android.service.notification.StatusBarNotification; import android.util.AttributeSet; import android.view.MotionEvent; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 164c496..8058933 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -36,6 +36,7 @@ import android.view.ViewAnimationUtils; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; + import com.android.systemui.R; import com.android.systemui.statusbar.phone.KeyguardAffordanceHelper; import com.android.systemui.statusbar.phone.PhoneStatusBar; @@ -79,6 +80,7 @@ public class KeyguardAffordanceView extends ImageView { private float mRestingAlpha = KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT; private boolean mSupportHardware; private boolean mFinishing; + private boolean mLaunchingAffordance; private CanvasProperty<Float> mHwCircleRadius; private CanvasProperty<Float> mHwCenterX; @@ -152,7 +154,7 @@ public class KeyguardAffordanceView extends ImageView { @Override protected void onDraw(Canvas canvas) { - mSupportHardware = canvas.isHardwareAccelerated(); + mSupportHardware = false;//canvas.isHardwareAccelerated(); drawBackgroundCircle(canvas); canvas.save(); canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2); @@ -161,9 +163,11 @@ public class KeyguardAffordanceView extends ImageView { } public void setPreviewView(View v) { + View oldPreviewView = mPreviewView; mPreviewView = v; if (mPreviewView != null) { - mPreviewView.setVisibility(INVISIBLE); + mPreviewView.setVisibility(mLaunchingAffordance + ? oldPreviewView.getVisibility() : INVISIBLE); } } @@ -176,7 +180,7 @@ public class KeyguardAffordanceView extends ImageView { } private void drawBackgroundCircle(Canvas canvas) { - if (mCircleRadius > 0) { + if (mCircleRadius > 0 || mFinishing) { if (mFinishing && mSupportHardware) { DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius, @@ -207,11 +211,12 @@ public class KeyguardAffordanceView extends ImageView { cancelAnimator(mPreviewClipper); mFinishing = true; mCircleStartRadius = mCircleRadius; - float maxCircleSize = getMaxCircleSize(); + final float maxCircleSize = getMaxCircleSize(); Animator animatorToRadius; if (mSupportHardware) { initHwProperties(); animatorToRadius = getRtAnimatorToRadius(maxCircleSize); + startRtAlphaFadeIn(); } else { animatorToRadius = getAnimatorToRadius(maxCircleSize); } @@ -222,6 +227,8 @@ public class KeyguardAffordanceView extends ImageView { public void onAnimationEnd(Animator animation) { mAnimationEndRunnable.run(); mFinishing = false; + mCircleRadius = maxCircleSize; + invalidate(); } }); animatorToRadius.start(); @@ -241,6 +248,36 @@ public class KeyguardAffordanceView extends ImageView { } } + /** + * Fades in the Circle on the RenderThread. It's used when finishing the circle when it had + * alpha 0 in the beginning. + */ + private void startRtAlphaFadeIn() { + if (mCircleRadius == 0 && mPreviewView == null) { + Paint modifiedPaint = new Paint(mCirclePaint); + modifiedPaint.setColor(mCircleColor); + modifiedPaint.setAlpha(0); + mHwCirclePaint = CanvasProperty.createPaint(modifiedPaint); + RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint, + RenderNodeAnimator.PAINT_ALPHA, 255); + animator.setTarget(this); + animator.setInterpolator(PhoneStatusBar.ALPHA_IN); + animator.setDuration(250); + animator.start(); + } + } + + public void instantFinishAnimation() { + cancelAnimator(mPreviewClipper); + if (mPreviewView != null) { + mPreviewView.setClipBounds(null); + mPreviewView.setVisibility(View.VISIBLE); + } + mCircleRadius = getMaxCircleSize(); + setImageAlpha(0, false); + invalidate(); + } + private void startRtCircleFadeOut(long duration) { RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint, RenderNodeAnimator.PAINT_ALPHA, 0); @@ -443,6 +480,7 @@ public class KeyguardAffordanceView extends ImageView { public void setImageAlpha(float alpha, boolean animate, long duration, Interpolator interpolator, Runnable runnable) { cancelAnimator(mAlphaAnimator); + alpha = mLaunchingAffordance ? 0 : alpha; int endAlpha = (int) (alpha * 255); final Drawable background = getBackground(); if (!animate) { @@ -509,4 +547,8 @@ public class KeyguardAffordanceView extends ImageView { return false; } } + + public void setLaunchingAffordance(boolean launchingAffordance) { + mLaunchingAffordance = launchingAffordance; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java index 01aa8d1..8688c28 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java @@ -86,6 +86,9 @@ public class NotificationBackgroundView extends View { if (mBackground != null) { mBackground.setCallback(this); } + if (mBackground instanceof RippleDrawable) { + ((RippleDrawable) mBackground).setForceSoftware(true); + } invalidate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java index 28d4a42..4e69999 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -183,8 +183,11 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { mStatusBarKeyguardViewManager.animateCollapsePanels( FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); break; - case MODE_WAKE_AND_UNLOCK: case MODE_WAKE_AND_UNLOCK_PULSING: + mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */); + // Fall through. + case MODE_WAKE_AND_UNLOCK: + mStatusBarWindowManager.setStatusBarFocusable(false); mDozeScrimController.abortPulsing(); mKeyguardViewMediator.onWakeAndUnlocking(); mScrimController.setWakeAndUnlocking(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java index 10019f9..60ebfdf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java @@ -86,9 +86,9 @@ public class KeyguardAffordanceHelper { mContext = context; mCallback = callback; initIcons(); - updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true); - updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true); - updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true); + updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false); + updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true, false); + updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false); initDimens(); } @@ -144,9 +144,7 @@ public class KeyguardAffordanceHelper { } else { mTouchSlopExeeded = false; } - mCallback.onSwipingStarted(targetView == mRightIcon); - mSwipingInProgress = true; - mTargetedView = targetView; + startSwiping(targetView); mInitialTouchX = x; mInitialTouchY = y; mTranslationOnDown = mTranslation; @@ -192,6 +190,12 @@ public class KeyguardAffordanceHelper { return true; } + private void startSwiping(View targetView) { + mCallback.onSwipingStarted(targetView == mRightIcon); + mSwipingInProgress = true; + mTargetedView = targetView; + } + private View getIconAtPosition(float x, float y) { if (leftSwipePossible() && isOnIcon(mLeftIcon, x, y)) { return mLeftIcon; @@ -324,7 +328,7 @@ public class KeyguardAffordanceHelper { boolean velIsInWrongDirection = vel * mTranslation < 0; snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection; vel = snapBack ^ velIsInWrongDirection ? 0 : vel; - fling(vel, snapBack || forceSnapBack); + fling(vel, snapBack || forceSnapBack, mTranslation < 0); } private boolean isBelowFalsingThreshold() { @@ -336,9 +340,8 @@ public class KeyguardAffordanceHelper { return (int) (mMinTranslationAmount * factor); } - private void fling(float vel, final boolean snapBack) { - float target = mTranslation < 0 - ? -mCallback.getMaxTranslationDistance() + private void fling(float vel, final boolean snapBack, boolean right) { + float target = right ? -mCallback.getMaxTranslationDistance() : mCallback.getMaxTranslationDistance(); target = snapBack ? 0 : target; @@ -352,8 +355,8 @@ public class KeyguardAffordanceHelper { }); animator.addListener(mFlingEndListener); if (!snapBack) { - startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable); - mCallback.onAnimationToSideStarted(mTranslation < 0, mTranslation, vel); + startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable, right); + mCallback.onAnimationToSideStarted(right, mTranslation, vel); } else { reset(true); } @@ -364,8 +367,9 @@ public class KeyguardAffordanceHelper { } } - private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable) { - KeyguardAffordanceView targetView = mTranslation > 0 ? mLeftIcon : mRightIcon; + private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable, + boolean right) { + KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon; targetView.finishAnimation(velocity, mAnimationEndRunnable); } @@ -383,19 +387,20 @@ public class KeyguardAffordanceHelper { fadeOutAlpha = Math.max(fadeOutAlpha, 0.0f); boolean animateIcons = isReset && animateReset; + boolean forceNoCircleAnimation = isReset && !animateReset; float radius = getRadiusFromTranslation(absTranslation); boolean slowAnimation = isReset && isBelowFalsingThreshold(); if (!isReset) { updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(), - false, false, false); + false, false, false, false); } else { updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(), - animateIcons, slowAnimation, false); + animateIcons, slowAnimation, false, forceNoCircleAnimation); } updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(), - animateIcons, slowAnimation, false); + animateIcons, slowAnimation, false, forceNoCircleAnimation); updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(), - animateIcons, slowAnimation, false); + animateIcons, slowAnimation, false, forceNoCircleAnimation); mTranslation = translation; } @@ -431,16 +436,21 @@ public class KeyguardAffordanceHelper { public void animateHideLeftRightIcon() { cancelAnimation(); - updateIcon(mRightIcon, 0f, 0f, true, false, false); - updateIcon(mLeftIcon, 0f, 0f, true, false, false); + updateIcon(mRightIcon, 0f, 0f, true, false, false, false); + updateIcon(mLeftIcon, 0f, 0f, true, false, false, false); } private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha, - boolean animate, boolean slowRadiusAnimation, boolean force) { + boolean animate, boolean slowRadiusAnimation, boolean force, + boolean forceNoCircleAnimation) { if (view.getVisibility() != View.VISIBLE && !force) { return; } - view.setCircleRadius(circleRadius, slowRadiusAnimation); + if (forceNoCircleAnimation) { + view.setCircleRadiusWithoutAnimation(circleRadius); + } else { + view.setCircleRadius(circleRadius, slowRadiusAnimation); + } updateIconAlpha(view, alpha, animate); } @@ -503,8 +513,36 @@ public class KeyguardAffordanceHelper { mMotionCancelled = true; if (mSwipingInProgress) { mCallback.onSwipingAborted(); + mSwipingInProgress = false; + } + } + + public boolean isSwipingInProgress() { + return mSwipingInProgress; + } + + public void launchAffordance(boolean animate, boolean left) { + if (mSwipingInProgress) { + // We don't want to mess with the state if the user is actually swiping already. + return; + } + KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon; + KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon; + startSwiping(targetView); + if (animate) { + fling(0, false, !left); + updateIcon(otherView, 0.0f, 0, true, false, true, false); + updateIcon(mCenterIcon, 0.0f, 0, true, false, true, false); + } else { + mCallback.onAnimationToSideStarted(!left, mTranslation, 0); + mTranslation = left ? mCallback.getMaxTranslationDistance() + : mCallback.getMaxTranslationDistance(); + updateIcon(mCenterIcon, 0.0f, 0.0f, false, false, true, false); + updateIcon(otherView, 0.0f, 0.0f, false, false, true, false); + targetView.instantFinishAnimation(); + mFlingEndListener.onAnimationEnd(null); + mAnimationEndRunnable.run(); } - mSwipingInProgress = false; } public interface Callback { 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 579889d..d30411a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -80,7 +80,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private static final Intent SECURE_CAMERA_INTENT = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE) .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - private static final Intent INSECURE_CAMERA_INTENT = + public static final Intent INSECURE_CAMERA_INTENT = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL); private static final int DOZE_ANIMATION_STAGGER_DELAY = 48; 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 5be768d..5557f9c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -203,6 +203,7 @@ public class NotificationPanelView extends PanelView implements private int mLastOrientation = -1; private boolean mClosingWithAlphaFadeOut; private boolean mHeadsUpAnimatingAway; + private boolean mLaunchingAffordance; private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() { @Override @@ -488,7 +489,9 @@ public class NotificationPanelView extends PanelView implements mIsLaunchTransitionFinished = false; mBlockTouches = false; mUnlockIconActive = false; - mAfforanceHelper.reset(true); + if (!mLaunchingAffordance) { + mAfforanceHelper.reset(false); + } closeQs(); mStatusBar.dismissPopups(); mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */, @@ -2393,4 +2396,36 @@ public class NotificationPanelView extends PanelView implements public boolean hasOverlappingRendering() { return !mDozing; } + + public void launchCamera(boolean animate) { + // If we are launching it when we are occluded already we don't want it to animate, + // nor setting these flags, since the occluded state doesn't change anymore, hence it's + // never reset. + if (!isFullyCollapsed()) { + mLaunchingAffordance = true; + setLaunchingAffordance(true); + } else { + animate = false; + } + mAfforanceHelper.launchAffordance(animate, getLayoutDirection() == LAYOUT_DIRECTION_RTL); + } + + public void onAffordanceLaunchEnded() { + mLaunchingAffordance = false; + setLaunchingAffordance(false); + } + + /** + * Set whether we are currently launching an affordance. This is currently only set when + * launched via a camera gesture. + */ + private void setLaunchingAffordance(boolean launchingAffordance) { + getLeftIcon().setLaunchingAffordance(launchingAffordance); + getRightIcon().setLaunchingAffordance(launchingAffordance); + getCenterIcon().setLaunchingAffordance(launchingAffordance); + } + + public boolean canCameraGestureBeLaunched() { + return !mAfforanceHelper.isSwipingInProgress(); + } } 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 649dad3..8063bbe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -66,6 +66,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.os.Vibrator; import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.RankingMap; @@ -482,6 +483,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private Runnable mLaunchTransitionEndRunnable; private boolean mLaunchTransitionFadingAway; private ExpandableNotificationRow mDraggedDownRow; + private boolean mLaunchCameraOnScreenTurningOn; + private PowerManager.WakeLock mGestureWakeLock; + private Vibrator mVibrator; // Fingerprint (as computed by getLoggingFingerprint() of the last logged state. private int mLastLoggedStateFingerprint; @@ -903,7 +907,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mBroadcastReceiver.onReceive(mContext, new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF)); - + mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, + "GestureWakeLock"); + mVibrator = mContext.getSystemService(Vibrator.class); // receive broadcasts IntentFilter filter = new IntentFilter(); @@ -1694,7 +1700,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, final boolean hasArtwork = artworkBitmap != null; if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) - && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) { + && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) + && mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) { // time to show some art! if (mBackdrop.getVisibility() != View.VISIBLE) { mBackdrop.setVisibility(View.VISIBLE); @@ -1749,31 +1757,40 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (DEBUG_MEDIA) { Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork"); } - mBackdrop.animate() - // Never let the alpha become zero - otherwise the RenderNode - // won't draw anything and uninitialized memory will show through - // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in libhwui. - .alpha(0.002f) - .setInterpolator(mBackdropInterpolator) - .setDuration(300) - .setStartDelay(0) - .withEndAction(new Runnable() { - @Override - public void run() { - mBackdrop.setVisibility(View.GONE); - mBackdropFront.animate().cancel(); - mBackdropBack.animate().cancel(); - mHandler.post(mHideBackdropFront); - } - }); - if (mKeyguardFadingAway) { - mBackdrop.animate() + if (mFingerprintUnlockController.getMode() + == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) { - // Make it disappear faster, as the focus should be on the activity behind. - .setDuration(mKeyguardFadingAwayDuration / 2) - .setStartDelay(mKeyguardFadingAwayDelay) - .setInterpolator(mLinearInterpolator) - .start(); + // We are unlocking directly - no animation! + mBackdrop.setVisibility(View.GONE); + } else { + mBackdrop.animate() + // Never let the alpha become zero - otherwise the RenderNode + // won't draw anything and uninitialized memory will show through + // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in + // libhwui. + .alpha(0.002f) + .setInterpolator(mBackdropInterpolator) + .setDuration(300) + .setStartDelay(0) + .withEndAction(new Runnable() { + @Override + public void run() { + mBackdrop.setVisibility(View.GONE); + mBackdropFront.animate().cancel(); + mBackdropBack.animate().cancel(); + mHandler.post(mHideBackdropFront); + } + }); + if (mKeyguardFadingAway) { + mBackdrop.animate() + + // Make it disappear faster, as the focus should be on the activity + // behind. + .setDuration(mKeyguardFadingAwayDuration / 2) + .setStartDelay(mKeyguardFadingAwayDelay) + .setInterpolator(mLinearInterpolator) + .start(); + } } } } @@ -2436,8 +2453,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, || mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT); boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave(); boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0; - - mIconController.setIconsDark(allowLight && light); + boolean animate = mFingerprintUnlockController == null + || (mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING + && mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK); + mIconController.setIconsDark(allowLight && light, animate); } // restore the recents bit if (wasRecentsVisible) { @@ -3370,6 +3391,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void onLaunchTransitionFadingEnded() { mNotificationPanel.setAlpha(1.0f); + mNotificationPanel.onAffordanceLaunchEnded(); + releaseGestureWakeLock(); runLaunchTransitionEndRunnable(); mLaunchTransitionFadingAway = false; mScrimController.forceHideScrims(false /* hide */); @@ -3457,6 +3480,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void onLaunchTransitionTimeout() { Log.w(TAG, "Launch transition: Timeout!"); + mNotificationPanel.onAffordanceLaunchEnded(); + releaseGestureWakeLock(); mNotificationPanel.resetViews(); } @@ -3508,10 +3533,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mQSPanel.refreshAllTiles(); } mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT); + releaseGestureWakeLock(); + mNotificationPanel.onAffordanceLaunchEnded(); mNotificationPanel.setAlpha(1f); return staying; } + private void releaseGestureWakeLock() { + if (mGestureWakeLock.isHeld()) { + mGestureWakeLock.release(); + } + } + public long calculateGoingToFullShadeDelay() { return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration; } @@ -3636,6 +3669,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed(); } + public void endAffordanceLaunch() { + releaseGestureWakeLock(); + mNotificationPanel.onAffordanceLaunchEnded(); + } + public boolean onBackPressed() { if (mStatusBarKeyguardViewManager.onBackPressed()) { return true; @@ -3867,6 +3905,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void onFinishedGoingToSleep() { + mNotificationPanel.onAffordanceLaunchEnded(); + releaseGestureWakeLock(); + mLaunchCameraOnScreenTurningOn = false; mDeviceInteractive = false; mWakeUpComingFromTouch = false; mWakeUpTouchLocation = null; @@ -3883,6 +3924,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void onScreenTurningOn() { mNotificationPanel.onScreenTurningOn(); + if (mLaunchCameraOnScreenTurningOn) { + mNotificationPanel.launchCamera(false); + mLaunchCameraOnScreenTurningOn = false; + } + } + + private void vibrateForCameraGesture() { + mVibrator.vibrate(1000L); } public void onScreenTurnedOn() { @@ -4029,8 +4078,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void appTransitionStarting(long startTime, long duration) { // Use own timings when Keyguard is going away, see keyguardGoingAway and - // setKeyguardFadingAway - if (!mKeyguardFadingAway) { + // setKeyguardFadingAway. When duration is 0, skip this one because no animation is really + // playing. + if (!mKeyguardFadingAway && duration > 0) { mIconController.appTransitionStarting(startTime, duration); } if (mIconPolicy != null) { @@ -4038,6 +4088,39 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } + @Override + public void onCameraLaunchGestureDetected() { + if (!mNotificationPanel.canCameraGestureBeLaunched()) { + return; + } + if (!mDeviceInteractive) { + PowerManager pm = mContext.getSystemService(PowerManager.class); + pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE"); + mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); + } + vibrateForCameraGesture(); + if (!mStatusBarKeyguardViewManager.isShowing()) { + startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT, + true /* dismissShade */); + } else { + if (!mDeviceInteractive) { + // Avoid flickering of the scrim when we instant launch the camera and the bouncer + // comes on. + mScrimController.dontAnimateBouncerChangesUntilNextFrame(); + mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L); + } + if (mStatusBarKeyguardViewManager.isScreenTurnedOn()) { + mNotificationPanel.launchCamera(mDeviceInteractive /* animate */); + } else { + // We need to defer the camera launch until the screen comes on, since otherwise + // we will dismiss us too early since we are waiting on an activity to be drawn and + // incorrectly get notified because of the screen on event (which resumes and pauses + // some activities) + mLaunchCameraOnScreenTurningOn = true; + } + } + } + public void notifyFpAuthModeChanged() { updateDozing(); } 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 cc6f396..b9e9292 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -87,6 +87,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, private View mDraggedHeadsUpView; private boolean mForceHideScrims; private boolean mSkipFirstFrame; + private boolean mDontAnimateBouncerChanges; public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim, boolean scrimSrcEnabled) { @@ -125,7 +126,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public void setBouncerShowing(boolean showing) { mBouncerShowing = showing; - mAnimateChange = !mExpanding; + mAnimateChange = !mExpanding && !mDontAnimateBouncerChanges; scheduleUpdate(); } @@ -360,6 +361,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public boolean onPreDraw() { mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this); mUpdatePending = false; + if (mDontAnimateBouncerChanges) { + mDontAnimateBouncerChanges = false; + } updateScrims(); mDurationOverride = -1; mAnimationDelay = 0; @@ -496,4 +500,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, mAnimateChange = false; scheduleUpdate(); } + + public void dontAnimateBouncerChangesUntilNextFrame() { + mDontAnimateBouncerChanges = true; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java index a1e9ece..18db5b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java @@ -19,6 +19,7 @@ import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; import android.content.Context; +import android.graphics.drawable.RippleDrawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 7ee47df..e9c4e49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -26,6 +26,7 @@ import android.graphics.Outline; import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.RippleDrawable; import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; @@ -184,6 +185,12 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } }); requestCaptureValues(); + + // RenderThread is doing more harm than good when touching the header (to expand quick + // settings), so disable it for this view + ((RippleDrawable) getBackground()).setForceSoftware(true); + ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true); + ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index 067e50e..5de1c13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -335,8 +335,10 @@ public class StatusBarIconController implements Tunable { } } - public void setIconsDark(boolean dark) { - if (mTransitionPending) { + public void setIconsDark(boolean dark, boolean animate) { + if (!animate) { + setIconTintInternal(dark ? 1.0f : 0.0f); + } else if (mTransitionPending) { deferIconTintChange(dark ? 1.0f : 0.0f); } else if (mTransitionDeferring) { animateIconTint(dark ? 1.0f : 0.0f, 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 59ee5c5..d0604c5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -179,6 +179,10 @@ public class StatusBarKeyguardViewManager { mPhoneStatusBar.onScreenTurningOn(); } + public boolean isScreenTurnedOn() { + return mScreenTurnedOn; + } + public void onScreenTurnedOn() { mScreenTurnedOn = true; if (mDeferScrimFadeOut) { @@ -385,6 +389,7 @@ public class StatusBarKeyguardViewManager { */ public boolean onBackPressed() { if (mBouncer.isShowing()) { + mPhoneStatusBar.endAffordanceLaunch(); reset(); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 82064a7..cf696a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -127,7 +127,7 @@ public class StackScrollAlgorithm { mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize( R.dimen.notification_collapse_second_card_padding); mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi - >= DisplayMetrics.DENSITY_XXHIGH; + >= DisplayMetrics.DENSITY_420; } public boolean shouldScaleDimmed() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index 920b682..2587b9f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -171,6 +171,10 @@ public class TvStatusBar extends BaseStatusBar { } @Override + public void onCameraLaunchGestureDetected() { + } + + @Override protected void updateHeadsUp(String key, NotificationData.Entry entry, boolean shouldInterrupt, boolean alertAgain) { } |