Merge "Fix NPE in AppWidgetService.addProvidersForPackageLocked()"
diff --git a/api/current.xml b/api/current.xml
index 4b19006..425dad4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -6829,6 +6829,17 @@
  visibility="public"
 >
 </field>
+<field name="safeMode"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843449"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="saveEnabled"
  type="int"
  transient="false"
@@ -41876,6 +41887,17 @@
  visibility="public"
 >
 </field>
+<field name="FLAG_VM_SAFE_MODE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16384"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="className"
  type="java.lang.String"
  transient="false"
@@ -72605,7 +72627,7 @@
  type="float"
  transient="false"
  volatile="false"
- value="0.001f"
+ value="0.0010f"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -83949,29 +83971,6 @@
  visibility="public"
 >
 </constructor>
-<method name="createImageThumbnail"
- return="android.graphics.Bitmap"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="cr" type="android.content.ContentResolver">
-</parameter>
-<parameter name="filePath" type="java.lang.String">
-</parameter>
-<parameter name="uri" type="android.net.Uri">
-</parameter>
-<parameter name="origId" type="long">
-</parameter>
-<parameter name="kind" type="int">
-</parameter>
-<parameter name="saveMini" type="boolean">
-</parameter>
-</method>
 <method name="createVideoThumbnail"
  return="android.graphics.Bitmap"
  abstract="false"
@@ -83985,7 +83984,7 @@
 <parameter name="filePath" type="java.lang.String">
 </parameter>
 </method>
-<method name="extractMiniThumb"
+<method name="extractThumbnail"
  return="android.graphics.Bitmap"
  abstract="false"
  native="false"
@@ -84001,10 +84000,38 @@
 </parameter>
 <parameter name="height" type="int">
 </parameter>
-<parameter name="recycle" type="boolean">
+</method>
+<method name="extractThumbnail"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="source" type="android.graphics.Bitmap">
+</parameter>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="options" type="int">
 </parameter>
 </method>
-<field name="MINI_THUMB_TARGET_SIZE"
+<field name="OPTIONS_RECYCLE_INPUT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_SIZE_MICRO_THUMBNAIL"
  type="int"
  transient="false"
  volatile="false"
@@ -84015,29 +84042,7 @@
  visibility="public"
 >
 </field>
-<field name="NO_RECYCLE_INPUT"
- type="boolean"
- transient="false"
- volatile="false"
- value="false"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="RECYCLE_INPUT"
- type="boolean"
- transient="false"
- volatile="false"
- value="true"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="THUMBNAIL_TARGET_SIZE"
+<field name="TARGET_SIZE_NORMAL_THUMBNAIL"
  type="int"
  transient="false"
  volatile="false"
@@ -86670,15 +86675,11 @@
  type="android.net.SSLCertificateSocketFactory"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
-<parameter name="socketReadTimeoutForSslHandshake" type="int">
+<parameter name="handshakeTimeoutMillis" type="int">
 </parameter>
-<exception name="KeyManagementException" type="java.security.KeyManagementException">
-</exception>
-<exception name="NoSuchAlgorithmException" type="java.security.NoSuchAlgorithmException">
-</exception>
 </constructor>
 <method name="createSocket"
  return="java.net.Socket"
@@ -86690,13 +86691,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="socket" type="java.net.Socket">
+<parameter name="k" type="java.net.Socket">
 </parameter>
-<parameter name="s" type="java.lang.String">
+<parameter name="host" type="java.lang.String">
 </parameter>
-<parameter name="i" type="int">
+<parameter name="port" type="int">
 </parameter>
-<parameter name="flag" type="boolean">
+<parameter name="close" type="boolean">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -86711,13 +86712,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="inaddr" type="java.net.InetAddress">
+<parameter name="addr" type="java.net.InetAddress">
 </parameter>
-<parameter name="i" type="int">
+<parameter name="port" type="int">
 </parameter>
-<parameter name="inaddr2" type="java.net.InetAddress">
+<parameter name="localAddr" type="java.net.InetAddress">
 </parameter>
-<parameter name="j" type="int">
+<parameter name="localPort" type="int">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -86732,9 +86733,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="inaddr" type="java.net.InetAddress">
+<parameter name="addr" type="java.net.InetAddress">
 </parameter>
-<parameter name="i" type="int">
+<parameter name="port" type="int">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -86749,13 +86750,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="s" type="java.lang.String">
+<parameter name="host" type="java.lang.String">
 </parameter>
-<parameter name="i" type="int">
+<parameter name="port" type="int">
 </parameter>
-<parameter name="inaddr" type="java.net.InetAddress">
+<parameter name="localAddr" type="java.net.InetAddress">
 </parameter>
-<parameter name="j" type="int">
+<parameter name="localPort" type="int">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -86770,9 +86771,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="s" type="java.lang.String">
+<parameter name="host" type="java.lang.String">
 </parameter>
-<parameter name="i" type="int">
+<parameter name="port" type="int">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -86787,7 +86788,22 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="socketReadTimeoutForSslHandshake" type="int">
+<parameter name="handshakeTimeoutMillis" type="int">
+</parameter>
+</method>
+<method name="getDefault"
+ return="javax.net.SocketFactory"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="handshakeTimeoutMillis" type="int">
+</parameter>
+<parameter name="cache" type="android.net.SSLSessionCache">
 </parameter>
 </method>
 <method name="getDefaultCipherSuites"
@@ -86801,6 +86817,21 @@
  visibility="public"
 >
 </method>
+<method name="getHttpSocketFactory"
+ return="org.apache.http.conn.ssl.SSLSocketFactory"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="handshakeTimeoutMillis" type="int">
+</parameter>
+<parameter name="cache" type="android.net.SSLSessionCache">
+</parameter>
+</method>
 <method name="getSupportedCipherSuites"
  return="java.lang.String[]"
  abstract="false"
@@ -86813,6 +86844,37 @@
 >
 </method>
 </class>
+<class name="SSLSessionCache"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="SSLSessionCache"
+ type="android.net.SSLSessionCache"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dir" type="java.io.File">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</constructor>
+<constructor name="SSLSessionCache"
+ type="android.net.SSLSessionCache"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+</class>
 <class name="TrafficStats"
  extends="java.lang.Object"
  abstract="false"
@@ -210313,7 +210375,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
 </parameter>
 </method>
 </interface>
@@ -214073,6 +214135,17 @@
  visibility="public"
 >
 </field>
+<field name="DEBUG_ENABLE_SAFEMODE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 </package>
 <package name="java.awt.font"
diff --git a/common/Android.mk b/common/Android.mk
index 76091eb..5c5b01b 100644
--- a/common/Android.mk
+++ b/common/Android.mk
@@ -19,6 +19,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := android-common
+LOCAL_SDK_VERSION := current
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
diff --git a/common/java/com/android/common/AndroidHttpClient.java b/common/java/com/android/common/AndroidHttpClient.java
index 99faf6e..4c65eb0 100644
--- a/common/java/com/android/common/AndroidHttpClient.java
+++ b/common/java/com/android/common/AndroidHttpClient.java
@@ -47,8 +47,6 @@
 import org.apache.http.protocol.BasicHttpProcessor;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
-import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -59,11 +57,11 @@
 import java.net.URI;
 import java.security.KeyManagementException;
 
+import android.content.Context;
 import android.content.ContentResolver;
+import android.net.SSLCertificateSocketFactory;
+import android.net.SSLSessionCache;
 import android.os.Looper;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.Log;
 
 /**
@@ -76,11 +74,9 @@
  * To retain cookies, simply add a cookie store to the HttpContext:</p>
  *
  * <pre>context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);</pre>
- * 
- * {@hide}
  */
 public final class AndroidHttpClient implements HttpClient {
-        
+
     // Gzip of data shorter than this probably won't be worthwhile
     public static long DEFAULT_SYNC_MIN_GZIP_BYTES = 256;
 
@@ -101,12 +97,11 @@
     /**
      * Create a new HttpClient with reasonable defaults (which you can update).
      *
-     * @param userAgent to report in your HTTP requests.
-     * @param sessionCache persistent session cache
+     * @param userAgent to report in your HTTP requests
+     * @param context to use for caching SSL sessions (may be null for no caching)
      * @return AndroidHttpClient for you to use for all your requests.
      */
-    public static AndroidHttpClient newInstance(String userAgent,
-            SSLClientSessionCache sessionCache) {
+    public static AndroidHttpClient newInstance(String userAgent, Context context) {
         HttpParams params = new BasicHttpParams();
 
         // Turn off stale checking.  Our connections break all the time anyway,
@@ -122,13 +117,16 @@
         // often wants to re-POST after a redirect, which we must do ourselves.
         HttpClientParams.setRedirecting(params, false);
 
+        // Use a session cache for SSL sockets
+        SSLSessionCache sessionCache = context == null ? null : new SSLSessionCache(context);
+
         // Set the specified user agent and register standard protocols.
         HttpProtocolParams.setUserAgent(params, userAgent);
         SchemeRegistry schemeRegistry = new SchemeRegistry();
         schemeRegistry.register(new Scheme("http",
                 PlainSocketFactory.getSocketFactory(), 80));
         schemeRegistry.register(new Scheme("https",
-                socketFactoryWithCache(sessionCache), 443));
+                SSLCertificateSocketFactory.getHttpSocketFactory(30 * 1000, sessionCache), 443));
 
         ClientConnectionManager manager =
                 new ThreadSafeClientConnManager(params, schemeRegistry);
@@ -139,32 +137,6 @@
     }
 
     /**
-     * Returns a socket factory backed by the given persistent session cache.
-     *
-     * @param sessionCache to retrieve sessions from, null for no cache
-     */
-    private static SSLSocketFactory socketFactoryWithCache(
-            SSLClientSessionCache sessionCache) {
-        if (sessionCache == null) {
-            // Use the default factory which doesn't support persistent
-            // caching.
-            return SSLSocketFactory.getSocketFactory();
-        }
-
-        // Create a new SSL context backed by the cache.
-        // TODO: Keep a weak *identity* hash map of caches to engines. In the
-        // mean time, if we have two engines for the same cache, they'll still
-        // share sessions but will have to do so through the persistent cache.
-        SSLContextImpl sslContext = new SSLContextImpl();
-        try {
-            sslContext.engineInit(null, null, null, sessionCache, null);
-        } catch (KeyManagementException e) {
-            throw new AssertionError(e);
-        }
-        return new SSLSocketFactory(sslContext.engineGetSocketFactory());
-    }
-
-    /**
      * Create a new HttpClient with reasonable defaults (which you can update).
      * @param userAgent to report in your HTTP requests.
      * @return AndroidHttpClient for you to use for all your requests.
@@ -339,9 +311,7 @@
      * Shorter data will not be compressed.
      */
     public static long getMinGzipSize(ContentResolver resolver) {
-        return Settings.Secure.getLong(resolver,
-                                       Settings.Secure.SYNC_MIN_GZIP_BYTES,
-                                       DEFAULT_SYNC_MIN_GZIP_BYTES);
+        return DEFAULT_SYNC_MIN_GZIP_BYTES;  // For now, this is just a constant.
     }
 
     /* cURL logging support. */
@@ -367,15 +337,6 @@
         }
 
         /**
-         * Returns true if auth logging is turned on for this configuration.  Can only be set on
-         * insecure devices.
-         */
-        private boolean isAuthLoggable() {
-            String secure = SystemProperties.get("ro.secure");
-            return "0".equals(secure) && Log.isLoggable(tag + "-auth", level);
-        }
-
-        /**
          * Prints a message using this configuration.
          */
         private void println(String message) {
@@ -421,8 +382,9 @@
             if (configuration != null
                     && configuration.isLoggable()
                     && request instanceof HttpUriRequest) {
-                configuration.println(toCurl((HttpUriRequest) request,
-                        configuration.isAuthLoggable()));
+                // Never print auth token -- we used to check ro.secure=0 to
+                // enable that, but can't do that in unbundled code.
+                configuration.println(toCurl((HttpUriRequest) request, false));
             }
         }
     }
