Files
frameworks_base/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java
Jim Miller 5ecd81154f Move keyguard to its own process.
This is in preparation to moving keyguard into its own process.

Moved keyguard source and resources into new .apk.

Got basic test app working.  Still need to implement MockPatternUtils
and means to pass it into KeyguardService with local binder interface.

Added new ACCESS_KEYGUARD_SECURE_STORAGE permission.

Temporarily disabled USER_PRESENT broadcast.

Remove unintentional whitespace changes in PhoneWindowManager, etc.

Checkpoint basic working version.

Move to systemui process.

Synchronize with TOT.

Sync with recent user API changes.

Fix bug with returing interface instead of stub for IKeyguardResult.  Create KeyguardServiceDelegate to allow
for runtime-selectable local or remote interface.

More keyguard crash robustness.

Keyguard crash recovery working.  Currently fails safe (locked).

Fix selector view which was still using frameworks resources.

Remove more references to internal framework variables.  Use aliases for those we should move but
currently have dependencies.

Allow runtime switching between service and local mode.

Fix layout issue on tablets where orientation was reading the incorrect constant
from the framework.  Remove more framework dependencies.

Fix PIN keyboard input.

Remove unnecessary copy of orientation attrs.

Remove unused user selector widget and attempt to get multi user working again.

Fix multi-user avatar icon by grabbing it from UserManager rather than directly since
keyguard can no longer read it.

Merge with AppWidget userId changes in master.

Change-Id: I254d6fc6423ae40f6d7fef50aead4caa701e5ad2
2013-02-27 17:27:53 -08:00

289 lines
11 KiB
Java

