summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java13
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java24
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/GlowPadView.java60
-rw-r--r--core/res/res/drawable-hdpi/add_widget.pngbin12967 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_add_widget.pngbin0 -> 316 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock.pngbin1898 -> 2722 bytes
-rw-r--r--core/res/res/drawable-hdpi/security_frame.9.pngbin6384 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/security_handle.pngbin516 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/add_widget.pngbin7732 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_add_widget.pngbin0 -> 262 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock.pngbin1530 -> 1933 bytes
-rw-r--r--core/res/res/drawable-mdpi/security_frame.9.pngbin6384 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/security_handle.pngbin516 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/add_widget.pngbin15737 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_add_widget.pngbin0 -> 422 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock.pngbin2484 -> 3730 bytes
-rw-r--r--core/res/res/drawable-xhdpi/security_frame.9.pngbin6384 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/security_handle.pngbin516 -> 0 bytes
-rw-r--r--core/res/res/layout-land/keyguard_widget_pager.xml2
-rw-r--r--core/res/res/layout-port/keyguard_host_view.xml2
-rw-r--r--core/res/res/layout-port/keyguard_widget_pager.xml2
-rw-r--r--core/res/res/layout/keyguard_account_view.xml4
-rw-r--r--core/res/res/layout/keyguard_add_widget.xml4
-rw-r--r--core/res/res/layout/keyguard_emergency_carrier_area.xml43
-rw-r--r--core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml73
-rw-r--r--core/res/res/layout/keyguard_face_unlock_view.xml5
-rw-r--r--core/res/res/layout/keyguard_glow_pad_view.xml6
-rw-r--r--core/res/res/layout/keyguard_message_area.xml (renamed from core/res/res/layout/keyguard_navigation.xml)17
-rw-r--r--core/res/res/layout/keyguard_message_area_large.xml (renamed from core/res/res/layout/empty_navigation.xml)14
-rw-r--r--core/res/res/layout/keyguard_password_view.xml13
-rw-r--r--core/res/res/layout/keyguard_pattern_view.xml8
-rw-r--r--core/res/res/layout/keyguard_pin_view.xml8
-rw-r--r--core/res/res/layout/keyguard_selector_view.xml4
-rw-r--r--core/res/res/layout/keyguard_sim_pin_view.xml5
-rw-r--r--core/res/res/layout/keyguard_sim_puk_view.xml4
-rw-r--r--core/res/res/values-land/integers.xml3
-rw-r--r--core/res/res/values-sw600dp-land/integers.xml3
-rw-r--r--core/res/res/values/arrays.xml8
-rwxr-xr-xcore/res/res/values/attrs.xml6
-rw-r--r--core/res/res/values/dimens.xml2
-rw-r--r--core/res/res/values/integers.xml1
-rw-r--r--core/res/res/values/styles.xml1
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java93
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java10
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java11
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java120
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java215
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java57
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java7
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java11
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java8
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java4
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java11
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java13
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java4
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java111
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java60
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java151
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java187
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/PagedView.java13
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java105
67 files changed, 1009 insertions, 540 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
deleted file mode 100644
index fb64a52b08e8..000000000000
--- a/core/res/res/drawable-hdpi/add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget.png b/core/res/res/drawable-hdpi/kg_add_widget.png
new file mode 100644
index 000000000000..8969a73ae39f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock.png b/core/res/res/drawable-hdpi/kg_security_lock.png
index 136d3adfa80d..5fb5a01505a4 100644
--- a/core/res/res/drawable-hdpi/kg_security_lock.png
+++ b/core/res/res/drawable-hdpi/kg_security_lock.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/security_frame.9.png b/core/res/res/drawable-hdpi/security_frame.9.png
deleted file mode 100644
index 9eeadc4d118f..000000000000
--- a/core/res/res/drawable-hdpi/security_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/security_handle.png b/core/res/res/drawable-hdpi/security_handle.png
deleted file mode 100644
index bd4640f7228c..000000000000
--- a/core/res/res/drawable-hdpi/security_handle.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/add_widget.png b/core/res/res/drawable-mdpi/add_widget.png
deleted file mode 100644
index ae2678770678..000000000000
--- a/core/res/res/drawable-mdpi/add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget.png b/core/res/res/drawable-mdpi/kg_add_widget.png
new file mode 100644
index 000000000000..314a635a3b89
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock.png b/core/res/res/drawable-mdpi/kg_security_lock.png
index 861760da8d1b..e75c82e6cfbd 100644
--- a/core/res/res/drawable-mdpi/kg_security_lock.png
+++ b/core/res/res/drawable-mdpi/kg_security_lock.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/security_frame.9.png b/core/res/res/drawable-mdpi/security_frame.9.png
deleted file mode 100644
index 9eeadc4d118f..000000000000
--- a/core/res/res/drawable-mdpi/security_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/security_handle.png b/core/res/res/drawable-mdpi/security_handle.png
deleted file mode 100644
index bd4640f7228c..000000000000
--- a/core/res/res/drawable-mdpi/security_handle.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/add_widget.png b/core/res/res/drawable-xhdpi/add_widget.png
deleted file mode 100644
index c02700cb519d..000000000000
--- a/core/res/res/drawable-xhdpi/add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget.png b/core/res/res/drawable-xhdpi/kg_add_widget.png
new file mode 100644
index 000000000000..54ee78b9d070
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock.png b/core/res/res/drawable-xhdpi/kg_security_lock.png
index 45445845d015..93cdf10f83d2 100644
--- a/core/res/res/drawable-xhdpi/kg_security_lock.png
+++ b/core/res/res/drawable-xhdpi/kg_security_lock.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/security_frame.9.png b/core/res/res/drawable-xhdpi/security_frame.9.png
deleted file mode 100644
index 9eeadc4d118f..000000000000
--- a/core/res/res/drawable-xhdpi/security_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/security_handle.png b/core/res/res/drawable-xhdpi/security_handle.png
deleted file mode 100644
index bd4640f7228c..000000000000
--- a/core/res/res/drawable-xhdpi/security_handle.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout-land/keyguard_widget_pager.xml b/core/res/res/layout-land/keyguard_widget_pager.xml
index 8b7b9a3fabcc..975288fa4cc2 100644
--- a/core/res/res/layout-land/keyguard_widget_pager.xml
+++ b/core/res/res/layout-land/keyguard_widget_pager.xml
@@ -28,4 +28,4 @@
android:clipChildren="false"
android:clipToPadding="false"
androidprv:pageSpacing="10dp">
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel>
+</com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel> \ No newline at end of file
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 15e984443092..ed55e61ce5b2 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
@@ -68,7 +67,6 @@
android:paddingLeft="@dimen/keyguard_security_view_margin"
android:paddingTop="@dimen/keyguard_security_view_margin"
android:paddingRight="@dimen/keyguard_security_view_margin"
- android:paddingBottom="@dimen/keyguard_security_view_margin"
android:gravity="center">
</com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
diff --git a/core/res/res/layout-port/keyguard_widget_pager.xml b/core/res/res/layout-port/keyguard_widget_pager.xml
index 6662f83ce62b..c02decdaf20e 100644
--- a/core/res/res/layout-port/keyguard_widget_pager.xml
+++ b/core/res/res/layout-port/keyguard_widget_pager.xml
@@ -29,4 +29,4 @@
android:clipChildren="false"
android:clipToPadding="false"
androidprv:pageSpacing="10dp">
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
+</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager> \ No newline at end of file
diff --git a/core/res/res/layout/keyguard_account_view.xml b/core/res/res/layout/keyguard_account_view.xml
index d1f9225ece83..78adfe754917 100644
--- a/core/res/res/layout/keyguard_account_view.xml
+++ b/core/res/res/layout/keyguard_account_view.xml
@@ -23,7 +23,9 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <include layout="@layout/keyguard_sim_puk_pin_account_navigation"/>
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
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_emergency_carrier_area.xml b/core/res/res/layout/keyguard_emergency_carrier_area.xml
index f9a593fd5038..655b77dbf718 100644
--- a/core/res/res/layout/keyguard_emergency_carrier_area.xml
+++ b/core/res/res/layout/keyguard_emergency_carrier_area.xml
@@ -36,16 +36,39 @@
android:textSize="@dimen/kg_status_line_font_size"
android:textColor="?android:attr/textColorSecondary"/>
- <com.android.internal.policy.impl.keyguard.EmergencyButton
- android:id="@+id/emergency_call_button"
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
- android:text="@string/kg_emergency_call_label"
- style="?android:attr/buttonBarButtonStyle"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"
- android:drawablePadding="8dip" />
+ android:layout_marginTop="-10dip"
+ style="?android:attr/buttonBarStyle"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:weightSum="2">
+
+ <com.android.internal.policy.impl.keyguard.EmergencyButton
+ android:id="@+id/emergency_call_button"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
+ android:text="@string/kg_emergency_call_label"
+ style="?android:attr/buttonBarButtonStyle"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary"
+ android:drawablePadding="8dip" />
+
+ <Button android:id="@+id/forgot_password_button"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:drawablePadding="8dip"
+ android:visibility="gone"/>
+ </LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml b/core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml
deleted file mode 100644
index eeb4178af956..000000000000
--- a/core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 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.
-*/
--->
-
-<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:gravity="center"
- android:layout_gravity="center_horizontal"
- android:layout_alignParentBottom="true">
-
- <com.android.internal.policy.impl.keyguard.CarrierText
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/buttonBarStyle"
- android:orientation="horizontal"
- android:gravity="center"
- android:weightSum="2">
-
- <com.android.internal.policy.impl.keyguard.EmergencyButton
- android:id="@+id/emergency_call_button"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
- android:text="@string/kg_emergency_call_label"
- style="?android:attr/buttonBarButtonStyle"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"
- android:drawablePadding="8dip" />
-
- <Button android:id="@+id/forgot_password_button"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
- style="?android:attr/buttonBarButtonStyle"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:drawablePadding="8dip"
- android:visibility="gone"/>
- </LinearLayout>
-
-</LinearLayout>
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
index 00f14f5c7290..ae7984c78333 100644
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ b/core/res/res/layout/keyguard_face_unlock_view.xml
@@ -25,7 +25,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/keyguard_navigation"/>
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
<RelativeLayout
android:id="@+id/face_unlock_area_view"
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/layout/keyguard_navigation.xml b/core/res/res/layout/keyguard_message_area.xml
index 8230c523c103..9f11a2c4705f 100644
--- a/core/res/res/layout/keyguard_navigation.xml
+++ b/core/res/res/layout/keyguard_message_area.xml
@@ -16,6 +16,17 @@
** limitations under the License.
*/
-->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <include layout="@layout/empty_navigation" />
-</merge>
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.internal.policy.impl.keyguard.KeyguardMessageArea
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:id="@+id/keyguard_message_area"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearance"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary" />
+
diff --git a/core/res/res/layout/empty_navigation.xml b/core/res/res/layout/keyguard_message_area_large.xml
index 642207066b80..584cec4e5a47 100644
--- a/core/res/res/layout/empty_navigation.xml
+++ b/core/res/res/layout/keyguard_message_area_large.xml
@@ -16,4 +16,16 @@
** limitations under the License.
*/
-->
-<merge xmlns:android="http://schemas.android.com/apk/res/android" /> \ No newline at end of file
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.internal.policy.impl.keyguard.KeyguardMessageArea
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:id="@+id/keyguard_message_area"
+ android:maxLines="4"
+ android:textAppearance="?android:attr/textAppearance"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary" />
+
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
index e28f2ac38bba..a184415919f6 100644
--- a/core/res/res/layout/keyguard_password_view.xml
+++ b/core/res/res/layout/keyguard_password_view.xml
@@ -29,6 +29,11 @@
android:layout_height="0dp"
android:layout_weight="1">
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -36,14 +41,6 @@
android:layout_gravity="center">
<LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:gravity="center">
- <include layout="@layout/keyguard_navigation"/>
- </LinearLayout>
-
- <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index bec03b41173d..0f6256a20ad9 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -32,14 +32,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
- <include layout="@layout/keyguard_navigation"/>
-
<!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
the pattern view for it to compute its size. This is an unusual case, caused by
LockPatternView's requirement to maintain a square aspect ratio based on the width
@@ -55,7 +57,7 @@
android:layout_gravity="center_horizontal"
android:gravity="center" />
- <include layout="@layout/keyguard_emergency_carrier_area_and_recovery"
+ <include layout="@layout/keyguard_emergency_carrier_area"
android:id="@+id/keyguard_selector_fade_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml
index 9b883afee9b1..d62570b4a857 100644
--- a/core/res/res/layout/keyguard_pin_view.xml
+++ b/core/res/res/layout/keyguard_pin_view.xml
@@ -25,6 +25,10 @@
android:layout_height="350dp"
android:orientation="vertical"
>
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
@@ -186,7 +190,7 @@
/>
<ImageButton
android:id="@+id/key_enter"
- style="@android:style/Widget.Button.NumPadKey"
+ style="@style/Widget.Button.NumPadKey"
android:gravity="center"
android:layout_width="0px"
android:layout_height="match_parent"
@@ -195,7 +199,7 @@
/>
</LinearLayout>
- <include layout="@layout/keyguard_emergency_carrier_area_and_recovery"
+ <include layout="@layout/keyguard_emergency_carrier_area"
android:id="@+id/keyguard_selector_fade_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
index daaf35bcdf5e..74034082747c 100644
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ b/core/res/res/layout/keyguard_selector_view.xml
@@ -36,6 +36,10 @@
android:clipToPadding="false"
android:gravity="center">
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
<include layout="@layout/keyguard_glow_pad_container" />
<include layout="@layout/keyguard_emergency_carrier_area"
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
index ae59d1de99ec..ad617091b18d 100644
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ b/core/res/res/layout/keyguard_sim_pin_view.xml
@@ -43,7 +43,10 @@
android:layout_height="wrap_content"
android:src="@drawable/ic_lockscreen_sim"/>
- <include layout="@layout/keyguard_sim_puk_pin_account_navigation"/>
+ <include layout="@layout/keyguard_message_area_large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
</LinearLayout>
<!-- Password entry field -->
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
index 414806fb4097..cc97005a6907 100644
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ b/core/res/res/layout/keyguard_sim_puk_view.xml
@@ -44,7 +44,9 @@
android:layout_height="wrap_content"
android:src="@drawable/ic_lockscreen_sim"/>
- <include layout="@layout/keyguard_sim_puk_pin_account_navigation"/>
+ <include layout="@layout/keyguard_message_area_large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
</LinearLayout>
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/dimens.xml b/core/res/res/values/dimens.xml
index 8a7632c1ec12..b830e798f613 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -266,7 +266,7 @@
<!-- Size of margin on the right of keyguard's status view -->
<dimen name="kg_status_line_font_right_margin">16dp</dimen>
- <!-- Top margin for the clock view -->
+ <!-- Top margin for the clock view -->
<dimen name="kg_clock_top_margin">-16dp</dimen>
<!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
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/styles.xml b/core/res/res/values/styles.xml
index da26e6a1c996..180f864bb3c4 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2503,4 +2503,5 @@ please see styles_device_defaults.xml.
<item name="android:textStyle">normal</item>
<item name="android:textColor">#80ffffff</item>
</style>
+
</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/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
index db7e231b19f2..17415a9d8c87 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
@@ -25,6 +25,7 @@ import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -32,10 +33,11 @@ import android.widget.ImageView.ScaleType;
import com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
-public class CameraWidgetFrame extends KeyguardWidgetFrame {
+public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
private static final String TAG = CameraWidgetFrame.class.getSimpleName();
private static final boolean DEBUG = KeyguardHostView.DEBUG;
private static final int WIDGET_ANIMATION_DURATION = 250;
+ private static final int WIDGET_WAIT_DURATION = 650;
interface Callbacks {
void onLaunchingCamera();
@@ -49,6 +51,10 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
private View mWidgetView;
private long mLaunchCameraStart;
private boolean mRendered;
+ private boolean mActive;
+ private boolean mChallengeActive;
+ private boolean mTransitioning;
+ private boolean mDown;
private final Runnable mLaunchCameraRunnable = new Runnable() {
@Override
@@ -63,6 +69,12 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
render();
}};
+ private final Runnable mTransitionToCameraRunnable = new Runnable() {
+ @Override
+ public void run() {
+ transitionToCamera();
+ }};
+
private CameraWidgetFrame(Context context, Callbacks callbacks,
KeyguardActivityLauncher activityLauncher) {
super(context);
@@ -93,10 +105,12 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
CameraWidgetFrame cameraWidgetFrame = new CameraWidgetFrame(context, callbacks, launcher);
cameraWidgetFrame.addView(preview);
cameraWidgetFrame.mWidgetView = widgetView;
+ preview.setOnClickListener(cameraWidgetFrame);
return cameraWidgetFrame;
}
private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) {
+ if (DEBUG) Log.d(TAG, "inflateWidgetView: " + widgetInfo.contextPackage);
View widgetView = null;
Exception exception = null;
try {
@@ -118,6 +132,7 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
}
private static View inflateGenericWidgetView(Context context) {
+ if (DEBUG) Log.d(TAG, "inflateGenericWidgetView");
ImageView iv = new ImageView(context);
iv.setImageResource(com.android.internal.R.drawable.ic_lockscreen_camera);
iv.setScaleType(ScaleType.CENTER);
@@ -154,6 +169,9 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
}
private void transitionToCamera() {
+ if (mTransitioning || mChallengeActive || mDown) return;
+ if (DEBUG) Log.d(TAG, "Transitioning to camera...");
+ mTransitioning = true;
int startWidth = getChildAt(0).getWidth();
int startHeight = getChildAt(0).getHeight();
@@ -174,10 +192,21 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
}
@Override
+ public void onClick(View v) {
+ if (DEBUG) Log.d(TAG, "clicked");
+ if (mTransitioning) return;
+ if (mActive && !mChallengeActive) {
+ cancelTransitionToCamera();
+ transitionToCamera();
+ }
+ }
+
+ @Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
-
+ if (DEBUG) Log.d(TAG, "onWindowFocusChanged: " + hasWindowFocus);
if (!hasWindowFocus) {
+ mTransitioning = false;
if (mLaunchCameraStart > 0) {
long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart;
if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime));
@@ -189,23 +218,69 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
@Override
public void onActive(boolean isActive) {
- if (isActive) {
- mHandler.post(new Runnable(){
- @Override
- public void run() {
- transitionToCamera();
- }});
+ mActive = isActive;
+ if (mActive) {
+ rescheduleTransitionToCamera();
} else {
reset();
}
}
+ @Override
+ public boolean onUserInteraction(int action) {
+ if (mTransitioning) return true;
+ if (DEBUG) Log.d(TAG, "onUserInteraction " + action);
+ mDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE;
+ if (mActive && !mChallengeActive) {
+ rescheduleTransitionToCamera();
+ }
+ return false;
+ }
+
+ @Override
+ protected void onFocusLost() {
+ Log.d(TAG, "onFocusLost");
+ cancelTransitionToCamera();
+ super.onFocusLost();
+ }
+
+ @Override
+ public void onChallengeActive(boolean challengeActive) {
+ if (DEBUG) Log.d(TAG, "onChallengeActive: " + challengeActive);
+ mChallengeActive = challengeActive;
+ if (mTransitioning) return;
+ if (mActive) {
+ if (mChallengeActive) {
+ cancelTransitionToCamera();
+ } else {
+ rescheduleTransitionToCamera();
+ }
+ }
+ }
+
+ private void rescheduleTransitionToCamera() {
+ if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis());
+ mHandler.removeCallbacks(mTransitionToCameraRunnable);
+ mHandler.postDelayed(mTransitionToCameraRunnable, WIDGET_WAIT_DURATION);
+ }
+
+ private void cancelTransitionToCamera() {
+ if (DEBUG) Log.d(TAG, "cancelTransitionToCamera at " + SystemClock.uptimeMillis());
+ mHandler.removeCallbacks(mTransitionToCameraRunnable);
+ }
+
private void onCameraLaunched() {
- reset();
mCallbacks.onCameraLaunched();
+ reset();
}
private void reset() {
+ if (DEBUG) Log.d(TAG, "reset");
+ mLaunchCameraStart = 0;
+ mTransitioning = false;
+ mChallengeActive = false;
+ mDown = false;
+ cancelTransitionToCamera();
animate().cancel();
setScaleX(1);
setScaleY(1);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
index 020fdbabb64b..4825e23ec9c9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
@@ -60,8 +60,10 @@ public class CheckLongPressHelper {
public void onMove(MotionEvent ev) {
float x = ev.getX();
float y = ev.getY();
+ boolean xMoved = Math.abs(mDownX - x) > mScaledTouchSlop;
+ boolean yMoved = Math.abs(mDownY - y) > mScaledTouchSlop;
- if (Math.sqrt(Math.pow(mDownX - x, 2) + Math.pow(mDownY - y, 2)) > mScaledTouchSlop) {
+ if (xMoved || yMoved) {
cancelLongPress();
}
}
@@ -77,4 +79,4 @@ public class CheckLongPressHelper {
public boolean hasPerformedLongPress() {
return mHasPerformedLongPress;
}
-} \ No newline at end of file
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
index 2eb10fe12795..9c21830cf710 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
@@ -91,9 +91,6 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
@Override
protected void onFinishInflate() {
- // We always set a dummy NavigationManager to avoid null checks
- mSecurityMessageDisplay = new KeyguardNavigationManager(null);
-
mLockPatternUtils = new LockPatternUtils(mContext);
mPasswordEntry = (TextView) findViewById(R.id.passwordEntry);
@@ -120,6 +117,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
}
}
});
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
}
@Override
@@ -219,12 +217,6 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
public void afterTextChanged(Editable s) {
}
- @Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- mSecurityMessageDisplay = display;
- reset();
- }
-
// Cause a VIRTUAL_KEY vibration
public void doHapticKeyClick() {
if (mEnableHaptics) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
index ea7a8e7e30e1..9c877550d4e0 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
@@ -84,9 +84,6 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit
protected void onFinishInflate() {
super.onFinishInflate();
- // We always set a dummy NavigationManager to avoid null checks
- mSecurityMessageDisplay = new KeyguardNavigationManager(null);
-
mLogin = (EditText) findViewById(R.id.login);
mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
mLogin.addTextChangedListener(this);
@@ -96,6 +93,8 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit
mOk = (Button) findViewById(R.id.ok);
mOk.setOnClickListener(this);
+
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
reset();
}
@@ -317,12 +316,6 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit
}
@Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- mSecurityMessageDisplay = display;
- reset();
- }
-
- @Override
public void showUsabilityHint() {
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index 4aa6b05dc7b8..e1160e066930 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -35,7 +35,6 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
private KeyguardSecurityCallback mKeyguardSecurityCallback;
private LockPatternUtils mLockPatternUtils;
private BiometricSensorUnlock mBiometricUnlock;
- private SecurityMessageDisplay mSecurityMessageDisplay;
private View mFaceUnlockAreaView;
private ImageButton mCancelButton;
@@ -215,11 +214,6 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
};
@Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- mSecurityMessageDisplay = display;
- }
-
- @Override
public void showUsabilityHint() {
}
}
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..3a01e64ff537 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
@@ -633,19 +625,7 @@ public class KeyguardHostView extends KeyguardViewBase {
View v = inflater.inflate(layoutId, this, false);
mSecurityViewContainer.addView(v);
updateSecurityView(v);
-
- view = (KeyguardSecurityView) v;
- TextView navigationText = ((TextView) findViewById(R.id.keyguard_message_area));
-
- // Some devices can fit a navigation area, others cannot. On devices that cannot,
- // we display the security message in status area.
- if (navigationText != null) {
- view.setSecurityMessageDisplay(new KeyguardNavigationManager(navigationText));
- } else {
- if (mKeyguardStatusViewManager != null) {
- view.setSecurityMessageDisplay(mKeyguardStatusViewManager);
- }
- }
+ view = (KeyguardSecurityView)v;
}
if (view instanceof KeyguardSelectorView) {
@@ -737,6 +717,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();
}
@@ -854,15 +835,14 @@ public class KeyguardHostView extends KeyguardViewBase {
@Override
public void onCameraLaunched() {
+ if (isCameraPage(mAppWidgetContainer.getCurrentPage())) {
+ mAppWidgetContainer.scrollLeft();
+ }
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
slider.showHandle(true);
slider.showChallenge(true);
}
- View v = mAppWidgetContainer.getChildAt(mAppWidgetContainer.getCurrentPage());
- if (v instanceof CameraWidgetFrame) {
- mAppWidgetContainer.scrollLeft();
- }
}
private SlidingChallengeLayout locateSlider() {
@@ -963,13 +943,6 @@ public class KeyguardHostView extends KeyguardViewBase {
}
});
}
-
- KeyguardStatusView ksv = (KeyguardStatusView)
- findViewById(R.id.keyguard_status_view_face_palm);
- if (ksv != null) {
- mKeyguardStatusViewManager = ksv.getManager();
- }
-
}
private void addWidgetsFromSettings() {
@@ -1050,6 +1023,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 +1033,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 +1044,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.getId() == R.id.keyguard_add_widget || v instanceof CameraWidgetFrame;
+ return v != null && v instanceof CameraWidgetFrame;
}
- private int getAppropriateWidgetPage() {
+ private boolean isAddPage(int pageIndex) {
+ View v = mAppWidgetContainer.getChildAt(pageIndex);
+ return v != null && v.getId() == R.id.keyguard_add_widget;
+ }
+
+ 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/KeyguardMessageArea.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
new file mode 100644
index 000000000000..ca78cf95a7eb
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2011 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.internal.policy.impl.keyguard;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import libcore.util.MutableInt;
+
+import com.android.internal.R;
+
+/***
+ * Manages a number of views inside of the given layout. See below for a list of widgets.
+ */
+class KeyguardMessageArea extends TextView {
+ static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
+ static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
+
+ static final int SECURITY_MESSAGE_DURATION = 5000;
+ static final String SEPARATOR = " ";
+
+ // are we showing battery information?
+ boolean mShowingBatteryInfo = false;
+
+ // last known plugged in state
+ boolean mPluggedIn = false;
+
+ // last known battery level
+ int mBatteryLevel = 100;
+
+ KeyguardUpdateMonitor mUpdateMonitor;
+
+ // Timeout before we reset the message to show charging/owner info
+ long mTimeout = SECURITY_MESSAGE_DURATION;
+
+ // Shadowed text values
+ protected boolean mBatteryCharged;
+ protected boolean mBatteryIsLow;
+
+ private Handler mHandler;
+
+ CharSequence mMessage;
+ boolean mShowingMessage;
+ Runnable mClearMessageRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mMessage = null;
+ mShowingMessage = false;
+ update();
+ }
+ };
+
+ public static class Helper implements SecurityMessageDisplay {
+ KeyguardMessageArea mMessageArea;
+ Helper(View v) {
+ mMessageArea = (KeyguardMessageArea) v.findViewById(R.id.keyguard_message_area);
+ if (mMessageArea == null) {
+ throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
+ }
+ }
+
+ public void setMessage(CharSequence msg, boolean important) {
+ if (!TextUtils.isEmpty(msg) && important) {
+ mMessageArea.mMessage = msg;
+ mMessageArea.securityMessageChanged();
+ }
+ }
+
+ public void setMessage(int resId, boolean important) {
+ if (resId != 0 && important) {
+ mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId);
+ mMessageArea.securityMessageChanged();
+ }
+ }
+
+ public void setMessage(int resId, boolean important, Object... formatArgs) {
+ if (resId != 0 && important) {
+ mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs);
+ mMessageArea.securityMessageChanged();
+ }
+ }
+
+ @Override
+ public void setTimeout(int timeoutMs) {
+ mMessageArea.mTimeout = timeoutMs;
+ }
+ }
+
+ private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
+ mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
+ mPluggedIn = status.isPluggedIn();
+ mBatteryLevel = status.level;
+ mBatteryCharged = status.isCharged();
+ mBatteryIsLow = status.isBatteryLow();
+ update();
+ }
+ };
+
+ public KeyguardMessageArea(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardMessageArea(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ // This is required to ensure marquee works
+ setSelected(true);
+
+ // Registering this callback immediately updates the battery state, among other things.
+ mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
+ mUpdateMonitor.registerCallback(mInfoCallback);
+ mHandler = new Handler(Looper.myLooper());
+
+ update();
+ }
+
+ public void securityMessageChanged() {
+ mShowingMessage = true;
+ update();
+ mHandler.removeCallbacks(mClearMessageRunnable);
+ if (mTimeout > 0) {
+ mHandler.postDelayed(mClearMessageRunnable, mTimeout);
+ }
+ announceForAccessibility(getText());
+ }
+
+ /**
+ * Update the status lines based on these rules:
+ * AlarmStatus: Alarm state always gets it's own line.
+ * Status1 is shared between help, battery status and generic unlock instructions,
+ * prioritized in that order.
+ * @param showStatusLines status lines are shown if true
+ */
+ void update() {
+ MutableInt icon = new MutableInt(0);
+ CharSequence status = concat(getChargeInfo(icon), getOwnerInfo(), getCurrentMessage());
+ setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
+ setText(status);
+ }
+
+
+ private CharSequence concat(Object... args) {
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < args.length; i++) {
+ final Object arg = args[i];
+ if (arg instanceof CharSequence) {
+ b.append((CharSequence)args[i]);
+ b.append(SEPARATOR);
+ } else if (arg instanceof String) {
+ b.append((String)args[i]);
+ b.append(SEPARATOR);
+ }
+ }
+ return b.toString();
+ }
+
+
+ CharSequence getCurrentMessage() {
+ return mShowingMessage ? mMessage : null;
+ }
+
+ String getOwnerInfo() {
+ ContentResolver res = getContext().getContentResolver();
+ final boolean ownerInfoEnabled = Settings.Secure.getIntForUser(res,
+ Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
+ return ownerInfoEnabled && !mShowingMessage ?
+ Settings.Secure.getStringForUser(res, Settings.Secure.LOCK_SCREEN_OWNER_INFO,
+ UserHandle.USER_CURRENT) : null;
+ }
+
+ private CharSequence getChargeInfo(MutableInt icon) {
+ CharSequence string = null;
+ if (mShowingBatteryInfo && !mShowingMessage) {
+ // Battery status
+ if (mPluggedIn) {
+ // Charging, charged or waiting to charge.
+ string = getContext().getString(mBatteryCharged ?
+ com.android.internal.R.string.lockscreen_charged
+ :com.android.internal.R.string.lockscreen_plugged_in, mBatteryLevel);
+ icon.value = CHARGING_ICON;
+ } else if (mBatteryIsLow) {
+ // Battery is low
+ string = getContext().getString(
+ com.android.internal.R.string.lockscreen_low_battery);
+ icon.value = BATTERY_LOW_ICON;
+ }
+ }
+ return string;
+ }
+
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java
deleted file mode 100644
index cec2668ff23e..000000000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.internal.policy.impl.keyguard;
-
-import android.widget.TextView;
-
-public class KeyguardNavigationManager implements SecurityMessageDisplay {
-
- private TextView mMessageArea;
-
- public KeyguardNavigationManager(TextView messageArea) {
- if (messageArea != null) {
- mMessageArea = messageArea;
- mMessageArea.setSelected(true); // Make marquee work
- }
- }
-
- public void setMessage(CharSequence msg, boolean important) {
- if (mMessageArea == null) return;
- mMessageArea.setText(msg);
- mMessageArea.announceForAccessibility(mMessageArea.getText());
- }
-
- public void setMessage(int resId, boolean important) {
- if (mMessageArea == null) return;
- if (resId != 0) {
- mMessageArea.setText(resId);
- mMessageArea.announceForAccessibility(mMessageArea.getText());
- } else {
- mMessageArea.setText("");
- }
- }
-
- public void setMessage(int resId, boolean important, Object... formatArgs) {
- if (mMessageArea == null) return;
- if (resId != 0) {
- mMessageArea.setText(mMessageArea.getContext().getString(resId, formatArgs));
- mMessageArea.announceForAccessibility(mMessageArea.getText());
- } else {
- mMessageArea.setText("");
- }
- }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
index 5cdf4d394f74..bea9aec13ed5 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
@@ -33,13 +33,6 @@ import com.android.internal.R;
public class KeyguardPINView extends KeyguardAbsKeyInputView
implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
- // To avoid accidental lockout due to events while the device in in the pocket, ignore
- // any passwords with length less than or equal to this length.
- private static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
-
- // Enable this if we want to hide the on-screen PIN keyboard when a physical one is showing
- private static final boolean ENABLE_HIDE_KEYBOARD = false;
-
public KeyguardPINView(Context context) {
this(context, null);
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index 408a9c8c22af..6b3446add9a1 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -110,10 +110,6 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
- // We always set a dummy NavigationManager to avoid null checks
- mSecurityMessageDisplay = new KeyguardNavigationManager(null);
-
mLockPatternUtils = mLockPatternUtils == null
? new LockPatternUtils(mContext) : mLockPatternUtils;
@@ -139,6 +135,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
setFocusableInTouchMode(true);
maybeEnableFallback(mContext);
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
}
private void updateFooter(FooterMode mode) {
@@ -376,12 +373,6 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
public KeyguardSecurityCallback getCallback() {
return mCallback;
}
-
- @Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- mSecurityMessageDisplay = display;
- reset();
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
index c3684c4ab9ef..26517435d8f0 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
@@ -61,7 +61,9 @@ public interface KeyguardSecurityView {
*/
KeyguardSecurityCallback getCallback();
- void setSecurityMessageDisplay(SecurityMessageDisplay display);
-
+ /**
+ * Instruct the view to show usability hints, if any.
+ *
+ */
void showUsabilityHint();
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
index 9cdbc2de203e..58cf56767b0c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
@@ -119,14 +119,6 @@ public class KeyguardSecurityViewFlipper extends ViewFlipper implements Keyguard
}
@Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- KeyguardSecurityView ksv = getSecurityView();
- if (ksv != null) {
- ksv.setSecurityMessageDisplay(display);
- }
- }
-
- @Override
public void showUsabilityHint() {
KeyguardSecurityView ksv = getSecurityView();
if (ksv != null) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index eba9a76d0309..6a9d7584574a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -261,8 +261,4 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
public KeyguardSecurityCallback getCallback() {
return mCallback;
}
-
- @Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
index 018a1aa752e0..fcf45ff8a880 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
@@ -76,9 +76,6 @@ public class KeyguardSimPinView extends LinearLayout
protected void onFinishInflate() {
super.onFinishInflate();
- // We always set a dummy NavigationManager to avoid null checks
- mSecurityMessageDisplay = new KeyguardNavigationManager(null);
-
mPinEntry = (EditText) findViewById(R.id.sim_pin_entry);
mPinEntry.setOnEditorActionListener(this);
mPinEntry.addTextChangedListener(this);
@@ -103,6 +100,9 @@ public class KeyguardSimPinView extends LinearLayout
}
});
}
+
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ mSecurityMessageDisplay.setTimeout(0);
reset();
}
@@ -269,9 +269,4 @@ public class KeyguardSimPinView extends LinearLayout
public void afterTextChanged(Editable s) {
}
- @Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- mSecurityMessageDisplay = display;
- reset();
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
index d0585b99f6ea..04658050d9b4 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
@@ -130,10 +130,6 @@ public class KeyguardSimPukView extends LinearLayout implements View.OnClickList
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
- // We always set a dummy NavigationManager to avoid null checks
- mSecurityMessageDisplay = new KeyguardNavigationManager(null);
-
mSimPinEntry = (TextView) findViewById(R.id.sim_pin_entry);
mSimPinEntry.setOnEditorActionListener(this);
mSimPinEntry.addTextChangedListener(this);
@@ -150,6 +146,9 @@ public class KeyguardSimPukView extends LinearLayout implements View.OnClickList
});
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());
+
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
reset();
}
@@ -338,10 +337,4 @@ public class KeyguardSimPukView extends LinearLayout implements View.OnClickList
@Override
public void afterTextChanged(Editable s) {
}
-
- @Override
- public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
- mSecurityMessageDisplay = display;
- reset();
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
index 2837a66a64a6..b4bd6e9e7a6c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
@@ -326,4 +326,8 @@ class KeyguardStatusViewManager implements SecurityMessageDisplay {
return mContainer.getContext();
}
+ @Override
+ public void setTimeout(int timeout_ms) {
+ }
+
}
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..abaf9ff241e4 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
@@ -17,20 +17,25 @@ 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 {
private KeyguardWidgetPager mPagedView;
- private int mCurrentPageIndex;
private ChallengeLayout mChallengeLayout;
private Runnable mHideHintsRunnable;
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 mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
+
+ // Paged view state
+ private int mPageListeningToSlider = -1;
+ private int mCurrentPage = -1;
+
int mChallengeTop = 0;
public KeyguardViewStateManager() {
@@ -66,28 +71,39 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
}
public void onPageSwitch(View newPage, int newPageIndex) {
- // Reset the previous page size and ensure the current page is sized appropriately
- if (mPagedView != null) {
- KeyguardWidgetFrame oldPage = mPagedView.getWidgetPageAt(mCurrentPageIndex);
- // Reset the old widget page to full size
- if (oldPage != null) {
- oldPage.resetSize();
+ // Reset the previous page size and ensure the current page is sized appropriately.
+ // We only modify the page state if it is not currently under control by the slider.
+ // This prevents conflicts.
+ if (mPagedView != null && mChallengeLayout != null) {
+ KeyguardWidgetFrame prevPage = mPagedView.getWidgetPageAt(mCurrentPage);
+ if (prevPage != null && mCurrentPage != mPageListeningToSlider) {
+ prevPage.resetSize();
}
KeyguardWidgetFrame newCurPage = mPagedView.getWidgetPageAt(newPageIndex);
- if (mChallengeLayout.isChallengeOverlapping()) {
- sizeWidgetFrameToChallengeTop(newCurPage);
+ boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+ if (challengeOverlapping && !newCurPage.isSmall()
+ && mPageListeningToSlider != newPageIndex) {
+ shrinkWidget(newCurPage);
}
}
- mCurrentPageIndex = newPageIndex;
+ mCurrentPage = newPageIndex;
}
- private void sizeWidgetFrameToChallengeTop(KeyguardWidgetFrame frame) {
- if (frame == null) return;
+ private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
mTmpPoint[0] = 0;
- mTmpPoint[1] = mChallengeTop;
+ mTmpPoint[1] = top;
mapPoint((View) mChallengeLayout, frame, mTmpPoint);
- frame.setChallengeTop(mTmpPoint[1]);
+ return mTmpPoint[1];
+ }
+
+ private void shrinkWidget(KeyguardWidgetFrame frame) {
+ if (frame != null && mChallengeLayout != null &&
+ mChallengeLayout instanceof SlidingChallengeLayout) {
+ SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+ int top = scl.getMaxChallengeTop();
+ frame.shrinkWidget(getChallengeTopRelativeToFrame(frame, top));
+ }
}
/**
@@ -114,20 +130,18 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
@Override
public void onScrollStateChanged(int scrollState) {
+ if (mPagedView == null || mChallengeLayout == null) return;
+ boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+
if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
- if (mPagedView == null) return;
+ KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider);
+ if (frame == null) return;
- boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
- int curPage = mPagedView.getCurrentPage();
- KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(curPage);
-
- if (frame != null) {
- if (!challengeOverlapping) {
- frame.resetSize();
- } else {
- sizeWidgetFrameToChallengeTop(frame);
- }
+ if (!challengeOverlapping) {
+ frame.resetSize();
}
+ frame.onChallengeActive(mChallengeLayout.isChallengeShowing());
+ frame.hideFrame(this);
if (challengeOverlapping) {
mPagedView.setOnlyAllowEdgeSwipes(true);
@@ -140,14 +154,49 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
} else {
mKeyguardSecurityContainer.onPause();
}
- } else {
+ mPageListeningToSlider = -1;
+ } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
+ // Whether dragging or settling, if the last state was idle, we use this signal
+ // to update the current page who will receive events from the sliding challenge.
+ // We resize the frame as appropriate.
+ mPageListeningToSlider = mPagedView.getNextPage();
+ KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider);
+ if (frame == null) return;
+
+ frame.showFrame(this);
+
+ // As soon as the security begins sliding, the widget becomes small (if it wasn't
+ // small to begin with).
+ if (!frame.isSmall()) {
+ // We need to fetch the final page, in case the pages are in motion.
+ mPageListeningToSlider = mPagedView.getNextPage();
+ System.out.println("Shrink widget from scroll state changed!");
+ shrinkWidget(frame);
+ }
// View is on the move. Pause the security view until it completes.
mKeyguardSecurityContainer.onPause();
+
+ frame.onChallengeActive(true);
+ }
+ mLastScrollState = scrollState;
+ }
+
+ @Override
+ public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
+ mChallengeTop = challengeTop;
+ KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider);
+ if (frame != null) {
+ frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop));
}
}
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
@@ -159,10 +208,4 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
}
-
- @Override
- public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
- mChallengeTop = challengeTop;
- }
-
}
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..57b9f7870e76 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
@@ -16,6 +16,9 @@
package com.android.internal.policy.impl.keyguard;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.content.res.Resources;
@@ -49,12 +52,20 @@ public class KeyguardWidgetFrame extends FrameLayout {
private final Rect mForegroundRect = new Rect();
private int mForegroundAlpha = 0;
private CheckLongPressHelper mLongPressHelper;
+ private Animator mFrameFade;
+ private boolean mIsSmall = false;
private float mBackgroundAlpha;
+ private float mContentAlpha;
private float mBackgroundAlphaMultiplier = 1.0f;
private Drawable mBackgroundDrawable;
private Rect mBackgroundRect = new Rect();
+ // Multiple callers may try and adjust the alpha of the frame. When a caller shows
+ // the outlines, we give that caller control, and nobody else can fade them out.
+ // This prevents animation conflicts.
+ private Object mBgAlphaController;
+
public KeyguardWidgetFrame(Context context) {
this(context, null, 0);
}
@@ -74,12 +85,17 @@ 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);
}
@Override
+ protected void onDetachedFromWindow() {
+ cancelLongPress();
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Watch for longpress events at this level to make sure
// users can always pick up this widget
@@ -133,6 +149,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 +197,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 +218,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 +234,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);
@@ -223,11 +253,28 @@ public class KeyguardWidgetFrame extends FrameLayout {
}
/**
+ * Set the top location of the challenge.
+ *
+ * @param top The top of the challenge, in _local_ coordinates, or -1 to indicate the challenge
+ * is down.
+ */
+ private void setChallengeTop(int top, boolean updateWidgetSize) {
+ // The widget starts below the padding, and extends to the top of the challengs.
+ int widgetHeight = top - getPaddingTop();
+ int frameHeight = top + getPaddingBottom();
+ setFrameHeight(frameHeight);
+ if (updateWidgetSize) {
+ setWidgetHeight(widgetHeight);
+ }
+ }
+
+ /**
* Depending on whether the security is up, the widget size needs to change
*
* @param height The height of the widget, -1 for full height
*/
- public void setWidgetHeight(int height) {
+ private void setWidgetHeight(int height) {
+ System.out.println("Set widget height: " + this + " : " + height);
boolean needLayout = false;
View widget = getContent();
if (widget != null) {
@@ -242,22 +289,56 @@ public class KeyguardWidgetFrame extends FrameLayout {
}
}
- /**
- * Set the top location of the challenge.
- *
- * @param top The top of the challenge, in _local_ coordinates, or -1 to indicate the challenge
- * is down.
- */
- public void setChallengeTop(int top) {
- // The widget starts below the padding, and extends to the top of the challengs.
- int widgetHeight = top - getPaddingTop();
- setWidgetHeight(widgetHeight);
+ public boolean isSmall() {
+ return mIsSmall;
+ }
+
+ public void adjustFrame(int challengeTop) {
+ setChallengeTop(challengeTop, false);
+ }
+
+ public void shrinkWidget(int challengeTop) {
+ mIsSmall = true;
+ setChallengeTop(challengeTop, true);
}
public void resetSize() {
+ mIsSmall = false;
+ setFrameHeight(getMeasuredHeight());
setWidgetHeight(LayoutParams.MATCH_PARENT);
}
+ public void setFrameHeight(int height) {
+ height = Math.min(height, getMeasuredHeight());
+ mBackgroundRect.set(0, 0, getMeasuredWidth(), height);
+ invalidate();
+ }
+
+ public void hideFrame(Object caller) {
+ fadeFrame(caller, false, 0f, 150);
+ }
+
+ public void showFrame(Object caller) {
+ fadeFrame(caller, true, 1f, 150);
+ }
+
+ public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) {
+ if (takeControl) {
+ mBgAlphaController = caller;
+ }
+
+ if (mBgAlphaController != caller) return;
+
+ if (mFrameFade != null) {
+ mFrameFade.cancel();
+ mFrameFade = null;
+ }
+ PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", alpha);
+ mFrameFade = ObjectAnimator.ofPropertyValuesHolder(this, bgAlpha);
+ mFrameFade.setDuration(duration);
+ mFrameFade.start();
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@@ -270,6 +351,7 @@ public class KeyguardWidgetFrame extends FrameLayout {
mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
mGradientColor, 0, Shader.TileMode.CLAMP);
mBackgroundRect.set(0, 0, w, h);
+ invalidate();
}
void setOverScrollAmount(float r, boolean left) {
@@ -284,4 +366,13 @@ public class KeyguardWidgetFrame extends FrameLayout {
public void onActive(boolean isActive) {
// hook for subclasses
}
+
+ public boolean onUserInteraction(int action) {
+ // hook for subclasses
+ return false;
+ }
+
+ public void onChallengeActive(boolean challengeActive) {
+ // hook for subclasses
+ }
}
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..a9bb7bb75608 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) {
@@ -130,6 +131,15 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
}
}
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage());
+ if (currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev.getAction())) {
+ return true;
+ }
+ return super.onTouchEvent(ev);
+ }
+
public void showPagingFeedback() {
// Nothing yet.
}
@@ -154,7 +164,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 +262,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 +270,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 +335,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 +357,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 +378,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
}
}
}
+
@Override
void boundByReorderablePages(boolean isReordering, int[] range) {
if (isReordering) {
@@ -418,7 +412,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
@Override
protected void onStartReordering() {
super.onStartReordering();
- setChildrenOutlineMultiplier(1.0f);
showOutlinesAndSidePages();
}
@@ -429,43 +422,63 @@ 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;
+ ArrayList<Animator> anims = new ArrayList<Animator>();
+
+ int duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
+ CHILDREN_OUTLINE_FADE_OUT_DURATION;
+
+ 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;
+ }
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+ alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha);
+ ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha);
+ anims.add(a);
+
+ float finalOutlineAlpha = show ? getAlphaForPage(mScreenCenter, i) : 0f;
+ child.fadeFrame(this, show, finalOutlineAlpha, 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/MultiPaneChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
index 3ccc7ea55ef8..a207f5d1048d 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
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/SecurityMessageDisplay.java b/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
index b57d8c13af96..ec6472faeea7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
@@ -22,4 +22,6 @@ public interface SecurityMessageDisplay {
public void setMessage(int resId, boolean important);
public void setMessage(int resId, boolean important, Object... formatArgs);
+
+ public void setTimeout(int timeout_ms);
}
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..3cd097fbbee6 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;
@@ -352,7 +374,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mScrollState = state;
animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
- animateFrame(state != SCROLL_STATE_IDLE, false);
+ animateFrame(false , false);
if (mScrollListener != null) {
mScrollListener.onScrollStateChanged(state);
}
@@ -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
@@ -802,6 +845,14 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
}
+ public int getMaxChallengeTop() {
+ if (mChallengeView == null) return 0;
+
+ final int layoutBottom = getLayoutBottom();
+ final int challengeHeight = mChallengeView.getHeight();
+ return layoutBottom - challengeHeight;
+ }
+
/**
* Move the bottom edge of mChallengeView to a new position and notify the listener
* if it represents a change in position. Changes made through this method will