diff --git a/common/java/com/android/common/ArrayListCursor.java b/common/java/com/android/common/ArrayListCursor.java
index cc1fe27..9ad5c36 100644
--- a/common/java/com/android/common/ArrayListCursor.java
+++ b/common/java/com/android/common/ArrayListCursor.java
@@ -115,11 +115,6 @@
     }
 
     @Override
-    public boolean deleteRow() {
-        return false;
-    }
-
-    @Override
     public String[] getColumnNames() {
         return mColumnNames;
     }
diff --git a/common/tools/make-iana-tld-pattern.py b/common/tools/make-iana-tld-pattern.py
new file mode 100755
index 0000000..ece4dcf
--- /dev/null
+++ b/common/tools/make-iana-tld-pattern.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+from urllib2 import urlopen
+
+TLD_PREFIX = r"""
+    /**
+     *  Regular expression pattern to match all IANA top-level domains.
+     *  List accurate as of 2010/02/05.  List taken from:
+     *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
+     *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
+     */
+    public static final Pattern TOP_LEVEL_DOMAIN = Pattern.compile(
+"""
+TLD_SUFFIX = '");'
+
+URL_PREFIX = r"""
+    /**
+     *  Regular expression pattern to match RFC 1738 URLs
+     *  List accurate as of 2010/02/05.  List taken from:
+     *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
+     *  This pattern is auto-generated by frameworkds/base/common/tools/make-iana-tld-pattern.py
+     */
+    public static final Pattern WEB_URL = Pattern.compile(
+        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+        + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
+        + "(?:"   // plus top level domain
+"""
+
+URL_SUFFIX = r"""
+        + "|(?:(?:25[0-5]|2[0-4]" // or ip address
+        + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
+        + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
+        + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+        + "|[1-9][0-9]|[0-9])))"
+        + "(?:\\:\\d{1,5})?)" // plus option port number
+        + "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
+        + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+        + "(?:\\b|$)"); // and finally, a word boundary or end of
+                        // input.  This is to stop foo.sure from
+                        // matching as foo.su
+"""
+
+class Bucket:
+    def __init__(self, baseLetter):
+        self.base=baseLetter
+        self.words=[]
+        self.letters=[]
+
+    def dump(self, isWebUrl=False, isFirst=False, isLast=False):
+        if (len(self.words) == 0) and (len(self.letters) == 0):
+            return ''
+
+        self.words.sort()
+        self.letters.sort()
+
+        output = '        ';
+
+        if isFirst:
+            if isWebUrl:
+                output += '+ "'
+            else:
+                output += '"('
+        else:
+            output += '+ "|'
+
+        if len(self.words) != 0:
+            output += '('
+
+            if isWebUrl:
+                output += '?:'
+
+        firstWord = 1
+        for word in self.words:
+            if firstWord == 0:
+                output += '|'
+            firstWord = 0
+            for letter in word:
+                if letter == '-':
+                    output += '\\\\'  # escape the '-' character.
+                output += letter
+
+        if len(self.words) > 0 and len(self.letters) > 0:
+            output += '|'
+
+        if len(self.letters) == 1:
+            output += '%c%c' % (self.base, self.letters[0])
+        elif len(self.letters) > 0:
+            output += '%c[' % self.base
+
+            for letter in self.letters:
+                output += letter
+
+            output += ']'
+
+        if len(self.words) != 0:
+            output += ')'
+
+        if not isLast:
+            output += '"'
+            output += '\n'
+
+        return output;
+
+    def add(self, line):
+        length = len(line)
+
+        if line.startswith('#') or (length == 0):
+            return;
+
+        if length == 2:
+            self.letters.append(line[1:2])
+        else:
+            self.words.append(line)
+
+def getBucket(buckets, line):
+    letter = line[0]
+    bucket = buckets.get(letter)
+
+    if bucket is None:
+        bucket = Bucket(letter)
+        buckets[letter] = bucket
+
+    return bucket
+
+def makePattern(prefix, suffix, buckets, isWebUrl=False):
+    output = prefix
+
+    output += getBucket(buckets, 'a').dump(isFirst=True, isWebUrl=isWebUrl)
+
+    for letter in range(ord('b'), ord('z')):
+        output += getBucket(buckets, chr(letter)).dump(isWebUrl=isWebUrl)
+
+    output += getBucket(buckets, 'z').dump(isLast=True, isWebUrl=isWebUrl)
+
+    if isWebUrl:
+        output += '))"'
+    else:
+        output += ')'
+
+    output += suffix
+
+    print output
+
+if __name__ == "__main__":
+    f = urlopen('http://data.iana.org/TLD/tlds-alpha-by-domain.txt')
+    domains = f.readlines()
+    f.close()
+
+    buckets = {}
+
+    for domain in domains:
+        domain = domain.lower()
+
+        if len(domain) > 0:
+            getBucket(buckets, domain[0]).add(domain.strip())
+
+    makePattern(TLD_PREFIX, TLD_SUFFIX, buckets, isWebUrl=False)
+    makePattern(URL_PREFIX, URL_SUFFIX, buckets, isWebUrl=True)
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6591313..123d9b7 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -178,12 +178,20 @@
     public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 1<<13;
     
     /**
+     * Value for {@link #flags}: set to true if this application would like to
+     * request the VM to operate under the safe mode. Comes from
+     * {@link android.R.styleable#AndroidManifestApplication_safeMode
+     * android:safeMode} of the &lt;application&gt; tag.
+     */
+    public static final int FLAG_VM_SAFE_MODE = 1<<14;
+
+    /**
      * Value for {@link #flags}: this is false if the application has set
      * its android:allowBackup to false, true otherwise.
      * 
      * {@hide}
      */
-    public static final int FLAG_ALLOW_BACKUP = 1<<14;
+    public static final int FLAG_ALLOW_BACKUP = 1<<15;
 
     /**
      * Value for {@link #flags}: this is false if the application has set
@@ -194,7 +202,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_KILL_AFTER_RESTORE = 1<<15;
+    public static final int FLAG_KILL_AFTER_RESTORE = 1<<16;
 
     /**
      * Value for {@link #flags}: this is true if the application has set
@@ -205,7 +213,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_RESTORE_NEEDS_APPLICATION = 1<<16;
+    public static final int FLAG_RESTORE_NEEDS_APPLICATION = 1<<17;
 
     /**
      * Value for {@link #flags}: this is true if the application has set
@@ -215,7 +223,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_NEVER_ENCRYPT = 1<<17;
+    public static final int FLAG_NEVER_ENCRYPT = 1<<18;
 
     /**
      * Value for {@link #flags}: Set to true if the application has been
@@ -223,7 +231,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_FORWARD_LOCK = 1<<18;
+    public static final int FLAG_FORWARD_LOCK = 1<<19;
 
     /**
      * Value for {@link #flags}: Set to true if the application is
@@ -231,7 +239,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_ON_SDCARD = 1<<19;
+    public static final int FLAG_ON_SDCARD = 1<<20;
 
     /**
      * Value for {@link #flags}: Set to true if the application is
@@ -239,7 +247,7 @@
      *
      * {@hide}
      */
-    public static final int FLAG_NATIVE_DEBUGGABLE = 1<<20;
+    public static final int FLAG_NATIVE_DEBUGGABLE = 1<<21;
 
     /**
      * Flags associated with the application.  Any combination of
@@ -250,7 +258,7 @@
      * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
      * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
      * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS},
-     * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}
+     * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}, {@link #FLAG_VM_SAFE_MODE}
      */
     public int flags = 0;
     
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0a6195f..d97b3dd 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1429,6 +1429,12 @@
         }
 
         if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestApplication_safeMode,