/*
* Copyright (C) 2012 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.keyguard;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import java.util.ArrayList;
public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
private float mAdjacentPagesAngle;
private static float MAX_SCROLL_PROGRESS = 1.3f;
private static float CAMERA_DISTANCE = 10000;
protected AnimatorSet mChildrenTransformsAnimator;
float[] mTmpTransform = new float[3];
public KeyguardWidgetCarousel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public KeyguardWidgetCarousel(Context context) {
this(context, null, 0);
}
public KeyguardWidgetCarousel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mAdjacentPagesAngle = context.getResources().getInteger(R.integer.kg_carousel_angle);
}
protected float getMaxScrollProgress() {
return MAX_SCROLL_PROGRESS;
}
public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
View child = getChildAt(index);
if (child == null) return 0f;
boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
float scrollProgress = getScrollProgress(screenCenter, child, index);
if (isOverScrollChild(index, scrollProgress)) {
return 1.0f;
} else if ((showSidePages && inVisibleRange) || index == getNextPage()) {
scrollProgress = getBoundedScrollProgress(screenCenter, child, index);
float alpha = 1.0f - 1.0f * Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
return alpha;
} else {
return 0f;
}
}
public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
if (inVisibleRange) {
return super.getOutlineAlphaForPage(screenCenter, index, showSidePages);
} else {
return 0f;
}
}
private void updatePageAlphaValues(int screenCenter) {
if (mChildrenOutlineFadeAnimation != null) {
mChildrenOutlineFadeAnimation.cancel();
mChildrenOutlineFadeAnimation = null;
}
boolean showSidePages = mShowingInitialHints || isPageMoving();
if (!isReordering(false)) {
for (int i = 0; i < getChildCount(); i++) {
KeyguardWidgetFrame child = getWidgetPageAt(i);
if (child != null) {
float outlineAlpha = getOutlineAlphaForPage(screenCenter, i, showSidePages);
float contentAlpha = getAlphaForPage(screenCenter, i,showSidePages);
child.setBackgroundAlpha(outlineAlpha);
child.setContentAlpha(contentAlpha);
}
}
}
}
public void showInitialPageHints() {
mShowingInitialHints = true;
int count = getChildCount();
for (int i = 0; i < count; i++) {
boolean inVisibleRange = i >= getNextPage() - 1 && i <= getNextPage() + 1;
KeyguardWidgetFrame child = getWidgetPageAt(i);
if (inVisibleRange) {
child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
child.setContentAlpha(1f);
} else {
child.setBackgroundAlpha(0f);
child.setContentAlpha(0f);
}
}
}
@Override
protected void screenScrolled(int screenCenter) {
mScreenCenter = screenCenter;
updatePageAlphaValues(screenCenter);
if (isReordering(false)) return;
for (int i = 0; i < getChildCount(); i++) {
KeyguardWidgetFrame v = getWidgetPageAt(i);
float scrollProgress = getScrollProgress(screenCenter, v, i);
float boundedProgress = getBoundedScrollProgress(screenCenter, v, i);
if (v == mDragView || v == null) continue;
v.setCameraDistance(CAMERA_DISTANCE);
if (isOverScrollChild(i, scrollProgress)) {
v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
} else {
int width = v.getMeasuredWidth();
float pivotX = (width / 2f) + boundedProgress * (width / 2f);
float pivotY = v.getMeasuredHeight() / 2;
float rotationY = - mAdjacentPagesAngle * boundedProgress;
v.setPivotX(pivotX);
v.setPivotY(pivotY);
v.setRotationY(rotationY);
v.setOverScrollAmount(0f, false);
}
float alpha = v.getAlpha();
// If the view has 0 alpha, we set it to be invisible so as to prevent
// it from accepting touches
if (alpha == 0) {
v.setVisibility(INVISIBLE);
} else if (v.getVisibility() != VISIBLE) {
v.setVisibility(VISIBLE);
}
}
}
void animatePagesToNeutral() {
if (mChildrenTransformsAnimator != null) {
mChildrenTransformsAnimator.cancel();
mChildrenTransformsAnimator = null;
}
int count = getChildCount();
PropertyValuesHolder alpha;
PropertyValuesHolder outlineAlpha;
PropertyValuesHolder rotationY;
ArrayList<Animator> anims = new ArrayList<Animator>();
for (int i = 0; i < count; i++) {
KeyguardWidgetFrame child = getWidgetPageAt(i);
boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
if (!inVisibleRange) {
child.setRotationY(0f);
}
alpha = PropertyValuesHolder.ofFloat("contentAlpha", 1.0f);
outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",
KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
rotationY = PropertyValuesHolder.ofFloat("rotationY", 0f);
ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha, rotationY);
child.setVisibility(VISIBLE);
if (!inVisibleRange) {
a.setInterpolator(mSlowFadeInterpolator);
}
anims.add(a);
}
int duration = REORDERING_ZOOM_IN_OUT_DURATION;
mChildrenTransformsAnimator = new AnimatorSet();
mChildrenTransformsAnimator.playTogether(anims);
mChildrenTransformsAnimator.setDuration(duration);
mChildrenTransformsAnimator.start();
}
private void getTransformForPage(int screenCenter, int index, float[] transform) {
View child = getChildAt(index);
float boundedProgress = getBoundedScrollProgress(screenCenter, child, index);
float rotationY = - mAdjacentPagesAngle * boundedProgress;
int width = child.getMeasuredWidth();
float pivotX = (width / 2f) + boundedProgress * (width / 2f);
float pivotY = child.getMeasuredHeight() / 2;
transform[0] = pivotX;
transform[1] = pivotY;
transform[2] = rotationY;
}
Interpolator mFastFadeInterpolator = new Interpolator() {
Interpolator mInternal = new DecelerateInterpolator(1.5f);
float mFactor = 2.5f;
@Override
public float getInterpolation(float input) {
return mInternal.getInterpolation(Math.min(mFactor * input, 1f));
}
};
Interpolator mSlowFadeInterpolator = new Interpolator() {
Interpolator mInternal = new AccelerateInterpolator(1.5f);
float mFactor = 1.3f;
@Override
public float getInterpolation(float input) {
input -= (1 - 1 / mFactor);
input = mFactor * Math.max(input, 0f);
return mInternal.getInterpolation(input);
}
};
void animatePagesToCarousel() {
if (mChildrenTransformsAnimator != null) {
mChildrenTransformsAnimator.cancel();
mChildrenTransformsAnimator = null;
}
int count = getChildCount();
PropertyValuesHolder alpha;
PropertyValuesHolder outlineAlpha;
PropertyValuesHolder rotationY;
PropertyValuesHolder pivotX;
PropertyValuesHolder pivotY;
ArrayList<Animator> anims = new ArrayList<Animator>();
for (int i = 0; i < count; i++) {
KeyguardWidgetFrame child = getWidgetPageAt(i);
float finalAlpha = getAlphaForPage(mScreenCenter, i, true);
float finalOutlineAlpha = getOutlineAlphaForPage(mScreenCenter, i, true);
getTransformForPage(mScreenCenter, i, mTmpTransform);
boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
ObjectAnimator a;
alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalAlpha);
outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", finalOutlineAlpha);
pivotX = PropertyValuesHolder.ofFloat("pivotX", mTmpTransform[0]);
pivotY = PropertyValuesHolder.ofFloat("pivotY", mTmpTransform[1]);
rotationY = PropertyValuesHolder.ofFloat("rotationY", mTmpTransform[2]);
if (inVisibleRange) {
// for the central pages we animate into a rotated state
a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha,
pivotX, pivotY, rotationY);
} else {
a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
a.setInterpolator(mFastFadeInterpolator);
}
anims.add(a);
}
int duration = REORDERING_ZOOM_IN_OUT_DURATION;
mChildrenTransformsAnimator = new AnimatorSet();
mChildrenTransformsAnimator.playTogether(anims);
mChildrenTransformsAnimator.setDuration(duration);
mChildrenTransformsAnimator.start();
}
protected void reorderStarting() {
mViewStateManager.fadeOutSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
animatePagesToNeutral();
}
protected boolean zoomIn(final Runnable onCompleteRunnable) {
animatePagesToCarousel();
return super.zoomIn(onCompleteRunnable);
}
@Override
protected void onEndReordering() {
super.onEndReordering();
mViewStateManager.fadeInSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
}
}