summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/17.txt34
-rw-r--r--api/current.txt34
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java1
-rw-r--r--core/java/android/text/format/DateFormat.java97
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/widget/DigitalClock.java31
-rw-r--r--core/java/android/widget/TextClock.java482
-rw-r--r--core/java/com/android/internal/policy/IFaceLockCallback.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java13
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock_focused.pngbin0 -> 2377 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock_normal.pngbin0 -> 2688 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock_pressed.pngbin0 -> 1760 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock_focused.pngbin0 -> 1567 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock_normal.pngbin0 -> 1899 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock_pressed.pngbin0 -> 1347 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock_focused.pngbin0 -> 3277 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock_normal.pngbin0 -> 3517 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock_pressed.pngbin0 -> 2173 bytes
-rw-r--r--core/res/res/drawable/keyguard_expand_challenge_handle.xml21
-rw-r--r--core/res/res/layout-port/keyguard_host_view.xml14
-rw-r--r--core/res/res/layout-sw600dp-port/keyguard_host_view.xml9
-rw-r--r--core/res/res/layout/keyguard_add_widget.xml4
-rw-r--r--core/res/res/layout/keyguard_emergency_carrier_area.xml3
-rw-r--r--core/res/res/layout/keyguard_face_unlock_view.xml3
-rw-r--r--core/res/res/layout/keyguard_glow_pad_view.xml2
-rw-r--r--core/res/res/layout/keyguard_message_area.xml3
-rw-r--r--core/res/res/layout/keyguard_password_view.xml1
-rw-r--r--core/res/res/layout/keyguard_pattern_view.xml6
-rw-r--r--core/res/res/layout/keyguard_pin_view.xml1
-rw-r--r--core/res/res/layout/keyguard_selector_view.xml3
-rw-r--r--core/res/res/layout/keyguard_status_view.xml5
-rwxr-xr-xcore/res/res/values/attrs.xml26
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--core/res/res/values/symbols.xml18
-rw-r--r--core/tests/ConnectivityManagerTest/AndroidManifest.xml1
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java47
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java6
-rw-r--r--location/java/android/location/Geofence.java4
-rw-r--r--location/java/android/location/LocationManager.java8
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java13
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java34
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java35
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java4
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java18
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java47
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/PagedView.java25
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java203
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java34
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java13
52 files changed, 995 insertions, 322 deletions
diff --git a/api/17.txt b/api/17.txt
index 45a3cc1..bdc7b19 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -491,6 +491,8 @@ package android {
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int format = 16843013; // 0x1010105
+ field public static final int format12Hour = 16843722; // 0x10103ca
+ field public static final int format24Hour = 16843723; // 0x10103cb
field public static final int fragment = 16843491; // 0x10102e3
field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
@@ -1074,6 +1076,7 @@ package android {
field public static final int thumbTextPadding = 16843634; // 0x1010372
field public static final int thumbnail = 16843429; // 0x10102a5
field public static final int tileMode = 16843265; // 0x1010201
+ field public static final int timeZone = 16843724; // 0x10103cc
field public static final int tint = 16843041; // 0x1010121
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
@@ -22296,14 +22299,14 @@ package android.text.format {
public class DateFormat {
ctor public DateFormat();
- method public static final java.lang.CharSequence format(java.lang.CharSequence, long);
- method public static final java.lang.CharSequence format(java.lang.CharSequence, java.util.Date);
- method public static final java.lang.CharSequence format(java.lang.CharSequence, java.util.Calendar);
- method public static final java.text.DateFormat getDateFormat(android.content.Context);
- method public static final char[] getDateFormatOrder(android.content.Context);
- method public static final java.text.DateFormat getLongDateFormat(android.content.Context);
- method public static final java.text.DateFormat getMediumDateFormat(android.content.Context);
- method public static final java.text.DateFormat getTimeFormat(android.content.Context);
+ method public static java.lang.CharSequence format(java.lang.CharSequence, long);
+ method public static java.lang.CharSequence format(java.lang.CharSequence, java.util.Date);
+ method public static java.lang.CharSequence format(java.lang.CharSequence, java.util.Calendar);
+ method public static java.text.DateFormat getDateFormat(android.content.Context);
+ method public static char[] getDateFormatOrder(android.content.Context);
+ method public static java.text.DateFormat getLongDateFormat(android.content.Context);
+ method public static java.text.DateFormat getMediumDateFormat(android.content.Context);
+ method public static java.text.DateFormat getTimeFormat(android.content.Context);
method public static boolean is24HourFormat(android.content.Context);
field public static final char AM_PM = 97; // 0x0061 'a'
field public static final char CAPITAL_AM_PM = 65; // 0x0041 'A'
@@ -29514,6 +29517,21 @@ package android.widget {
field public int span;
}
+ public class TextClock extends android.widget.TextView {
+ ctor public TextClock(android.content.Context);
+ ctor public TextClock(android.content.Context, android.util.AttributeSet);
+ ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
+ method public java.lang.CharSequence getFormat12Hour();
+ method public java.lang.CharSequence getFormat24Hour();
+ method public java.lang.String getTimeZone();
+ method public boolean is24HourModeEnabled();
+ method public void setFormat12Hour(java.lang.CharSequence);
+ method public void setFormat24Hour(java.lang.CharSequence);
+ method public void setTimeZone(java.lang.String);
+ field public static final java.lang.CharSequence DEFAULT_FORMAT_12_HOUR;
+ field public static final java.lang.CharSequence DEFAULT_FORMAT_24_HOUR;
+ }
+
public class TextSwitcher extends android.widget.ViewSwitcher {
ctor public TextSwitcher(android.content.Context);
ctor public TextSwitcher(android.content.Context, android.util.AttributeSet);
diff --git a/api/current.txt b/api/current.txt
index 45a3cc1..bdc7b19 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -491,6 +491,8 @@ package android {
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int format = 16843013; // 0x1010105
+ field public static final int format12Hour = 16843722; // 0x10103ca
+ field public static final int format24Hour = 16843723; // 0x10103cb
field public static final int fragment = 16843491; // 0x10102e3
field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
@@ -1074,6 +1076,7 @@ package android {
field public static final int thumbTextPadding = 16843634; // 0x1010372
field public static final int thumbnail = 16843429; // 0x10102a5
field public static final int tileMode = 16843265; // 0x1010201
+ field public static final int timeZone = 16843724; // 0x10103cc
field public static final int tint = 16843041; // 0x1010121
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
@@ -22296,14 +22299,14 @@ package android.text.format {
public class DateFormat {
ctor public DateFormat();
- method public static final java.lang.CharSequence format(java.lang.CharSequence, long);
- method public static final java.lang.CharSequence format(java.lang.CharSequence, java.util.Date);
- method public static final java.lang.CharSequence format(java.lang.CharSequence, java.util.Calendar);
- method public static final java.text.DateFormat getDateFormat(android.content.Context);
- method public static final char[] getDateFormatOrder(android.content.Context);
- method public static final java.text.DateFormat getLongDateFormat(android.content.Context);
- method public static final java.text.DateFormat getMediumDateFormat(android.content.Context);
- method public static final java.text.DateFormat getTimeFormat(android.content.Context);
+ method public static java.lang.CharSequence format(java.lang.CharSequence, long);
+ method public static java.lang.CharSequence format(java.lang.CharSequence, java.util.Date);
+ method public static java.lang.CharSequence format(java.lang.CharSequence, java.util.Calendar);
+ method public static java.text.DateFormat getDateFormat(android.content.Context);
+ method public static char[] getDateFormatOrder(android.content.Context);
+ method public static java.text.DateFormat getLongDateFormat(android.content.Context);
+ method public static java.text.DateFormat getMediumDateFormat(android.content.Context);
+ method public static java.text.DateFormat getTimeFormat(android.content.Context);
method public static boolean is24HourFormat(android.content.Context);
field public static final char AM_PM = 97; // 0x0061 'a'
field public static final char CAPITAL_AM_PM = 65; // 0x0041 'A'
@@ -29514,6 +29517,21 @@ package android.widget {
field public int span;
}
+ public class TextClock extends android.widget.TextView {
+ ctor public TextClock(android.content.Context);
+ ctor public TextClock(android.content.Context, android.util.AttributeSet);
+ ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
+ method public java.lang.CharSequence getFormat12Hour();
+ method public java.lang.CharSequence getFormat24Hour();
+ method public java.lang.String getTimeZone();
+ method public boolean is24HourModeEnabled();
+ method public void setFormat12Hour(java.lang.CharSequence);
+ method public void setFormat24Hour(java.lang.CharSequence);
+ method public void setTimeZone(java.lang.String);
+ field public static final java.lang.CharSequence DEFAULT_FORMAT_12_HOUR;
+ field public static final java.lang.CharSequence DEFAULT_FORMAT_24_HOUR;
+ }
+
public class TextSwitcher extends android.widget.ViewSwitcher {
ctor public TextSwitcher(android.content.Context);
ctor public TextSwitcher(android.content.Context, android.util.AttributeSet);
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index fcecd04..d56556f 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -144,6 +144,7 @@ public class AppWidgetHostView extends FrameLayout {
// We add padding to the AppWidgetHostView if necessary
Rect padding = getDefaultPaddingForWidget(mContext, info.provider, null);
setPadding(padding.left, padding.top, padding.right, padding.bottom);
+ setContentDescription(info.label);
}
}
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index c36273e..3c984b5 100644
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -249,12 +249,13 @@ public class DateFormat {
synchronized (sLocaleLock) {
sIs24HourLocale = locale;
- sIs24Hour = !value.equals("12");
+ sIs24Hour = value.equals("24");
}
+
+ return sIs24Hour;
}
- boolean b24 = !(value == null || value.equals("12"));
- return b24;
+ return value.equals("24");
}
/**
@@ -263,7 +264,7 @@ public class DateFormat {
* @param context the application context
* @return the {@link java.text.DateFormat} object that properly formats the time.
*/
- public static final java.text.DateFormat getTimeFormat(Context context) {
+ public static java.text.DateFormat getTimeFormat(Context context) {
boolean b24 = is24HourFormat(context);
int res;
@@ -283,7 +284,7 @@ public class DateFormat {
* @param context the application context
* @return the {@link java.text.DateFormat} object that properly formats the date.
*/
- public static final java.text.DateFormat getDateFormat(Context context) {
+ public static java.text.DateFormat getDateFormat(Context context) {
String value = Settings.System.getString(context.getContentResolver(),
Settings.System.DATE_FORMAT);
@@ -353,7 +354,7 @@ public class DateFormat {
* @param context the application context
* @return the {@link java.text.DateFormat} object that formats the date in long form.
*/
- public static final java.text.DateFormat getLongDateFormat(Context context) {
+ public static java.text.DateFormat getLongDateFormat(Context context) {
return java.text.DateFormat.getDateInstance(java.text.DateFormat.LONG);
}
@@ -363,7 +364,7 @@ public class DateFormat {
* @param context the application context
* @return the {@link java.text.DateFormat} object that formats the date in long form.
*/
- public static final java.text.DateFormat getMediumDateFormat(Context context) {
+ public static java.text.DateFormat getMediumDateFormat(Context context) {
return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM);
}
@@ -376,7 +377,7 @@ public class DateFormat {
* not just the day, month, and year, and not necessarily in the same
* order returned here.
*/
- public static final char[] getDateFormatOrder(Context context) {
+ public static char[] getDateFormatOrder(Context context) {
char[] order = new char[] {DATE, MONTH, YEAR};
String value = getDateFormatString(context);
int index = 0;
@@ -420,7 +421,7 @@ public class DateFormat {
* @param inTimeInMillis in milliseconds since Jan 1, 1970 GMT
* @return a {@link CharSequence} containing the requested text
*/
- public static final CharSequence format(CharSequence inFormat, long inTimeInMillis) {
+ public static CharSequence format(CharSequence inFormat, long inTimeInMillis) {
return format(inFormat, new Date(inTimeInMillis));
}
@@ -431,7 +432,7 @@ public class DateFormat {
* @param inDate the date to format
* @return a {@link CharSequence} containing the requested text
*/
- public static final CharSequence format(CharSequence inFormat, Date inDate) {
+ public static CharSequence format(CharSequence inFormat, Date inDate) {
Calendar c = new GregorianCalendar();
c.setTime(inDate);
@@ -440,13 +441,75 @@ public class DateFormat {
}
/**
+ * Indicates whether the specified format string contains seconds.
+ *
+ * Always returns false if the input format is null.
+ *
+ * @param inFormat the format string, as described in {@link android.text.format.DateFormat}
+ *
+ * @return true if the format string contains {@link #SECONDS}, false otherwise
+ *
+ * @hide
+ */
+ public static boolean hasSeconds(CharSequence inFormat) {
+ if (inFormat == null) return false;
+
+ final int length = inFormat.length();
+
+ int c;
+ int count;
+
+ for (int i = 0; i < length; i += count) {
+ count = 1;
+ c = inFormat.charAt(i);
+
+ if (c == QUOTE) {
+ count = skipQuotedText(inFormat, i, length);
+ } else if (c == SECONDS) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static int skipQuotedText(CharSequence s, int i, int len) {
+ if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
+ return 2;
+ }
+
+ int count = 1;
+ // skip leading quote
+ i++;
+
+ while (i < len) {
+ char c = s.charAt(i);
+
+ if (c == QUOTE) {
+ count++;
+ // QUOTEQUOTE -> QUOTE
+ if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
+ i++;
+ } else {
+ break;
+ }
+ } else {
+ i++;
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ /**
* Given a format string and a {@link java.util.Calendar} object, returns a CharSequence
* containing the requested date.
* @param inFormat the format string, as described in {@link android.text.format.DateFormat}
* @param inDate the date to format
* @return a {@link CharSequence} containing the requested text
*/
- public static final CharSequence format(CharSequence inFormat, Calendar inDate) {
+ public static CharSequence format(CharSequence inFormat, Calendar inDate) {
SpannableStringBuilder s = new SpannableStringBuilder(inFormat);
int c;
int count;
@@ -545,7 +608,7 @@ public class DateFormat {
return s.toString();
}
- private static final String getMonthString(Calendar inDate, int count, int kind) {
+ private static String getMonthString(Calendar inDate, int count, int kind) {
boolean standalone = (kind == STANDALONE_MONTH);
int month = inDate.get(Calendar.MONTH);
@@ -563,7 +626,7 @@ public class DateFormat {
}
}
- private static final String getTimeZoneString(Calendar inDate, int count) {
+ private static String getTimeZoneString(Calendar inDate, int count) {
TimeZone tz = inDate.getTimeZone();
if (count < 2) { // FIXME: shouldn't this be <= 2 ?
@@ -576,7 +639,7 @@ public class DateFormat {
}
}
- private static final String formatZoneOffset(int offset, int count) {
+ private static String formatZoneOffset(int offset, int count) {
offset /= 1000; // milliseconds to seconds
StringBuilder tb = new StringBuilder();
@@ -595,13 +658,13 @@ public class DateFormat {
return tb.toString();
}
- private static final String getYearString(Calendar inDate, int count) {
+ private static String getYearString(Calendar inDate, int count) {
int year = inDate.get(Calendar.YEAR);
return (count <= 2) ? zeroPad(year % 100, 2)
: String.format(Locale.getDefault(), "%d", year);
}
- private static final int appendQuotedText(SpannableStringBuilder s, int i, int len) {
+ private static int appendQuotedText(SpannableStringBuilder s, int i, int len) {
if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
s.delete(i, i + 1);
return 1;
@@ -638,7 +701,7 @@ public class DateFormat {
return count;
}
- private static final String zeroPad(int inValue, int inMinDigits) {
+ private static String zeroPad(int inValue, int inMinDigits) {
return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue);
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 9d0d4f0..d5e1ed3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17697,7 +17697,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
boolean mScalingRequired;
/**
- * If set, ViewAncestor doesn't use its lame animation for when the window resizes.
+ * If set, ViewRootImpl doesn't use its lame animation for when the window resizes.
*/
boolean mTurnOffWindowResizeAnim;
diff --git a/core/java/android/widget/DigitalClock.java b/core/java/android/widget/DigitalClock.java
index 3e9107f..c6b6dd6 100644
--- a/core/java/android/widget/DigitalClock.java
+++ b/core/java/android/widget/DigitalClock.java
@@ -17,7 +17,6 @@
package android.widget;
import android.content.Context;
-import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.SystemClock;
@@ -32,14 +31,12 @@ import java.util.Calendar;
/**
* Like AnalogClock, but digital. Shows seconds.
*
- * FIXME: implement separate views for hours/minutes/seconds, so
- * proportional fonts don't shake rendering
- *
- * @deprecated It is recommended you use a {@link TextView} and {@link DateFormat}
- * to implement the same behavior.
+ * @deprecated It is recommended you use {@link TextClock} instead.
*/
@Deprecated
public class DigitalClock extends TextView {
+ // FIXME: implement separate views for hours/minutes/seconds, so
+ // proportional fonts don't shake rendering
Calendar mCalendar;
private final static String m12 = "h:mm:ss aa";
@@ -86,16 +83,16 @@ public class DigitalClock extends TextView {
* requests a tick on the next hard-second boundary
*/
mTicker = new Runnable() {
- public void run() {
- if (mTickerStopped) return;
- mCalendar.setTimeInMillis(System.currentTimeMillis());
- setText(DateFormat.format(mFormat, mCalendar));
- invalidate();
- long now = SystemClock.uptimeMillis();
- long next = now + (1000 - now % 1000);
- mHandler.postAtTime(mTicker, next);
- }
- };
+ public void run() {
+ if (mTickerStopped) return;
+ mCalendar.setTimeInMillis(System.currentTimeMillis());
+ setText(DateFormat.format(mFormat, mCalendar));
+ invalidate();
+ long now = SystemClock.uptimeMillis();
+ long next = now + (1000 - now % 1000);
+ mHandler.postAtTime(mTicker, next);
+ }
+ };
mTicker.run();
}
@@ -134,12 +131,14 @@ public class DigitalClock extends TextView {
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
+ //noinspection deprecation
event.setClassName(DigitalClock.class.getName());
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
+ //noinspection deprecation
info.setClassName(DigitalClock.class.getName());
}
}
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
new file mode 100644
index 0000000..4c46658
--- /dev/null
+++ b/core/java/android/widget/TextClock.java
@@ -0,0 +1,482 @@
+/*
+ * 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 android.widget;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.TypedArray;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+
+import com.android.internal.R;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import static android.view.ViewDebug.ExportedProperty;
+import static android.widget.RemoteViews.*;
+
+/**
+ * <p><code>TextClock</code> can display the current date and/or time as
+ * a formatted string.</p>
+ *
+ * <p>This view honors the 24-hour format system setting. As such, it is
+ * possible and recommended to provide two different formatting patterns:
+ * one to display the date/time in 24-hour mode and one to display the
+ * date/time in 12-hour mode.</p>
+ *
+ * <p>It is possible to determine whether the system is currently in
+ * 24-hour mode by calling {@link #is24HourModeEnabled()}.</p>
+ *
+ * <p>The rules used by this widget to decide how to format the date and
+ * time are the following:</p>
+ * <ul>
+ * <li>In 24-hour mode:
+ * <ul>
+ * <li>Use the value returned by {@link #getFormat24Hour()} when non-null</li>
+ * <li>Otherwise, use the value returned by {@link #getFormat12Hour()} when non-null</li>
+ * <li>Otherwise, use {@link #DEFAULT_FORMAT_24_HOUR}</li>
+ * </ul>
+ * </li>
+ * <li>In 12-hour mode:
+ * <ul>
+ * <li>Use the value returned by {@link #getFormat12Hour()} when non-null</li>
+ * <li>Otherwise, use the value returned by {@link #getFormat24Hour()} when non-null</li>
+ * <li>Otherwise, use {@link #DEFAULT_FORMAT_12_HOUR}</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * <p>The {@link CharSequence} instances used as formatting patterns when calling either
+ * {@link #setFormat24Hour(CharSequence)} or {@link #setFormat12Hour(CharSequence)} can
+ * contain styling information. To do so, use a {@link android.text.Spanned} object.</p>
+ *
+ * @attr ref android.R.styleable#TextClock_format12Hour
+ * @attr ref android.R.styleable#TextClock_format24Hour
+ * @attr ref android.R.styleable#TextClock_timeZone
+ */
+@RemoteView
+public class TextClock extends TextView {
+ /**
+ * The default formatting pattern in 12-hour mode. This pattenr is used
+ * if {@link #setFormat12Hour(CharSequence)} is called with a null pattern
+ * or if no pattern was specified when creating an instance of this class.
+ *
+ * This default pattern shows only the time, hours and minutes, and an am/pm
+ * indicator.
+ *
+ * @see #setFormat12Hour(CharSequence)
+ * @see #getFormat12Hour()
+ */
+ public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm aa";
+
+ /**
+ * The default formatting pattern in 24-hour mode. This pattenr is used
+ * if {@link #setFormat24Hour(CharSequence)} is called with a null pattern
+ * or if no pattern was specified when creating an instance of this class.
+ *
+ * This default pattern shows only the time, hours and minutes.
+ *
+ * @see #setFormat24Hour(CharSequence)
+ * @see #getFormat24Hour()
+ */
+ public static final CharSequence DEFAULT_FORMAT_24_HOUR = "k:mm";
+
+ private CharSequence mFormat12 = DEFAULT_FORMAT_12_HOUR;
+ private CharSequence mFormat24 = DEFAULT_FORMAT_24_HOUR;
+
+ @ExportedProperty
+ private CharSequence mFormat;
+ @ExportedProperty
+ private boolean mHasSeconds;
+
+ private boolean mAttached;
+
+ private Calendar mTime;
+ private String mTimeZone;
+
+ private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ chooseFormat();
+ onTimeChanged();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ chooseFormat();
+ onTimeChanged();
+ }
+ };
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mTimeZone == null) {
+ if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
+ final String timeZone = intent.getStringExtra("time-zone");
+ createTime(timeZone);
+ }
+ onTimeChanged();
+ }
+ }
+ };
+
+ private final Runnable mTicker = new Runnable() {
+ public void run() {
+ onTimeChanged();
+
+ long now = SystemClock.uptimeMillis();
+ long next = now + (1000 - now % 1000);
+
+ getHandler().postAtTime(mTicker, next);
+ }
+ };
+
+ /**
+ * Creates a new clock using the default patterns
+ * {@link #DEFAULT_FORMAT_24_HOUR} and {@link #DEFAULT_FORMAT_12_HOUR}
+ * respectively for the 24-hour and 12-hour modes.
+ *
+ * @param context The Context the view is running in, through which it can
+ * access the current theme, resources, etc.
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public TextClock(Context context) {
+ super(context);
+ init();
+ }
+
+ /**
+ * Creates a new clock inflated from XML. This object's properties are
+ * intialized from the attributes specified in XML.
+ *
+ * This constructor uses a default style of 0, so the only attribute values
+ * applied are those in the Context's Theme and the given AttributeSet.
+ *
+ * @param context The Context the view is running in, through which it can
+ * access the current theme, resources, etc.
+ * @param attrs The attributes of the XML tag that is inflating the view
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public TextClock(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ /**
+ * Creates a new clock inflated from XML. This object's properties are
+ * intialized from the attributes specified in XML.
+ *
+ * @param context The Context the view is running in, through which it can
+ * access the current theme, resources, etc.
+ * @param attrs The attributes of the XML tag that is inflating the view
+ * @param defStyle The default style to apply to this view. If 0, no style
+ * will be applied (beyond what is included in the theme). This may
+ * either be an attribute resource, whose value will be retrieved
+ * from the current theme, or an explicit style resource
+ */
+ public TextClock(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextClock, defStyle, 0);
+ try {
+ CharSequence format;
+
+ format = a.getText(R.styleable.TextClock_format12Hour);
+ mFormat12 = format == null ? DEFAULT_FORMAT_12_HOUR : format;
+
+ format = a.getText(R.styleable.TextClock_format24Hour);
+ mFormat24 = format == null ? DEFAULT_FORMAT_24_HOUR : format;
+
+ mTimeZone = a.getString(R.styleable.TextClock_timeZone);
+ } finally {
+ a.recycle();
+ }
+
+ init();
+ }
+
+ private void init() {
+ createTime(mTimeZone);
+ // Wait until onAttachedToWindow() to handle the ticker
+ chooseFormat(false);
+ }
+
+ private void createTime(String timeZone) {
+ if (timeZone != null) {
+ mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone));
+ } else {
+ mTime = Calendar.getInstance();
+ }
+ }
+
+ /**
+ * Returns the formatting pattern used to display the date and/or time
+ * in 12-hour mode. The formatting pattern syntax is described in
+ * {@link DateFormat}.
+ *
+ * @return A {@link CharSequence} or null.
+ *
+ * @see #setFormat12Hour(CharSequence)
+ * @see #is24HourModeEnabled()
+ */
+ @ExportedProperty
+ public CharSequence getFormat12Hour() {
+ return mFormat12;
+ }
+
+ /**
+ * Specifies the formatting pattern used to display the date and/or time
+ * in 12-hour mode. The formatting pattern syntax is described in
+ * {@link DateFormat}.
+ *
+ * If this pattern is set to null, {@link #getFormat24Hour()} will be used
+ * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns
+ * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
+ * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
+ *
+ * @param format A date/time formatting pattern as described in {@link DateFormat}
+ *
+ * @see #getFormat12Hour()
+ * @see #is24HourModeEnabled()
+ * @see #DEFAULT_FORMAT_12_HOUR
+ * @see DateFormat
+ *
+ * @attr ref android.R.styleable#TextClock_format12Hour
+ */
+ public void setFormat12Hour(CharSequence format) {
+ mFormat12 = format;
+
+ chooseFormat();
+ onTimeChanged();
+ }
+
+ /**
+ * Returns the formatting pattern used to display the date and/or time
+ * in 24-hour mode. The formatting pattern syntax is described in
+ * {@link DateFormat}.
+ *
+ * @return A {@link CharSequence} or null.
+ *
+ * @see #setFormat24Hour(CharSequence)
+ * @see #is24HourModeEnabled()
+ */
+ @ExportedProperty
+ public CharSequence getFormat24Hour() {
+ return mFormat24;
+ }
+
+ /**
+ * Specifies the formatting pattern used to display the date and/or time
+ * in 24-hour mode. The formatting pattern syntax is described in
+ * {@link DateFormat}.
+ *
+ * If this pattern is set to null, {@link #getFormat12Hour()} will be used
+ * even in 24-hour mode. If both 24-hour and 12-hour formatting patterns
+ * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
+ * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
+ *
+ * @param format A date/time formatting pattern as described in {@link DateFormat}
+ *
+ * @see #getFormat24Hour()
+ * @see #is24HourModeEnabled()
+ * @see #DEFAULT_FORMAT_24_HOUR
+ * @see DateFormat
+ *
+ * @attr ref android.R.styleable#TextClock_format24Hour
+ */
+ public void setFormat24Hour(CharSequence format) {
+ mFormat24 = format;
+
+ chooseFormat();
+ onTimeChanged();
+ }
+
+ /**
+ * Indicates whether the system is currently using the 24-hour mode.
+ *
+ * When the system is in 24-hour mode, this view will use the pattern
+ * returned by {@link #getFormat24Hour()}. In 12-hour mode, the pattern
+ * returned by {@link #getFormat12Hour()} is used instead.
+ *
+ * If either one of the formats is null, the other format is used. If
+ * both formats are null, the default values {@link #DEFAULT_FORMAT_12_HOUR}
+ * and {@link #DEFAULT_FORMAT_24_HOUR} are used instead.
+ *
+ * @return true if time should be displayed in 24-hour format, false if it
+ * should be displayed in 12-hour format.
+ *
+ * @see #setFormat12Hour(CharSequence)
+ * @see #getFormat12Hour()
+ * @see #setFormat24Hour(CharSequence)
+ * @see #getFormat24Hour()
+ */
+ public boolean is24HourModeEnabled() {
+ return DateFormat.is24HourFormat(getContext());
+ }
+
+ /**
+ * Indicates which time zone is currently used by this view.
+ *
+ * @return The ID of the current time zone or null if the default time zone,
+ * as set by the user, must be used
+ *
+ * @see TimeZone
+ * @see java.util.TimeZone#getAvailableIDs()
+ * @see #setTimeZone(String)
+ */
+ public String getTimeZone() {
+ return mTimeZone;
+ }
+
+ /**
+ * Sets the specified time zone to use in this clock. When the time zone
+ * is set through this method, system time zone changes (when the user
+ * sets the time zone in settings for instance) will be ignored.
+ *
+ * @param timeZone The desired time zone's ID as specified in {@link TimeZone}
+ * or null to user the time zone specified by the user
+ * (system time zone)
+ *
+ * @see #getTimeZone()
+ * @see java.util.TimeZone#getAvailableIDs()
+ * @see TimeZone#getTimeZone(String)
+ *
+ * @attr ref android.R.styleable#TextClock_timeZone
+ */
+ public void setTimeZone(String timeZone) {
+ mTimeZone = timeZone;
+
+ createTime(timeZone);
+ onTimeChanged();
+ }
+
+ /**
+ * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()}
+ * depending on whether the user has selected 24-hour format.
+ *
+ * Calling this method does not schedule or unschedule the time ticker.
+ */
+ private void chooseFormat() {
+ chooseFormat(true);
+ }
+
+ /**
+ * Selects either one of {@link #getFormat12Hour()} or {@link #getFormat24Hour()}
+ * depending on whether the user has selected 24-hour format.
+ *
+ * @param handleTicker true if calling this method should schedule/unschedule the
+ * time ticker, false otherwise
+ */
+ private void chooseFormat(boolean handleTicker) {
+ final boolean format24Requested = is24HourModeEnabled();
+
+ if (format24Requested) {
+ mFormat = abc(mFormat24, mFormat12, DEFAULT_FORMAT_24_HOUR);
+ } else {
+ mFormat = abc(mFormat12, mFormat24, DEFAULT_FORMAT_12_HOUR);
+ }
+
+ boolean hadSeconds = mHasSeconds;
+ mHasSeconds = DateFormat.hasSeconds(mFormat);
+
+ if (handleTicker) {
+ if (hadSeconds != mHasSeconds) {
+ if (hadSeconds) getHandler().removeCallbacks(mTicker);
+ else mTicker.run();
+ }
+ }
+ }
+
+ /**
+ * Returns a if not null, else return b if not null, else return c.
+ */
+ private static CharSequence abc(CharSequence a, CharSequence b, CharSequence c) {
+ return a == null ? (b == null ? c : b) : a;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (!mAttached) {
+ mAttached = true;
+
+ registerReceiver();
+ registerObserver();
+
+ createTime(mTimeZone);
+
+ if (mHasSeconds) {
+ mTicker.run();
+ } else {
+ onTimeChanged();
+ }
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ if (mAttached) {
+ unregisterReceiver();
+ unregisterObserver();
+
+ getHandler().removeCallbacks(mTicker);
+
+ mAttached = false;
+ }
+ }
+
+ private void registerReceiver() {
+ final IntentFilter filter = new IntentFilter();
+
+ filter.addAction(Intent.ACTION_TIME_TICK);
+ filter.addAction(Intent.ACTION_TIME_CHANGED);
+ filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+
+ getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
+ }
+
+ private void registerObserver() {
+ final ContentResolver resolver = getContext().getContentResolver();
+ resolver.registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver);
+ }
+
+ private void unregisterReceiver() {
+ getContext().unregisterReceiver(mIntentReceiver);
+ }
+
+ private void unregisterObserver() {
+ final ContentResolver resolver = getContext().getContentResolver();
+ resolver.unregisterContentObserver(mFormatChangeObserver);
+ }
+
+ private void onTimeChanged() {
+ mTime.setTimeInMillis(System.currentTimeMillis());
+ setText(DateFormat.format(mFormat, mTime));
+ }
+}
diff --git a/core/java/com/android/internal/policy/IFaceLockCallback.aidl b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
index eb902fd..280e4d5 100644
--- a/core/java/com/android/internal/policy/IFaceLockCallback.aidl
+++ b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
@@ -22,6 +22,5 @@ oneway interface IFaceLockCallback {
void unlock();
void cancel();
void reportFailedAttempt();
- void exposeFallback();
void pokeWakelock(int millis);
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 6c5ed7e..7a76ab0 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -18,7 +18,6 @@ package com.android.internal.widget;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -33,11 +32,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.R;
@@ -657,9 +654,11 @@ public class LockPatternView extends View {
handleActionMove(event);
return true;
case MotionEvent.ACTION_CANCEL:
- resetPattern();
- mPatternInProgress = false;
- notifyPatternCleared();
+ if (mPatternInProgress) {
+ mPatternInProgress = false;
+ resetPattern();
+ notifyPatternCleared();
+ }
if (PROFILE_DRAWING) {
if (mDrawingProfilingStarted) {
Debug.stopMethodTracing();
@@ -826,7 +825,7 @@ public class LockPatternView extends View {
mPatternInProgress = true;
mPatternDisplayMode = DisplayMode.Correct;
notifyPatternStarted();
- } else {
+ } else if (mPatternInProgress) {
mPatternInProgress = false;
notifyPatternCleared();
}
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_focused.png b/core/res/res/drawable-hdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..9a82799
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_normal.png b/core/res/res/drawable-hdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..d608707
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..7ca995d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_focused.png b/core/res/res/drawable-mdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..c3608f9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_normal.png b/core/res/res/drawable-mdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..7957c79
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..41715f5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..db22016
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..17ebb5f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..186b6ff
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable/keyguard_expand_challenge_handle.xml b/core/res/res/drawable/keyguard_expand_challenge_handle.xml
new file mode 100644
index 0000000..3e0780b
--- /dev/null
+++ b/core/res/res/drawable/keyguard_expand_challenge_handle.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:drawable="@drawable/kg_security_lock_focused" />
+ <item android:state_pressed="true" android:drawable="@drawable/kg_security_lock_pressed" />
+ <item android:drawable="@drawable/kg_security_lock_normal" />
+</selector>
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index a3c8105..bba1b04 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -31,8 +31,7 @@
<com.android.internal.policy.impl.keyguard.SlidingChallengeLayout
android:id="@+id/sliding_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- androidprv:dragIcon="@drawable/kg_security_lock">
+ android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
@@ -68,6 +67,17 @@
android:gravity="center">
</com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
+
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ androidprv:layout_childType="expandChallengeHandle"
+ android:focusable="true"
+ android:background="@null"
+ android:src="@drawable/keyguard_expand_challenge_handle"
+ android:scaleType="center"
+ android:contentDescription="@string/keyguard_accessibility_expand_lock_area" />
+
</com.android.internal.policy.impl.keyguard.SlidingChallengeLayout>
</com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
index 3953c95..5d858ae 100644
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -38,7 +38,7 @@
android:id="@+id/app_widget_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- androidprv:layout_centerWithinArea="0.55"
+ androidprv:layout_centerWithinArea="0.5"
androidprv:layout_childType="widget"
androidprv:layout_maxWidth="480dp"
androidprv:layout_maxHeight="480dp" />
@@ -52,8 +52,11 @@
<com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer
android:id="@+id/keyguard_security_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ androidprv:layout_centerWithinArea="0.5"
androidprv:layout_childType="challenge"
android:layout_gravity="center_horizontal|bottom">
<com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
diff --git a/core/res/res/layout/keyguard_add_widget.xml b/core/res/res/layout/keyguard_add_widget.xml
index fd5e565..db166ac 100644
--- a/core/res/res/layout/keyguard_add_widget.xml
+++ b/core/res/res/layout/keyguard_add_widget.xml
@@ -27,6 +27,7 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:contentDescription="@string/keyguard_accessibility_widget_empty_slot"
>
<ImageView
android:id="@+id/keyguard_add_widget_view"
@@ -35,6 +36,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="24dp"
- android:src="@drawable/kg_add_widget" />
+ android:src="@drawable/kg_add_widget"
+ android:contentDescription="@string/keyguard_accessibility_add_widget"/>
</FrameLayout>
</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 655b77d..52adc04 100644
--- a/core/res/res/layout/keyguard_emergency_carrier_area.xml
+++ b/core/res/res/layout/keyguard_emergency_carrier_area.xml
@@ -25,7 +25,8 @@
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center_horizontal"
- android:layout_alignParentBottom="true">
+ android:layout_alignParentBottom="true"
+ android:clickable="true">
<com.android.internal.policy.impl.keyguard.CarrierText
android:layout_width="wrap_content"
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
index 976d0c6..39e8f31 100644
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ b/core/res/res/layout/keyguard_face_unlock_view.xml
@@ -23,7 +23,8 @@
android:id="@+id/keyguard_face_unlock_view"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:contentDescription="@string/keyguard_accessibility_face_unlock">
<include layout="@layout/keyguard_message_area"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml
index a416a77..ef1c133 100644
--- a/core/res/res/layout/keyguard_glow_pad_view.xml
+++ b/core/res/res/layout/keyguard_glow_pad_view.xml
@@ -27,7 +27,7 @@
android:layout_gravity="center"
android:orientation="horizontal"
android:gravity="@integer/kg_selector_gravity"
- android:focusable="true"
+ android:contentDescription="@string/keyguard_accessibility_slide_area"
prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
diff --git a/core/res/res/layout/keyguard_message_area.xml b/core/res/res/layout/keyguard_message_area.xml
index 9f11a2c..37463cf 100644
--- a/core/res/res/layout/keyguard_message_area.xml
+++ b/core/res/res/layout/keyguard_message_area.xml
@@ -28,5 +28,6 @@
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearance"
android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary" />
+ android:textColor="?android:attr/textColorSecondary"
+ android:clickable="true" />
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
index b6faf5b..a054d07 100644
--- a/core/res/res/layout/keyguard_password_view.xml
+++ b/core/res/res/layout/keyguard_password_view.xml
@@ -23,6 +23,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
+ android:contentDescription="@string/keyguard_accessibility_password_unlock"
>
<Space
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index 0f6256a..5ebc000 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -26,7 +26,8 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:gravity="center_horizontal">
+ android:gravity="center_horizontal"
+ android:contentDescription="@string/keyguard_accessibility_pattern_unlock">
<FrameLayout
android:layout_width="match_parent"
@@ -55,7 +56,8 @@
android:layout_marginBottom="4dip"
android:layout_marginStart="8dip"
android:layout_gravity="center_horizontal"
- android:gravity="center" />
+ android:gravity="center"
+ android:contentDescription="@string/keyguard_accessibility_pattern_area" />
<include layout="@layout/keyguard_emergency_carrier_area"
android:id="@+id/keyguard_selector_fade_container"
diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml
index 2529196..29e69f3 100644
--- a/core/res/res/layout/keyguard_pin_view.xml
+++ b/core/res/res/layout/keyguard_pin_view.xml
@@ -24,6 +24,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
+ android:contentDescription="@string/keyguard_accessibility_pin_unlock"
>
<include layout="@layout/keyguard_message_area"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
index 7403408..941e78e 100644
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ b/core/res/res/layout/keyguard_selector_view.xml
@@ -26,7 +26,8 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:contentDescription="@string/keyguard_accessibility_slide_unlock">
<FrameLayout
android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml
index 9532a88..7467928 100644
--- a/core/res/res/layout/keyguard_status_view.xml
+++ b/core/res/res/layout/keyguard_status_view.xml
@@ -31,12 +31,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|top"
- android:contentDescription="@*android:string/keyguard_accessibility_status">
+ android:contentDescription="@android:string/keyguard_accessibility_status">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:focusable="true">
<com.android.internal.policy.impl.keyguard.ClockView
android:id="@+id/clock_view"
android:layout_width="wrap_content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 507dfdf..6f307a7 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3046,6 +3046,24 @@
<!-- Present the text in ALL CAPS. This may use a small-caps form when available. -->
<attr name="textAllCaps" format="boolean" />
</declare-styleable>
+ <declare-styleable name="TextClock">
+ <!-- Specifies the formatting pattern used to show the time and/or date
+ in 12-hour mode. Please refer to {@link android.text.format.DateFormat}
+ for a complete description of accepted formatting patterns.
+ The default pattern is "h:mm aa". -->
+ <attr name="format12Hour" format="string"/>
+ <!-- Specifies the formatting pattern used to show the time and/or date
+ in 24-hour mode. Please refer to {@link android.text.format.DateFormat}
+ for a complete description of accepted formatting patterns.
+ The default pattern is "k:mm". -->
+ <attr name="format24Hour" format="string"/>
+ <!-- Specifies the time zone to use. When this attribute is specified, the
+ TextClock will ignore the time zone of the system. To use the user's
+ time zone, do not specify this attribute. The default value is the
+ user's time zone. Please refer to {@link java.util.TimeZone} for more
+ information about time zone ids. -->
+ <attr name="timeZone" format="string"/>
+ </declare-styleable>
<declare-styleable name="TextSwitcher">
</declare-styleable>
<declare-styleable name="TextView">
@@ -5794,13 +5812,11 @@
<enum name="scrim" value="4" />
<!-- The home for widgets. All widgets will be descendents of this. -->
<enum name="widgets" value="5" />
+ <!-- This is a handle that is used for expanding the
+ security challenge container when it is collapsed. -->
+ <enum name="expandChallengeHandle" value="6" />
</attr>
- <declare-styleable name="SlidingChallengeLayout">
- <attr name="dragHandle" format="reference" />
- <attr name="dragIcon" format="reference" />
- </declare-styleable>
-
<declare-styleable name="SlidingChallengeLayout_Layout">
<attr name="layout_childType" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 62ef8b6..a5dae7e 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2019,6 +2019,9 @@
<public type="attr" name="permissionFlags" id="0x010103c7" />
<public type="attr" name="checkedTextViewStyle" id="0x010103c8" />
<public type="attr" name="showOnLockScreen" id="0x010103c9" />
+ <public type="attr" name="format12Hour" id="0x010103ca" />
+ <public type="attr" name="format24Hour" id="0x010103cb" />
+ <public type="attr" name="timeZone" id="0x010103cc" />
<public type="style" name="Widget.Holo.CheckedTextView" id="0x010301d9" />
<public type="style" name="Widget.Holo.Light.CheckedTextView" id="0x010301da" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5af60c8..05b3068 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -555,10 +555,26 @@
<java-symbol type="string" name="keyboardview_keycode_enter" />
<java-symbol type="string" name="keyboardview_keycode_mode_change" />
<java-symbol type="string" name="keyboardview_keycode_shift" />
+ <java-symbol type="string" name="keyguard_accessibility_add_widget" />
+ <java-symbol type="string" name="keyguard_accessibility_camera" />
+ <java-symbol type="string" name="keyguard_accessibility_expand_lock_area" />
+ <java-symbol type="string" name="keyguard_accessibility_face_unlock" />
<java-symbol type="string" name="keygaurd_accessibility_media_controls" />
+ <java-symbol type="string" name="keyguard_accessibility_pattern_area" />
+ <java-symbol type="string" name="keyguard_accessibility_pattern_unlock" />
+ <java-symbol type="string" name="keyguard_accessibility_password_unlock" />
+ <java-symbol type="string" name="keyguard_accessibility_pin_unlock" />
+ <java-symbol type="string" name="keyguard_accessibility_slide_area" />
+ <java-symbol type="string" name="keyguard_accessibility_slide_unlock" />
<java-symbol type="string" name="keyguard_accessibility_status" />
<java-symbol type="string" name="keyguard_accessibility_user_selector" />
- <java-symbol type="string" name="keyguard_accessibility_widget_changed" />
+ <java-symbol type="string" name="keyguard_accessibility_widget" />
+ <java-symbol type="string" name="keyguard_accessibility_widget_deleted" />
+ <java-symbol type="string" name="keyguard_accessibility_widget_empty_slot" />
+ <java-symbol type="string" name="keyguard_accessibility_widget_reorder_start" />
+ <java-symbol type="string" name="keyguard_accessibility_widget_reorder_end" />
+ <java-symbol type="string" name="keyguard_accessibility_unlock_area_collapsed" />
+ <java-symbol type="string" name="keyguard_accessibility_unlock_area_expanded" />
<java-symbol type="string" name="kilobyteShort" />
<java-symbol type="string" name="last_month" />
<java-symbol type="string" name="launchBrowserDefault" />
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 1bbc7df..5db7ffc 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -74,4 +74,5 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.INJECT_EVENTS" />
</manifest>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 561e33e..245f537 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -65,6 +65,8 @@ public class ConnectivityManagerTestActivity extends Activity {
public static final long LONG_TIMEOUT = 50 * 1000;
// 2 minutes timer between wifi stop and start
public static final long WIFI_STOP_START_INTERVAL = 2 * 60 * 1000;
+ // Set ping test timer to be 3 minutes
+ public static final long PING_TIMER = 3 * 60 *1000;
public static final int SUCCESS = 0; // for Wifi tethering state change
public static final int FAILURE = 1;
public static final int INIT = -1;
@@ -517,37 +519,36 @@ public class ConnectivityManagerTestActivity extends Activity {
* @return true if the ping test is successful, false otherwise.
*/
public boolean pingTest(String[] pingServerList) {
- boolean result = false;
String[] hostList = {"www.google.com", "www.yahoo.com",
"www.bing.com", "www.facebook.com", "www.ask.com"};
if (pingServerList != null) {
hostList = pingServerList;
}
- try {
- // assume the chance that all servers are down is very small
- for (int i = 0; i < hostList.length; i++ ) {
- String host = hostList[i];
- log("Start ping test, ping " + host);
- Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
- int status = p.waitFor();
- if (status == 0) {
- // if any of the ping test is successful, return true
- result = true;
- break;
- } else {
- result = false;
- log("ping " + host + " failed.");
+
+ long startTime = System.currentTimeMillis();
+ while ((System.currentTimeMillis() - startTime) < PING_TIMER) {
+ try {
+ // assume the chance that all servers are down is very small
+ for (int i = 0; i < hostList.length; i++ ) {
+ String host = hostList[i];
+ log("Start ping test, ping " + host);
+ Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
+ int status = p.waitFor();
+ if (status == 0) {
+ // if any of the ping test is successful, return true
+ return true;
+ }
}
+ } catch (UnknownHostException e) {
+ log("Ping test Fail: Unknown Host");
+ } catch (IOException e) {
+ log("Ping test Fail: IOException");
+ } catch (InterruptedException e) {
+ log("Ping test Fail: InterruptedException");
}
- } catch (UnknownHostException e) {
- log("Ping test Fail: Unknown Host");
- } catch (IOException e) {
- log("Ping test Fail: IOException");
- } catch (InterruptedException e) {
- log("Ping test Fail: InterruptedException");
}
- log("return");
- return result;
+ // ping test timeout
+ return false;
}
/**
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 79d928c..7bfb594 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -28,6 +28,7 @@ import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.PowerManager;
import android.provider.Settings;
+import android.view.KeyEvent;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
@@ -289,6 +290,11 @@ public class WifiStressTest
// Turn screen on again
mAct.turnScreenOn();
+ // Wait for 2 seconds for the lock screen
+ sleep(2 * 1000, "wait 2 seconds for lock screen");
+ // Disable lock screen by inject menu key event
+ mRunner.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
+
// Measure the time for Wi-Fi to get connected
long startTime = System.currentTimeMillis();
assertTrue("Wait for Wi-Fi enable timeout after wake up",
diff --git a/location/java/android/location/Geofence.java b/location/java/android/location/Geofence.java
index b3e4a88..791d3d0 100644
--- a/location/java/android/location/Geofence.java
+++ b/location/java/android/location/Geofence.java
@@ -22,7 +22,7 @@ import android.os.Parcelable;
/**
* Represents a geographical boundary, also known as a geofence.
*
- * <p>Currently only circular geofences are supported.
+ * <p>Currently only circular geofences are supported and they do not support altitude changes.
*/
public final class Geofence implements Parcelable {
/** @hide */
@@ -34,7 +34,7 @@ public final class Geofence implements Parcelable {
private final float mRadius;
/**
- * Create a horizontal, circular geofence.
+ * Create a circular geofence (on a flat, horizontal plane).
*
* @param latitude latitude in degrees
* @param longitude longitude in degrees
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 59a5624..653e8d1 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -811,6 +811,10 @@ public class LocationManager {
/**
* Register for fused location updates using a LocationRequest and callback.
*
+ * <p>Upon a location update, the system delivers the new {@link Location} to the
+ * provided {@link LocationListener}, by calling its {@link
+ * LocationListener#onLocationChanged} method.</p>
+ *
* <p>The system will automatically select and enable the best providers
* to compute a location for your application. It may use only passive
* locations, or just a single location source, or it may fuse together
@@ -869,6 +873,10 @@ public class LocationManager {
/**
* Register for fused location updates using a LocationRequest and a pending intent.
*
+ * <p>Upon a location update, the system delivers the new {@link Location} with your provided
+ * {@link PendingIntent}, as the value for {@link LocationManager#KEY_LOCATION_CHANGED}
+ * in the intent's extras.</p>
+ *
* <p> To unregister for Location updates, use: {@link #removeUpdates(PendingIntent)}.
*
* <p> See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)}
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 3dd0a8f..2728bfc 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
@@ -34,6 +34,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
+import com.android.internal.R;
import com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
@@ -63,7 +64,10 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli
private final Runnable mLaunchCameraRunnable = new Runnable() {
@Override
public void run() {
+ if (!mTransitioning)
+ return;
mLaunchCameraStart = SystemClock.uptimeMillis();
+ if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart);
mActivityLauncher.launchCamera();
}};
@@ -107,6 +111,8 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
preview.setScaleType(ScaleType.FIT_CENTER);
+ preview.setContentDescription(preview.getContext().getString(
+ R.string.keyguard_accessibility_camera));
CameraWidgetFrame cameraWidgetFrame = new CameraWidgetFrame(context, callbacks, launcher);
cameraWidgetFrame.addView(preview);
cameraWidgetFrame.mWidgetView = widgetView;
@@ -271,7 +277,7 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli
@Override
protected void onFocusLost() {
- Log.d(TAG, "onFocusLost");
+ if (DEBUG) Log.d(TAG, "onFocusLost");
cancelTransitionToCamera();
super.onFocusLost();
}
@@ -290,6 +296,11 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli
}
}
+ public void onScreenTurnedOff() {
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOff");
+ reset();
+ }
+
private void rescheduleTransitionToCamera() {
if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis());
mHandler.removeCallbacks(mTransitionToCameraRunnable);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
index faf0ca0..9858c77 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
@@ -57,8 +57,7 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
private final int MSG_UNLOCK = 2;
private final int MSG_CANCEL = 3;
private final int MSG_REPORT_FAILED_ATTEMPT = 4;
- private final int MSG_EXPOSE_FALLBACK = 5;
- private final int MSG_POKE_WAKELOCK = 6;
+ private final int MSG_POKE_WAKELOCK = 5;
// TODO: This was added for the purpose of adhering to what the biometric interface expects
// the isRunning() function to return. However, it is probably not necessary to have both
@@ -220,9 +219,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
case MSG_REPORT_FAILED_ATTEMPT:
handleReportFailedAttempt();
break;
- case MSG_EXPOSE_FALLBACK:
- handleExposeFallback();
- break;
case MSG_POKE_WAKELOCK:
handlePokeWakelock(msg.arg1);
break;
@@ -310,6 +306,10 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
*/
void handleCancel() {
if (DEBUG) Log.d(TAG, "handleCancel()");
+ // We are going to the backup method, so we don't want to see Face Unlock again until the
+ // next time the user visits keyguard.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+
mKeyguardScreenCallback.showBackupSecurity();
stop();
mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT);
@@ -320,17 +320,11 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
*/
void handleReportFailedAttempt() {
if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
- mKeyguardScreenCallback.reportFailedUnlockAttempt();
- }
+ // We are going to the backup method, so we don't want to see Face Unlock again until the
+ // next time the user visits keyguard.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
- /**
- * Hides the Face Unlock view to expose the backup lock. Called when the Face Unlock service UI
- * is started, indicating there is no need to continue displaying the underlying view because
- * the service UI is now covering the backup lock.
- */
- void handleExposeFallback() {
- if (DEBUG) Log.d(TAG, "handleExposeFallback()");
- // No longer required because face unlock doesn't cover backup unlock.
+ mKeyguardScreenCallback.reportFailedUnlockAttempt();
}
/**
@@ -443,16 +437,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
}
/**
- * Called when the Face Unlock service starts displaying the UI, indicating that the backup
- * unlock can be exposed because the Face Unlock service is now covering the backup with its
- * UI.
- */
- public void exposeFallback() {
- if (DEBUG) Log.d(TAG, "exposeFallback()");
- mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
- }
-
- /**
* Called when Face Unlock wants to keep the screen alive and active for a specific amount
* of time.
*/
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
index 4c50069..8283af2 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
@@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.Log;
@@ -118,8 +119,7 @@ public abstract class KeyguardActivityLauncher {
public void launchActivity(final Intent intent, boolean showsWhileLocked, boolean animate) {
final Context context = getContext();
final Bundle animation = animate ? null :
- ActivityOptions.makeCustomAnimation(context, com.android.internal.R.anim.fade_in,
- com.android.internal.R.anim.fade_out).toBundle();
+ ActivityOptions.makeCustomAnimation(context, 0, 0).toBundle();
LockPatternUtils lockPatternUtils = getLockPatternUtils();
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
@@ -133,6 +133,8 @@ public abstract class KeyguardActivityLauncher {
Log.w(TAG, "can't dismiss keyguard on launch");
}
try {
+ if (DEBUG) Log.d(TAG, String.format("Starting activity for intent %s at %s",
+ intent, SystemClock.uptimeMillis()));
context.startActivityAsUser(intent, animation,
new UserHandle(UserHandle.USER_CURRENT));
} catch (ActivityNotFoundException e) {
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 a884568..c0095de 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -93,6 +93,7 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
@Override
public void onResume() {
if (DEBUG) Log.d(TAG, "onResume()");
+ mIsShowing = KeyguardUpdateMonitor.getInstance(mContext).isKeyguardVisible();
maybeStartBiometricUnlock();
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
}
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 3b2ded2..ca3d0a2 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -39,6 +39,7 @@ import android.os.Bundle;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
@@ -49,6 +50,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.widget.RemoteViews.OnClickHandler;
@@ -115,8 +117,7 @@ public class KeyguardHostView extends KeyguardViewBase {
// The following enables the MENU key to work for testing automation
mEnableMenuKey = shouldEnableMenuKey();
- setFocusable(true);
- setFocusableInTouchMode(true);
+ mViewStateManager = new KeyguardViewStateManager();
}
@Override
@@ -150,8 +151,6 @@ public class KeyguardHostView extends KeyguardViewBase {
@Override
protected void onFinishInflate() {
- mViewStateManager = new KeyguardViewStateManager();
-
// Grab instances of and make any necessary changes to the main layouts. Create
// view state manager and wire up necessary listeners / callbacks.
mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
@@ -423,8 +422,8 @@ public class KeyguardHostView extends KeyguardViewBase {
void showPrimarySecurityScreen(boolean turningOff) {
SecurityMode securityMode = mSecurityModel.getSecurityMode();
if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
- if (!turningOff && KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()
- && !KeyguardUpdateMonitor.getInstance(mContext).getIsFirstBoot()) {
+ if (!turningOff &&
+ KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
// If we're not turning off, then allow biometric alternate.
// We'll reload it when the device comes back on.
securityMode = mSecurityModel.getAlternateFor(securityMode);
@@ -500,7 +499,6 @@ public class KeyguardHostView extends KeyguardViewBase {
// If the alternate unlock was suppressed, it can now be safely
// enabled because the user has left keyguard.
KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
- KeyguardUpdateMonitor.getInstance(mContext).setIsFirstBoot(false);
// If there's a pending runnable because the user interacted with a widget
// and we're leaving keyguard, then run it.
@@ -711,10 +709,18 @@ public class KeyguardHostView extends KeyguardViewBase {
@Override
public void onScreenTurnedOff() {
- if (DEBUG) Log.d(TAG, "screen off, instance " + Integer.toHexString(hashCode()));
+ if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
+ Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+ // Once the screen turns off, we no longer consider this to be first boot and we want the
+ // biometric unlock to start next time keyguard is shown.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
saveStickyWidgetIndex();
showPrimarySecurityScreen(true);
getSecurityView(mCurrentSecuritySelection).onPause();
+ CameraWidgetFrame cameraPage = findCameraPage();
+ if (cameraPage != null) {
+ cameraPage.onScreenTurnedOff();
+ }
}
@Override
@@ -824,7 +830,7 @@ public class KeyguardHostView extends KeyguardViewBase {
public void onLaunchingCamera() {
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
- slider.showHandle(false);
+ slider.setHandleAlpha(0);
}
}
@@ -835,7 +841,7 @@ public class KeyguardHostView extends KeyguardViewBase {
}
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
- slider.showHandle(true);
+ slider.setHandleAlpha(1);
slider.showChallenge(true);
}
}
@@ -1140,6 +1146,15 @@ public class KeyguardHostView extends KeyguardViewBase {
mAppWidgetContainer.setCurrentPage(pageToShow);
}
+ private CameraWidgetFrame findCameraPage() {
+ for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
+ if (isCameraPage(i)) {
+ return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
+ }
+ }
+ return null;
+ }
+
private boolean isCameraPage(int pageIndex) {
View v = mAppWidgetContainer.getChildAt(pageIndex);
return v != null && v instanceof CameraWidgetFrame;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
index b35450c..64bbdd3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
@@ -72,7 +72,9 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
@Override
public void onResume() {
super.onResume();
- mImm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
+ // XXX this is still not right because onResume is being called every time the page changes
+ mPasswordEntry.requestFocus();
+ mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
}
@Override
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 316825a..5fb8cf0 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -92,6 +92,7 @@ public class KeyguardUpdateMonitor {
private CharSequence mTelephonySpn;
private int mRingMode;
private int mPhoneState;
+ private boolean mKeyguardIsVisible;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -200,7 +201,6 @@ public class KeyguardUpdateMonitor {
}
}
};
- private boolean mIsFirstBoot;
/**
* When we receive a
@@ -567,14 +567,20 @@ public class KeyguardUpdateMonitor {
*/
private void handleKeyguardVisibilityChanged(int showing) {
if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
+ boolean isShowing = (showing == 1);
+ mKeyguardIsVisible = isShowing;
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onKeyguardVisibilityChanged(showing == 1);
+ cb.onKeyguardVisibilityChanged(isShowing);
}
}
}
+ public boolean isKeyguardVisible() {
+ return mKeyguardIsVisible;
+ }
+
private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
final boolean nowPluggedIn = current.isPluggedIn();
final boolean wasPluggedIn = old.isPluggedIn();
@@ -778,12 +784,4 @@ public class KeyguardUpdateMonitor {
|| simState == IccCardConstants.State.PUK_REQUIRED
|| simState == IccCardConstants.State.PERM_DISABLED);
}
-
- public void setIsFirstBoot(boolean b) {
- mIsFirstBoot = b;
- }
-
- public boolean getIsFirstBoot() {
- return mIsFirstBoot;
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 53cbb39..fe4ac5b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -522,7 +522,6 @@ public class KeyguardViewMediator {
// Disable alternate unlock right after boot until things have settled.
mUpdateMonitor.setAlternateUnlockEnabled(false);
- mUpdateMonitor.setIsFirstBoot(true);
doKeyguardLocked();
}
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 667b2d6..b023573 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -21,7 +21,6 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
-import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
@@ -32,6 +31,8 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -134,6 +135,14 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex);
if (newWidgetPage != null) {
newWidgetPage.onActive(true);
+ newWidgetPage.requestAccessibilityFocus();
+ }
+ if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ onInitializeAccessibilityEvent(event);
+ onPopulateAccessibilityEvent(event);
+ mParent.requestSendAccessibilityEvent(this, event);
}
}
if (mViewStateManager != null) {
@@ -141,6 +150,13 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
}
}
+ @Override
+ public void sendAccessibilityEvent(int eventType) {
+ if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
+ super.sendAccessibilityEvent(eventType);
+ }
+ }
+
private void userActivity() {
if (mCallbacks != null) {
mCallbacks.onUserActivityTimeoutChanged();
@@ -227,10 +243,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
// The framework adds a default padding to AppWidgetHostView. We don't need this padding
// for the Keyguard, so we override it to be 0.
widget.setPadding(0, 0, 0, 0);
- if (widget instanceof AppWidgetHostView) {
- AppWidgetHostView awhv = (AppWidgetHostView) widget;
- widget.setContentDescription(awhv.getAppWidgetInfo().label);
- }
frame.addView(widget, lp);
} else {
frame = (KeyguardWidgetFrame) widget;
@@ -245,6 +257,15 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
} else {
addView(frame, pageIndex, pageLp);
}
+
+ // Update the frame content description.
+ View content = (widget == frame) ? frame.getContent() : widget;
+ if (content != null) {
+ String contentDescription = mContext.getString(
+ com.android.internal.R.string.keyguard_accessibility_widget,
+ content.getContentDescription());
+ frame.setContentDescription(contentDescription);
+ }
}
/**
@@ -361,22 +382,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
}
@Override
- public String getCurrentPageDescription() {
- final int nextPageIndex = getNextPage();
- if (nextPageIndex >= 0 && nextPageIndex < getChildCount()) {
- KeyguardWidgetFrame frame = getWidgetPageAt(nextPageIndex);
- CharSequence title = frame.getChildAt(0).getContentDescription();
- if (title == null) {
- title = "";
- }
- return mContext.getString(
- com.android.internal.R.string.keyguard_accessibility_widget_changed,
- title, nextPageIndex + 1, getChildCount());
- }
- return super.getCurrentPageDescription();
- }
-
- @Override
protected void overScroll(float amount) {
acceleratedOverScroll(amount);
}
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 c93b11a..6eeada5 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -539,27 +539,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (mTouchState == TOUCH_STATE_REST) {
pageEndMoving();
}
-
onPostReorderingAnimationCompleted();
-
- // Notify the user when the page changes
- AccessibilityManager accessibilityManager = (AccessibilityManager)
- getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
- if (accessibilityManager.isEnabled()) {
- AccessibilityEvent ev =
- AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
- ev.getText().add(getCurrentPageDescription());
- sendAccessibilityEventUnchecked(ev);
- }
return true;
}
return false;
}
- public String getCurrentPageDescription() {
- return "";
- }
-
@Override
public void computeScroll() {
computeScrollHelper();
@@ -2013,6 +1998,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
protected void onStartReordering() {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_widget_reorder_start));
+ }
+
// Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
mTouchState = TOUCH_STATE_REORDERING;
mIsReordering = true;
@@ -2033,6 +2023,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
protected void onEndReordering() {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_widget_reorder_end));
+ }
mIsReordering = false;
}
@@ -2298,6 +2292,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
/* Accessibility */
+
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
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 2e735a0..af7dc15 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -29,12 +29,14 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
+import android.util.MathUtils;
import android.util.Property;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.widget.Scroller;
@@ -56,18 +58,15 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
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;
private Drawable mFrameDrawable;
- private Drawable mDragIconDrawable;
private boolean mEdgeCaptured;
// Initialized during measurement from child layoutparams
+ private View mExpandChallengeView;
private View mChallengeView;
private View mScrimView;
private View mWidgetsView;
@@ -113,6 +112,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
// that should remain on-screen
private int mTouchSlop;
+ private int mTouchSlopSquare;
float mHandleAlpha;
float mFrameAlpha;
@@ -184,6 +184,15 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
};
+ private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!isChallengeShowing()) {
+ showChallenge(true);
+ }
+ }
+ };
+
/**
* Listener interface that reports changes in scroll state of the challenge area.
*/
@@ -235,13 +244,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- final TypedArray a = context.obtainStyledAttributes(attrs,
- R.styleable.SlidingChallengeLayout, defStyle, 0);
- setDragDrawables(a.getDrawable(R.styleable.SlidingChallengeLayout_dragHandle),
- a.getDrawable(R.styleable.SlidingChallengeLayout_dragIcon));
-
- a.recycle();
-
mScroller = new Scroller(context, sMotionInterpolator);
final ViewConfiguration vc = ViewConfiguration.get(context);
@@ -252,6 +254,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ mTouchSlopSquare = mTouchSlop * mTouchSlop;
final float density = res.getDisplayMetrics().density;
@@ -267,25 +270,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
setWillNotDraw(false);
}
- public void setDragDrawables(Drawable handle, Drawable icon) {
- mHandleDrawable = handle;
- mDragIconDrawable = icon;
- }
-
- public void setDragIconDrawable(Drawable d) {
- mDragIconDrawable = d;
- }
-
- public void showHandle(boolean visible) {
- if (visible) {
- if (mHandleAnimation != null) {
- mHandleAnimation.cancel();
- mHandleAnimation = null;
- }
- mHandleAlpha = 1.f;
- invalidate();
- } else {
- animateHandle(false);
+ public void setHandleAlpha(float alpha) {
+ if (mExpandChallengeView != null) {
+ mExpandChallengeView.setAlpha(alpha);
}
}
@@ -469,7 +456,27 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
private void setChallengeShowing(boolean showChallenge) {
+ if (mChallengeShowing == showChallenge) {
+ return;
+ }
mChallengeShowing = showChallenge;
+ if (mChallengeShowing) {
+ mExpandChallengeView.setVisibility(View.INVISIBLE);
+ mChallengeView.setVisibility(View.VISIBLE);
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ mChallengeView.requestAccessibilityFocus();
+ mChallengeView.announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_unlock_area_expanded));
+ }
+ } else {
+ mExpandChallengeView.setVisibility(View.VISIBLE);
+ mChallengeView.setVisibility(View.INVISIBLE);
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ mExpandChallengeView.requestAccessibilityFocus();
+ mChallengeView.announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_unlock_area_collapsed));
+ }
+ }
}
/**
@@ -573,12 +580,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
for (int i = 0; i < count; i++) {
final float x = ev.getX(i);
final float y = ev.getY(i);
-
- if (!mIsBouncing &&
- (isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
- (isInChallengeView(x, y) &&
- (mScrollState == SCROLL_STATE_SETTLING || !mChallengeShowing))) &&
- mActivePointerId == INVALID_POINTER) {
+ if (!mIsBouncing && mActivePointerId == INVALID_POINTER
+ && ((isInDragHandle(x, y) && MathUtils.sq(x - mGestureStartX)
+ + MathUtils.sq(y - mGestureStartY) > mTouchSlopSquare)
+ || crossedDragHandle(x, y, mGestureStartY)
+ || (isInChallengeView(x, y) && (mScrollState == SCROLL_STATE_SETTLING
+ || !mChallengeShowing)))) {
mActivePointerId = ev.getPointerId(i);
mGestureStartX = x;
mGestureStartY = y;
@@ -634,12 +641,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
break;
}
case MotionEvent.ACTION_UP:
- if (OPEN_ON_CLICK
- && isInDragHandle(mGestureStartX, mGestureStartY)
- && Math.abs(ev.getX() - mGestureStartX) <= mTouchSlop
- && Math.abs(ev.getY() - mGestureStartY) <= mTouchSlop) {
- showChallenge(true);
- } else if (mDragging) {
+ if (mDragging) {
mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
}
@@ -749,19 +751,19 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
private boolean isInChallengeView(float x, float y) {
- if (mChallengeView == null) return false;
-
- return x >= mChallengeView.getLeft() && y >= mChallengeView.getTop() &&
- x < mChallengeView.getRight() && y < mChallengeView.getBottom();
+ return isPointInView(x, y, mChallengeView);
}
private boolean isInDragHandle(float x, float y) {
- if (mChallengeView == null) return false;
+ return isPointInView(x, y, mExpandChallengeView);
+ }
- return x >= mDragHandleEdgeSlop &&
- y >= mChallengeView.getTop() - getDragHandleSizeAbove() &&
- x < getWidth() - mDragHandleEdgeSlop &&
- y < mChallengeView.getTop() + getDragHandleSizeBelow();
+ private boolean isPointInView(float x, float y, View view) {
+ if (view == null) {
+ return false;
+ }
+ return x >= view.getLeft() && y >= view.getTop()
+ && x < view.getRight() && y < view.getBottom();
}
private boolean crossedDragHandle(float x, float y, float initialY) {
@@ -786,7 +788,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
// Find one and only one challenge view.
final View oldChallengeView = mChallengeView;
+ final View oldExpandChallengeView = mChallengeView;
mChallengeView = null;
+ mExpandChallengeView = null;
final int count = getChildCount();
// First iteration through the children finds special children and sets any associated
@@ -794,7 +798,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
if (mChallengeView != null) {
throw new IllegalStateException(
@@ -806,31 +809,42 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
// We're going to play silly games with the frame's background drawable later.
mFrameDrawable = mChallengeView.getBackground();
-
if (!mHasLayout) {
// Set up the margin correctly based on our content for the first run.
mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
}
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+ if (mExpandChallengeView != null) {
+ throw new IllegalStateException(
+ "There may only be one child with layout_childType"
+ + "=\"expandChallengeHandle\"");
+ }
+ mExpandChallengeView = child;
+ if (mExpandChallengeView != oldExpandChallengeView) {
+ mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
+ mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
+ }
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
setScrimView(child);
} else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
mWidgetsView = child;
}
-
- if (child.getVisibility() == GONE) continue;
}
// We want to measure the challenge view first, since the KeyguardWidgetPager
// needs to do things its measure pass that are dependent on the challenge view
// having been measured.
- if (mChallengeView != null) {
+ if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
measureChildWithMargins(mChallengeView, widthSpec, 0, heightSpec, 0);
}
// Measure the rest of the children
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
// Don't measure the challenge view twice!
if (child != mChallengeView) {
measureChildWithMargins(child, widthSpec, 0, heightSpec, 0);
@@ -869,6 +883,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
* (1 - mChallengeOffset));
child.setAlpha(getChallengeAlpha());
child.layout(left, bottom - childHeight, left + childWidth, bottom);
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+ child.layout(0, b - mChallengeBottomBound, width, b);
} else {
// Non-challenge views lay out from the upper left, layered.
child.layout(paddingLeft + lp.leftMargin,
@@ -886,33 +902,11 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
}
- public void computeScroll() {
- super.computeScroll();
-
- if (!mScroller.isFinished()) {
- if (mChallengeView == null) {
- // Can't scroll if the view is missing.
- Log.e(TAG, "Challenge view missing in computeScroll");
- mScroller.abortAnimation();
- return;
- }
-
- mScroller.computeScrollOffset();
- moveChallengeTo(mScroller.getCurrY());
-
- if (mScroller.isFinished()) {
- post(mEndScrollRunnable);
- }
- }
- }
-
@Override
public void draw(Canvas c) {
super.draw(c);
-
- final Paint debugPaint;
if (DEBUG) {
- debugPaint = new Paint();
+ final Paint debugPaint = new Paint();
debugPaint.setColor(0x40FF00CC);
// show the isInDragHandle() rect
c.drawRect(mDragHandleEdgeSlop,
@@ -921,46 +915,24 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mChallengeView.getTop() + getDragHandleSizeBelow(),
debugPaint);
}
+ }
- if (mChallengeView != null && mHandleAlpha > 0) {
- final int top = mChallengeView.getTop();
- final int handleHeight;
- final int challengeLeft = mChallengeView.getLeft();
- final int challengeRight = mChallengeView.getRight();
- if (mHandleDrawable != null) {
- handleHeight = mHandleDrawable.getIntrinsicHeight();
- mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight);
- mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF));
- mHandleDrawable.draw(c);
- } else {
- handleHeight = 0;
- }
+ public void computeScroll() {
+ super.computeScroll();
- if (DEBUG) {
- // now show the actual drag handle
- debugPaint.setStyle(Paint.Style.STROKE);
- debugPaint.setStrokeWidth(1);
- debugPaint.setColor(0xFF80FF00);
- c.drawRect(challengeLeft, top, challengeRight, top + handleHeight, debugPaint);
+ if (!mScroller.isFinished()) {
+ if (mChallengeView == null) {
+ // Can't scroll if the view is missing.
+ Log.e(TAG, "Challenge view missing in computeScroll");
+ mScroller.abortAnimation();
+ return;
}
- if (mDragIconDrawable != null) {
- final int closedTop = getLayoutBottom() - mDragHandleClosedBelow;
- final int iconWidth = mDragIconDrawable.getIntrinsicWidth();
- final int iconHeight = mDragIconDrawable.getIntrinsicHeight();
- final int iconLeft = (challengeLeft + challengeRight - iconWidth) / 2;
- final int iconTop = closedTop +
- (mDragHandleClosedBelow - mDragHandleClosedAbove - iconHeight) / 2;
- mDragIconDrawable.setBounds(iconLeft, iconTop, iconLeft + iconWidth,
- iconTop + iconHeight);
- mDragIconDrawable.setAlpha((int) (mHandleAlpha * 0xFF));
- mDragIconDrawable.draw(c);
-
- if (DEBUG) {
- debugPaint.setColor(0xFF00FF00);
- c.drawRect(iconLeft, iconTop, iconLeft + iconWidth,
- iconTop + iconHeight, debugPaint);
- }
+ mScroller.computeScrollOffset();
+ moveChallengeTo(mScroller.getCurrY());
+
+ if (mScroller.isFinished()) {
+ post(mEndScrollRunnable);
}
}
}
@@ -1096,6 +1068,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
public static final int CHILD_TYPE_CHALLENGE = 2;
public static final int CHILD_TYPE_SCRIM = 4;
public static final int CHILD_TYPE_WIDGETS = 5;
+ public static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;
public LayoutParams() {
this(MATCH_PARENT, WRAP_CONTENT);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java
index e4d9215..e4768e2 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java
@@ -61,7 +61,7 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
private final int MSG_UNLOCK = 4;
private final int MSG_CANCEL = 5;
private final int MSG_REPORT_FAILED_ATTEMPT = 6;
- private final int MSG_EXPOSE_FALLBACK = 7;
+ //private final int MSG_EXPOSE_FALLBACK = 7;
private final int MSG_POKE_WAKELOCK = 8;
// TODO: This was added for the purpose of adhering to what the biometric interface expects
@@ -258,9 +258,9 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
case MSG_REPORT_FAILED_ATTEMPT:
handleReportFailedAttempt();
break;
- case MSG_EXPOSE_FALLBACK:
- handleExposeFallback();
- break;
+ //case MSG_EXPOSE_FALLBACK:
+ //handleExposeFallback();
+ //break;
case MSG_POKE_WAKELOCK:
handlePokeWakelock(msg.arg1);
break;
@@ -401,14 +401,14 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
* is started, indicating there is no need to continue displaying the underlying view because
* the service UI is now covering the backup lock.
*/
- void handleExposeFallback() {
- if (DEBUG) Log.d(TAG, "handleExposeFallback()");
- if (mFaceUnlockView != null) {
- mFaceUnlockView.setVisibility(View.INVISIBLE);
- } else {
- Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()");
- }
- }
+ //void handleExposeFallback() {
+ // if (DEBUG) Log.d(TAG, "handleExposeFallback()");
+ // if (mFaceUnlockView != null) {
+ // mFaceUnlockView.setVisibility(View.INVISIBLE);
+ // } else {
+ // Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()");
+ // }
+ //}
/**
* Pokes the wakelock to keep the screen alive and active for a specific amount of time.
@@ -534,11 +534,11 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
* unlock can be exposed because the Face Unlock service is now covering the backup with its
* UI.
**/
- @Override
- public void exposeFallback() {
- if (DEBUG) Log.d(TAG, "exposeFallback()");
- mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
- }
+ //@Override
+ //public void exposeFallback() {
+ // if (DEBUG) Log.d(TAG, "exposeFallback()");
+ // mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
+ //}
/**
* Called when Face Unlock wants to keep the screen alive and active for a specific amount
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index dcf87350..18b46fb 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -584,6 +584,7 @@ class TouchExplorer implements EventStreamTransformation {
// a given distance perform a drag.
mCurrentState = STATE_DRAGGING;
mDraggingPointerId = pointerId;
+ event.setEdgeFlags(receivedTracker.getLastReceivedDownEdgeFlags());
sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits,
policyFlags);
} else {
@@ -1752,6 +1753,9 @@ class TouchExplorer implements EventStreamTransformation {
// Which pointers are down.
private int mReceivedPointersDown;
+ // The edge flags of the last received down event.
+ private int mLastReceivedDownEdgeFlags;
+
// Which down pointers are active.
private int mActivePointers;
@@ -1947,6 +1951,13 @@ class TouchExplorer implements EventStreamTransformation {
}
/**
+ * @return The edge flags of the last received down event.
+ */
+ public int getLastReceivedDownEdgeFlags() {
+ return mLastReceivedDownEdgeFlags;
+ }
+
+ /**
* @return Whether the last received pointer that went up was active.
*/
public boolean wasLastReceivedUpPointerActive() {
@@ -1995,6 +2006,8 @@ class TouchExplorer implements EventStreamTransformation {
mLastReceivedUpPointerDownX = 0;
mLastReceivedUpPointerDownX = 0;
+ mLastReceivedDownEdgeFlags = event.getEdgeFlags();
+
mReceivedPointersDown |= pointerFlag;
mReceivedPointerDownX[pointerId] = event.getX(pointerIndex);
mReceivedPointerDownY[pointerId] = event.getY(pointerIndex);