+                false)) {
+            ai.flags |= ApplicationInfo.FLAG_VM_SAFE_MODE;
+        }
+
+        if (sa.getBoolean(
                 com.android.internal.R.styleable.AndroidManifestApplication_hasCode,
                 true)) {
             ai.flags |= ApplicationInfo.FLAG_HAS_CODE;
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index e40f1b8..ed76b15 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -40,224 +40,174 @@
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
+import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
 import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
 import org.apache.harmony.xnet.provider.jsse.SSLParameters;
 
 /**
- * SSLSocketFactory that provides optional (on debug devices, only) skipping of ssl certificfate
- * chain validation and custom read timeouts used just when connecting to the server/negotiating
- * an ssl session.
- *
- * You can skip the ssl certificate checking at runtime by setting socket.relaxsslcheck=yes on
- * devices that do not have have ro.secure set.
+ * SSLSocketFactory implementation with several extra features:
+ * <ul>
+ * <li>Timeout specification for SSL handshake operations
+ * <li>Optional SSL session caching with {@link SSLSessionCache}
+ * <li>On development devices, "setprop socket.relaxsslcheck yes" bypasses all
+ * SSL certificate checks, for testing with development servers
+ * </ul>
+ * Note that the handshake timeout does not apply to actual connection.
+ * If you want a connection timeout as well, use {@link #createSocket()} and
+ * {@link Socket#connect(SocketAddress, int)}.
  */
 public class SSLCertificateSocketFactory extends SSLSocketFactory {
+    private static final String TAG = "SSLCertificateSocketFactory";
 
-    private static final String LOG_TAG = "SSLCertificateSocketFactory";
-
-    private static final TrustManager[] TRUST_MANAGER = new TrustManager[] {
+    private static final TrustManager[] INSECURE_TRUST_MANAGER = new TrustManager[] {
         new X509TrustManager() {
-            public X509Certificate[] getAcceptedIssuers() {
-                return null;
-            }
-
-            public void checkClientTrusted(X509Certificate[] certs,
-                    String authType) { }
-
-            public void checkServerTrusted(X509Certificate[] certs,
-                    String authType) { }
+            public X509Certificate[] getAcceptedIssuers() { return null; }
+            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
+            public void checkServerTrusted(X509Certificate[] certs, String authType) { }
         }
     };
 
-    private final SSLSocketFactory mFactory;
+    private SSLSocketFactory mInsecureFactory = null;
+    private SSLSocketFactory mSecureFactory = null;
 
-    private final int mSocketReadTimeoutForSslHandshake;
+    private final int mHandshakeTimeoutMillis;
+    private final SSLClientSessionCache mSessionCache;
 
-    /**
-     * Do not use this constructor (will be deprecated).  Use {@link #getDefault(int)} instead.
-     */
-    public SSLCertificateSocketFactory(int socketReadTimeoutForSslHandshake)
-            throws NoSuchAlgorithmException, KeyManagementException {
-        this(socketReadTimeoutForSslHandshake, null /* cache */);
+    /** @deprecated Use {@link #getDefault(int)} instead. */
+    public SSLCertificateSocketFactory(int handshakeTimeoutMillis) {
+        this(handshakeTimeoutMillis, null /* cache */);
     }
 
-    private SSLCertificateSocketFactory(int socketReadTimeoutForSslHandshake,
-            SSLClientSessionCache cache) throws NoSuchAlgorithmException, KeyManagementException {
-        SSLContextImpl sslContext = new SSLContextImpl();
-        sslContext.engineInit(null /* kms */,
-            TRUST_MANAGER, new java.security.SecureRandom(),
-            cache /* client cache */, null /* server cache */);
-        this.mFactory = sslContext.engineGetSocketFactory();
-        this.mSocketReadTimeoutForSslHandshake = socketReadTimeoutForSslHandshake;
+    private SSLCertificateSocketFactory(int handshakeTimeoutMillis, SSLSessionCache cache) {
+        mHandshakeTimeoutMillis = handshakeTimeoutMillis;
+        mSessionCache = cache == null ? null : cache.mSessionCache;
     }
 
     /**
      * Returns a new instance of a socket factory using the specified socket read
      * timeout while connecting with the server/negotiating an ssl session.
      *
-     * @param socketReadTimeoutForSslHandshake the socket read timeout used for performing
-     *        ssl handshake. The socket read timeout is set back to 0 after the handshake.
-     * @return a new SocketFactory, or null on error
+     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
+     *         for none.  The socket timeout is reset to 0 after the handshake.
+     * @return a new SocketFactory with the specified parameters
      */
-    public static SocketFactory getDefault(int socketReadTimeoutForSslHandshake) {
-        return getDefault(socketReadTimeoutForSslHandshake, null /* cache */);
+    public static SocketFactory getDefault(int handshakeTimeoutMillis) {
+        return getDefault(handshakeTimeoutMillis, null /* cache */);
     }
 
     /**
-     * Returns a new instance of a socket factory using the specified socket read
-     * timeout while connecting with the server/negotiating an ssl session.
+     * Returns a new instance of a socket factory using the specified socket
+     * read timeout while connecting with the server/negotiating an ssl session
      * Persists ssl sessions using the provided {@link SSLClientSessionCache}.
      *
-     * @param socketReadTimeoutForSslHandshake the socket read timeout used for performing
-     *        ssl handshake. The socket read timeout is set back to 0 after the handshake.
-     * @param cache The {@link SSLClientSessionCache} to use, if any.
-     * @return a new SocketFactory, or null on error
+     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
+     *         for none.  The socket timeout is reset to 0 after the handshake.
+     * @param cache The {@link SSLClientSessionCache} to use, or null for no cache.
+     * @return a new SocketFactory with the specified parameters
+     */
+    public static SocketFactory getDefault(int handshakeTimeoutMillis, SSLSessionCache cache) {
+        return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache);
+    }
+
+    /**
+     * Returns a socket factory (also named SSLSocketFactory, but in a different
+     * namespace) for use with the Apache HTTP stack.
      *
-     * @hide
-    */
-    public static SocketFactory getDefault(int socketReadTimeoutForSslHandshake,
-            SSLClientSessionCache cache) {
+     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
+     *         for none.  The socket timeout is reset to 0 after the handshake.
+     * @param cache The {@link SSLClientSessionCache} to use, or null for no cache.
+     * @return a new SocketFactory with the specified parameters
+     */
+    public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(
+            int handshakeTimeoutMillis,
+            SSLSessionCache cache) {
+        return new org.apache.http.conn.ssl.SSLSocketFactory(
+                new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache));
+    }
+
+    private SSLSocketFactory makeSocketFactory(TrustManager[] trustManagers) {
         try {
-            return new SSLCertificateSocketFactory(socketReadTimeoutForSslHandshake, cache);
-        } catch (NoSuchAlgorithmException e) {
-            Log.e(LOG_TAG, 
-                    "SSLCertifcateSocketFactory.getDefault" +
-                    " NoSuchAlgorithmException " , e);
-            return null;
+            SSLContextImpl sslContext = new SSLContextImpl();
+            sslContext.engineInit(null, trustManagers, null, mSessionCache, null);
+            return sslContext.engineGetSocketFactory();
         } catch (KeyManagementException e) {
-            Log.e(LOG_TAG, 
-                    "SSLCertifcateSocketFactory.getDefault" +
-                    " KeyManagementException " , e);
-            return null; 
+            Log.wtf(TAG, e);
+            return (SSLSocketFactory) SSLSocketFactory.getDefault();  // Fallback
         }
     }
 
-    private boolean hasValidCertificateChain(Certificate[] certs) 
-            throws IOException {
-        boolean trusted = (certs != null && (certs.length > 0));
-
-        if (trusted) {
-            try {
-                // the authtype we pass in doesn't actually matter
-                SSLParameters.getDefaultTrustManager()
-                        .checkServerTrusted((X509Certificate[]) certs, "RSA");
-            } catch (GeneralSecurityException e) { 
-                String exceptionMessage = e != null ? e.getMessage() : "none";
-                if (Config.LOGD) {
-                    Log.d(LOG_TAG,"hasValidCertificateChain(): sec. exception: "
-                         + exceptionMessage);
-                }
-                trusted = false;
-            }
-        }
-
-        return trusted;
-    }
-
-    private void validateSocket(SSLSocket sslSock, String destHost) 
-            throws IOException
-    {
-        if (Config.LOGV) {
-            Log.v(LOG_TAG,"validateSocket() to host "+destHost);
-        }
-
-        String relaxSslCheck = SystemProperties.get("socket.relaxsslcheck");
-        String secure = SystemProperties.get("ro.secure");
-
+    private synchronized SSLSocketFactory getDelegate() {
         // only allow relaxing the ssl check on non-secure builds where the relaxation is
         // specifically requested.
-        if ("0".equals(secure) && "yes".equals(relaxSslCheck)) {
-            if (Config.LOGD) {
-                Log.d(LOG_TAG,"sys prop socket.relaxsslcheck is set," +
-                        " ignoring invalid certs");
+        if ("0".equals(SystemProperties.get("ro.secure")) &&
+            "yes".equals(SystemProperties.get("socket.relaxsslcheck"))) {
+            if (mInsecureFactory == null) {
+                Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***");
+                mInsecureFactory = makeSocketFactory(INSECURE_TRUST_MANAGER);
             }
-            return;
-        }
-
-        Certificate[] certs = null;
-        sslSock.setUseClientMode(true);
-        sslSock.startHandshake();
-        certs = sslSock.getSession().getPeerCertificates();
-
-        // check that the root certificate in the chain belongs to
-        // a CA we trust
-        if (certs == null) {
-            Log.e(LOG_TAG, 
-                    "[SSLCertificateSocketFactory] no trusted root CA");
-            throw new IOException("no trusted root CA");
-        }
-
-        if (Config.LOGV) {
-            Log.v(LOG_TAG,"validateSocket # certs = " +certs.length);
-        }
-
-        if (!hasValidCertificateChain(certs)) {
-            if (Config.LOGD) {
-                Log.d(LOG_TAG,"validateSocket(): certificate untrusted!");
+            return mInsecureFactory;
+        } else {
+            if (mSecureFactory == null) {
+                mSecureFactory = makeSocketFactory(null);
             }
-            throw new IOException("Certificate untrusted");
-        }
-
-        X509Certificate lastChainCert = (X509Certificate) certs[0];
-
-        if (!DomainNameValidator.match(lastChainCert, destHost)) {
-            if (Config.LOGD) {
-                Log.d(LOG_TAG,"validateSocket(): domain name check failed");
-            }
-            throw new IOException("Domain Name check failed");
+            return mSecureFactory;
         }
     }
 
-    public Socket createSocket(Socket socket, String s, int i, boolean flag)
-            throws IOException
-    {
-        throw new IOException("Cannot validate certification without a hostname");       
+    @Override
+    public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException {
+        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close);
+        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
+        return s;
     }
 
-    public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr2, int j)
-            throws IOException
-    {
-        throw new IOException("Cannot validate certification without a hostname");       
+    @Override
+    public Socket createSocket() throws IOException {
+        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket();
+        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
+        return s;
     }
 
-    public Socket createSocket(InetAddress inaddr, int i) throws IOException {
-        throw new IOException("Cannot validate certification without a hostname");       
+    @Override
+    public Socket createSocket(InetAddress addr, int port, InetAddress localAddr, int localPort)
+            throws IOException {
+        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
+                addr, port, localAddr, localPort);
+        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
+        return s;
     }
 
-    public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
-        SSLSocket sslSock = (SSLSocket) mFactory.createSocket(s, i, inaddr, j);
-
-        if (mSocketReadTimeoutForSslHandshake >= 0) {
-            sslSock.setSoTimeout(mSocketReadTimeoutForSslHandshake);
-        }
-
-        validateSocket(sslSock,s);
-        sslSock.setSoTimeout(0);
-        
-        return sslSock;
+    @Override
+    public Socket createSocket(InetAddress addr, int port) throws IOException {
+        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port);
+        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
+        return s;
     }
 
-    public Socket createSocket(String s, int i) throws IOException {
-        SSLSocket sslSock = (SSLSocket) mFactory.createSocket(s, i);
-
-        if (mSocketReadTimeoutForSslHandshake >= 0) {
-            sslSock.setSoTimeout(mSocketReadTimeoutForSslHandshake);
-        }
-        
-        validateSocket(sslSock,s);
-        sslSock.setSoTimeout(0);
-
-        return sslSock;
+    @Override
+    public Socket createSocket(String host, int port, InetAddress localAddr, int localPort)
+            throws IOException {
+        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
+                host, port, localAddr, localPort);
+        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
+        return s;
     }
 
+    @Override
+    public Socket createSocket(String host, int port) throws IOException {
+        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port);
+        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
+        return s;
+    }
+
+    @Override
     public String[] getDefaultCipherSuites() {
-        return mFactory.getSupportedCipherSuites();
+        return getDelegate().getSupportedCipherSuites();
     }
 
+    @Override
     public String[] getSupportedCipherSuites() {
-        return mFactory.getSupportedCipherSuites();
+        return getDelegate().getSupportedCipherSuites();
     }
 }
-
-
diff --git a/core/java/android/net/SSLSessionCache.java b/core/java/android/net/SSLSessionCache.java
new file mode 100644
index 0000000..4cbeb94
--- /dev/null
+++ b/core/java/android/net/SSLSessionCache.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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.net;
+
+import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
+
+import android.content.Context;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * File-based cache of established SSL sessions.  When re-establishing a
+ * connection to the same server, using an SSL session cache can save some time,
+ * power, and bandwidth by skipping directly to an encrypted stream.
+ * This is a persistent cache which can span executions of the application.
+ *
+ * @see SSLCertificateSocketFactory
+ */
+public final class SSLSessionCache {
+    private static final String TAG = "SSLSessionCache";
+    /* package */ final SSLClientSessionCache mSessionCache;
+
+    /**
+     * Create a session cache using the specified directory.
+     * Individual session entries will be files within the directory.
+     * Multiple instances for the same directory share data internally.
+     *
+     * @param dir to store session files in (created if necessary)
+     * @throws IOException if the cache can't be opened
+     */
+    public SSLSessionCache(File dir) throws IOException {
+        mSessionCache = FileClientSessionCache.usingDirectory(dir);
+    }
+
+    /**
+     * Create a session cache at the default location for this app.
+     * Multiple instances share data internally.
+     *
+     * @param context for the application
+     */
+    public SSLSessionCache(Context context) {
+        File dir = context.getDir("sslcache", Context.MODE_PRIVATE);
+        SSLClientSessionCache cache = null;
+        try {
+            cache = FileClientSessionCache.usingDirectory(dir);
+        } catch (IOException e) {
+            Log.w(TAG, "Unable to create SSL session cache in " + dir, e);
+        }
+        mSessionCache = cache;
+    }
+}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 699ddb2..4887783 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -504,6 +504,9 @@
             argsForZygote.add("--runtime-init");
             argsForZygote.add("--setuid=" + uid);
             argsForZygote.add("--setgid=" + gid);
+            if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
+                argsForZygote.add("--enable-safemode");
+            }
             if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
                 argsForZygote.add("--enable-debugger");
             }
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 211bc0a..74a03da 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -383,10 +383,10 @@
                     if (isVideo) {
                         bitmap = ThumbnailUtils.createVideoThumbnail(filePath);
                         if (kind == MICRO_KIND && bitmap != null) {
-                            bitmap = ThumbnailUtils.extractMiniThumb(bitmap,
-                                    ThumbnailUtils.MINI_THUMB_TARGET_SIZE,
-                                    ThumbnailUtils.MINI_THUMB_TARGET_SIZE,
-                                    ThumbnailUtils.RECYCLE_INPUT);
+                            bitmap = ThumbnailUtils.extractThumbnail(bitmap,
+                                    ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
+                                    ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
+                                    ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
                         }
                     } else {
                         bitmap = ThumbnailUtils.createImageThumbnail(cr, filePath, uri, origId,
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c2cdcc0..076903b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2814,22 +2814,6 @@
                 "sms_outgoing_check_max_count";
 
         /**
-         * Enable use of ssl session caching.
-         * 'db' - save each session in a (per process) database
-         * 'file' - save each session in a (per process) file
-         * not set or any other value - normal java in-memory caching
-         * @hide
-         */
-        public static final String SSL_SESSION_CACHE = "ssl_session_cache";
-
-        /**
-         * How many bytes long a message has to be, in order to be gzipped.
-         * @hide
-         */
-        public static final String SYNC_MIN_GZIP_BYTES =
-                "sync_min_gzip_bytes";
-
-        /**
          * The number of promoted sources in GlobalSearch.
          * @hide
          */
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 631e7d8..da0c5a2 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -295,7 +295,10 @@
         /** from --peer-wait */
         boolean peerWait;
 
-        /** from --enable-debugger, --enable-checkjni, --enable-assert */
+        /**
+         * From --enable-debugger, --enable-checkjni, --enable-assert, and
+         * --enable-safemode
+         */
         int debugFlags;
 
         /** from --classpath */
@@ -363,6 +366,8 @@
                             arg.substring(arg.indexOf('=') + 1));
                 } else if (arg.equals("--enable-debugger")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
+                } else if (arg.equals("--enable-safemode")) {
+                    debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
                 } else if (arg.equals("--enable-checkjni")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
                 } else if (arg.equals("--enable-assert")) {
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index 51f7f69..c9014723 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -216,61 +216,6 @@
         }
     }
 
-    /**
-     * Sets keyboard extension. Keyboard extension is shown when input is detected above keyboard
-     * while keyboard has focus.
-     *
-     * @param resId
-     */
-    public void setExtension(int resId) {
-        mExtensionResId = resId;
-    }
-
-    /**
-     * Get current extesion resource id.
-     *
-     * @return resource id, 0 if not set.
-     */
-    public int getExtension() {
-        return mExtensionResId;
-    }
-
-    private void updateSpaceBarForLocale() {
-        if (mLocale != null) {
-            // Create the graphic for spacebar
-            Bitmap buffer = Bitmap.createBitmap(mSpaceKey.width, mSpaceIcon.getIntrinsicHeight(),
-                    Bitmap.Config.ARGB_8888);
-            Canvas canvas = new Canvas(buffer);
-            canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
-            Paint paint = new Paint();
-            paint.setAntiAlias(true);
-            // TODO: Make the text size a customizable attribute
-            paint.setTextSize(22);
-            paint.setTextAlign(Align.CENTER);
-            // Draw a drop shadow for the text
-            paint.setShadowLayer(1f, 0, 0, 0xFF000000);
-            paint.setColor(0x80C0C0C0);
-            canvas.drawText(mLocale.getDisplayLanguage(mLocale),
-                    buffer.getWidth() / 2, - paint.ascent() + 2, paint);
-            int x = (buffer.getWidth() - mSpaceIcon.getIntrinsicWidth()) / 2;
-            int y = buffer.getHeight() - mSpaceIcon.getIntrinsicHeight();
-            mSpaceIcon.setBounds(x, y,
-                    x + mSpaceIcon.getIntrinsicWidth(), y + mSpaceIcon.getIntrinsicHeight());
-            mSpaceIcon.draw(canvas);
-            mSpaceKey.icon = new BitmapDrawable(mRes, buffer);
-            mSpaceKey.repeatable = false;
-        } else {
-            mSpaceKey.icon = mRes.getDrawable(R.drawable.sym_keyboard_space);
-            mSpaceKey.repeatable = true;
-        }
-    }
-
-    public void setLanguage(Locale locale) {
-        if (mLocale != null && mLocale.equals(locale)) return;
-        mLocale = locale;
-        updateSpaceBarForLocale();
-    }
-
     static class LatinKey extends Keyboard.Key {
         private boolean mShiftLockEnabled;
         private boolean mEnabled = true;
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index b809afc..c2862b0 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -22,15 +22,11 @@
 import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.text.Editable;
-import android.text.Selection;
-import android.util.Log;
+import android.provider.Settings;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewRoot;
-import android.view.inputmethod.InputConnection;
-import android.widget.EditText;
 import com.android.internal.R;
 
 public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener {
@@ -40,7 +36,6 @@
     private static final int KEYBOARD_STATE_NORMAL = 0;
     private static final int KEYBOARD_STATE_SHIFTED = 1;
     private static final int KEYBOARD_STATE_CAPSLOCK = 2;
-    private static final String TAG = "PasswordEntryKeyboardHelper";
     private int mKeyboardMode = KEYBOARD_MODE_ALPHA;
     private int mKeyboardState = KEYBOARD_STATE_NORMAL;
     private PasswordEntryKeyboard mQwertyKeyboard;
@@ -90,10 +85,15 @@
             case KEYBOARD_MODE_ALPHA:
                 mKeyboardView.setKeyboard(mQwertyKeyboard);
                 mKeyboardState = KEYBOARD_STATE_NORMAL;
+                final boolean visiblePassword = Settings.System.getInt(
+                        mContext.getContentResolver(),
+                        Settings.System.TEXT_SHOW_PASSWORD, 1) != 0;
+                mKeyboardView.setPreviewEnabled(visiblePassword);
                 break;
             case KEYBOARD_MODE_NUMERIC:
                 mKeyboardView.setKeyboard(mNumericKeyboard);
                 mKeyboardState = KEYBOARD_STATE_NORMAL;
+                mKeyboardView.setPreviewEnabled(false); // never show popup for numeric keypad
                 break;
         }
         mKeyboardMode = mode;
@@ -122,7 +122,6 @@
     }
 
     public void onKey(int primaryCode, int[] keyCodes) {
-        Log.v(TAG, "Key code = " + Integer.toHexString(primaryCode));
         if (primaryCode == Keyboard.KEYCODE_DELETE) {
             handleBackspace();
         } else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
@@ -201,7 +200,7 @@
     }
 
     public void onPress(int primaryCode) {
-
+        // TODO: vibration support.
     }
 
     public void onRelease(int primaryCode) {
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
index 9b93fc2..3e6f6f3 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
@@ -17,27 +17,17 @@
 package com.android.internal.widget;
 
 import android.content.Context;
-import android.inputmethodservice.Keyboard;
 import android.inputmethodservice.KeyboardView;
 import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.widget.PopupWindow;
-import com.android.internal.R;
 
 public class PasswordEntryKeyboardView extends KeyboardView {
 
-    public static final int KEYCODE_OPTIONS = -100;
+    static final int KEYCODE_OPTIONS = -100;
     static final int KEYCODE_SHIFT_LONGPRESS = -101;
     static final int KEYCODE_VOICE = -102;
     static final int KEYCODE_F1 = -103;
     static final int KEYCODE_NEXT_LANGUAGE = -104;
 
-    private boolean mExtensionVisible;
-    private PasswordEntryKeyboardView mExtension;
-    private PopupWindow mExtensionPopup;
-    private boolean mFirstEvent;
-
     public PasswordEntryKeyboardView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -46,107 +36,4 @@
         super(context, attrs, defStyle);
     }
 
-    @Override
-    public boolean onTouchEvent(MotionEvent me) {
-        if (((PasswordEntryKeyboard) getKeyboard()).getExtension() == 0) {
-            return super.onTouchEvent(me);
-        }
-        if (me.getY() < 0) {
-            if (mExtensionVisible) {
-                int action = me.getAction();
-                if (mFirstEvent) action = MotionEvent.ACTION_DOWN;
-                mFirstEvent = false;
-                MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
-                        action,
-                        me.getX(), me.getY() + mExtension.getHeight(), me.getMetaState());
-                boolean result = mExtension.onTouchEvent(translated);
-                translated.recycle();
-                if (me.getAction() == MotionEvent.ACTION_UP
-                        || me.getAction() == MotionEvent.ACTION_CANCEL) {
-                    closeExtension();
-                }
-                return result;
-            } else {
-                if (openExtension()) {
-                    MotionEvent cancel = MotionEvent.obtain(me.getDownTime(), me.getEventTime(),
-                            MotionEvent.ACTION_CANCEL, me.getX() - 100, me.getY() - 100, 0);
-                    super.onTouchEvent(cancel);
-                    cancel.recycle();
-                    if (mExtension.getHeight() > 0) {
-                        MotionEvent translated = MotionEvent.obtain(me.getEventTime(),
-                                me.getEventTime(),
-                                MotionEvent.ACTION_DOWN,
-                                me.getX(), me.getY() + mExtension.getHeight(),
-                                me.getMetaState());
-                        mExtension.onTouchEvent(translated);
-                        translated.recycle();
-                    } else {
-                        mFirstEvent = true;
-                    }
-                }
-                return true;
-            }
-        } else if (mExtensionVisible) {
-            closeExtension();
-            // Send a down event into the main keyboard first
-            MotionEvent down = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
-                    MotionEvent.ACTION_DOWN, me.getX(), me.getY(), me.getMetaState());
-            super.onTouchEvent(down);
-            down.recycle();
-            // Send the actual event
-            return super.onTouchEvent(me);
-        } else {
-            return super.onTouchEvent(me);
-        }
-    }
-
-    private boolean openExtension() {
-        if (((PasswordEntryKeyboard) getKeyboard()).getExtension() == 0) return false;
-        makePopupWindow();
-        mExtensionVisible = true;
-        return true;
-    }
-
-    private void makePopupWindow() {
-        if (mExtensionPopup == null) {
-            int[] windowLocation = new int[2];
-            mExtensionPopup = new PopupWindow(getContext());
-            mExtensionPopup.setBackgroundDrawable(null);
-            LayoutInflater li = (LayoutInflater) getContext().getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            mExtension = (PasswordEntryKeyboardView) li.inflate(
-                    R.layout.password_keyboard_input, null);
-            mExtension.setOnKeyboardActionListener(getOnKeyboardActionListener());
-            mExtension.setPopupParent(this);
-            mExtension.setPopupOffset(0, -windowLocation[1]);
-            Keyboard keyboard;
-            mExtension.setKeyboard(keyboard = new PasswordEntryKeyboard(getContext(),
-                    ((PasswordEntryKeyboard) getKeyboard()).getExtension()));
-            mExtensionPopup.setContentView(mExtension);
-            mExtensionPopup.setWidth(getWidth());
-            mExtensionPopup.setHeight(keyboard.getHeight());
-            getLocationInWindow(windowLocation);
-            // TODO: Fix the "- 30".
-            mExtension.setPopupOffset(0, -windowLocation[1] - 30);
-            mExtensionPopup.showAtLocation(this, 0, 0, -keyboard.getHeight()
-                    + windowLocation[1]);
-        } else {
-            mExtension.setVisibility(VISIBLE);
-        }
-    }
-
-    @Override
-    public void closing() {
-        super.closing();
-        if (mExtensionPopup != null && mExtensionPopup.isShowing()) {
-            mExtensionPopup.dismiss();
-            mExtensionPopup = null;
-        }
-    }
-
-    private void closeExtension() {
-        mExtension.setVisibility(INVISIBLE);
-        mExtension.closing();
-        mExtensionVisible = false;
-    }
 }
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index b089df6..ab675c7 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -37,7 +37,7 @@
             android:layout_marginLeft="6dip"
             android:layout_marginTop="10dip"
             android:layout_marginBottom="10dip"
-            android:gravity="center"
+            android:gravity="left"
             android:ellipsize="marquee"
             android:text="@android:string/keyguard_password_enter_password_code"
             android:textAppearance="?android:attr/textAppearanceLarge"
@@ -53,7 +53,7 @@
             android:inputType="textPassword"
             android:gravity="center"
             android:layout_gravity="center"
-            android:textSize="32sp"
+            android:textSize="24sp"
             android:textAppearance="?android:attr/textAppearanceLarge"
             android:background="@drawable/password_field_default"
             android:textColor="#ffffffff"
diff --git a/core/res/res/layout/password_keyboard_input.xml b/core/res/res/layout/password_keyboard_input.xml
deleted file mode 100755
index e40b69e..0000000
--- a/core/res/res/layout/password_keyboard_input.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
--->
-
-<com.android.passwordunlockdemo.LatinKeyboardView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@android:id/keyboardView"
-        android:layout_alignParentBottom="true"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="#00000000"
-        android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
-        />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 2da23eb..70bc000 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -215,6 +215,10 @@
          running on a device that is running in user mode. -->
     <attr name="debuggable" format="boolean" />
     
+    <!-- Flag indicating whether the application requests the VM to operate in
+         the safe mode.  -->
+    <attr name="safeMode" format="boolean" />
+
     <!-- Flag indicating whether the given application component is available
          to other applications.  If false, it can only be accessed by
          applications with its same user id (which usually means only by
@@ -685,6 +689,7 @@
              override the component specific values). -->
         <attr name="enabled" />
         <attr name="debuggable" />
+        <attr name="safeMode" />
         <!-- Name of activity to be launched for managing the application's space on the device. -->
         <attr name="manageSpaceActivity" />
         <attr name="allowClearUserData" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 596e0b2..7706f30 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1229,5 +1229,6 @@
   <eat-comment />
   <public type="attr" name="neverEncrypt" id="0x010102b7" />
   <public type="attr" name="installLocation" id="0x010102b8" />
+  <public type="attr" name="safeMode" id="0x010102b9" />
     
 </resources>
diff --git a/core/res/res/xml-land/password_kbd_qwerty.xml b/core/res/res/xml-land/password_kbd_qwerty.xml
index a3d4e88..8245cc1 100755
--- a/core/res/res/xml-land/password_kbd_qwerty.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty.xml
@@ -26,29 +26,28 @@
     >
 
     <Row>
-        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
-        <Key android:codes="119" android:keyLabel="w"/>
-        <Key android:codes="101" android:keyLabel="e"/>
-        <Key android:codes="114" android:keyLabel="r"/>
-        <Key android:codes="116" android:keyLabel="t"/>
-        <Key android:codes="121" android:keyLabel="y"/>
-        <Key android:codes="117" android:keyLabel="u"/>
-        <Key android:codes="105" android:keyLabel="i"/>
-        <Key android:codes="111" android:keyLabel="o"/>
-        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="w"/>
+        <Key android:keyLabel="e"/>
+        <Key android:keyLabel="r"/>
+        <Key android:keyLabel="t"/>
+        <Key android:keyLabel="y"/>
+        <Key android:keyLabel="u"/>
+        <Key android:keyLabel="i"/>
+        <Key android:keyLabel="o"/>
+        <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
-            android:keyEdgeFlags="left"/>
-        <Key android:codes="115" android:keyLabel="s"/>
-        <Key android:codes="100" android:keyLabel="d"/>
-        <Key android:codes="102" android:keyLabel="f"/>
-        <Key android:codes="103" android:keyLabel="g"/>
-        <Key android:codes="104" android:keyLabel="h"/>
-        <Key android:codes="106" android:keyLabel="j"/>
-        <Key android:codes="107" android:keyLabel="k"/>
-        <Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="a" android:horizontalGap="5%p" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="s"/>
+        <Key android:keyLabel="d"/>
+        <Key android:keyLabel="f"/>
+        <Key android:keyLabel="g"/>
+        <Key android:keyLabel="h"/>
+        <Key android:keyLabel="j"/>
+        <Key android:keyLabel="k"/>
+        <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
@@ -56,13 +55,13 @@
             android:keyWidth="15%p" android:isModifier="true"
             android:iconPreview="@drawable/sym_keyboard_feedback_shift"
             android:isSticky="true" android:keyEdgeFlags="left"/>
-        <Key android:codes="122" android:keyLabel="z"/>
-        <Key android:codes="120" android:keyLabel="x"/>
-        <Key android:codes="99" android:keyLabel="c"/>
-        <Key android:codes="118" android:keyLabel="v"/>
-        <Key android:codes="98" android:keyLabel="b"/>
-        <Key android:codes="110" android:keyLabel="n"/>
-        <Key android:codes="109" android:keyLabel="m"/>
+        <Key android:keyLabel="z"/>
+        <Key android:keyLabel="x"/>
+        <Key android:keyLabel="c"/>
+        <Key android:keyLabel="v"/>
+        <Key android:keyLabel="b"/>
+        <Key android:keyLabel="n"/>
+        <Key android:keyLabel="m"/>
         <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
             android:keyWidth="15%p" android:keyEdgeFlags="right"
             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
@@ -76,9 +75,9 @@
         <Key android:keyLabel="-" />
         <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
             android:iconPreview="@drawable/sym_keyboard_feedback_space"
-            android:keyWidth="20%p" android:isRepeatable="true"/>
+            android:keyWidth="20%p"/>
         <Key android:keyLabel="=" />
-        <Key android:codes="46" android:keyLabel="."
+        <Key android:keyLabel="."
             android:keyWidth="10%p"/>
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
             android:iconPreview="@drawable/sym_keyboard_feedback_return"
diff --git a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
index 2285d91..6117e78 100755
--- a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
@@ -26,29 +26,29 @@
     >
 
     <Row>
-        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
-        <Key android:codes="119" android:keyLabel="w"/>
-        <Key android:codes="101" android:keyLabel="e"/>
-        <Key android:codes="114" android:keyLabel="r"/>
-        <Key android:codes="116" android:keyLabel="t"/>
-        <Key android:codes="121" android:keyLabel="y"/>
-        <Key android:codes="117" android:keyLabel="u"/>
-        <Key android:codes="105" android:keyLabel="i"/>
-        <Key android:codes="111" android:keyLabel="o"/>
-        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="w"/>
+        <Key android:keyLabel="e"/>
+        <Key android:keyLabel="r"/>
+        <Key android:keyLabel="t"/>
+        <Key android:keyLabel="y"/>
+        <Key android:keyLabel="u"/>
+        <Key android:keyLabel="i"/>
+        <Key android:keyLabel="o"/>
+        <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+        <Key android:keyLabel="a" android:horizontalGap="5%p"
             android:keyEdgeFlags="left"/>
-        <Key android:codes="115" android:keyLabel="s"/>
-        <Key android:codes="100" android:keyLabel="d"/>
-        <Key android:codes="102" android:keyLabel="f"/>
-        <Key android:codes="103" android:keyLabel="g"/>
-        <Key android:codes="104" android:keyLabel="h"/>
-        <Key android:codes="106" android:keyLabel="j"/>
-        <Key android:codes="107" android:keyLabel="k"/>
-        <Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="s"/>
+        <Key android:keyLabel="d"/>
+        <Key android:keyLabel="f"/>
+        <Key android:keyLabel="g"/>
+        <Key android:keyLabel="h"/>
+        <Key android:keyLabel="j"/>
+        <Key android:keyLabel="k"/>
+        <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
@@ -56,13 +56,13 @@
             android:keyWidth="15%p" android:isModifier="true"
             android:iconPreview="@drawable/sym_keyboard_feedback_shift"
             android:isSticky="true" android:keyEdgeFlags="left"/>
-        <Key android:codes="122" android:keyLabel="z"/>
-        <Key android:codes="120" android:keyLabel="x"/>
-        <Key android:codes="99" android:keyLabel="c"/>
-        <Key android:codes="118" android:keyLabel="v"/>
-        <Key android:codes="98" android:keyLabel="b"/>
-        <Key android:codes="110" android:keyLabel="n"/>
-        <Key android:codes="109" android:keyLabel="m"/>
+        <Key android:keyLabel="z"/>
+        <Key android:keyLabel="x"/>
+        <Key android:keyLabel="c"/>
+        <Key android:keyLabel="v"/>
+        <Key android:keyLabel="b"/>
+        <Key android:keyLabel="n"/>
+        <Key android:keyLabel="m"/>
         <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
             android:keyWidth="15%p" android:keyEdgeFlags="right"
             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
@@ -76,10 +76,10 @@
         <Key android:keyLabel="_" />
         <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
             android:iconPreview="@drawable/sym_keyboard_feedback_space"
-            android:keyWidth="20%p" android:isRepeatable="true"/>
+            android:keyWidth="20%p"/>
         <Key android:keyLabel="+" />
-        <Key android:codes="46" android:keyLabel="."/>
-        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+        <Key android:keyLabel="."/>
+        <Key android:keyIcon="@drawable/sym_keyboard_return"
             android:iconPreview="@drawable/sym_keyboard_feedback_return"
             android:keyWidth="20%p" android:keyEdgeFlags="right"/>
     </Row>
diff --git a/core/res/res/xml/password_kbd_extension.xml b/core/res/res/xml/password_kbd_extension.xml
index 354594e..28b7efe 100755
--- a/core/res/res/xml/password_kbd_extension.xml
+++ b/core/res/res/xml/password_kbd_extension.xml
@@ -40,22 +40,15 @@
     </Row>
 
     <Row android:rowEdgeFlags="bottom">
-        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"
-        />
-        <Key android:codes="50" android:keyLabel="2"
-        />
-        <Key android:codes="51" android:keyLabel="3"
-        />
-        <Key android:codes="52" android:keyLabel="4"
-        />
-        <Key android:codes="53" android:keyLabel="5"
-        />
-        <Key android:codes="54" android:keyLabel="6"/>
-        <Key android:codes="55" android:keyLabel="7"
-        />
-        <Key android:codes="56" android:keyLabel="8"/>
-        <Key android:codes="57" android:keyLabel="9"/>
-        <Key android:codes="48" android:keyLabel="0"
-                android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="2"/>
+        <Key android:keyLabel="3"/>
+        <Key android:keyLabel="4"/>
+        <Key android:keyLabel="5"/>
+        <Key android:keyLabel="6"/>
+        <Key android:keyLabel="7"/>
+        <Key android:keyLabel="8"/>
+        <Key android:keyLabel="9"/>
+        <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
     </Row>
 </Keyboard>
diff --git a/core/res/res/xml/password_kbd_qwerty.xml b/core/res/res/xml/password_kbd_qwerty.xml
index d4a454b..5fa9b8a 100755
--- a/core/res/res/xml/password_kbd_qwerty.xml
+++ b/core/res/res/xml/password_kbd_qwerty.xml
@@ -26,42 +26,42 @@
     >
 
     <Row android:rowEdgeFlags="top">
-        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
-        <Key android:codes="50" android:keyLabel="2"/>
-        <Key android:codes="51" android:keyLabel="3"/>
-        <Key android:codes="52" android:keyLabel="4"/>
-        <Key android:codes="53" android:keyLabel="5"/>
-        <Key android:codes="54" android:keyLabel="6"/>
-        <Key android:codes="55" android:keyLabel="7"/>
-        <Key android:codes="56" android:keyLabel="8"/>
-        <Key android:codes="57" android:keyLabel="9"/>
-        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="2"/>
+        <Key android:keyLabel="3"/>
+        <Key android:keyLabel="4"/>
+        <Key android:keyLabel="5"/>
+        <Key android:keyLabel="6"/>
+        <Key android:keyLabel="7"/>
+        <Key android:keyLabel="8"/>
+        <Key android:keyLabel="9"/>
+        <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
-        <Key android:codes="119" android:keyLabel="w"/>
-        <Key android:codes="101" android:keyLabel="e"/>
-        <Key android:codes="114" android:keyLabel="r"/>
-        <Key android:codes="116" android:keyLabel="t"/>
-        <Key android:codes="121" android:keyLabel="y"/>
-        <Key android:codes="117" android:keyLabel="u"/>
-        <Key android:codes="105" android:keyLabel="i"/>
-        <Key android:codes="111" android:keyLabel="o"/>
-        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="w"/>
+        <Key android:keyLabel="e"/>
+        <Key android:keyLabel="r"/>
+        <Key android:keyLabel="t"/>
+        <Key android:keyLabel="y"/>
+        <Key android:keyLabel="u"/>
+        <Key android:keyLabel="i"/>
+        <Key android:keyLabel="o"/>
+        <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+        <Key android:keyLabel="a" android:horizontalGap="5%p"
             android:keyEdgeFlags="left"/>
-        <Key android:codes="115" android:keyLabel="s"/>
-        <Key android:codes="100" android:keyLabel="d"/>
-        <Key android:codes="102" android:keyLabel="f"/>
-        <Key android:codes="103" android:keyLabel="g"/>
-        <Key android:codes="104" android:keyLabel="h"/>
-        <Key android:codes="106" android:keyLabel="j"/>
-        <Key android:codes="107" android:keyLabel="k"/>
-        <Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="s"/>
+        <Key android:keyLabel="d"/>
+        <Key android:keyLabel="f"/>
+        <Key android:keyLabel="g"/>
+        <Key android:keyLabel="h"/>
+        <Key android:keyLabel="j"/>
+        <Key android:keyLabel="k"/>
+        <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
@@ -69,13 +69,13 @@
             android:keyWidth="15%p" android:isModifier="true"
             android:iconPreview="@drawable/sym_keyboard_feedback_shift"
             android:isSticky="true" android:keyEdgeFlags="left"/>
-        <Key android:codes="122" android:keyLabel="z"/>
-        <Key android:codes="120" android:keyLabel="x"/>
-        <Key android:codes="99" android:keyLabel="c"/>
-        <Key android:codes="118" android:keyLabel="v"/>
-        <Key android:codes="98" android:keyLabel="b"/>
-        <Key android:codes="110" android:keyLabel="n"/>
-        <Key android:codes="109" android:keyLabel="m"/>
+        <Key android:keyLabel="z"/>
+        <Key android:keyLabel="x"/>
+        <Key android:keyLabel="c"/>
+        <Key android:keyLabel="v"/>
+        <Key android:keyLabel="b"/>
+        <Key android:keyLabel="n"/>
+        <Key android:keyLabel="m"/>
         <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
             android:keyWidth="15%p" android:keyEdgeFlags="right"
             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
@@ -89,9 +89,9 @@
         <Key android:keyLabel="-" />
         <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
             android:iconPreview="@drawable/sym_keyboard_feedback_space"
-            android:keyWidth="20%p" android:isRepeatable="true"/>
+            android:keyWidth="20%p"/>
         <Key android:keyLabel="=" />
-        <Key android:codes="46" android:keyLabel="."
+        <Key android:keyLabel="."
             android:keyWidth="10%p"/>
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
             android:iconPreview="@drawable/sym_keyboard_feedback_ok"
diff --git a/core/res/res/xml/password_kbd_qwerty_shifted.xml b/core/res/res/xml/password_kbd_qwerty_shifted.xml
index f341d9e..e491aff 100755
--- a/core/res/res/xml/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml/password_kbd_qwerty_shifted.xml
@@ -26,42 +26,42 @@
     >
 
     <Row android:rowEdgeFlags="top">
-        <Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/>
-        <Key android:codes="35" android:keyLabel="\#"/>
-        <Key android:codes="36" android:keyLabel="$"/>
-        <Key android:codes="37" android:keyLabel="%"/>
-        <Key android:codes="38" android:keyLabel="&amp;"/>
-        <Key android:codes="42" android:keyLabel="*"/>
-        <Key android:codes="45" android:keyLabel="-"/>
+        <Key android:keyLabel="\@" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="\#"/>
+        <Key android:keyLabel="$"/>
+        <Key android:keyLabel="%"/>
+        <Key android:keyLabel="&amp;"/>
+        <Key android:keyLabel="*"/>
+        <Key android:keyLabel="-"/>
         <Key android:keyLabel="+"/>
-        <Key android:codes="40" android:keyLabel="("/>
-        <Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="("/>
+        <Key android:keyLabel=")" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
-        <Key android:codes="119" android:keyLabel="w"/>
-        <Key android:codes="101" android:keyLabel="e"/>
-        <Key android:codes="114" android:keyLabel="r"/>
-        <Key android:codes="116" android:keyLabel="t"/>
-        <Key android:codes="121" android:keyLabel="y"/>
-        <Key android:codes="117" android:keyLabel="u"/>
-        <Key android:codes="105" android:keyLabel="i"/>
-        <Key android:codes="111" android:keyLabel="o"/>
-        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="w"/>
+        <Key android:keyLabel="e"/>
+        <Key android:keyLabel="r"/>
+        <Key android:keyLabel="t"/>
+        <Key android:keyLabel="y"/>
+        <Key android:keyLabel="u"/>
+        <Key android:keyLabel="i"/>
+        <Key android:keyLabel="o"/>
+        <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+        <Key android:keyLabel="a" android:horizontalGap="5%p"
             android:keyEdgeFlags="left"/>
-        <Key android:codes="115" android:keyLabel="s"/>
-        <Key android:codes="100" android:keyLabel="d"/>
-        <Key android:codes="102" android:keyLabel="f"/>
-        <Key android:codes="103" android:keyLabel="g"/>
-        <Key android:codes="104" android:keyLabel="h"/>
-        <Key android:codes="106" android:keyLabel="j"/>
-        <Key android:codes="107" android:keyLabel="k"/>
-        <Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="s"/>
+        <Key android:keyLabel="d"/>
+        <Key android:keyLabel="f"/>
+        <Key android:keyLabel="g"/>
+        <Key android:keyLabel="h"/>
+        <Key android:keyLabel="j"/>
+        <Key android:keyLabel="k"/>
+        <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
@@ -69,13 +69,13 @@
             android:keyWidth="15%p" android:isModifier="true"
             android:iconPreview="@drawable/sym_keyboard_feedback_shift"
             android:isSticky="true" android:keyEdgeFlags="left"/>
-        <Key android:codes="122" android:keyLabel="z"/>
-        <Key android:codes="120" android:keyLabel="x"/>
-        <Key android:codes="99" android:keyLabel="c"/>
-        <Key android:codes="118" android:keyLabel="v"/>
-        <Key android:codes="98" android:keyLabel="b"/>
-        <Key android:codes="110" android:keyLabel="n"/>
-        <Key android:codes="109" android:keyLabel="m"/>
+        <Key android:keyLabel="z"/>
+        <Key android:keyLabel="x"/>
+        <Key android:keyLabel="c"/>
+        <Key android:keyLabel="v"/>
+        <Key android:keyLabel="b"/>
+        <Key android:keyLabel="n"/>
+        <Key android:keyLabel="m"/>
         <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
             android:keyWidth="15%p" android:keyEdgeFlags="right"
             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
@@ -89,9 +89,9 @@
         <Key android:keyLabel="_" />
         <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
             android:iconPreview="@drawable/sym_keyboard_feedback_space"
-            android:keyWidth="20%p" android:isRepeatable="true"/>
+            android:keyWidth="20%p"/>
         <Key android:keyLabel="+" />
-        <Key android:codes="46" android:keyLabel="."/>
+        <Key android:keyLabel="."/>
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
             android:iconPreview="@drawable/sym_keyboard_feedback_ok"
             android:keyWidth="20%p" android:keyEdgeFlags="right"/>
diff --git a/core/res/res/xml/password_kbd_symbols.xml b/core/res/res/xml/password_kbd_symbols.xml
index c97e6ae..14a7ec8 100755
--- a/core/res/res/xml/password_kbd_symbols.xml
+++ b/core/res/res/xml/password_kbd_symbols.xml
@@ -26,32 +26,32 @@
     >
 
     <Row>
-        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
-        <Key android:codes="50" android:keyLabel="2"/>
-        <Key android:codes="51" android:keyLabel="3"/>
-        <Key android:codes="52" android:keyLabel="4"/>
-        <Key android:codes="53" android:keyLabel="5"/>
-        <Key android:codes="54" android:keyLabel="6"/>
-        <Key android:codes="55" android:keyLabel="7"/>
-        <Key android:codes="56" android:keyLabel="8"/>
-        <Key android:codes="57" android:keyLabel="9"/>
-        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
+        <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="2"/>
+        <Key android:keyLabel="3"/>
+        <Key android:keyLabel="4"/>
+        <Key android:keyLabel="5"/>
+        <Key android:keyLabel="6"/>
+        <Key android:keyLabel="7"/>
+        <Key android:keyLabel="8"/>
+        <Key android:keyLabel="9"/>
+        <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
     </Row>
 
     <Row>
-        <Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/>
-        <Key android:codes="35" android:keyLabel="\#"/>
-        <Key android:codes="36" android:keyLabel="$"/>
-        <Key android:codes="37" android:keyLabel="%"/>
-        <Key android:codes="38" android:keyLabel="&amp;"/>
-        <Key android:codes="42" android:keyLabel="*"/>
-        <Key android:codes="45" android:keyLabel="-"/>
+        <Key android:keyLabel="\@" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="\#"/>
+        <Key android:keyLabel="$"/>
+        <Key android:keyLabel="%"/>
+        <Key android:keyLabel="&amp;"/>
+        <Key android:keyLabel="*"/>
+        <Key android:keyLabel="-"/>
         <Key android:keyLabel="+"/>
-        <Key android:codes="40" android:keyLabel="("
+        <Key android:keyLabel="("
                 android:popupKeyboard="@xml/password_kbd_popup_template"
                 android:popupCharacters="[{&lt;"
         />
-        <Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right"
+        <Key android:keyLabel=")" android:keyEdgeFlags="right"
                 android:popupKeyboard="@xml/password_kbd_popup_template"
                 android:popupCharacters="]}&gt;"
         />
@@ -61,13 +61,13 @@
         <Key android:codes="-1" android:keyLabel="@string/password_keyboard_label_alt_key"
                 android:keyWidth="15%p" android:isModifier="true"
                 android:isSticky="true" android:keyEdgeFlags="left"/>
-        <Key android:codes="33" android:keyLabel="!"/>
-        <Key android:codes="34" android:keyLabel="&quot;"/>
-        <Key android:codes="39" android:keyLabel="\'"/>
-        <Key android:codes="58" android:keyLabel=":"/>
-        <Key android:codes="59" android:keyLabel=";"/>
-        <Key android:codes="47" android:keyLabel="/" />
-        <Key android:codes="63" android:keyLabel="\?"/>
+        <Key android:keyLabel="!"/>
+        <Key android:keyLabel="&quot;"/>
+        <Key android:keyLabel="\'"/>
+        <Key android:keyLabel=":"/>
+        <Key android:keyLabel=";"/>
+        <Key android:keyLabel="/" />
+        <Key android:keyLabel="\?"/>
         <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
             android:keyWidth="15%p" android:keyEdgeFlags="right"
             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
@@ -80,8 +80,7 @@
         <Key android:keyLabel="," android:keyWidth="10%p"/>
         <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
             android:keyWidth="40%p"
-            android:iconPreview="@drawable/sym_keyboard_feedback_space"
-            android:isRepeatable="true"/>
+            android:iconPreview="@drawable/sym_keyboard_feedback_space"/>
         <Key android:keyLabel="." android:keyWidth="10%p" />
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
             android:keyWidth="20%p" android:keyEdgeFlags="right"
diff --git a/core/res/res/xml/password_kbd_symbols_shift.xml b/core/res/res/xml/password_kbd_symbols_shift.xml
index 97ec3c5f..4b84f4b 100755
--- a/core/res/res/xml/password_kbd_symbols_shift.xml
+++ b/core/res/res/xml/password_kbd_symbols_shift.xml
@@ -76,8 +76,7 @@
         <Key android:keyLabel="„" android:keyWidth="10%p" />
         <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
             android:keyWidth="40%p"
-            android:iconPreview="@drawable/sym_keyboard_feedback_space"
-            android:isRepeatable="true"/>
+            android:iconPreview="@drawable/sym_keyboard_feedback_space"/>
         <Key android:keyLabel="…" android:keyWidth="10%p" />
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
             android:keyWidth="20%p" android:keyEdgeFlags="right"
diff --git a/keystore/tests/src/android/security/SystemKeyStoreTest.java b/keystore/tests/src/android/security/SystemKeyStoreTest.java
index a9e2687..a4d744b 100644
--- a/keystore/tests/src/android/security/SystemKeyStoreTest.java
+++ b/keystore/tests/src/android/security/SystemKeyStoreTest.java
@@ -60,7 +60,7 @@
 
     public void testBasicAccess() throws Exception {
         try {
-            byte[] newKey = mSysKeyStore.generateNewKey(128, "Blowfish", keyName);
+            byte[] newKey = mSysKeyStore.generateNewKey(128, "AES", keyName);
             assertNotNull(newKey);
             byte[] recKey = mSysKeyStore.retrieveKey(keyName);
             assertEquals(newKey.length, recKey.length);
@@ -75,8 +75,9 @@
             assertNotNull(newKeyStr);
             String recKeyStr = mSysKeyStore.retrieveKeyHexString(keyName2);
             assertEquals(newKeyStr, recKeyStr);
+
             mSysKeyStore.deleteKey(keyName2);
-            String nullKey2 = mSysKeyStore.retrieveKeyHexString(keyName);
+            String nullKey2 = mSysKeyStore.retrieveKeyHexString(keyName2);
             assertNull(nullKey2);
         } catch (Exception e) {
             fail();
diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
index dec5587..888b5cd 100644
--- a/libs/rs/java/ImageProcessing/res/raw/threshold.rs
+++ b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
@@ -5,40 +5,34 @@
     char a;
 };
 
-void filter(struct color_s *in, struct color_s *out, struct vec3_s *luminanceVector) {
-    struct vec3_s pixel;
-    pixel.x = (in->r & 0xFF) / 255.0f;
-    pixel.y = (in->g & 0xFF) / 255.0f;
-    pixel.z = (in->b & 0xFF) / 255.0f;
-
-    float luminance = vec3Dot(luminanceVector, &pixel);
-    luminance = maxf(0.0f, luminance - Params->threshold);
-    vec3Scale(&pixel, signf(luminance));
-
-    out->a = in->a;
-    out->r = pixel.x * 255.0f;
-    out->g = pixel.y * 255.0f;
-    out->b = pixel.z * 255.0f;
-}
-
 void main() {
+    int t = uptimeMillis();
+
     struct color_s *in = (struct color_s *) InPixel;
     struct color_s *out = (struct color_s *) OutPixel;
-    
-    struct vec3_s luminanceVector;
-    luminanceVector.x = 0.2125f;
-    luminanceVector.y = 0.7154f;
-    luminanceVector.z = 0.0721f;
 
     int count = Params->inWidth * Params->inHeight;
     int i;
+    float threshold = (Params->threshold * 255.f);
+
+    //testFnc(count, threshold, in, out);
 
     for (i = 0; i < count; i++) {
-        filter(in, out, &luminanceVector);
+        float luminance = 0.2125f * in->r +
+                          0.7154f * in->g +
+                          0.0721f * in->b;
+        if (luminance > threshold) {
+            *out = *in;
+        } else {
+            *((int *)out) = *((int *)in) & 0xff000000;
+        }
 
         in++;
         out++;
     }
 
+    t= uptimeMillis() - t;
+    debugI32("Filter time", t);
+
     sendToClient(&count, 1, 4, 0);
 }
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 568d3ab..9ce53d8 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -31,11 +31,13 @@
 import android.view.SurfaceHolder;
 import android.widget.ImageView;
 import android.widget.SeekBar;
+import java.lang.Math;
 
 public class ImageProcessingActivity extends Activity implements SurfaceHolder.Callback {
     private Bitmap mBitmap;
     private Params mParams;
     private Script.Invokable mInvokable;
+    private int[] mInData;
     private int[] mOutData;
 
     @SuppressWarnings({"FieldCanBeLocal"})
@@ -87,6 +89,31 @@
         }
     }
 
+    private void javaFilter() {
+        long t = java.lang.System.currentTimeMillis();
+        int count = mParams.inWidth * mParams.inHeight;
+        float threshold = mParams.threshold * 255.f;
+
+        for (int i = 0; i < count; i++) {
+            final float r = (float)((mInData[i] >> 0) & 0xff);
+            final float g = (float)((mInData[i] >> 8) & 0xff);
+            final float b = (float)((mInData[i] >> 16) & 0xff);
+
+            final float luminance = 0.2125f * r +
+                              0.7154f * g +
+                              0.0721f * b;
+            if (luminance > threshold) {
+                mOutData[i] = mInData[i];
+            } else {
+                mOutData[i] = mInData[i] & 0xff000000;
+            }
+        }
+
+        t = java.lang.System.currentTimeMillis() - t;
+
+        android.util.Log.v("Img", "frame time ms " + t);
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -106,7 +133,15 @@
                 if (fromUser) {
                     mParams.threshold = progress / 100.0f;
                     mParamsAllocation.data(mParams);
-                    mInvokable.execute();
+
+                    if (true) {
+                        mInvokable.execute();
+                    } else {
+                        javaFilter();
+                        mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0,
+                                mParams.outWidth, mParams.outHeight);
+                        mDisplayView.invalidate();
+                    }
                 }
             }
 
@@ -149,9 +184,9 @@
                 Element.createUser(mRS, Element.DataType.SIGNED_32),
                 pixelCount);
 
