diff options
34 files changed, 409 insertions, 224 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 23c12f6f57c5..f482335721ff 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3216,20 +3216,27 @@ public final class Settings { /** - * This preference contains the string that shows for owner info on LockScren. + * This preference contains the string that shows for owner info on LockScreen. * @hide */ public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info"; /** - * Id of the user-selected appwidget on the lockscreen, or -1 if none + * Ids of the user-selected appwidgets on the lockscreen (comma-delimited). * @hide */ public static final String LOCK_SCREEN_APPWIDGET_IDS = "lock_screen_appwidget_ids"; /** - * This preference enables showing the owner info on LockScren. + * Index of the lockscreen appwidget to restore, -1 if none. + * @hide + */ + public static final String LOCK_SCREEN_STICKY_APPWIDGET = + "lock_screen_sticky_appwidget"; + + /** + * This preference enables showing the owner info on LockScreen. * @hide */ public static final String LOCK_SCREEN_OWNER_INFO_ENABLED = diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index f6ae83ca19af..f8c3b4deb4ef 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -150,7 +150,6 @@ public class LockPatternUtils { private final ContentResolver mContentResolver; private DevicePolicyManager mDevicePolicyManager; private ILockSettings mLockSettingsService; - private int mStickyWidgetIndex = -1; // The current user is set by KeyguardViewMediator and shared by all LockPatternUtils. private static volatile int sCurrentUserId = UserHandle.USER_NULL; @@ -1162,6 +1161,21 @@ public class LockPatternUtils { return true; } + public int getStickyAppWidgetIndex() { + return Settings.Secure.getIntForUser( + mContentResolver, + Settings.Secure.LOCK_SCREEN_STICKY_APPWIDGET, + -1, + UserHandle.USER_CURRENT); + } + + public void setStickyAppWidgetIndex(int value) { + Settings.Secure.putIntForUser(mContentResolver, + Settings.Secure.LOCK_SCREEN_STICKY_APPWIDGET, + value, + UserHandle.USER_CURRENT); + } + private long getLong(String secureSettingKey, long defaultValue) { try { return getLockSettings().getLong(secureSettingKey, defaultValue, @@ -1311,12 +1325,4 @@ public class LockPatternUtils { return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true); } - public int getStickyWidgetIndex() { - return mStickyWidgetIndex; - } - - public void setStickyWidgetIndex(int stickyWidgetIndex) { - mStickyWidgetIndex = stickyWidgetIndex; - } - } diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java index b7f64ece50bd..209bd3cb1424 100644 --- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java +++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java @@ -116,6 +116,8 @@ public class GlowPadView extends View { private float mOuterRadius = 0.0f; private float mSnapMargin = 0.0f; + private float mFirstItemOffset = 0.0f; + private boolean mMagneticTargets = false; private boolean mDragging; private int mNewTargetResources; @@ -212,6 +214,9 @@ public class GlowPadView extends View { mInnerRadius = a.getDimension(R.styleable.GlowPadView_innerRadius, mInnerRadius); mOuterRadius = a.getDimension(R.styleable.GlowPadView_outerRadius, mOuterRadius); mSnapMargin = a.getDimension(R.styleable.GlowPadView_snapMargin, mSnapMargin); + mFirstItemOffset = (float) Math.toRadians( + a.getFloat(R.styleable.GlowPadView_firstItemOffset, + (float) Math.toDegrees(mFirstItemOffset))); mVibrationDuration = a.getInt(R.styleable.GlowPadView_vibrationDuration, mVibrationDuration); mFeedbackCount = a.getInt(R.styleable.GlowPadView_feedbackCount, @@ -223,6 +228,7 @@ public class GlowPadView extends View { getResourceId(a, R.styleable.GlowPadView_outerRingDrawable)); mAlwaysTrackFinger = a.getBoolean(R.styleable.GlowPadView_alwaysTrackFinger, false); + mMagneticTargets = a.getBoolean(R.styleable.GlowPadView_magneticTargets, mMagneticTargets); int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable); Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null; @@ -820,6 +826,7 @@ public class GlowPadView extends View { int ntargets = targets.size(); float x = 0.0f; float y = 0.0f; + float activeAngle = 0.0f; int actionIndex = event.findPointerIndex(mPointerId); if (actionIndex == -1) { @@ -852,15 +859,18 @@ public class GlowPadView extends View { for (int i = 0; i < ntargets; i++) { TargetDrawable target = targets.get(i); - double targetMinRad = (i - 0.5) * 2 * Math.PI / ntargets; - double targetMaxRad = (i + 0.5) * 2 * Math.PI / ntargets; + double targetMinRad = mFirstItemOffset + (i - 0.5) * 2 * Math.PI / ntargets; + double targetMaxRad = mFirstItemOffset + (i + 0.5) * 2 * Math.PI / ntargets; if (target.isEnabled()) { boolean angleMatches = (angleRad > targetMinRad && angleRad <= targetMaxRad) || (angleRad + 2 * Math.PI > targetMinRad && - angleRad + 2 * Math.PI <= targetMaxRad); + angleRad + 2 * Math.PI <= targetMaxRad) || + (angleRad - 2 * Math.PI > targetMinRad && + angleRad - 2 * Math.PI <= targetMaxRad); if (angleMatches && (dist2(tx, ty) > snapDistance2)) { activeTarget = i; + activeAngle = (float) -angleRad; } } } @@ -888,6 +898,9 @@ public class GlowPadView extends View { if (target.hasState(TargetDrawable.STATE_FOCUSED)) { target.setState(TargetDrawable.STATE_INACTIVE); } + if (mMagneticTargets) { + updateTargetPosition(mActiveTarget, mWaveCenterX, mWaveCenterY); + } } // Focus the new target if (activeTarget != -1) { @@ -895,6 +908,9 @@ public class GlowPadView extends View { if (target.hasState(TargetDrawable.STATE_FOCUSED)) { target.setState(TargetDrawable.STATE_FOCUSED); } + if (mMagneticTargets) { + updateTargetPosition(activeTarget, mWaveCenterX, mWaveCenterY, activeAngle); + } if (AccessibilityManager.getInstance(mContext).isEnabled()) { String targetContentDescription = getTargetDescription(activeTarget); announceForAccessibility(targetContentDescription); @@ -1039,14 +1055,15 @@ public class GlowPadView extends View { if (DEBUG) dump(); } - private void updateTargetPositions(float centerX, float centerY) { - // Reposition the target drawables if the view changed. - ArrayList<TargetDrawable> targets = mTargetDrawables; - final int size = targets.size(); - final float alpha = (float) (-2.0f * Math.PI / size); - for (int i = 0; i < size; i++) { + private void updateTargetPosition(int i, float centerX, float centerY) { + final float angle = getAngle(getSliceAngle(), i); + updateTargetPosition(i, centerX, centerY, angle); + } + + private void updateTargetPosition(int i, float centerX, float centerY, float angle) { + if (i >= 0) { + ArrayList<TargetDrawable> targets = mTargetDrawables; final TargetDrawable targetIcon = targets.get(i); - final float angle = alpha * i; targetIcon.setPositionX(centerX); targetIcon.setPositionY(centerY); targetIcon.setX(mOuterRadius * (float) Math.cos(angle)); @@ -1054,6 +1071,29 @@ public class GlowPadView extends View { } } + private void updateTargetPositions(float centerX, float centerY) { + updateTargetPositions(centerX, centerY, false); + } + + private void updateTargetPositions(float centerX, float centerY, boolean skipActive) { + final int size = mTargetDrawables.size(); + final float alpha = getSliceAngle(); + // Reposition the target drawables if the view changed. + for (int i = 0; i < size; i++) { + if (!skipActive || i != mActiveTarget) { + updateTargetPosition(i, centerX, centerY, getAngle(alpha, i)); + } + } + } + + private float getAngle(float alpha, int i) { + return mFirstItemOffset + alpha * i; + } + + private float getSliceAngle() { + return (float) (-2.0f * Math.PI / mTargetDrawables.size()); + } + private void updatePointCloudPosition(float centerX, float centerY) { mPointCloud.setCenter(centerX, centerY); } diff --git a/core/res/res/drawable-hdpi/add_widget.png b/core/res/res/drawable-hdpi/add_widget.png Binary files differdeleted file mode 100644 index fb64a52b08e8..000000000000 --- a/core/res/res/drawable-hdpi/add_widget.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_add_widget.png b/core/res/res/drawable-hdpi/kg_add_widget.png Binary files differnew file mode 100644 index 000000000000..8969a73ae39f --- /dev/null +++ b/core/res/res/drawable-hdpi/kg_add_widget.png diff --git a/core/res/res/drawable-hdpi/kg_security_lock.png b/core/res/res/drawable-hdpi/kg_security_lock.png Binary files differindex 136d3adfa80d..5fb5a01505a4 100644 --- a/core/res/res/drawable-hdpi/kg_security_lock.png +++ b/core/res/res/drawable-hdpi/kg_security_lock.png diff --git a/core/res/res/drawable-hdpi/security_frame.9.png b/core/res/res/drawable-hdpi/security_frame.9.png Binary files differdeleted file mode 100644 index 9eeadc4d118f..000000000000 --- a/core/res/res/drawable-hdpi/security_frame.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/security_handle.png b/core/res/res/drawable-hdpi/security_handle.png Binary files differdeleted file mode 100644 index bd4640f7228c..000000000000 --- a/core/res/res/drawable-hdpi/security_handle.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/add_widget.png b/core/res/res/drawable-mdpi/add_widget.png Binary files differdeleted file mode 100644 index ae2678770678..000000000000 --- a/core/res/res/drawable-mdpi/add_widget.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_add_widget.png b/core/res/res/drawable-mdpi/kg_add_widget.png Binary files differnew file mode 100644 index 000000000000..314a635a3b89 --- /dev/null +++ b/core/res/res/drawable-mdpi/kg_add_widget.png diff --git a/core/res/res/drawable-mdpi/kg_security_lock.png b/core/res/res/drawable-mdpi/kg_security_lock.png Binary files differindex 861760da8d1b..e75c82e6cfbd 100644 --- a/core/res/res/drawable-mdpi/kg_security_lock.png +++ b/core/res/res/drawable-mdpi/kg_security_lock.png diff --git a/core/res/res/drawable-mdpi/security_frame.9.png b/core/res/res/drawable-mdpi/security_frame.9.png Binary files differdeleted file mode 100644 index 9eeadc4d118f..000000000000 --- a/core/res/res/drawable-mdpi/security_frame.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/security_handle.png b/core/res/res/drawable-mdpi/security_handle.png Binary files differdeleted file mode 100644 index bd4640f7228c..000000000000 --- a/core/res/res/drawable-mdpi/security_handle.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/add_widget.png b/core/res/res/drawable-xhdpi/add_widget.png Binary files differdeleted file mode 100644 index c02700cb519d..000000000000 --- a/core/res/res/drawable-xhdpi/add_widget.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_add_widget.png b/core/res/res/drawable-xhdpi/kg_add_widget.png Binary files differnew file mode 100644 index 000000000000..54ee78b9d070 --- /dev/null +++ b/core/res/res/drawable-xhdpi/kg_add_widget.png diff --git a/core/res/res/drawable-xhdpi/kg_security_lock.png b/core/res/res/drawable-xhdpi/kg_security_lock.png Binary files differindex 45445845d015..93cdf10f83d2 100644 --- a/core/res/res/drawable-xhdpi/kg_security_lock.png +++ b/core/res/res/drawable-xhdpi/kg_security_lock.png diff --git a/core/res/res/drawable-xhdpi/security_frame.9.png b/core/res/res/drawable-xhdpi/security_frame.9.png Binary files differdeleted file mode 100644 index 9eeadc4d118f..000000000000 --- a/core/res/res/drawable-xhdpi/security_frame.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/security_handle.png b/core/res/res/drawable-xhdpi/security_handle.png Binary files differdeleted file mode 100644 index bd4640f7228c..000000000000 --- a/core/res/res/drawable-xhdpi/security_handle.png +++ /dev/null diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml index 15e984443092..2caa72f000db 100644 --- a/core/res/res/layout-port/keyguard_host_view.xml +++ b/core/res/res/layout-port/keyguard_host_view.xml @@ -32,7 +32,6 @@ android:id="@+id/sliding_layout" android:layout_width="match_parent" android:layout_height="match_parent" - androidprv:dragHandle="@drawable/kg_security_grip" androidprv:dragIcon="@drawable/kg_security_lock"> <FrameLayout diff --git a/core/res/res/layout/keyguard_add_widget.xml b/core/res/res/layout/keyguard_add_widget.xml index fa811d7bc9db..fd5e565faa0f 100644 --- a/core/res/res/layout/keyguard_add_widget.xml +++ b/core/res/res/layout/keyguard_add_widget.xml @@ -35,6 +35,6 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:padding="24dp" - android:src="@drawable/add_widget" /> + android:src="@drawable/kg_add_widget" /> </FrameLayout> -</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
\ No newline at end of file +</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame> diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml index 509e77b95bb1..a416a777cefd 100644 --- a/core/res/res/layout/keyguard_glow_pad_view.xml +++ b/core/res/res/layout/keyguard_glow_pad_view.xml @@ -29,14 +29,16 @@ android:gravity="@integer/kg_selector_gravity" android:focusable="true" - prvandroid:targetDrawables="@*android:array/lockscreen_targets_with_camera" - prvandroid:targetDescriptions="@*android:array/lockscreen_target_descriptions_with_camera" + prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only" + prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only" prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions" prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle" prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring" prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius" prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius" prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin" + prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset" + prvandroid:magneticTargets="true" prvandroid:feedbackCount="1" prvandroid:vibrationDuration="20" prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius" diff --git a/core/res/res/values-land/integers.xml b/core/res/res/values-land/integers.xml index 6613d6897ac3..020fd23cec81 100644 --- a/core/res/res/values-land/integers.xml +++ b/core/res/res/values-land/integers.xml @@ -22,4 +22,5 @@ <integer name="kg_selector_gravity">0x13</integer> <integer name="kg_widget_region_weight">45</integer> <integer name="kg_security_flipper_weight">55</integer> -</resources>
\ No newline at end of file + <integer name="kg_glowpad_rotation_offset">-90</integer> +</resources> diff --git a/core/res/res/values-sw600dp-land/integers.xml b/core/res/res/values-sw600dp-land/integers.xml index 5f5d263b29dd..b724c9099d87 100644 --- a/core/res/res/values-sw600dp-land/integers.xml +++ b/core/res/res/values-sw600dp-land/integers.xml @@ -19,4 +19,5 @@ <resources> <integer name="kg_widget_region_weight">50</integer> <integer name="kg_security_flipper_weight">50</integer> -</resources>
\ No newline at end of file + <integer name="kg_glowpad_rotation_offset">0</integer> +</resources> diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml index 8744bfe8c1c6..1e966f7cc508 100644 --- a/core/res/res/values/arrays.xml +++ b/core/res/res/values/arrays.xml @@ -398,6 +398,14 @@ <item>@null</item> </array> + <array name="lockscreen_targets_unlock_only"> + <item>@*android:drawable/ic_lockscreen_unlock</item> + </array> + + <array name="lockscreen_target_descriptions_unlock_only"> + <item>@*android:string/description_target_unlock</item> + </array> + <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad --> <string-array translatable="false" name="lockscreen_num_pad_klondike"> <item></item><!-- 0 --> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 48d47458e34c..d186c4a85f66 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -5465,6 +5465,12 @@ <!-- Used when the handle shouldn't wait to be hit before following the finger --> <attr name="alwaysTrackFinger"/> + <!-- Location along the circle of the first item, in degrees.--> + <attr name="firstItemOffset" format="float" /> + + <!-- Causes targets to snap to the finger location on activation. --> + <attr name="magneticTargets" format="boolean" /> + <attr name="gravity" /> </declare-styleable> diff --git a/core/res/res/values/integers.xml b/core/res/res/values/integers.xml index 91ad5d8eecf1..d1df2a4ca318 100644 --- a/core/res/res/values/integers.xml +++ b/core/res/res/values/integers.xml @@ -20,4 +20,5 @@ <integer name="kg_carousel_angle">75</integer> <integer name="kg_security_flip_duration">75</integer> <integer name="kg_security_fade_duration">75</integer> + <integer name="kg_glowpad_rotation_offset">0</integer> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 60a2e9139cf5..7ebf7e7bfd6b 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1234,7 +1234,7 @@ <java-symbol type="drawable" name="magnified_region_frame" /> <java-symbol type="drawable" name="menu_background" /> <java-symbol type="drawable" name="stat_sys_secure" /> - <java-symbol type="drawable" name="security_frame" /> + <java-symbol type="drawable" name="kg_bouncer_bg_white" /> <java-symbol type="id" name="action_mode_bar_stub" /> <java-symbol type="id" name="alarm_status" /> <java-symbol type="id" name="backspace" /> diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index b8467299a46a..4147b092a50c 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -249,14 +249,6 @@ public class KeyguardHostView extends KeyguardViewBase { mViewMediatorCallback.onUserActivityTimeoutChanged(); } } - - @Override - public void onPageSwitch(int newPageIndex) { - if (!isCameraOrAdd(newPageIndex)) { - if (DEBUG) Log.d(TAG, "Setting sticky widget index: " + newPageIndex); - mLockPatternUtils.setStickyWidgetIndex(newPageIndex); - } - } }; @Override @@ -737,6 +729,7 @@ public class KeyguardHostView extends KeyguardViewBase { @Override public void onScreenTurnedOff() { if (DEBUG) Log.d(TAG, "screen off, instance " + Integer.toHexString(hashCode())); + saveStickyWidgetIndex(); showPrimarySecurityScreen(true); getSecurityView(mCurrentSecuritySelection).onPause(); } @@ -859,8 +852,7 @@ public class KeyguardHostView extends KeyguardViewBase { slider.showHandle(true); slider.showChallenge(true); } - View v = mAppWidgetContainer.getChildAt(mAppWidgetContainer.getCurrentPage()); - if (v instanceof CameraWidgetFrame) { + if (isCameraPage(mAppWidgetContainer.getCurrentPage())) { mAppWidgetContainer.scrollLeft(); } } @@ -1050,6 +1042,8 @@ public class KeyguardHostView extends KeyguardViewBase { @Override public Parcelable onSaveInstanceState() { + if (DEBUG) Log.d(TAG, "onSaveInstanceState"); + saveStickyWidgetIndex(); Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); ss.transportState = mTransportState; @@ -1058,6 +1052,7 @@ public class KeyguardHostView extends KeyguardViewBase { @Override public void onRestoreInstanceState(Parcelable state) { + if (DEBUG) Log.d(TAG, "onRestoreInstanceState"); if (!(state instanceof SavedState)) { super.onRestoreInstanceState(state); return; @@ -1068,70 +1063,82 @@ public class KeyguardHostView extends KeyguardViewBase { post(mSwitchPageRunnable); } + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused")); + if (!hasWindowFocus) { + saveStickyWidgetIndex(); + } + } + private void showAppropriateWidgetPage() { - boolean music = mTransportControl.isMusicPlaying() || mTransportState == TRANSPORT_VISIBLE; - if (music) { + boolean isMusicPlaying = + mTransportControl.isMusicPlaying() || mTransportState == TRANSPORT_VISIBLE; + if (isMusicPlaying) { mTransportState = TRANSPORT_VISIBLE; } else if (mTransportState == TRANSPORT_VISIBLE) { mTransportState = TRANSPORT_INVISIBLE; } - int pageToShow = getAppropriateWidgetPage(); + int pageToShow = getAppropriateWidgetPage(isMusicPlaying); mAppWidgetContainer.setCurrentPage(pageToShow); } - private boolean isCameraOrAdd(int pageIndex) { + private boolean isCameraPage(int pageIndex) { + View v = mAppWidgetContainer.getChildAt(pageIndex); + return v != null && v instanceof CameraWidgetFrame; + } + + private boolean isAddPage(int pageIndex) { View v = mAppWidgetContainer.getChildAt(pageIndex); - return v.getId() == R.id.keyguard_add_widget || v instanceof CameraWidgetFrame; + return v != null && v.getId() == R.id.keyguard_add_widget; } - private int getAppropriateWidgetPage() { + private int getAppropriateWidgetPage(boolean isMusicPlaying) { // assumes at least one widget (besides camera + add) - boolean music = mTransportControl.isMusicPlaying() || mTransportState == TRANSPORT_VISIBLE; // if music playing, show transport - if (music) { + if (isMusicPlaying) { if (DEBUG) Log.d(TAG, "Music playing, show transport"); return mAppWidgetContainer.indexOfChild(mTransportControl); } - // if multi-user applicable, show it - UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - View multiUserView = findViewById(R.id.keyguard_multi_user_selector); - int multiUserPosition = mAppWidgetContainer.indexOfChild(multiUserView); - if (multiUserPosition != -1 && userManager.getUsers(true).size() > 1) { - if (DEBUG) Log.d(TAG, "Multi-user applicable, show it"); - return multiUserPosition; - } - - // if we have a sticky widget, show it - int stickyWidgetIndex = mLockPatternUtils.getStickyWidgetIndex(); + // if we have a valid sticky widget, show it + int stickyWidgetIndex = mLockPatternUtils.getStickyAppWidgetIndex(); if (stickyWidgetIndex > -1 && stickyWidgetIndex < mAppWidgetContainer.getChildCount() - && !isCameraOrAdd(stickyWidgetIndex)) { - if (DEBUG) Log.d(TAG, "Sticky widget found, show it"); + && !isAddPage(stickyWidgetIndex) + && !isCameraPage(stickyWidgetIndex)) { + if (DEBUG) Log.d(TAG, "Valid sticky widget found, show page " + stickyWidgetIndex); return stickyWidgetIndex; } - // if we have a status view, show it - View statusView = findViewById(R.id.keyguard_status_view); - int statusViewIndex = mAppWidgetContainer.indexOfChild(statusView); - if (statusViewIndex > -1) { - if (DEBUG) Log.d(TAG, "Status widget found, show it"); - return mAppWidgetContainer.indexOfChild(statusView); - } - - // else the right-most (except for camera) + // else show the right-most widget (except for camera) int rightMost = mAppWidgetContainer.getChildCount() - 1; - if (mAppWidgetContainer.getChildAt(rightMost) instanceof CameraWidgetFrame) { + if (isCameraPage(rightMost)) { rightMost--; } - if (DEBUG) Log.d(TAG, "Show right-most"); + if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost); return rightMost; } + private void saveStickyWidgetIndex() { + int stickyWidgetIndex = mAppWidgetContainer.getCurrentPage(); + if (isAddPage(stickyWidgetIndex)) { + stickyWidgetIndex++; + } + if (isCameraPage(stickyWidgetIndex)) { + stickyWidgetIndex--; + } + if (stickyWidgetIndex < 0 || stickyWidgetIndex >= mAppWidgetContainer.getChildCount()) { + stickyWidgetIndex = -1; + } + if (DEBUG) Log.d(TAG, "saveStickyWidgetIndex: " + stickyWidgetIndex); + mLockPatternUtils.setStickyAppWidgetIndex(stickyWidgetIndex); + } + private void enableUserSelectorIfNecessary() { - // if there are multiple users, we need to add the multi-user switcher widget to the - // keyguard. + // if there are multiple users, we need to enable to multi-user switcher UserManager mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); List<UserInfo> users = mUm.getUsers(true); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index c163b975fbc9..806c6f096fee 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -17,7 +17,6 @@ package com.android.internal.policy.impl.keyguard; import android.os.Handler; import android.os.Looper; -import android.util.Log; import android.view.View; public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChallengeScrolledListener { @@ -29,6 +28,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle private KeyguardSecurityView mKeyguardSecurityContainer; private int[] mTmpPoint = new int[2]; private static final int SCREEN_ON_HINT_DURATION = 1000; + private static final int SCREEN_ON_RING_HINT_DELAY = 300; Handler mMainQueue = new Handler(Looper.myLooper()); int mChallengeTop = 0; @@ -147,7 +147,12 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle } public void showUsabilityHints() { - mKeyguardSecurityContainer.showUsabilityHint(); + mMainQueue.postDelayed( new Runnable() { + @Override + public void run() { + mKeyguardSecurityContainer.showUsabilityHint(); + } + } , SCREEN_ON_RING_HINT_DELAY); mPagedView.showInitialPageHints(); mHideHintsRunnable = new Runnable() { @Override diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java index 02c32d4d6e32..cf16ef2a715d 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java @@ -17,12 +17,14 @@ package com.android.internal.policy.impl.keyguard; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import com.android.internal.R; public class KeyguardWidgetCarousel extends KeyguardWidgetPager { private float mAdjacentPagesAngle; + private static float MAX_SCROLL_PROGRESS = 1.3f; private static float CAMERA_DISTANCE = 10000; public KeyguardWidgetCarousel(Context context, AttributeSet attrs) { @@ -39,43 +41,73 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager { } protected float getMaxScrollProgress() { - return 1.5f; + return MAX_SCROLL_PROGRESS; + } + + public float getAlphaForPage(int screenCenter, int index) { + View child = getChildAt(index); + if (child == null) return 0f; + + float scrollProgress = getScrollProgress(screenCenter, child, index); + if (!isOverScrollChild(index, scrollProgress)) { + scrollProgress = getBoundedScrollProgress(screenCenter, child, index); + float alpha = 1 - Math.abs(scrollProgress / MAX_SCROLL_PROGRESS); + return alpha; + } else { + return 1f; + } } private void updatePageAlphaValues(int screenCenter) { - boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX; - if (!isInOverscroll) { + if (mChildrenOutlineFadeAnimation != null) { + mChildrenOutlineFadeAnimation.cancel(); + mChildrenOutlineFadeAnimation = null; + } + if (!isReordering(false)) { for (int i = 0; i < getChildCount(); i++) { KeyguardWidgetFrame child = getWidgetPageAt(i); if (child != null) { - float scrollProgress = getScrollProgress(screenCenter, child, i); - if (!isReordering(false)) { - child.setBackgroundAlphaMultiplier( - backgroundAlphaInterpolator(Math.abs(scrollProgress))); - } else { - child.setBackgroundAlphaMultiplier(1f); - } + float alpha = getAlphaForPage(screenCenter, i); + child.setBackgroundAlpha(alpha); + child.setContentAlpha(alpha); } } } + } @Override protected void screenScrolled(int screenCenter) { + mScreenCenter = screenCenter; updatePageAlphaValues(screenCenter); for (int i = 0; i < getChildCount(); i++) { KeyguardWidgetFrame v = getWidgetPageAt(i); - if (v == mDragView) continue; - if (v != null) { - float scrollProgress = getScrollProgress(screenCenter, v, i); + float scrollProgress = getScrollProgress(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 { + scrollProgress = getBoundedScrollProgress(screenCenter, v, i); int width = v.getMeasuredWidth(); float pivotX = (width / 2f) + scrollProgress * (width / 2f); float pivotY = v.getMeasuredHeight() / 2; float rotationY = - mAdjacentPagesAngle * scrollProgress; - v.setCameraDistance(CAMERA_DISTANCE); 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); } } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index 9e1189c3bf26..20e86ad5475d 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -51,6 +51,7 @@ public class KeyguardWidgetFrame extends FrameLayout { private CheckLongPressHelper mLongPressHelper; private float mBackgroundAlpha; + private float mContentAlpha; private float mBackgroundAlphaMultiplier = 1.0f; private Drawable mBackgroundDrawable; private Rect mBackgroundRect = new Rect(); @@ -74,7 +75,7 @@ public class KeyguardWidgetFrame extends FrameLayout { int padding = (int) (res.getDisplayMetrics().density * 8); setPadding(padding, padding, padding, padding); - mBackgroundDrawable = res.getDrawable(R.drawable.security_frame); + mBackgroundDrawable = res.getDrawable(R.drawable.kg_bouncer_bg_white); mGradientColor = res.getColor(com.android.internal.R.color.kg_widget_pager_gradient); mGradientPaint.setXfermode(sAddBlendMode); } @@ -133,6 +134,23 @@ public class KeyguardWidgetFrame extends FrameLayout { mLongPressHelper.cancelLongPress(); } + + private void drawGradientOverlay(Canvas c) { + mGradientPaint.setShader(mForegroundGradient); + mGradientPaint.setAlpha(mForegroundAlpha); + c.drawRect(mForegroundRect, mGradientPaint); + } + + protected void drawBg(Canvas canvas) { + if (mBackgroundAlpha > 0.0f) { + Drawable bg = mBackgroundDrawable; + + bg.setAlpha((int) (mBackgroundAlpha * mBackgroundAlphaMultiplier * 255)); + bg.setBounds(mBackgroundRect); + bg.draw(canvas); + } + } + @Override protected void dispatchDraw(Canvas canvas) { drawBg(canvas); @@ -164,6 +182,14 @@ public class KeyguardWidgetFrame extends FrameLayout { } } + public void enableHardwareLayers() { + setLayerType(LAYER_TYPE_HARDWARE, null); + } + + public void disableHardwareLayers() { + setLayerType(LAYER_TYPE_NONE, null); + } + public View getContent() { return getChildAt(0); } @@ -177,28 +203,12 @@ public class KeyguardWidgetFrame extends FrameLayout { } } - private void drawGradientOverlay(Canvas c) { - mGradientPaint.setShader(mForegroundGradient); - mGradientPaint.setAlpha(mForegroundAlpha); - c.drawRect(mForegroundRect, mGradientPaint); - } - - protected void drawBg(Canvas canvas) { - if (mBackgroundAlpha > 0.0f) { - Drawable bg = mBackgroundDrawable; - - bg.setAlpha((int) (mBackgroundAlpha * mBackgroundAlphaMultiplier * 255)); - bg.setBounds(mBackgroundRect); - bg.draw(canvas); - } - } - public float getBackgroundAlpha() { return mBackgroundAlpha; } public void setBackgroundAlphaMultiplier(float multiplier) { - if (mBackgroundAlphaMultiplier != multiplier) { + if (Float.compare(mBackgroundAlphaMultiplier, multiplier) != 0) { mBackgroundAlphaMultiplier = multiplier; invalidate(); } @@ -209,13 +219,18 @@ public class KeyguardWidgetFrame extends FrameLayout { } public void setBackgroundAlpha(float alpha) { - if (mBackgroundAlpha != alpha) { + if (Float.compare(mBackgroundAlpha, alpha) != 0) { mBackgroundAlpha = alpha; invalidate(); } } + public float getContentAlpha() { + return mContentAlpha; + } + public void setContentAlpha(float alpha) { + mContentAlpha = alpha; View content = getContent(); if (content != null) { content.setAlpha(alpha); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index 63e7fddd8463..09ce4db4e10b 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -15,6 +15,9 @@ */ package com.android.internal.policy.impl.keyguard; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; @@ -27,33 +30,32 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.OnLongClickListener; import android.view.ViewGroup; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; +import java.util.ArrayList; + public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener, OnLongClickListener { ZInterpolator mZInterpolator = new ZInterpolator(0.5f); private static float CAMERA_DISTANCE = 10000; - private static float TRANSITION_MAX_ROTATION = 30; + protected static float OVERSCROLL_MAX_ROTATION = 30; private static final boolean PERFORM_OVERSCROLL_ROTATION = true; private KeyguardViewStateManager mViewStateManager; private LockPatternUtils mLockPatternUtils; // Related to the fading in / out background outlines - private static final int CHILDREN_OUTLINE_FADE_OUT_DELAY = 0; private static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375; - private static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100; - private ObjectAnimator mChildrenOutlineFadeInAnimation; - private ObjectAnimator mChildrenOutlineFadeOutAnimation; + private static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 75; + protected AnimatorSet mChildrenOutlineFadeAnimation; private float mChildrenOutlineAlpha = 0; private float mSidePagesAlpha = 1f; + protected int mScreenCenter; private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000; @@ -114,7 +116,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit if (mCallbacks != null) { mCallbacks.onUserActivityTimeoutChanged(); mCallbacks.userActivity(); - mCallbacks.onPageSwitch(newPageIndex); } KeyguardWidgetFrame oldWidgetPage = getWidgetPageAt(oldPageIndex); if (oldWidgetPage != null) { @@ -154,7 +155,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit public interface Callbacks { public void userActivity(); public void onUserActivityTimeoutChanged(); - public void onPageSwitch(int newPageIndex); } public void addWidget(View widget) { @@ -253,13 +253,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit @Override protected void onPageBeginMoving() { - // Enable hardware layers while pages are moving - // TODO: We should only do this for the two views that are actually moving - int children = getChildCount(); - for (int i = 0; i < children; i++) { - getWidgetPageAt(i).enableHardwareLayersForContent(); - } - if (mViewStateManager != null) { mViewStateManager.onPageBeginMoving(); } @@ -268,16 +261,24 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit @Override protected void onPageEndMoving() { - // Disable hardware layers while pages are moving + if (mViewStateManager != null) { + mViewStateManager.onPageEndMoving(); + } + hideOutlinesAndSidePages(); + } + + private void enablePageLayers() { int children = getChildCount(); for (int i = 0; i < children; i++) { - getWidgetPageAt(i).disableHardwareLayersForContent(); + getWidgetPageAt(i).enableHardwareLayersForContent(); } + } - if (mViewStateManager != null) { - mViewStateManager.onPageEndMoving(); + private void disablePageLayers() { + int children = getChildCount(); + for (int i = 0; i < children; i++) { + getWidgetPageAt(i).disableHardwareLayersForContent(); } - hideOutlinesAndSidePages(); } /* @@ -325,25 +326,21 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } private void updatePageAlphaValues(int screenCenter) { + } + + public float getAlphaForPage(int screenCenter, int index) { + return 1f; + } + + protected boolean isOverScrollChild(int index, float scrollProgress) { boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX; - if (!isInOverscroll) { - for (int i = 0; i < getChildCount(); i++) { - KeyguardWidgetFrame child = getWidgetPageAt(i); - if (child != null) { - float scrollProgress = getScrollProgress(screenCenter, child, i); - if (!isReordering(false)) { - child.setBackgroundAlphaMultiplier( - backgroundAlphaInterpolator(Math.abs(scrollProgress))); - } else { - child.setBackgroundAlphaMultiplier(1f); - } - } - } - } + return (isInOverscroll && (index == 0 && scrollProgress < 0 || + index == getChildCount() - 1 && scrollProgress > 0)); } @Override protected void screenScrolled(int screenCenter) { + mScreenCenter = screenCenter; updatePageAlphaValues(screenCenter); for (int i = 0; i < getChildCount(); i++) { KeyguardWidgetFrame v = getWidgetPageAt(i); @@ -351,30 +348,17 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit if (v != null) { float scrollProgress = getScrollProgress(screenCenter, v, i); - float alpha = 1.0f; - v.setCameraDistance(mDensity * CAMERA_DISTANCE); - if (PERFORM_OVERSCROLL_ROTATION) { - if (i == 0 && scrollProgress < 0) { - // Over scroll to the left - v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); - v.setOverScrollAmount(Math.abs(scrollProgress), true); - alpha = 1.0f; - // On the first page, we don't want the page to have any lateral motion - } else if (i == getChildCount() - 1 && scrollProgress > 0) { - // Over scroll to the right - v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); - alpha = 1.0f; - v.setOverScrollAmount(Math.abs(scrollProgress), false); - // On the last page, we don't want the page to have any lateral motion. - } else { - v.setRotationY(0f); - v.setOverScrollAmount(0, false); - } + if (isOverScrollChild(i, scrollProgress) && PERFORM_OVERSCROLL_ROTATION) { + v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress); + v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0); + } else { + v.setRotationY(0f); + v.setOverScrollAmount(0, false); } - v.setAlpha(alpha); + 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) { @@ -385,6 +369,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } } } + @Override void boundByReorderablePages(boolean isReordering, int[] range) { if (isReordering) { @@ -418,7 +403,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit @Override protected void onStartReordering() { super.onStartReordering(); - setChildrenOutlineMultiplier(1.0f); showOutlinesAndSidePages(); } @@ -429,43 +413,62 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } void showOutlinesAndSidePages() { - if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel(); - if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel(); - - PropertyValuesHolder outlinesAlpha = - PropertyValuesHolder.ofFloat("childrenOutlineAlpha", 1.0f); - PropertyValuesHolder sidePagesAlpha = PropertyValuesHolder.ofFloat("sidePagesAlpha", 1.0f); - mChildrenOutlineFadeInAnimation = - ObjectAnimator.ofPropertyValuesHolder(this, outlinesAlpha, sidePagesAlpha); + enablePageLayers(); + animateOutlinesAndSidePages(true); + } - mChildrenOutlineFadeInAnimation.setDuration(CHILDREN_OUTLINE_FADE_IN_DURATION); - mChildrenOutlineFadeInAnimation.start(); + void hideOutlinesAndSidePages() { + animateOutlinesAndSidePages(false); } public void showInitialPageHints() { - // We start with everything showing - setChildrenOutlineAlpha(1.0f); - setSidePagesAlpha(1.0f); - setChildrenOutlineMultiplier(1.0f); - - int currPage = getCurrentPage(); - KeyguardWidgetFrame frame = getWidgetPageAt(currPage); - frame.setBackgroundAlphaMultiplier(0f); + showOutlinesAndSidePages(); } - void hideOutlinesAndSidePages() { - if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel(); - if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel(); - - PropertyValuesHolder outlinesAlpha = - PropertyValuesHolder.ofFloat("childrenOutlineAlpha", 0f); - PropertyValuesHolder sidePagesAlpha = PropertyValuesHolder.ofFloat("sidePagesAlpha", 0f); - mChildrenOutlineFadeOutAnimation = - ObjectAnimator.ofPropertyValuesHolder(this, outlinesAlpha, sidePagesAlpha); - - mChildrenOutlineFadeOutAnimation.setDuration(CHILDREN_OUTLINE_FADE_OUT_DURATION); - mChildrenOutlineFadeOutAnimation.setStartDelay(CHILDREN_OUTLINE_FADE_OUT_DELAY); - mChildrenOutlineFadeOutAnimation.start(); + void animateOutlinesAndSidePages(final boolean show) { + if (mChildrenOutlineFadeAnimation != null) { + mChildrenOutlineFadeAnimation.cancel(); + mChildrenOutlineFadeAnimation = null; + } + + int count = getChildCount(); + PropertyValuesHolder alpha; + PropertyValuesHolder outlineAlpha; + ArrayList<Animator> anims = new ArrayList<Animator>(); + + int curPage = getNextPage(); + for (int i = 0; i < count; i++) { + float finalContentAlpha; + if (show) { + finalContentAlpha = getAlphaForPage(mScreenCenter, i); + } else if (!show && i == curPage) { + finalContentAlpha = 1f; + } else { + finalContentAlpha = 0f; + } + float finalOutlineAlpha = show ? getAlphaForPage(mScreenCenter, i) : 0f; + KeyguardWidgetFrame child = getWidgetPageAt(i); + alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha); + outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",finalOutlineAlpha); + ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha); + anims.add(a); + } + + int duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION : + CHILDREN_OUTLINE_FADE_OUT_DURATION; + mChildrenOutlineFadeAnimation = new AnimatorSet(); + mChildrenOutlineFadeAnimation.playTogether(anims); + + mChildrenOutlineFadeAnimation.setDuration(duration); + mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (!show) { + disablePageLayers(); + } + } + }); + mChildrenOutlineFadeAnimation.start(); } public void setChildrenOutlineAlpha(float alpha) { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java index 3562071a2a1c..25ce6d0f1dba 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java @@ -201,8 +201,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc // We use the min scale to determine how much to expand the actually PagedView measured // dimensions such that when we are zoomed out, the view is not clipped private int REORDERING_DROP_REPOSITION_DURATION = 200; - private int REORDERING_REORDER_REPOSITION_DURATION = 350; - private int REORDERING_ZOOM_IN_OUT_DURATION = 250; + protected int REORDERING_REORDER_REPOSITION_DURATION = 350; + protected int REORDERING_ZOOM_IN_OUT_DURATION = 250; private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 500; private float REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE = 0.1f; private float mMinScale = 1f; @@ -1162,6 +1162,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc return 1.0f; } + protected float getBoundedScrollProgress(int screenCenter, View v, int page) { + final int halfScreenSize = getViewportWidth() / 2; + + screenCenter = Math.min(mScrollX + halfScreenSize, screenCenter); + screenCenter = Math.max(halfScreenSize, screenCenter); + + return getScrollProgress(screenCenter, v, page); + } + protected float getScrollProgress(int screenCenter, View v, int page) { final int halfScreenSize = getViewportWidth() / 2; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java index 506b79d208df..304171c28dab 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.FloatProperty; @@ -44,6 +45,18 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout private static final String TAG = "SlidingChallengeLayout"; private static final boolean DEBUG = false; + // The drag handle is measured in dp above & below the top edge of the + // challenge view; these parameters change based on whether the challenge + // is open or closed. + private static final int DRAG_HANDLE_CLOSED_ABOVE = 32; // dp + private static final int DRAG_HANDLE_CLOSED_BELOW = 32; // dp + private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp + private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp + + private static final boolean OPEN_ON_CLICK = true; + + private static final int HANDLE_ANIMATE_DURATION = 200; // ms + // Drawn to show the drag handle in closed state; crossfades to the challenge view // when challenge is fully visible private Drawable mHandleDrawable; @@ -82,13 +95,20 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout private VelocityTracker mVelocityTracker; private int mMinVelocity; private int mMaxVelocity; - private float mGestureStartY; // where did you touch the screen to start this gesture? + private float mGestureStartX, mGestureStartY; // where did you first touch the screen? private int mGestureStartChallengeBottom; // where was the challenge at that time? - private int mDragHandleSize; // handle hitrect extension into the challenge view - private int mDragHandleHeadroom; // extend the handle's hitrect this far above the line + + private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view + private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line + private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view + private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line + private int mDragHandleEdgeSlop; private int mChallengeBottomBound; // Number of pixels from the top of the challenge view // that should remain on-screen + + private int mTouchSlop; + float mHandleAlpha; float mFrameAlpha; private ObjectAnimator mHandleAnimation; @@ -125,9 +145,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } }; - private static final int DRAG_HANDLE_DEFAULT_SIZE = 32; // dp - private static final int HANDLE_ANIMATE_DURATION = 200; // ms - // True if at least one layout pass has happened since the view was attached. private boolean mHasLayout; @@ -224,20 +241,25 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout mDragHandleEdgeSlop = getResources().getDimensionPixelSize( R.dimen.kg_edge_swipe_region_size); + mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + setWillNotDraw(false); } public void setDragDrawables(Drawable handle, Drawable icon) { final float density = getResources().getDisplayMetrics().density; - final int defaultSize = (int) (DRAG_HANDLE_DEFAULT_SIZE * density + 0.5f); final int handleHeight = handle != null ? handle.getIntrinsicHeight() : 0; final int iconHeight = icon != null ? icon.getIntrinsicHeight() : 0; - mDragHandleSize = Math.max(handleHeight > 0 ? handleHeight : defaultSize, - iconHeight > 0 ? iconHeight : defaultSize); // top half of the lock icon, plus another 25% to be sure - mDragHandleHeadroom = (int) (iconHeight * 0.75f); - mChallengeBottomBound = (mDragHandleSize + mDragHandleHeadroom + handleHeight) / 2; + mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f); + mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f); + mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f); + mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f); + + // how much space to account for in the handle when closed + mChallengeBottomBound = + (mDragHandleClosedBelow + mDragHandleClosedAbove + handleHeight) / 2; mHandleDrawable = handle; mDragIconDrawable = icon; @@ -477,9 +499,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } mVelocityTracker.addMovement(ev); + //Log.v(TAG, "onIntercept: " + ev); + final int action = ev.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: + mGestureStartX = ev.getX(); mGestureStartY = ev.getY(); mBlockDrag = false; break; @@ -500,7 +525,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) && mActivePointerId == INVALID_POINTER) { mActivePointerId = ev.getPointerId(i); - mGestureStartY = ev.getY(); + mGestureStartX = x; + mGestureStartY = y; mGestureStartChallengeBottom = getChallengeBottom(); mDragging = true; } else if (isInChallengeView(x, y)) { @@ -532,10 +558,13 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } mVelocityTracker.addMovement(ev); + //Log.v(TAG, "onTouch: " + ev); + final int action = ev.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: mBlockDrag = false; + mGestureStartX = ev.getX(); mGestureStartY = ev.getY(); break; @@ -551,7 +580,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout break; } case MotionEvent.ACTION_UP: - if (mDragging) { + if (OPEN_ON_CLICK + && isInDragHandle(mGestureStartX, mGestureStartY) + && Math.abs(ev.getX() - mGestureStartX) <= mTouchSlop + && Math.abs(ev.getY() - mGestureStartY) <= mTouchSlop) { + showChallenge(true); + } else if (mDragging) { mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity); showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId)); } @@ -568,6 +602,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) || (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) && mActivePointerId == INVALID_POINTER) { + mGestureStartX = x; mGestureStartY = y; mActivePointerId = ev.getPointerId(i); mGestureStartChallengeBottom = getChallengeBottom(); @@ -605,8 +640,11 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout * We only want to add additional vertical space to the drag handle when the panel is fully * closed. */ - private int getDragHandleHeadroom() { - return isChallengeShowing() ? 0 : mDragHandleHeadroom; + private int getDragHandleSizeAbove() { + return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove; + } + private int getDragHandleSizeBelow() { + return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow; } private boolean isInChallengeView(float x, float y) { @@ -620,17 +658,17 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if (mChallengeView == null) return false; return x >= mDragHandleEdgeSlop && - y >= mChallengeView.getTop() - getDragHandleHeadroom() && + y >= mChallengeView.getTop() - getDragHandleSizeAbove() && x < getWidth() - mDragHandleEdgeSlop && - y < mChallengeView.getTop() + mDragHandleSize; + y < mChallengeView.getTop() + getDragHandleSizeBelow(); } private boolean crossedDragHandle(float x, float y, float initialY) { final int challengeTop = mChallengeView.getTop(); return x >= 0 && x < getWidth() && - initialY < (challengeTop - getDragHandleHeadroom()) && - y > challengeTop + mDragHandleSize; + initialY < (challengeTop - getDragHandleSizeAbove()) && + y > challengeTop + getDragHandleSizeBelow(); } @Override @@ -760,20 +798,25 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout debugPaint.setColor(0x40FF00CC); // show the isInDragHandle() rect c.drawRect(mDragHandleEdgeSlop, - mChallengeView.getTop() - getDragHandleHeadroom(), + mChallengeView.getTop() - getDragHandleSizeAbove(), getWidth() - mDragHandleEdgeSlop, - mChallengeView.getTop() + mDragHandleSize, + mChallengeView.getTop() + getDragHandleSizeBelow(), debugPaint); } - if (mChallengeView != null && mHandleAlpha > 0 && mHandleDrawable != null) { + if (mChallengeView != null && mHandleAlpha > 0) { final int top = mChallengeView.getTop(); - final int handleHeight = mHandleDrawable.getIntrinsicHeight(); + final int handleHeight; final int challengeLeft = mChallengeView.getLeft(); final int challengeRight = mChallengeView.getRight(); - mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight); - mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF)); - mHandleDrawable.draw(c); + if (mHandleDrawable != null) { + handleHeight = mHandleDrawable.getIntrinsicHeight(); + mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight); + mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF)); + mHandleDrawable.draw(c); + } else { + handleHeight = 0; + } if (DEBUG) { // now show the actual drag handle |