diff options
35 files changed, 312 insertions, 99 deletions
diff --git a/api/current.txt b/api/current.txt index a50970a02ed6..078ed5377034 100644 --- a/api/current.txt +++ b/api/current.txt @@ -25635,10 +25635,8 @@ package android.transition { ctor public TransitionManager(); method public static void beginDelayedTransition(android.view.ViewGroup); method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition); - method public static android.transition.Transition getDefaultTransition(); method public static void go(android.transition.Scene); method public static void go(android.transition.Scene, android.transition.Transition); - method public void setDefaultTransition(android.transition.Transition); method public void setTransition(android.transition.Scene, android.transition.Transition); method public void setTransition(android.transition.Scene, android.transition.Scene, android.transition.Transition); method public void transitionTo(android.transition.Scene); diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index 5a919fb8209e..f9c1d318a9f6 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -35,10 +35,12 @@ public final class Bundle implements Parcelable, Cloneable { public static final Bundle EMPTY; static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L' + static final Parcel EMPTY_PARCEL; static { EMPTY = new Bundle(); EMPTY.mMap = ArrayMap.EMPTY; + EMPTY_PARCEL = Parcel.obtain(); } // Invariant - exactly one of mMap / mParcelledData will be null @@ -115,9 +117,13 @@ public final class Bundle implements Parcelable, Cloneable { */ public Bundle(Bundle b) { if (b.mParcelledData != null) { - mParcelledData = Parcel.obtain(); - mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize()); - mParcelledData.setDataPosition(0); + if (b.mParcelledData == EMPTY_PARCEL) { + mParcelledData = EMPTY_PARCEL; + } else { + mParcelledData = Parcel.obtain(); + mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize()); + mParcelledData.setDataPosition(0); + } } else { mParcelledData = null; } @@ -216,6 +222,18 @@ public final class Bundle implements Parcelable, Cloneable { return; } + if (mParcelledData == EMPTY_PARCEL) { + if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + + ": empty"); + if (mMap == null) { + mMap = new ArrayMap<String, Object>(1); + } else { + mMap.erase(); + } + mParcelledData = null; + return; + } + int N = mParcelledData.readInt(); if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + ": reading " + N + " maps"); @@ -1652,11 +1670,20 @@ public final class Bundle implements Parcelable, Cloneable { final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds); try { if (mParcelledData != null) { - int length = mParcelledData.dataSize(); - parcel.writeInt(length); - parcel.writeInt(BUNDLE_MAGIC); - parcel.appendFrom(mParcelledData, 0, length); + if (mParcelledData == EMPTY_PARCEL) { + parcel.writeInt(0); + } else { + int length = mParcelledData.dataSize(); + parcel.writeInt(length); + parcel.writeInt(BUNDLE_MAGIC); + parcel.appendFrom(mParcelledData, 0, length); + } } else { + // Special case for empty bundles. + if (mMap == null || mMap.size() <= 0) { + parcel.writeInt(0); + return; + } int lengthPos = parcel.dataPosition(); parcel.writeInt(-1); // dummy, will hold length parcel.writeInt(BUNDLE_MAGIC); @@ -1690,6 +1717,13 @@ public final class Bundle implements Parcelable, Cloneable { } void readFromParcelInner(Parcel parcel, int length) { + if (length == 0) { + // Empty Bundle or end of data. + mParcelledData = EMPTY_PARCEL; + mHasFds = false; + mFdsKnown = true; + return; + } int magic = parcel.readInt(); if (magic != BUNDLE_MAGIC) { //noinspection ThrowableInstanceNeverThrown @@ -1716,8 +1750,12 @@ public final class Bundle implements Parcelable, Cloneable { @Override public synchronized String toString() { if (mParcelledData != null) { - return "Bundle[mParcelledData.dataSize=" + - mParcelledData.dataSize() + "]"; + if (mParcelledData == EMPTY_PARCEL) { + return "Bundle[EMPTY_PARCEL]"; + } else { + return "Bundle[mParcelledData.dataSize=" + + mParcelledData.dataSize() + "]"; + } } return "Bundle[" + mMap.toString() + "]"; } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 02b1998264a2..94b961793e26 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -611,11 +611,15 @@ public final class Parcel { here.fillInStackTrace(); Log.d(TAG, "Writing " + N + " ArrayMap entries", here); } + int startPos; for (int i=0; i<N; i++) { - if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + ": key=0x" - + (val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0) + " " + val.keyAt(i)); + if (DEBUG_ARRAY_MAP) startPos = dataPosition(); writeValue(val.keyAt(i)); writeValue(val.valueAt(i)); + if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + " " + + (dataPosition()-startPos) + " bytes: key=0x" + + Integer.toHexString(val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0) + + " " + val.keyAt(i)); } } @@ -2303,11 +2307,14 @@ public final class Parcel { here.fillInStackTrace(); Log.d(TAG, "Reading " + N + " ArrayMap entries", here); } + int startPos; while (N > 0) { + if (DEBUG_ARRAY_MAP) startPos = dataPosition(); Object key = readValue(loader); - if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read #" + (N-1) + ": key=0x" - + (key != null ? key.hashCode() : 0) + " " + key); Object value = readValue(loader); + if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read #" + (N-1) + " " + + (dataPosition()-startPos) + " bytes: key=0x" + + Integer.toHexString((key != null ? key.hashCode() : 0)) + " " + key); outVal.append(key, value); N--; } diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 1456387ea83d..5273c20abf9d 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -231,10 +231,11 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { final FileDescriptor fd = openInternal(file, mode); if (fd == null) return null; - final FileDescriptor[] comm = createCommSocketPair(true); + final FileDescriptor[] comm = createCommSocketPair(); final ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd, comm[0]); // Kick off thread to watch for status updates + IoUtils.setBlocking(comm[1], true); final ListenerBridge bridge = new ListenerBridge(comm[1], handler.getLooper(), listener); bridge.start(); @@ -378,7 +379,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { */ public static ParcelFileDescriptor[] createReliablePipe() throws IOException { try { - final FileDescriptor[] comm = createCommSocketPair(false); + final FileDescriptor[] comm = createCommSocketPair(); final FileDescriptor[] fds = Libcore.os.pipe(); return new ParcelFileDescriptor[] { new ParcelFileDescriptor(fds[0], comm[0]), @@ -416,7 +417,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { */ public static ParcelFileDescriptor[] createReliableSocketPair() throws IOException { try { - final FileDescriptor[] comm = createCommSocketPair(false); + final FileDescriptor[] comm = createCommSocketPair(); final FileDescriptor fd0 = new FileDescriptor(); final FileDescriptor fd1 = new FileDescriptor(); Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1); @@ -428,13 +429,13 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { } } - private static FileDescriptor[] createCommSocketPair(boolean blocking) throws IOException { + private static FileDescriptor[] createCommSocketPair() throws IOException { try { final FileDescriptor comm1 = new FileDescriptor(); final FileDescriptor comm2 = new FileDescriptor(); Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2); - IoUtils.setBlocking(comm1, blocking); - IoUtils.setBlocking(comm2, blocking); + IoUtils.setBlocking(comm1, false); + IoUtils.setBlocking(comm2, false); return new FileDescriptor[] { comm1, comm2 }; } catch (ErrnoException e) { throw e.rethrowAsIOException(); @@ -670,34 +671,35 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { } try { - try { - if (status != Status.SILENCE) { - final byte[] buf = getOrCreateStatusBuffer(); - int writePtr = 0; + if (status == Status.SILENCE) return; + + // Since we're about to close, read off any remote status. It's + // okay to remember missing here. + mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer()); - Memory.pokeInt(buf, writePtr, status, ByteOrder.BIG_ENDIAN); - writePtr += 4; + // Skip writing status when other end has already gone away. + if (mStatus != null) return; + + try { + final byte[] buf = getOrCreateStatusBuffer(); + int writePtr = 0; - if (msg != null) { - final byte[] rawMsg = msg.getBytes(); - final int len = Math.min(rawMsg.length, buf.length - writePtr); - System.arraycopy(rawMsg, 0, buf, writePtr, len); - writePtr += len; - } + Memory.pokeInt(buf, writePtr, status, ByteOrder.BIG_ENDIAN); + writePtr += 4; - Libcore.os.write(mCommFd, buf, 0, writePtr); + if (msg != null) { + final byte[] rawMsg = msg.getBytes(); + final int len = Math.min(rawMsg.length, buf.length - writePtr); + System.arraycopy(rawMsg, 0, buf, writePtr, len); + writePtr += len; } + + Libcore.os.write(mCommFd, buf, 0, writePtr); } catch (ErrnoException e) { // Reporting status is best-effort Log.w(TAG, "Failed to report status: " + e); } - if (status != Status.SILENCE) { - // Since we're about to close, read off any remote status. It's - // okay to remember missing here. - mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer()); - } - } finally { IoUtils.closeQuietly(mCommFd); mCommFd = null; diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java index 9b1494d79ae7..3bf67902e986 100644 --- a/core/java/android/transition/TransitionManager.java +++ b/core/java/android/transition/TransitionManager.java @@ -82,6 +82,8 @@ public class TransitionManager { * an {@link AutoTransition} instance. * * @param transition The default transition to be used for scene changes. + * + * @hide pending later changes */ public void setDefaultTransition(Transition transition) { sDefaultTransition = transition; @@ -93,6 +95,8 @@ public class TransitionManager { * * @return The current default transition. * @see #setDefaultTransition(Transition) + * + * @hide pending later changes */ public static Transition getDefaultTransition() { return sDefaultTransition; @@ -105,7 +109,7 @@ public class TransitionManager { * transition to run. * @param transition The transition that will play when the given scene is * entered. A value of null will result in the default behavior of - * using the {@link #getDefaultTransition() default transition} instead. + * using the default transition instead. */ public void setTransition(Scene scene, Transition transition) { mSceneTransitions.put(scene, transition); @@ -121,7 +125,7 @@ public class TransitionManager { * be run * @param transition The transition that will play when the given scene is * entered. A value of null will result in the default behavior of - * using the {@link #getDefaultTransition() default transition} instead. + * using the default transition instead. */ public void setTransition(Scene fromScene, Scene toScene, Transition transition) { ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene); @@ -139,8 +143,8 @@ public class TransitionManager { * * @param scene The scene being entered * @return The Transition to be used for the given scene change. If no - * Transition was specified for this scene change, the {@link #getDefaultTransition() - * default transition} will be used instead. + * Transition was specified for this scene change, the default transition + * will be used instead. */ private Transition getTransition(Scene scene) { Transition transition = null; diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index e82ad1ec24d4..490eab87f75c 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -97,6 +97,13 @@ the SIM card. --> <string name="needPuk">Your SIM card is PUK-locked. Type the PUK code to unlock it.</string> <string name="needPuk2">Type PUK2 to unblock SIM card.</string> + <!-- Displayed when user attempts to change SIM PIN1 without enabling PIN1. --> + <string name="enablePin">Unsuccessful, enable SIM/RUIM Lock.</string> + <!-- Displayed when a SIM PIN/PUK is entered incorrectly. --> + <plurals name="pinpuk_attempts"> + <item quantity="one">You have <xliff:g id="number">%d</xliff:g> remaining attempt before SIM is locked.</item> + <item quantity="other">You have <xliff:g id="number">%d</xliff:g> remaining attempts before SIM is locked.</item> + </plurals> <!-- Title for the dialog used to display the user's IMEI number [CHAR LIMIT=10] --> <string name="imei">IMEI</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index dc0841ab1041..a5573c98f17b 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -612,6 +612,7 @@ <java-symbol type="string" name="more_item_label" /> <java-symbol type="string" name="needPuk" /> <java-symbol type="string" name="needPuk2" /> + <java-symbol type="string" name="enablePin" /> <java-symbol type="string" name="new_app_action" /> <java-symbol type="string" name="new_app_description" /> <java-symbol type="string" name="noApplications" /> @@ -965,6 +966,7 @@ <java-symbol type="plurals" name="num_minutes_ago" /> <java-symbol type="plurals" name="num_seconds_ago" /> <java-symbol type="plurals" name="restr_pin_countdown" /> + <java-symbol type="plurals" name="pinpuk_attempts" /> <java-symbol type="array" name="carrier_properties" /> <java-symbol type="array" name="config_data_usage_network_types" /> diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf Binary files differindex 072b842925fd..c5b9c676ce6b 100644 --- a/data/fonts/Roboto-Bold.ttf +++ b/data/fonts/Roboto-Bold.ttf diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf Binary files differindex 74919ff649ea..032021453de4 100644 --- a/data/fonts/Roboto-BoldItalic.ttf +++ b/data/fonts/Roboto-BoldItalic.ttf diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf Binary files differindex 4642d6f688c0..38ba5705ea1e 100644 --- a/data/fonts/Roboto-Italic.ttf +++ b/data/fonts/Roboto-Italic.ttf diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf Binary files differindex 13bf13af00e3..271606b01360 100644 --- a/data/fonts/Roboto-Light.ttf +++ b/data/fonts/Roboto-Light.ttf diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf Binary files differindex 130672a9071f..17ef355a8de4 100644 --- a/data/fonts/Roboto-LightItalic.ttf +++ b/data/fonts/Roboto-LightItalic.ttf diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf Binary files differindex 0ba95c98c467..746906381b01 100644 --- a/data/fonts/Roboto-Regular.ttf +++ b/data/fonts/Roboto-Regular.ttf diff --git a/data/fonts/Roboto-Thin.ttf b/data/fonts/Roboto-Thin.ttf Binary files differindex 309c22d358a8..74efe4df214d 100644 --- a/data/fonts/Roboto-Thin.ttf +++ b/data/fonts/Roboto-Thin.ttf diff --git a/data/fonts/Roboto-ThinItalic.ttf b/data/fonts/Roboto-ThinItalic.ttf Binary files differindex 0b53ba4d3825..f08ea5153b20 100644 --- a/data/fonts/Roboto-ThinItalic.ttf +++ b/data/fonts/Roboto-ThinItalic.ttf diff --git a/data/fonts/RobotoCondensed-Bold.ttf b/data/fonts/RobotoCondensed-Bold.ttf Binary files differindex f0fd409ef3ad..1252d00e5165 100644 --- a/data/fonts/RobotoCondensed-Bold.ttf +++ b/data/fonts/RobotoCondensed-Bold.ttf diff --git a/data/fonts/RobotoCondensed-BoldItalic.ttf b/data/fonts/RobotoCondensed-BoldItalic.ttf Binary files differindex e67b02b083be..e914a07019f1 100644 --- a/data/fonts/RobotoCondensed-BoldItalic.ttf +++ b/data/fonts/RobotoCondensed-BoldItalic.ttf diff --git a/data/fonts/RobotoCondensed-Italic.ttf b/data/fonts/RobotoCondensed-Italic.ttf Binary files differindex a08414bd57f3..8a570cf89958 100644 --- a/data/fonts/RobotoCondensed-Italic.ttf +++ b/data/fonts/RobotoCondensed-Italic.ttf diff --git a/data/fonts/RobotoCondensed-Regular.ttf b/data/fonts/RobotoCondensed-Regular.ttf Binary files differindex 713fd30c4ae7..a16b9cb90970 100644 --- a/data/fonts/RobotoCondensed-Regular.ttf +++ b/data/fonts/RobotoCondensed-Regular.ttf diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png Binary files differdeleted file mode 100644 index 6402d3d428b0..000000000000 --- a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png +++ /dev/null diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png Binary files differdeleted file mode 100644 index 83be04650a0b..000000000000 --- a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png +++ /dev/null diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png Binary files differdeleted file mode 100644 index a7e063a5c8c1..000000000000 --- a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png +++ /dev/null diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png Binary files differdeleted file mode 100644 index 53af5a54faa5..000000000000 --- a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png +++ /dev/null diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png Binary files differdeleted file mode 100644 index e4172ce65002..000000000000 --- a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png +++ /dev/null diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png Binary files differdeleted file mode 100644 index e2c76217f128..000000000000 --- a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png +++ /dev/null diff --git a/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml b/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml deleted file mode 100644 index 6c081bf2c948..000000000000 --- a/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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_enabled="true" android:drawable="@drawable/ic_lockscreen_forgotpassword_normal" /> - <item android:state_pressed="true" android:drawable="@drawable/ic_lockscreen_forgotpassword_pressed" /> - <item android:drawable="@drawable/ic_lockscreen_forgotpassword_normal" /> -</selector> diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml index 313fe9fc48c1..8be15cb4e30f 100644 --- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml +++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml @@ -42,7 +42,7 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="-10dip" + android:layout_marginTop="@dimen/eca_overlap" style="?android:attr/buttonBarStyle" android:orientation="horizontal" android:gravity="center" @@ -66,12 +66,10 @@ android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" - android:drawableLeft="@drawable/lockscreen_forgot_password_button" style="?android:attr/buttonBarButtonStyle" android:textSize="@dimen/kg_status_line_font_size" android:textColor="?android:attr/textColorSecondary" android:textAppearance="?android:attr/textAppearanceMedium" - android:drawablePadding="8dip" android:visibility="gone" android:textAllCaps="@bool/kg_use_all_caps" /> </LinearLayout> diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml index f8a13626f463..ea5ef2708289 100644 --- a/packages/Keyguard/res/values-sw600dp/dimens.xml +++ b/packages/Keyguard/res/values-sw600dp/dimens.xml @@ -66,4 +66,7 @@ <dimen name="widget_label_font_size">16dp</dimen> <dimen name="widget_big_font_size">141dp</dimen> + <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text. + Should be 0 on devices with plenty of room (e.g. tablets) --> + <dimen name="eca_overlap">0dip</dimen> </resources> diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml index a1ad120194a6..71e9924743f5 100644 --- a/packages/Keyguard/res/values/dimens.xml +++ b/packages/Keyguard/res/values/dimens.xml @@ -150,6 +150,10 @@ security mode. --> <dimen name="kg_small_widget_height">160dp</dimen> + <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text. + Should be 0 on devices with plenty of room (e.g. tablets) --> + <dimen name="eca_overlap">-10dip</dimen> + <!-- Default clock parameters --> <dimen name="bottom_text_spacing_digital">-8dp</dimen> <dimen name="label_font_size">14dp</dimen> diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml index abc4483705bd..4738049f9984 100644 --- a/packages/Keyguard/res/values/strings.xml +++ b/packages/Keyguard/res/values/strings.xml @@ -24,12 +24,12 @@ <!-- Instructions telling the user to enter their SIM PUK to unlock the keyguard. Displayed in one line in a large font. --> - <string name="keyguard_password_enter_puk_code">Type PUK and new PIN code</string> + <string name="keyguard_password_enter_puk_code">Type SIM PUK and new PIN code</string> <!-- Prompt to enter SIM PUK in Edit Text Box in unlock screen --> - <string name="keyguard_password_enter_puk_prompt">PUK code</string> + <string name="keyguard_password_enter_puk_prompt">SIM PUK code</string> <!-- Prompt to enter New SIM PIN in Edit Text Box in unlock screen --> - <string name="keyguard_password_enter_pin_prompt">New PIN code</string> + <string name="keyguard_password_enter_pin_prompt">New SIM PIN code</string> <!-- Displayed as hint in passwordEntry EditText on PasswordUnlockScreen [CHAR LIMIT=30]--> <string name="keyguard_password_entry_touch_hint"><font size="17">Touch to type password</font></string> @@ -249,8 +249,6 @@ <string name="kg_enter_confirm_pin_hint">Confirm desired PIN code</string> <!-- Message shown in dialog while the device is unlocking the SIM card --> <string name="kg_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string> - <!-- Message shown when the user enters the wrong PIN code --> - <string name="kg_password_wrong_pin_code">Incorrect PIN code.</string> <!-- Message shown when the user enters an invalid SIM pin password in PUK screen --> <string name="kg_invalid_sim_pin_hint">Type a PIN that is 4 to 8 numbers.</string> <!-- Message shown when the user enters an invalid PUK code in the PUK screen --> @@ -333,6 +331,34 @@ <!-- The delete-widget drop target button text --> <string name="kg_reordering_delete_drop_target_text">Remove</string> + <!-- Instructions telling the user that they entered the wrong SIM PIN for the last time. + Displayed in a dialog box. --> + <string name="kg_password_wrong_pin_code_pukked">Incorrect SIM PIN code you must now contact your carrier to unlock your device.</string> + <!-- Instructions telling the user that they entered the wrong SIM PIN while trying + to unlock the keyguard. Displayed in a dialog box. --> + <plurals name="kg_password_wrong_pin_code"> + <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item> + <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempts.</item> + </plurals> + + <!-- Instructions telling the user that they have exhausted SIM PUK retries and the SIM is now unusable. + Displayed in a dialog box. --> + <string name="kg_password_wrong_puk_code_dead">SIM is unusable. Contact your carrier.</string> + <!-- Instructions telling the user that they entered the wrong puk while trying + to unlock the keyguard. Displayed in a dialog box. --> + <plurals name="kg_password_wrong_puk_code"> + <item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item> + <item quantity="other">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item> + </plurals> + <!-- Instructions telling the user that the operation to unlock the keyguard + with SIM PIN failed. Displayed in one line in a large font. --> + <string name="kg_password_pin_failed">SIM PIN operation failed!</string> + <!-- Instructions telling the user that the operation to unlock the keyguard + with PUK failed. Displayed in one line in a large font. --> + <string name="kg_password_puk_failed">SIM PUK operation failed!</string> + <!-- Notification telling the user that the PIN1 they entered is valid --> + <string name="kg_pin_accepted">Code Accepted!</string> + <!-- Transport control strings --> <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. --> <string name="keyguard_transport_prev_description">Previous track button</string> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java index 50594073d2b7..e39622a54c66 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java @@ -17,11 +17,16 @@ package com.android.keyguard; import com.android.internal.telephony.ITelephony; +import com.android.internal.telephony.PhoneConstants; import android.content.Context; +import android.content.DialogInterface; import android.app.Activity; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.ProgressDialog; +import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.text.Editable; @@ -30,6 +35,7 @@ import android.text.TextWatcher; import android.text.method.DigitsKeyListener; import android.util.AttributeSet; import android.view.View; +import android.util.Log; import android.view.WindowManager; import android.widget.TextView.OnEditorActionListener; @@ -38,10 +44,14 @@ import android.widget.TextView.OnEditorActionListener; */ public class KeyguardSimPinView extends KeyguardAbsKeyInputView implements KeyguardSecurityView, OnEditorActionListener, TextWatcher { + private static final String LOG_TAG = "KeyguardSimPinView"; + private static final boolean DEBUG = KeyguardViewMediator.DEBUG; private ProgressDialog mSimUnlockProgressDialog = null; private volatile boolean mSimCheckInProgress; + private AlertDialog mRemainingAttemptsDialog; + public KeyguardSimPinView(Context context) { this(context, null); } @@ -55,6 +65,23 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView mPasswordEntry.setEnabled(true); } + private String getPinPasswordErrorMessage(int attemptsRemaining) { + String displayMessage; + + if (attemptsRemaining == 0) { + displayMessage = getContext().getString(R.string.kg_password_wrong_pin_code_pukked); + } else if (attemptsRemaining > 0) { + displayMessage = getContext().getResources() + .getQuantityString(R.plurals.kg_password_wrong_pin_code, attemptsRemaining, + attemptsRemaining); + } else { + displayMessage = getContext().getString(R.string.kg_password_pin_failed); + } + if (DEBUG) Log.d(LOG_TAG, "getPinPasswordErrorMessage:" + + " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage); + return displayMessage; + } + @Override protected boolean shouldLockout(long deadline) { // SIM PIN doesn't have a timed lockout @@ -109,6 +136,8 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView | InputType.TYPE_NUMBER_VARIATION_PASSWORD); mPasswordEntry.requestFocus(); + + mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default } @Override @@ -135,22 +164,22 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView mPin = pin; } - abstract void onSimCheckResponse(boolean success); + abstract void onSimCheckResponse(final int result, final int attemptsRemaining); @Override public void run() { try { - final boolean result = ITelephony.Stub.asInterface(ServiceManager - .checkService("phone")).supplyPin(mPin); + final int[] result = ITelephony.Stub.asInterface(ServiceManager + .checkService("phone")).supplyPinReportResult(mPin); post(new Runnable() { public void run() { - onSimCheckResponse(result); + onSimCheckResponse(result[0], result[1]); } }); } catch (RemoteException e) { post(new Runnable() { public void run() { - onSimCheckResponse(false); + onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); } }); } @@ -164,14 +193,28 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView mContext.getString(R.string.kg_sim_unlock_progress_dialog_message)); mSimUnlockProgressDialog.setIndeterminate(true); mSimUnlockProgressDialog.setCancelable(false); - if (!(mContext instanceof Activity)) { - mSimUnlockProgressDialog.getWindow().setType( - WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - } + mSimUnlockProgressDialog.getWindow().setType( + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); } return mSimUnlockProgressDialog; } + private Dialog getSimRemainingAttemptsDialog(int remaining) { + String msg = getPinPasswordErrorMessage(remaining); + if (mRemainingAttemptsDialog == null) { + Builder builder = new AlertDialog.Builder(mContext); + builder.setMessage(msg); + builder.setCancelable(false); + builder.setNeutralButton(R.string.ok, null); + mRemainingAttemptsDialog = builder.create(); + mRemainingAttemptsDialog.getWindow().setType( + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + } else { + mRemainingAttemptsDialog.setMessage(msg); + } + return mRemainingAttemptsDialog; + } + @Override protected void verifyPasswordAndUnlock() { String entry = mPasswordEntry.getText().toString(); @@ -189,20 +232,34 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView if (!mSimCheckInProgress) { mSimCheckInProgress = true; // there should be only one new CheckSimPin(mPasswordEntry.getText().toString()) { - void onSimCheckResponse(final boolean success) { + void onSimCheckResponse(final int result, final int attemptsRemaining) { post(new Runnable() { public void run() { if (mSimUnlockProgressDialog != null) { mSimUnlockProgressDialog.hide(); } - if (success) { - // before closing the keyguard, report back that the sim is unlocked - // so it knows right away. + if (result == PhoneConstants.PIN_RESULT_SUCCESS) { KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(); mCallback.dismiss(true); } else { - mSecurityMessageDisplay.setMessage - (R.string.kg_password_wrong_pin_code, true); + if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) { + if (attemptsRemaining <= 2) { + // this is getting critical - show dialog + getSimRemainingAttemptsDialog(attemptsRemaining).show(); + } else { + // show message + mSecurityMessageDisplay.setMessage( + getPinPasswordErrorMessage(attemptsRemaining), true); + } + } else { + // "PIN operation failed!" - no idea what this was and no way to + // find out. :/ + mSecurityMessageDisplay.setMessage(getContext().getString( + R.string.kg_password_pin_failed), true); + } + if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock " + + " CheckSimPin.onSimCheckResponse: " + result + + " attemptsRemaining=" + attemptsRemaining); mPasswordEntry.setText(""); } mCallback.userActivity(0); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java index 2ae4cc7ba653..31518a1e31f8 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java @@ -16,10 +16,10 @@ package com.android.keyguard; -import com.android.internal.telephony.ITelephony; - import android.content.Context; +import android.animation.AnimatorSet.Builder; import android.app.Activity; +import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.os.RemoteException; @@ -29,21 +29,29 @@ import android.text.InputType; import android.text.TextWatcher; import android.text.method.DigitsKeyListener; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.view.WindowManager; import android.widget.TextView.OnEditorActionListener; +import com.android.internal.telephony.ITelephony; +import com.android.internal.telephony.PhoneConstants; + + /** * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier. */ public class KeyguardSimPukView extends KeyguardAbsKeyInputView implements KeyguardSecurityView, OnEditorActionListener, TextWatcher { + private static final String LOG_TAG = "KeyguardSimPukView"; + private static final boolean DEBUG = KeyguardViewMediator.DEBUG; private ProgressDialog mSimUnlockProgressDialog = null; private volatile boolean mCheckInProgress; private String mPukText; private String mPinText; private StateMachine mStateMachine = new StateMachine(); + private AlertDialog mRemainingAttemptsDialog; private class StateMachine { final int ENTER_PUK = 0; @@ -93,6 +101,23 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView } } + private String getPukPasswordErrorMessage(int attemptsRemaining) { + String displayMessage; + + if (attemptsRemaining == 0) { + displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead); + } else if (attemptsRemaining > 0) { + displayMessage = getContext().getResources() + .getQuantityString(R.plurals.kg_password_wrong_puk_code, attemptsRemaining, + attemptsRemaining); + } else { + displayMessage = getContext().getString(R.string.kg_password_puk_failed); + } + if (DEBUG) Log.d(LOG_TAG, "getPukPasswordErrorMessage:" + + " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage); + return displayMessage; + } + public KeyguardSimPukView(Context context) { this(context, null); } @@ -190,23 +215,23 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView mPin = pin; } - abstract void onSimLockChangedResponse(boolean success); + abstract void onSimLockChangedResponse(final int result, final int attemptsRemaining); @Override public void run() { try { - final boolean result = ITelephony.Stub.asInterface(ServiceManager - .checkService("phone")).supplyPuk(mPuk, mPin); + final int[] result = ITelephony.Stub.asInterface(ServiceManager + .checkService("phone")).supplyPukReportResult(mPuk, mPin); post(new Runnable() { public void run() { - onSimLockChangedResponse(result); + onSimLockChangedResponse(result[0], result[1]); } }); } catch (RemoteException e) { post(new Runnable() { public void run() { - onSimLockChangedResponse(false); + onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); } }); } @@ -228,6 +253,22 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView return mSimUnlockProgressDialog; } + private Dialog getPukRemainingAttemptsDialog(int remaining) { + String msg = getPukPasswordErrorMessage(remaining); + if (mRemainingAttemptsDialog == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + builder.setMessage(msg); + builder.setCancelable(false); + builder.setNeutralButton(R.string.ok, null); + mRemainingAttemptsDialog = builder.create(); + mRemainingAttemptsDialog.getWindow().setType( + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + } else { + mRemainingAttemptsDialog.setMessage(msg); + } + return mRemainingAttemptsDialog; + } + private boolean checkPuk() { // make sure the puk is at least 8 digits long. if (mPasswordEntry.getText().length() >= 8) { @@ -257,17 +298,33 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView if (!mCheckInProgress) { mCheckInProgress = true; new CheckSimPuk(mPukText, mPinText) { - void onSimLockChangedResponse(final boolean success) { + void onSimLockChangedResponse(final int result, final int attemptsRemaining) { post(new Runnable() { public void run() { if (mSimUnlockProgressDialog != null) { mSimUnlockProgressDialog.hide(); } - if (success) { + if (result == PhoneConstants.PIN_RESULT_SUCCESS) { + KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(); mCallback.dismiss(true); } else { + if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) { + if (attemptsRemaining <= 2) { + // this is getting critical - show dialog + getPukRemainingAttemptsDialog(attemptsRemaining).show(); + } else { + // show message + mSecurityMessageDisplay.setMessage( + getPukPasswordErrorMessage(attemptsRemaining), true); + } + } else { + mSecurityMessageDisplay.setMessage(getContext().getString( + R.string.kg_password_puk_failed), true); + } + if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock " + + " UpdateSim.onSimCheckResponse: " + + " attemptsRemaining=" + attemptsRemaining); mStateMachine.reset(); - mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true); } mCheckInProgress = false; } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 497d48c56a41..2e5dedfb15d8 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -740,7 +740,10 @@ final class ActivityStack { prev.state = ActivityState.PAUSING; prev.task.touchActiveTime(); clearLaunchTime(prev); - prev.updateThumbnail(screenshotActivities(prev), null); + final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(); + if (next == null || next.task != prev.task) { + prev.updateThumbnail(screenshotActivities(prev), null); + } stopFullyDrawnTraceIfNeeded(); mService.updateCpuStats(); diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 584411b83db7..7bd2c8412e97 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -155,6 +155,26 @@ interface ITelephony { boolean supplyPuk(String puk, String pin); /** + * Supply a pin to unlock the SIM. Blocks until a result is determined. + * Returns a specific success/error code. + * @param pin The pin to check. + * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code + * retValue[1] = number of attempts remaining if known otherwise -1 + */ + int[] supplyPinReportResult(String pin); + + /** + * Supply puk to unlock the SIM and set SIM pin to new pin. + * Blocks until a result is determined. + * Returns a specific success/error code + * @param puk The puk to check + * pin The pin to check. + * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code + * retValue[1] = number of attempts remaining if known otherwise -1 + */ + int[] supplyPukReportResult(String puk, String pin); + + /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated * without SEND (so <code>dial</code> is not appropriate). * diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 4a4a62b9640d..416325591352 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -86,6 +86,14 @@ public class PhoneConstants { public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged"; /** + * Return codes for supplyPinReturnResult and + * supplyPukReturnResult APIs + */ + public static final int PIN_RESULT_SUCCESS = 0; + public static final int PIN_PASSWORD_INCORRECT = 1; + public static final int PIN_GENERAL_FAILURE = 2; + + /** * Return codes for <code>enableApnType()</code> */ public static final int APN_ALREADY_ACTIVE = 0; |