-        final int[] data = new int[pixelCount];
-        mBitmap.getPixels(data, 0, mParams.inWidth, 0, 0, mParams.inWidth, mParams.inHeight);
-        mInPixelsAllocation.data(data);
+        mInData = new int[pixelCount];
+        mBitmap.getPixels(mInData, 0, mParams.inWidth, 0, 0, mParams.inWidth, mParams.inHeight);
+        mInPixelsAllocation.data(mInData);
 
         mOutData = new int[pixelCount];
         mOutPixelsAllocation.data(mOutData);
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 225d4b6..30d95e3 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -46,41 +46,32 @@
     private static final String TAG = "ThumbnailUtils";
 
     /* Maximum pixels size for created bitmap. */
-    private static final int THUMBNAIL_MAX_NUM_PIXELS = 512 * 384;
-    private static final int MINI_THUMB_MAX_NUM_PIXELS = 128 * 128;
+    private static final int MAX_NUM_PIXELS_THUMBNAIL = 512 * 384;
+    private static final int MAX_NUM_PIXELS_MICRO_THUMBNAIL = 128 * 128;
     private static final int UNCONSTRAINED = -1;
 
-    /* Whether we should rotate the resulting bitmap. */
-    private static final boolean ROTATE_AS_NEEDED = true;
-    private static final boolean NO_ROTATE = false;
-
-    /* Whether we should create bitmap in native memory. */
-    private static final boolean USE_NATIVE = true;
-    private static final boolean NO_NATIVE = false;
+    /* Options used internally. */
+    private static final int OPTIONS_NONE = 0x0;
+    private static final int OPTIONS_DO_NOT_USE_NATIVE = 0x1;
+    private static final int OPTIONS_SCALE_UP = 0x2;
 
     /**
      * Constant used to indicate we should recycle the input in
-     * {@link #extractMiniThumb(Bitmap, int, int, boolean)} unless the output is the input.
+     * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input.
      */
-    public static final boolean RECYCLE_INPUT = true;
-
-    /**
-     * Constant used to indicate we should not recycle the input in
-     * {@link #extractMiniThumb(Bitmap, int, int, boolean)}.
-     */
-    public static final boolean NO_RECYCLE_INPUT = false;
+    public static final int OPTIONS_RECYCLE_INPUT = 0x4;
 
     /**
      * Constant used to indicate the dimension of normal thumbnail in
-     * {@link #extractMiniThumb(Bitmap, int, int, boolean)}.
+     * {@link #extractThumbnail(Bitmap, int, int, int)}.
      */
-    public static final int THUMBNAIL_TARGET_SIZE = 320;
+    public static final int TARGET_SIZE_NORMAL_THUMBNAIL = 320;
 
     /**
-     * Constant used to indicate the dimension of mini thumbnail in
-     * {@link #extractMiniThumb(Bitmap, int, int, boolean)}.
+     * Constant used to indicate the dimension of micro thumbnail in
+     * {@link #extractThumbnail(Bitmap, int, int, int)}.
      */
-    public static final int MINI_THUMB_TARGET_SIZE = 96;
+    public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;
 
     /**
      * This method first examines if the thumbnail embedded in EXIF is bigger than our target
@@ -97,14 +88,16 @@
      * @param kind either MINI_KIND or MICRO_KIND
      * @param saveMini Whether to save MINI_KIND thumbnail obtained in this method.
      * @return Bitmap
+     *
+     * @hide This method is only used by media framework and media provider internally.
      */
     public static Bitmap createImageThumbnail(ContentResolver cr, String filePath, Uri uri,
             long origId, int kind, boolean saveMini) {
         boolean wantMini = (kind == Images.Thumbnails.MINI_KIND || saveMini);
         int targetSize = wantMini ?
-                THUMBNAIL_TARGET_SIZE : MINI_THUMB_TARGET_SIZE;
+                TARGET_SIZE_NORMAL_THUMBNAIL : TARGET_SIZE_MICRO_THUMBNAIL;
         int maxPixels = wantMini ?
-                THUMBNAIL_MAX_NUM_PIXELS : MINI_THUMB_MAX_NUM_PIXELS;
+                MAX_NUM_PIXELS_THUMBNAIL : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
         SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
         Bitmap bitmap = null;
         MediaFileType fileType = MediaFile.getFileType(filePath);
@@ -134,16 +127,16 @@
 
         if (kind == Images.Thumbnails.MICRO_KIND) {
             // now we make it a "square thumbnail" for MICRO_KIND thumbnail
-            bitmap = extractMiniThumb(bitmap,
-                    MINI_THUMB_TARGET_SIZE,
-                    MINI_THUMB_TARGET_SIZE, RECYCLE_INPUT);
+            bitmap = extractThumbnail(bitmap,
+                    TARGET_SIZE_MICRO_THUMBNAIL,
+                    TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT);
         }
         return bitmap;
     }
 
     /**
      * Create a video thumbnail for a video. May return null if the video is
-     * corrupt.
+     * corrupt or the format is not supported.
      *
      * @param filePath
      */
@@ -174,10 +167,22 @@
      * @param source original bitmap source
      * @param width targeted width
      * @param height targeted height
-     * @param recycle whether we want to recycle the input
      */
-    public static Bitmap extractMiniThumb(
-            Bitmap source, int width, int height, boolean recycle) {
+    public static Bitmap extractThumbnail(
+            Bitmap source, int width, int height) {
+        return extractThumbnail(source, width, height, OPTIONS_NONE);
+    }
+
+    /**
+     * Creates a centered bitmap of the desired size.
+     *
+     * @param source original bitmap source
+     * @param width targeted width
+     * @param height targeted height
+     * @param options options used during thumbnail extraction
+     */
+    public static Bitmap extractThumbnail(
+            Bitmap source, int width, int height, int options) {
         if (source == null) {
             return null;
         }
@@ -190,8 +195,9 @@
         }
         Matrix matrix = new Matrix();
         matrix.setScale(scale, scale);
-        Bitmap miniThumbnail = transform(matrix, source, width, height, true, recycle);
-        return miniThumbnail;
+        Bitmap thumbnail = transform(matrix, source, width, height,
+                OPTIONS_SCALE_UP | options);
+        return thumbnail;
     }
 
     /*
@@ -272,7 +278,7 @@
     private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
             Uri uri, ContentResolver cr) {
         return makeBitmap(minSideLength, maxNumOfPixels, uri, cr,
-                NO_NATIVE);
+            OPTIONS_DO_NOT_USE_NATIVE);
     }
 
     /**
@@ -281,7 +287,8 @@
      * whether they want the Bitmap be created in native memory.
      */
     private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
-            Uri uri, ContentResolver cr, boolean useNative) {
+            Uri uri, ContentResolver cr, int opt) {
+        boolean useNative = (opt & OPTIONS_DO_NOT_USE_NATIVE) != 0;
         ParcelFileDescriptor input = null;
         try {
             input = cr.openFileDescriptor(uri, "r");
@@ -340,29 +347,6 @@
         return b;
     }
 
-    /**
-     * Rotates the bitmap by the specified degree.
-     * If a new bitmap is created, the original bitmap is recycled.
-     */
-    private static Bitmap rotate(Bitmap b, int degrees) {
-        if (degrees != 0 && b != null) {
-            Matrix m = new Matrix();
-            m.setRotate(degrees,
-                    (float) b.getWidth() / 2, (float) b.getHeight() / 2);
-            try {
-                Bitmap b2 = Bitmap.createBitmap(
-                        b, 0, 0, b.getWidth(), b.getHeight(), m, true);
-                if (b != b2) {
-                    b.recycle();
-                    b = b2;
-                }
-            } catch (OutOfMemoryError ex) {
-                // We have no memory to rotate. Return the original bitmap.
-            }
-        }
-        return b;
-    }
-
     private static void closeSilently(ParcelFileDescriptor c) {
       if (c == null) return;
       try {
@@ -388,8 +372,9 @@
             Bitmap source,
             int targetWidth,
             int targetHeight,
-            boolean scaleUp,
-            boolean recycle) {
+            int options) {
+        boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
+        boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;
 
         int deltaX = source.getWidth() - targetWidth;
         int deltaY = source.getHeight() - targetHeight;
diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp
index bd3596e..bb3717f 100644
--- a/media/libmedia/MediaScannerClient.cpp
+++ b/media/libmedia/MediaScannerClient.cpp
@@ -64,29 +64,27 @@
 
 bool MediaScannerClient::addStringTag(const char* name, const char* value)
 {
-    if (mLocaleEncoding != kEncodingNone) {
-        // don't bother caching strings that are all ASCII.
-        // call handleStringTag directly instead.
-        // check to see if value (which should be utf8) has any non-ASCII characters
-        bool nonAscii = false;
-        const char* chp = value;
-        char ch;
-        while ((ch = *chp++)) {
-            if (ch & 0x80) {
-                nonAscii = true;
-                break;
-            }
+    // don't bother caching strings that are all ASCII.
+    // call handleStringTag directly instead.
+    // check to see if value (which should be utf8) has any non-ASCII characters
+    bool nonAscii = false;
+    const char* chp = value;
+    char ch;
+    while ((ch = *chp++)) {
+        if (ch & 0x80) {
+            nonAscii = true;
+            break;
         }
-
-        if (nonAscii) {
-            // save the strings for later so they can be used for native encoding detection
-            mNames->push_back(name);
-            mValues->push_back(value);
-            return true;
-        }
-        // else fall through
     }
 
+    if (nonAscii) {
+        // save the strings for later so they can be used for native encoding detection
+        mNames->push_back(name);
+        mValues->push_back(value);
+        return true;
+    }
+    // else fall through
+
     // autodetection is not necessary, so no need to cache the values
     // pass directly to the client instead
     return handleStringTag(name, value);
@@ -198,23 +196,29 @@
 
 void MediaScannerClient::endFile()
 {
-    if (mLocaleEncoding != kEncodingNone) {
-        int size = mNames->size();
-        uint32_t encoding = kEncodingAll;
+    int size = mNames->size();
+    uint32_t encoding = kEncodingAll;
 
-        // compute a bit mask containing all possible encodings
-        for (int i = 0; i < mNames->size(); i++)
-            encoding &= possibleEncodings(mValues->getEntry(i));
+    // compute a bit mask containing all possible encodings
+    for (int i = 0; i < mNames->size(); i++)
+        encoding &= possibleEncodings(mValues->getEntry(i));
 
-        // if the locale encoding matches, then assume we have a native encoding.
-        if (encoding & mLocaleEncoding)
-            convertValues(mLocaleEncoding);
+    // If one of the possible encodings matches the locale encoding, use that.
+    // Otherwise, if there is only one possible encoding, use that.
+    if (encoding & mLocaleEncoding)
+        convertValues(mLocaleEncoding);
+    else if ((encoding & (encoding - 1)) == 0)
+        convertValues(encoding);
+    else {
+        // TODO: try harder to disambiguate the encoding, perhaps by looking at
+        // other files by same artist, or even the user's entire collection.
+        // For now, fall through and insert the strings as they are.
+    }
 
-        // finally, push all name/value pairs to the client
-        for (int i = 0; i < mNames->size(); i++) {
-            if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
-                break;
-        }
+    // finally, push all name/value pairs to the client
+    for (int i = 0; i < mNames->size(); i++) {
+        if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
+            break;
     }
     // else addStringTag() has done all the work so we have nothing to do
 
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6383f0c..1a8109c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -185,6 +185,11 @@
             mAudioEncoder == AUDIO_ENCODER_AMR_NB
                 ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB);
 
+    int32_t maxInputSize;
+    CHECK(audioSource->getFormat()->findInt32(
+                kKeyMaxInputSize, &maxInputSize));
+
+    encMeta->setInt32(kKeyMaxInputSize, maxInputSize);
     encMeta->setInt32(kKeyChannelCount, 1);
     encMeta->setInt32(kKeySampleRate, sampleRate);
 
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index caff452..bf4424b 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -173,12 +173,15 @@
                 buffer->range_length(),
                 mFile);
 
-        buffer->release();
-        buffer = NULL;
-
         if (n < (ssize_t)buffer->range_length()) {
+            buffer->release();
+            buffer = NULL;
+
             break;
         }
+
+        buffer->release();
+        buffer = NULL;
     }
 
     Mutex::Autolock autoLock(mLock);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 7951fb7..60cf5a2 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -373,8 +373,11 @@
                     failedToStopSupplicantOrUnloadDriver = true;
                 }
 
-                // We must reset the interface before we unload the driver
-                mWifiStateTracker.resetInterface(false);
+                /**
+                 * Reset connections and disable interface
+                 * before we unload the driver
+                 */
+                mWifiStateTracker.resetConnections(true);
 
                 if (!WifiNative.unloadDriver()) {
                     Log.e(TAG, "Failed to unload Wi-Fi driver.");
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 98ded37..87ed252 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1949,6 +1949,9 @@
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
             }
+            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0) {
+                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
+            }
             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
             }
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index cb615d2..afaed24 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -835,7 +835,7 @@
                     WifiNative.closeSupplicantConnection();
                 }
                 if (died) {
-                    resetInterface(false);
+                    resetConnections(true);
                 }
                 // When supplicant dies, kill the DHCP thread
                 if (mDhcpTarget != null) {
@@ -1074,6 +1074,13 @@
                         DetailedState saveState = getNetworkInfo().getDetailedState();
                         handleDisconnectedState(DetailedState.DISCONNECTED);
                         setDetailedStateInternal(saveState);
+                    } else {
+                        /**
+                         *  stop DHCP to ensure there is a new IP address
+                         *  even if the supplicant transitions without disconnect
+                         *  COMPLETED -> ASSOCIATED -> COMPLETED
+                         */
+                        resetConnections(false);
                     }
                     configureInterface();
                     mLastBssid = result.BSSID;
@@ -1279,12 +1286,11 @@
      * {@code DISCONNECTED} or {@code FAILED}.
      */
     private void handleDisconnectedState(DetailedState newState) {
-        if (LOCAL_LOGD) Log.d(TAG, "Deconfiguring interface and stopping DHCP");
         if (mDisconnectPending) {
             cancelDisconnect();
         }
         mDisconnectExpected = false;
-        resetInterface(true);
+        resetConnections(true);
         setDetailedState(newState);
         sendNetworkStateChangeBroadcast(mLastBssid);
         mWifiInfo.setBSSID(null);
@@ -1294,10 +1300,11 @@
     }
 
     /**
-     * Resets the Wi-Fi interface by clearing any state, resetting any sockets
+     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
      * using the interface, stopping DHCP, and disabling the interface.
      */
-    public void resetInterface(boolean reenable) {
+    public void resetConnections(boolean disableInterface) {
+        if (LOCAL_LOGD) Log.d(TAG, "Reset connections and stopping DHCP");
         mHaveIpAddress = false;
         mObtainingIpAddress = false;
         mWifiInfo.setIpAddress(0);
@@ -1317,9 +1324,14 @@
             Log.e(TAG, "Could not stop DHCP");
         }
 
-        NetworkUtils.disableInterface(mInterfaceName);
-        // we no longer net to start the interface (driver does this for us)
-        // and it led to problems - removed.
+        /**
+         * Interface is re-enabled in the supplicant
+         * when moving out of ASSOCIATING state
+         */
+        if(disableInterface) {
+            if (LOCAL_LOGD) Log.d(TAG, "Disabling interface");
+            NetworkUtils.disableInterface(mInterfaceName);
+        }
     }
 
     /**
@@ -1538,7 +1550,7 @@
     public synchronized boolean restart() {
         if (mRunState == RUN_STATE_STOPPED) {
             mRunState = RUN_STATE_STARTING;
-            resetInterface(true);
+            resetConnections(true);
             return WifiNative.startDriverCommand();
         } else if (mRunState == RUN_STATE_STOPPING) {
             mRunState = RUN_STATE_STARTING;
@@ -1969,7 +1981,7 @@
                         oDns2 != mDhcpInfo.dns2));
 
             if (changed) {
-                resetInterface(true);
+                resetConnections(true);
                 configureInterface();
                 if (mUseStaticIp) {
                     mTarget.sendEmptyMessage(EVENT_CONFIGURATION_CHANGED);