Merge "Fix documentation of requestCode parameter."
diff --git a/Android.mk b/Android.mk
index b919e9f..dab3229 100644
--- a/Android.mk
+++ b/Android.mk
@@ -235,7 +235,7 @@
 			$(framework_res_source_path)/com/android/internal/R.java
 
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit ext okhttp
+LOCAL_JAVA_LIBRARIES := bouncycastle conscrypt core core-junit ext okhttp
 
 LOCAL_MODULE := framework
 LOCAL_MODULE_CLASS := JAVA_LIBRARIES
@@ -400,6 +400,7 @@
 
 framework_docs_LOCAL_JAVA_LIBRARIES := \
 			bouncycastle \
+			conscrypt \
 			core \
 			okhttp \
 			ext \
diff --git a/api/current.txt b/api/current.txt
index e46dbeb..ccd214b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15916,7 +15916,7 @@
     method public static void startMethodTracing(java.lang.String, int);
     method public static void startMethodTracing(java.lang.String, int, int);
     method public static void startNativeTracing();
-    method public static void stopAllocCounting();
+    method public static deprecated void stopAllocCounting();
     method public static void stopMethodTracing();
     method public static void stopNativeTracing();
     method public static long threadCpuTimeNanos();
@@ -30455,7 +30455,7 @@
     ctor public CharConversionException(java.lang.String);
   }
 
-  public abstract interface Closeable {
+  public abstract interface Closeable implements java.lang.AutoCloseable {
     method public abstract void close() throws java.io.IOException;
   }
 
@@ -30625,7 +30625,7 @@
     method public abstract boolean accept(java.io.File);
   }
 
-  public class FileInputStream extends java.io.InputStream implements java.io.Closeable {
+  public class FileInputStream extends java.io.InputStream {
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
@@ -30639,7 +30639,7 @@
     ctor public FileNotFoundException(java.lang.String);
   }
 
-  public class FileOutputStream extends java.io.OutputStream implements java.io.Closeable {
+  public class FileOutputStream extends java.io.OutputStream {
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
@@ -30778,7 +30778,7 @@
     ctor public NotSerializableException(java.lang.String);
   }
 
-  public abstract interface ObjectInput implements java.io.DataInput {
+  public abstract interface ObjectInput implements java.lang.AutoCloseable java.io.DataInput {
     method public abstract int available() throws java.io.IOException;
     method public abstract void close() throws java.io.IOException;
     method public abstract int read() throws java.io.IOException;
@@ -30840,7 +30840,7 @@
     method public abstract void validateObject() throws java.io.InvalidObjectException;
   }
 
-  public abstract interface ObjectOutput implements java.io.DataOutput {
+  public abstract interface ObjectOutput implements java.lang.AutoCloseable java.io.DataOutput {
     method public abstract void close() throws java.io.IOException;
     method public abstract void flush() throws java.io.IOException;
     method public abstract void write(byte[]) throws java.io.IOException;
@@ -31339,6 +31339,7 @@
 
   public class AssertionError extends java.lang.Error {
     ctor public AssertionError();
+    ctor public AssertionError(java.lang.String, java.lang.Throwable);
     ctor public AssertionError(java.lang.Object);
     ctor public AssertionError(boolean);
     ctor public AssertionError(char);
@@ -31348,10 +31349,15 @@
     ctor public AssertionError(double);
   }
 
+  public abstract interface AutoCloseable {
+    method public abstract void close() throws java.lang.Exception;
+  }
+
   public final class Boolean implements java.lang.Comparable java.io.Serializable {
     ctor public Boolean(java.lang.String);
     ctor public Boolean(boolean);
     method public boolean booleanValue();
+    method public static int compare(boolean, boolean);
     method public int compareTo(java.lang.Boolean);
     method public static boolean getBoolean(java.lang.String);
     method public static boolean parseBoolean(java.lang.String);
@@ -31366,6 +31372,7 @@
   public final class Byte extends java.lang.Number implements java.lang.Comparable {
     ctor public Byte(byte);
     ctor public Byte(java.lang.String) throws java.lang.NumberFormatException;
+    method public static int compare(byte, byte);
     method public int compareTo(java.lang.Byte);
     method public static java.lang.Byte decode(java.lang.String) throws java.lang.NumberFormatException;
     method public double doubleValue();
@@ -31403,16 +31410,20 @@
     method public static int codePointBefore(char[], int, int);
     method public static int codePointCount(java.lang.CharSequence, int, int);
     method public static int codePointCount(char[], int, int);
+    method public static int compare(char, char);
     method public int compareTo(java.lang.Character);
     method public static int digit(char, int);
     method public static int digit(int, int);
     method public static char forDigit(int, int);
     method public static byte getDirectionality(char);
     method public static byte getDirectionality(int);
+    method public static java.lang.String getName(int);
     method public static int getNumericValue(char);
     method public static int getNumericValue(int);
     method public static int getType(char);
     method public static int getType(int);
+    method public static char highSurrogate(int);
+    method public static boolean isBmpCodePoint(int);
     method public static boolean isDefined(char);
     method public static boolean isDefined(int);
     method public static boolean isDigit(char);
@@ -31441,6 +31452,7 @@
     method public static boolean isSpaceChar(char);
     method public static boolean isSpaceChar(int);
     method public static boolean isSupplementaryCodePoint(int);
+    method public static boolean isSurrogate(char);
     method public static boolean isSurrogatePair(char, char);
     method public static boolean isTitleCase(char);
     method public static boolean isTitleCase(int);
@@ -31453,6 +31465,7 @@
     method public static boolean isValidCodePoint(int);
     method public static boolean isWhitespace(char);
     method public static boolean isWhitespace(int);
+    method public static char lowSurrogate(int);
     method public static int offsetByCodePoints(java.lang.CharSequence, int, int);
     method public static int offsetByCodePoints(char[], int, int, int, int);
     method public static char reverseBytes(char);
@@ -31981,6 +31994,7 @@
     ctor public Integer(int);
     ctor public Integer(java.lang.String) throws java.lang.NumberFormatException;
     method public static int bitCount(int);
+    method public static int compare(int, int);
     method public int compareTo(java.lang.Integer);
     method public static java.lang.Integer decode(java.lang.String) throws java.lang.NumberFormatException;
     method public double doubleValue();
@@ -32032,12 +32046,14 @@
   public class LinkageError extends java.lang.Error {
     ctor public LinkageError();
     ctor public LinkageError(java.lang.String);
+    ctor public LinkageError(java.lang.String, java.lang.Throwable);
   }
 
   public final class Long extends java.lang.Number implements java.lang.Comparable {
     ctor public Long(long);
     ctor public Long(java.lang.String) throws java.lang.NumberFormatException;
     method public static int bitCount(long);
+    method public static int compare(long, long);
     method public int compareTo(java.lang.Long);
     method public static java.lang.Long decode(java.lang.String) throws java.lang.NumberFormatException;
     method public double doubleValue();
@@ -32294,6 +32310,9 @@
     ctor public RuntimePermission(java.lang.String, java.lang.String);
   }
 
+  public abstract class SafeVarargs implements java.lang.annotation.Annotation {
+  }
+
   public class SecurityException extends java.lang.RuntimeException {
     ctor public SecurityException();
     ctor public SecurityException(java.lang.String);
@@ -32350,6 +32369,7 @@
   public final class Short extends java.lang.Number implements java.lang.Comparable {
     ctor public Short(java.lang.String) throws java.lang.NumberFormatException;
     ctor public Short(short);
+    method public static int compare(short, short);
     method public int compareTo(java.lang.Short);
     method public static java.lang.Short decode(java.lang.String) throws java.lang.NumberFormatException;
     method public double doubleValue();
@@ -32621,6 +32641,7 @@
     method public static java.util.Map<java.lang.String, java.lang.String> getenv();
     method public static int identityHashCode(java.lang.Object);
     method public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
+    method public static java.lang.String lineSeparator();
     method public static void load(java.lang.String);
     method public static void loadLibrary(java.lang.String);
     method public static java.lang.String mapLibraryName(java.lang.String);
@@ -32753,11 +32774,14 @@
     ctor public Throwable(java.lang.String);
     ctor public Throwable(java.lang.String, java.lang.Throwable);
     ctor public Throwable(java.lang.Throwable);
+    ctor protected Throwable(java.lang.String, java.lang.Throwable, boolean, boolean);
+    method public final void addSuppressed(java.lang.Throwable);
     method public java.lang.Throwable fillInStackTrace();
     method public java.lang.Throwable getCause();
     method public java.lang.String getLocalizedMessage();
     method public java.lang.String getMessage();
     method public java.lang.StackTraceElement[] getStackTrace();
+    method public final java.lang.Throwable[] getSuppressed();
     method public java.lang.Throwable initCause(java.lang.Throwable);
     method public void printStackTrace();
     method public void printStackTrace(java.io.PrintStream);
@@ -33052,6 +33076,10 @@
 
   public class Modifier {
     ctor public Modifier();
+    method public static int classModifiers();
+    method public static int constructorModifiers();
+    method public static int fieldModifiers();
+    method public static int interfaceModifiers();
     method public static boolean isAbstract(int);
     method public static boolean isFinal(int);
     method public static boolean isInterface(int);
@@ -33064,6 +33092,7 @@
     method public static boolean isSynchronized(int);
     method public static boolean isTransient(int);
     method public static boolean isVolatile(int);
+    method public static int methodModifiers();
     method public static java.lang.String toString(int);
     field public static final int ABSTRACT = 1024; // 0x400
     field public static final int FINAL = 16; // 0x10
@@ -33403,7 +33432,7 @@
     method public synchronized void setSocketAddress(java.net.SocketAddress);
   }
 
-  public class DatagramSocket {
+  public class DatagramSocket implements java.io.Closeable {
     ctor public DatagramSocket() throws java.net.SocketException;
     ctor public DatagramSocket(int) throws java.net.SocketException;
     ctor public DatagramSocket(int, java.net.InetAddress) throws java.net.SocketException;
@@ -33600,6 +33629,7 @@
     method public java.lang.String getHostAddress();
     method public java.lang.String getHostName();
     method public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException;
+    method public static java.net.InetAddress getLoopbackAddress();
     method public boolean isAnyLocalAddress();
     method public boolean isLinkLocalAddress();
     method public boolean isLoopbackAddress();
@@ -33622,6 +33652,7 @@
     method public final boolean equals(java.lang.Object);
     method public final java.net.InetAddress getAddress();
     method public final java.lang.String getHostName();
+    method public final java.lang.String getHostString();
     method public final int getPort();
     method public final int hashCode();
     method public final boolean isUnresolved();
@@ -33678,10 +33709,12 @@
   }
 
   public final class NetworkInterface {
+    method public static java.net.NetworkInterface getByIndex(int) throws java.net.SocketException;
     method public static java.net.NetworkInterface getByInetAddress(java.net.InetAddress) throws java.net.SocketException;
     method public static java.net.NetworkInterface getByName(java.lang.String) throws java.net.SocketException;
     method public java.lang.String getDisplayName();
     method public byte[] getHardwareAddress() throws java.net.SocketException;
+    method public int getIndex();
     method public java.util.Enumeration<java.net.InetAddress> getInetAddresses();
     method public java.util.List<java.net.InterfaceAddress> getInterfaceAddresses();
     method public int getMTU() throws java.net.SocketException;
@@ -33759,7 +33792,7 @@
     method public abstract java.util.List<java.security.cert.Certificate> getServerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
   }
 
-  public class ServerSocket {
+  public class ServerSocket implements java.io.Closeable {
     ctor public ServerSocket() throws java.io.IOException;
     ctor public ServerSocket(int) throws java.io.IOException;
     ctor public ServerSocket(int, int) throws java.io.IOException;
@@ -33785,7 +33818,7 @@
     method public static synchronized void setSocketFactory(java.net.SocketImplFactory) throws java.io.IOException;
   }
 
-  public class Socket {
+  public class Socket implements java.io.Closeable {
     ctor public Socket();
     ctor public Socket(java.net.Proxy);
     ctor public Socket(java.lang.String, int) throws java.io.IOException, java.net.UnknownHostException;
@@ -34463,9 +34496,10 @@
     field public static final java.nio.channels.FileChannel.MapMode READ_WRITE;
   }
 
-  public abstract class FileLock {
+  public abstract class FileLock implements java.lang.AutoCloseable {
     ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
     method public final java.nio.channels.FileChannel channel();
+    method public final void close() throws java.io.IOException;
     method public final boolean isShared();
     method public abstract boolean isValid();
     method public final boolean overlaps(long, long);
@@ -34580,7 +34614,7 @@
     field public static final int OP_WRITE = 4; // 0x4
   }
 
-  public abstract class Selector {
+  public abstract class Selector implements java.io.Closeable {
     ctor protected Selector();
     method public abstract void close() throws java.io.IOException;
     method public abstract boolean isOpen();
@@ -36516,7 +36550,7 @@
     method public abstract void truncate(long) throws java.sql.SQLException;
   }
 
-  public abstract interface Connection implements java.sql.Wrapper {
+  public abstract interface Connection implements java.lang.AutoCloseable java.sql.Wrapper {
     method public abstract void clearWarnings() throws java.sql.SQLException;
     method public abstract void close() throws java.sql.SQLException;
     method public abstract void commit() throws java.sql.SQLException;
@@ -36945,7 +36979,7 @@
     method public abstract void setObject(java.lang.Object) throws java.sql.SQLException;
   }
 
-  public abstract interface ResultSet implements java.sql.Wrapper {
+  public abstract interface ResultSet implements java.lang.AutoCloseable java.sql.Wrapper {
     method public abstract boolean absolute(int) throws java.sql.SQLException;
     method public abstract void afterLast() throws java.sql.SQLException;
     method public abstract void beforeFirst() throws java.sql.SQLException;
@@ -37451,7 +37485,7 @@
     method public abstract java.lang.String getSavepointName() throws java.sql.SQLException;
   }
 
-  public abstract interface Statement implements java.sql.Wrapper {
+  public abstract interface Statement implements java.lang.AutoCloseable java.sql.Wrapper {
     method public abstract void addBatch(java.lang.String) throws java.sql.SQLException;
     method public abstract void cancel() throws java.sql.SQLException;
     method public abstract void clearBatch() throws java.sql.SQLException;
@@ -38351,11 +38385,19 @@
     method public int nextClearBit(int);
     method public int nextSetBit(int);
     method public void or(java.util.BitSet);
+    method public int previousClearBit(int);
+    method public int previousSetBit(int);
     method public void set(int);
     method public void set(int, boolean);
     method public void set(int, int, boolean);
     method public void set(int, int);
     method public int size();
+    method public byte[] toByteArray();
+    method public long[] toLongArray();
+    method public static java.util.BitSet valueOf(long[]);
+    method public static java.util.BitSet valueOf(java.nio.LongBuffer);
+    method public static java.util.BitSet valueOf(byte[]);
+    method public static java.util.BitSet valueOf(java.nio.ByteBuffer);
     method public void xor(java.util.BitSet);
   }
 
@@ -38488,7 +38530,10 @@
     method public static java.util.SortedSet<E> checkedSortedSet(java.util.SortedSet<E>, java.lang.Class<E>);
     method public static void copy(java.util.List<? super T>, java.util.List<? extends T>);
     method public static boolean disjoint(java.util.Collection<?>, java.util.Collection<?>);
+    method public static java.util.Enumeration<T> emptyEnumeration();
+    method public static java.util.Iterator<T> emptyIterator();
     method public static final java.util.List<T> emptyList();
+    method public static java.util.ListIterator<T> emptyListIterator();
     method public static final java.util.Map<K, V> emptyMap();
     method public static final java.util.Set<T> emptySet();
     method public static java.util.Enumeration<T> enumeration(java.util.Collection<T>);
@@ -38541,11 +38586,16 @@
   public class ConcurrentModificationException extends java.lang.RuntimeException {
     ctor public ConcurrentModificationException();
     ctor public ConcurrentModificationException(java.lang.String);
+    ctor public ConcurrentModificationException(java.lang.String, java.lang.Throwable);
+    ctor public ConcurrentModificationException(java.lang.Throwable);
   }
 
   public final class Currency implements java.io.Serializable {
+    method public static java.util.Set<java.util.Currency> getAvailableCurrencies();
     method public java.lang.String getCurrencyCode();
     method public int getDefaultFractionDigits();
+    method public java.lang.String getDisplayName();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public static java.util.Currency getInstance(java.lang.String);
     method public static java.util.Currency getInstance(java.util.Locale);
     method public java.lang.String getSymbol();
@@ -39210,7 +39260,7 @@
     field public static final long TTL_NO_EXPIRATION_CONTROL = -2L; // 0xfffffffffffffffeL
   }
 
-  public final class Scanner implements java.util.Iterator {
+  public final class Scanner implements java.io.Closeable java.util.Iterator {
     ctor public Scanner(java.io.File) throws java.io.FileNotFoundException;
     ctor public Scanner(java.io.File, java.lang.String) throws java.io.FileNotFoundException;
     ctor public Scanner(java.lang.String);
@@ -40852,6 +40902,7 @@
     method public static java.util.logging.Logger getAnonymousLogger();
     method public static java.util.logging.Logger getAnonymousLogger(java.lang.String);
     method public java.util.logging.Filter getFilter();
+    method public static java.util.logging.Logger getGlobal();
     method public java.util.logging.Handler[] getHandlers();
     method public java.util.logging.Level getLevel();
     method public static java.util.logging.Logger getLogger(java.lang.String);
@@ -41198,6 +41249,7 @@
     ctor public Deflater(int, boolean);
     method public int deflate(byte[]);
     method public synchronized int deflate(byte[], int, int);
+    method public synchronized int deflate(byte[], int, int, int);
     method public synchronized void end();
     method public synchronized void finish();
     method public synchronized boolean finished();
@@ -41220,8 +41272,11 @@
     field public static final int DEFAULT_STRATEGY = 0; // 0x0
     field public static final int DEFLATED = 8; // 0x8
     field public static final int FILTERED = 1; // 0x1
+    field public static final int FULL_FLUSH = 3; // 0x3
     field public static final int HUFFMAN_ONLY = 2; // 0x2
     field public static final int NO_COMPRESSION = 0; // 0x0
+    field public static final int NO_FLUSH = 0; // 0x0
+    field public static final int SYNC_FLUSH = 2; // 0x2
   }
 
   public class DeflaterInputStream extends java.io.FilterInputStream {
@@ -41233,9 +41288,12 @@
   }
 
   public class DeflaterOutputStream extends java.io.FilterOutputStream {
-    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater);
     ctor public DeflaterOutputStream(java.io.OutputStream);
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater);
     ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, int);
+    ctor public DeflaterOutputStream(java.io.OutputStream, boolean);
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, boolean);
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, int, boolean);
     method protected void deflate() throws java.io.IOException;
     method public void finish() throws java.io.IOException;
     field protected byte[] buf;
@@ -41330,7 +41388,7 @@
     ctor public ZipException(java.lang.String);
   }
 
-  public class ZipFile {
+  public class ZipFile implements java.io.Closeable {
     ctor public ZipFile(java.io.File) throws java.io.IOException, java.util.zip.ZipException;
     ctor public ZipFile(java.lang.String) throws java.io.IOException;
     ctor public ZipFile(java.io.File, int) throws java.io.IOException;
@@ -41366,6 +41424,11 @@
 
 package javax.crypto {
 
+  public class AEADBadTagException extends javax.crypto.BadPaddingException {
+    ctor public AEADBadTagException();
+    ctor public AEADBadTagException(java.lang.String);
+  }
+
   public class BadPaddingException extends java.security.GeneralSecurityException {
     ctor public BadPaddingException(java.lang.String);
     ctor public BadPaddingException();
@@ -41406,6 +41469,9 @@
     method public final int update(byte[], int, int, byte[]) throws javax.crypto.ShortBufferException;
     method public final int update(byte[], int, int, byte[], int) throws javax.crypto.ShortBufferException;
     method public final int update(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.ShortBufferException;
+    method public final void updateAAD(byte[]);
+    method public final void updateAAD(byte[], int, int);
+    method public final void updateAAD(java.nio.ByteBuffer);
     method public final byte[] wrap(java.security.Key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException;
     field public static final int DECRYPT_MODE = 2; // 0x2
     field public static final int ENCRYPT_MODE = 1; // 0x1
@@ -41445,6 +41511,8 @@
     method protected abstract byte[] engineUpdate(byte[], int, int);
     method protected abstract int engineUpdate(byte[], int, int, byte[], int) throws javax.crypto.ShortBufferException;
     method protected int engineUpdate(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.ShortBufferException;
+    method protected void engineUpdateAAD(byte[], int, int);
+    method protected void engineUpdateAAD(java.nio.ByteBuffer);
     method protected byte[] engineWrap(java.security.Key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException;
   }
 
@@ -41703,6 +41771,13 @@
     method public java.math.BigInteger getY();
   }
 
+  public class GCMParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public GCMParameterSpec(int, byte[]);
+    ctor public GCMParameterSpec(int, byte[], int, int);
+    method public byte[] getIV();
+    method public int getTLen();
+  }
+
   public class IvParameterSpec implements java.security.spec.AlgorithmParameterSpec {
     ctor public IvParameterSpec(byte[]);
     ctor public IvParameterSpec(byte[], int, int);
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 0668be6..6f37180 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -7,6 +7,7 @@
 
 #define LOG_TAG "appproc"
 
+#include <cutils/properties.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <utils/Log.h>
@@ -144,7 +145,10 @@
      * This breaks some programs which improperly embed
      * an out of date copy of Android's linker.
      */
-    if (getenv("NO_ADDR_COMPAT_LAYOUT_FIXUP") == NULL) {
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.kernel.qemu", value, "");
+    bool is_qemu = (strcmp(value, "1") == 0);
+    if ((getenv("NO_ADDR_COMPAT_LAYOUT_FIXUP") == NULL) && !is_qemu) {
         int current = personality(0xFFFFFFFF);
         if ((current & ADDR_COMPAT_LAYOUT) == 0) {
             personality(current | ADDR_COMPAT_LAYOUT);
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index a21df0d..6dc9f3d5 100644
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -56,12 +56,14 @@
                     return;
                 }
             } else if (command.equals("keyevent")) {
-                if (args.length == 2) {
-                    int keyCode = KeyEvent.keyCodeFromString(args[1]);
-                    if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
-                        keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[1]);
+                if (args.length >= 2) {
+                    for (int i=1; i < args.length; i++) {
+                        int keyCode = KeyEvent.keyCodeFromString(args[i]);
+                        if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
+                            keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
+                        }
+                        sendKeyEvent(keyCode);
                     }
-                    sendKeyEvent(keyCode);
                     return;
                 }
             } else if (command.equals("tap")) {
@@ -223,7 +225,7 @@
                 DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,
                 DEFAULT_EDGE_FLAGS);
         event.setSource(inputSource);
-        Log.i("Input", "injectMotionEvent: " + event);
+        Log.i(TAG, "injectMotionEvent: " + event);
         InputManager.getInstance().injectInputEvent(event,
                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
@@ -235,7 +237,7 @@
     private void showUsage() {
         System.err.println("usage: input ...");
         System.err.println("       input text <string>");
-        System.err.println("       input keyevent <key code number or name>");
+        System.err.println("       input keyevent <key code number or name> ...");
         System.err.println("       input [touchscreen|touchpad] tap <x> <y>");
         System.err.println("       input [touchscreen|touchpad] swipe <x1> <y1> <x2> <y2>");
         System.err.println("       input trackball press");
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 22fd9a9..8281e30 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -92,8 +92,7 @@
 import com.android.internal.os.RuntimeInit;
 import com.android.internal.os.SamplingProfilerIntegration;
 import com.android.internal.util.Objects;
-
-import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
+import com.android.org.conscrypt.OpenSSLSocketImpl;
 
 import java.io.File;
 import java.io.FileDescriptor;
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 0017c46a..747f162 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -30,9 +30,9 @@
 import android.util.LruCache;
 import android.util.Printer;
 
-import java.sql.Date;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.Map;
 import java.util.regex.Pattern;
 
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 6f1cc94..d6b90c3 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -424,7 +424,7 @@
                 showWindow(true);
             }
             // If user uses hard keyboard, IME button should always be shown.
-            boolean showing = onEvaluateInputViewShown();
+            boolean showing = isInputViewShown();
             mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
                     mBackDisposition);
             if (resultReceiver != null) {
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 37601fc..d587e68 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -178,6 +178,7 @@
                 mLinkProperties = dhcpInfoInternal.makeLinkProperties();
                 mLinkProperties.setInterfaceName(mIface);
 
+                mNetworkInfo.setIsAvailable(true);
                 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
                 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
                 msg.sendToTarget();
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 2a2f7cf..37f04d3 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -18,6 +18,9 @@
 
 import android.os.SystemProperties;
 import android.util.Log;
+import com.android.org.conscrypt.OpenSSLContextImpl;
+import com.android.org.conscrypt.OpenSSLSocketImpl;
+import com.android.org.conscrypt.SSLClientSessionCache;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
@@ -36,9 +39,6 @@
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 
 /**
  * SSLSocketFactory implementation with several extra features:
diff --git a/core/java/android/net/SSLSessionCache.java b/core/java/android/net/SSLSessionCache.java
index 4cbeb94..15421de 100644
--- a/core/java/android/net/SSLSessionCache.java
+++ b/core/java/android/net/SSLSessionCache.java
@@ -16,12 +16,12 @@
 
 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 com.android.org.conscrypt.FileClientSessionCache;
+import com.android.org.conscrypt.SSLClientSessionCache;
+
 import java.io.File;
 import java.io.IOException;
 
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index f66075d..3652a4c 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -16,21 +16,22 @@
 
 package android.net.http;
 
+import com.android.org.conscrypt.SSLParametersImpl;
+import com.android.org.conscrypt.TrustManagerImpl;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.security.KeyManagementException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import javax.net.ssl.DefaultHostnameVerifier;
 import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.X509TrustManager;
-import org.apache.harmony.security.provider.cert.X509CertImpl;
-import org.apache.harmony.xnet.provider.jsse.SSLParametersImpl;
-import org.apache.harmony.xnet.provider.jsse.TrustManagerImpl;
 
 /**
  * Class responsible for all server certificate validation functionality
@@ -118,8 +119,14 @@
 
         X509Certificate[] serverCertificates = new X509Certificate[certChain.length];
 
-        for (int i = 0; i < certChain.length; ++i) {
-            serverCertificates[i] = new X509CertImpl(certChain[i]);
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            for (int i = 0; i < certChain.length; ++i) {
+                serverCertificates[i] = (X509Certificate) cf.generateCertificate(
+                        new ByteArrayInputStream(certChain[i]));
+            }
+        } catch (CertificateException e) {
+            throw new IOException("can't read certificate", e);
         }
 
         return verifyServerDomainAndCertificates(serverCertificates, domain, authType);
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 84765a5..f421d29 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -18,9 +18,9 @@
 
 import android.content.Context;
 import android.util.Log;
-import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
+import com.android.org.conscrypt.FileClientSessionCache;
+import com.android.org.conscrypt.OpenSSLContextImpl;
+import com.android.org.conscrypt.SSLClientSessionCache;
 import org.apache.http.Header;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index 64eacbc..cfe5f27 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -16,7 +16,7 @@
 
 package android.net.http;
 
-import org.apache.harmony.xnet.provider.jsse.TrustManagerImpl;
+import com.android.org.conscrypt.TrustManagerImpl;
 
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 2e77237..fd01da9 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -577,6 +577,7 @@
      *
      * @see #startAllocCounting()
      */
+    @Deprecated
     public static void stopAllocCounting() {
         VMDebug.stopAllocCounting();
     }
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
index e1cc90e..3d75dc8 100644
--- a/core/java/android/security/IKeystoreService.java
+++ b/core/java/android/security/IKeystoreService.java
@@ -78,7 +78,7 @@
                 return _result;
             }
 
-            public int insert(String name, byte[] item, int uid) throws RemoteException {
+            public int insert(String name, byte[] item, int uid, int flags) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
@@ -87,6 +87,7 @@
                     _data.writeString(name);
                     _data.writeByteArray(item);
                     _data.writeInt(uid);
+                    _data.writeInt(flags);
                     mRemote.transact(Stub.TRANSACTION_insert, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.readInt();
@@ -243,7 +244,7 @@
                 return _result;
             }
 
-            public int generate(String name, int uid) throws RemoteException {
+            public int generate(String name, int uid, int flags) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
@@ -251,6 +252,7 @@
                     _data.writeInterfaceToken(DESCRIPTOR);
                     _data.writeString(name);
                     _data.writeInt(uid);
+                    _data.writeInt(flags);
                     mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.readInt();
@@ -261,7 +263,8 @@
                 return _result;
             }
 
-            public int import_key(String name, byte[] data, int uid) throws RemoteException {
+            public int import_key(String name, byte[] data, int uid, int flags)
+                    throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
@@ -270,6 +273,7 @@
                     _data.writeString(name);
                     _data.writeByteArray(data);
                     _data.writeInt(uid);
+                    _data.writeInt(flags);
                     mRemote.transact(Stub.TRANSACTION_import, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.readInt();
@@ -538,7 +542,7 @@
 
     public byte[] get(String name) throws RemoteException;
 
-    public int insert(String name, byte[] item, int uid) throws RemoteException;
+    public int insert(String name, byte[] item, int uid, int flags) throws RemoteException;
 
     public int del(String name, int uid) throws RemoteException;
 
@@ -556,9 +560,9 @@
 
     public int zero() throws RemoteException;
 
-    public int generate(String name, int uid) throws RemoteException;
+    public int generate(String name, int uid, int flags) throws RemoteException;
 
-    public int import_key(String name, byte[] data, int uid) throws RemoteException;
+    public int import_key(String name, byte[] data, int uid, int flags) throws RemoteException;
 
     public byte[] sign(String name, byte[] data) throws RemoteException;
 
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 50b1a29..ff5106a 100644
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -31,6 +31,7 @@
 import java.util.TimeZone;
 import java.text.SimpleDateFormat;
 
+import libcore.icu.ICU;
 import libcore.icu.LocaleData;
 
 /**
@@ -278,39 +279,13 @@
      * Gets the current date format stored as a char array. The array will contain
      * 3 elements ({@link #DATE}, {@link #MONTH}, and {@link #YEAR}) in the order
      * specified by the user's format preference.  Note that this order is
-     * only appropriate for all-numeric dates; spelled-out (MEDIUM and LONG)
+     * <i>only</i> appropriate for all-numeric dates; spelled-out (MEDIUM and LONG)
      * dates will generally contain other punctuation, spaces, or words,
      * not just the day, month, and year, and not necessarily in the same
      * order returned here.
      */
     public static char[] getDateFormatOrder(Context context) {
-        char[] order = new char[] {DATE, MONTH, YEAR};
-        String value = getDateFormatString(context);
-        int index = 0;
-        boolean foundDate = false;
-        boolean foundMonth = false;
-        boolean foundYear = false;
-
-        for (char c : value.toCharArray()) {
-            if (!foundDate && (c == DATE)) {
-                foundDate = true;
-                order[index] = DATE;
-                index++;
-            }
-
-            if (!foundMonth && (c == MONTH || c == STANDALONE_MONTH)) {
-                foundMonth = true;
-                order[index] = MONTH;
-                index++;
-            }
-
-            if (!foundYear && (c == YEAR)) {
-                foundYear = true;
-                order[index] = YEAR;
-                index++;
-            }
-        }
-        return order;
+        return ICU.getDateFormatOrder(getDateFormatString(context));
     }
 
     private static String getDateFormatString(Context context) {
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 5a4f322..33964a0 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -235,7 +235,7 @@
      * during the lifetime of an activity.
      */
     public static String getTimeZoneDatabaseVersion() {
-        return ZoneInfoDB.getVersion();
+        return ZoneInfoDB.getInstance().getVersion();
     }
 
     /** @hide Field length that can hold 999 days of time */
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index c2a3e58..4649a8b 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -628,8 +628,8 @@
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
-    //  native/include/android/keycodes.h
-    //  frameworks/base/include/ui/KeycodeLabels.h
+    //  frameworks/native/include/android/keycodes.h
+    //  frameworks/base/include/androidfw/KeycodeLabels.h
     //  external/webkit/WebKit/android/plugins/ANPKeyCodes.h
     //  frameworks/base/core/res/res/values/attrs.xml
     //  emulator?
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0d2141f..75b8e97 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10525,8 +10525,9 @@
      * handler can be used to pump events in the UI events queue.
      */
     public Handler getHandler() {
-        if (mAttachInfo != null) {
-            return mAttachInfo.mHandler;
+        final AttachInfo attachInfo = mAttachInfo;
+        if (attachInfo != null) {
+            return attachInfo.mHandler;
         }
         return null;
     }
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 023dfa8..7fe81dd 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -40,13 +40,13 @@
 
 import junit.framework.Assert;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
 import java.net.URLEncoder;
-import java.nio.charset.Charsets;
 import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -55,9 +55,8 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.harmony.security.provider.cert.X509CertImpl;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLKey;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder;
+import com.android.org.conscrypt.OpenSSLKey;
+import com.android.org.conscrypt.OpenSSLKeyHolder;
 
 class BrowserFrame extends Handler {
 
@@ -1079,10 +1078,12 @@
             String url) {
         final SslError sslError;
         try {
-            X509Certificate cert = new X509CertImpl(certDER);
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            X509Certificate cert = (X509Certificate) cf.generateCertificate(
+                    new ByteArrayInputStream(certDER));
             SslCertificate sslCert = new SslCertificate(cert);
             sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert, url);
-        } catch (IOException e) {
+        } catch (Exception e) {
             // Can't get the certificate, not much to do.
             Log.e(LOGTAG, "Can't get the certificate from WebKit, canceling");
             nativeSslCertErrorCancel(handle, certError);
@@ -1200,9 +1201,11 @@
      */
     private void setCertificate(byte cert_der[]) {
         try {
-            X509Certificate cert = new X509CertImpl(cert_der);
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            X509Certificate cert = (X509Certificate) cf.generateCertificate(
+                    new ByteArrayInputStream(cert_der));
             mCallbackProxy.onReceivedCertificate(new SslCertificate(cert));
-        } catch (IOException e) {
+        } catch (Exception e) {
             // Can't get the certificate, not much to do.
             Log.e(LOGTAG, "Can't get the certificate from WebKit, canceling");
             return;
diff --git a/core/java/android/webkit/ClientCertRequestHandler.java b/core/java/android/webkit/ClientCertRequestHandler.java
index f5a60f6..d7a6806 100644
--- a/core/java/android/webkit/ClientCertRequestHandler.java
+++ b/core/java/android/webkit/ClientCertRequestHandler.java
@@ -20,9 +20,9 @@
 import java.security.PrivateKey;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
-import org.apache.harmony.xnet.provider.jsse.NativeCrypto;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLKey;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder;
+import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.OpenSSLKey;
+import com.android.org.conscrypt.OpenSSLKeyHolder;
 
 /**
  * ClientCertRequestHandler: class responsible for handling client
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 07d3a7a..fdf8e78 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -23,6 +23,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.text.InputType;
 import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
@@ -38,6 +39,7 @@
 
 import com.android.internal.R;
 
+import java.text.DateFormatSymbols;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
@@ -45,6 +47,8 @@
 import java.util.Locale;
 import java.util.TimeZone;
 
+import libcore.icu.ICU;
+
 /**
  * This class is a widget for selecting a date. The date can be selected by a
  * year, month, and day spinners or a {@link CalendarView}. The set of spinners
@@ -477,14 +481,27 @@
         mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
 
         mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
-        mShortMonths = new String[mNumberOfMonths];
-        for (int i = 0; i < mNumberOfMonths; i++) {
-            mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
-                    DateUtils.LENGTH_MEDIUM);
+        mShortMonths = new DateFormatSymbols().getShortMonths();
+
+        if (usingNumericMonths()) {
+            // We're in a locale where a date should either be all-numeric, or all-text.
+            // All-text would require custom NumberPicker formatters for day and year.
+            mShortMonths = new String[mNumberOfMonths];
+            for (int i = 0; i < mNumberOfMonths; ++i) {
+                mShortMonths[i] = String.format("%d", i + 1);
+            }
         }
     }
 
     /**
+     * Tests whether the current locale is one where there are no real month names,
+     * such as Chinese, Japanese, or Korean locales.
+     */
+    private boolean usingNumericMonths() {
+        return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
+    }
+
+    /**
      * Gets a calendar for locale bootstrapped with the value of a given calendar.
      *
      * @param oldCalendar The old calendar.
@@ -508,24 +525,27 @@
      */
     private void reorderSpinners() {
         mSpinners.removeAllViews();
-        char[] order = DateFormat.getDateFormatOrder(getContext());
+        // We use numeric spinners for year and day, but textual months. Ask icu4c what
+        // order the user's locale uses for that combination. http://b/7207103.
+        String pattern = ICU.getBestDateTimePattern("yyyyMMMdd", Locale.getDefault().toString());
+        char[] order = ICU.getDateFormatOrder(pattern);
         final int spinnerCount = order.length;
         for (int i = 0; i < spinnerCount; i++) {
             switch (order[i]) {
-                case DateFormat.DATE:
+                case 'd':
                     mSpinners.addView(mDaySpinner);
                     setImeOptions(mDaySpinner, spinnerCount, i);
                     break;
-                case DateFormat.MONTH:
+                case 'M':
                     mSpinners.addView(mMonthSpinner);
                     setImeOptions(mMonthSpinner, spinnerCount, i);
                     break;
-                case DateFormat.YEAR:
+                case 'y':
                     mSpinners.addView(mYearSpinner);
                     setImeOptions(mYearSpinner, spinnerCount, i);
                     break;
                 default:
-                    throw new IllegalArgumentException();
+                    throw new IllegalArgumentException(Arrays.toString(order));
             }
         }
     }
@@ -660,6 +680,10 @@
         mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
         mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
         mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+
+        if (usingNumericMonths()) {
+            mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+        }
     }
 
     /**
diff --git a/core/java/android/widget/HeaderViewListAdapter.java b/core/java/android/widget/HeaderViewListAdapter.java
index 0685e61..222f108 100644
--- a/core/java/android/widget/HeaderViewListAdapter.java
+++ b/core/java/android/widget/HeaderViewListAdapter.java
@@ -145,7 +145,7 @@
     }
 
     public boolean isEnabled(int position) {
-        // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
+        // Header (negative positions will throw an IndexOutOfBoundsException)
         int numHeaders = getHeadersCount();
         if (position < numHeaders) {
             return mHeaderViewInfos.get(position).isSelectable;
@@ -161,12 +161,12 @@
             }
         }
 
-        // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
+        // Footer (off-limits positions will throw an IndexOutOfBoundsException)
         return mFooterViewInfos.get(adjPosition - adapterCount).isSelectable;
     }
 
     public Object getItem(int position) {
-        // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
+        // Header (negative positions will throw an IndexOutOfBoundsException)
         int numHeaders = getHeadersCount();
         if (position < numHeaders) {
             return mHeaderViewInfos.get(position).data;
@@ -182,7 +182,7 @@
             }
         }
 
-        // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
+        // Footer (off-limits positions will throw an IndexOutOfBoundsException)
         return mFooterViewInfos.get(adjPosition - adapterCount).data;
     }
 
@@ -206,7 +206,7 @@
     }
 
     public View getView(int position, View convertView, ViewGroup parent) {
-        // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
+        // Header (negative positions will throw an IndexOutOfBoundsException)
         int numHeaders = getHeadersCount();
         if (position < numHeaders) {
             return mHeaderViewInfos.get(position).view;
@@ -222,7 +222,7 @@
             }
         }
 
-        // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
+        // Footer (off-limits positions will throw an IndexOutOfBoundsException)
         return mFooterViewInfos.get(adjPosition - adapterCount).view;
     }
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9e43749..4ac16d8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -35,6 +35,7 @@
 
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
+import libcore.io.OsConstants;
 
 import java.io.BufferedReader;
 import java.io.FileDescriptor;
@@ -479,12 +480,25 @@
      */
     private static boolean startSystemServer()
             throws MethodAndArgsCaller, RuntimeException {
+        long capabilities = posixCapabilitiesAsBits(
+            OsConstants.CAP_KILL,
+            OsConstants.CAP_NET_ADMIN,
+            OsConstants.CAP_NET_BIND_SERVICE,
+            OsConstants.CAP_NET_BROADCAST,
+            OsConstants.CAP_NET_RAW,
+            OsConstants.CAP_SYS_BOOT,
+            OsConstants.CAP_SYS_MODULE,
+            OsConstants.CAP_SYS_NICE,
+            OsConstants.CAP_SYS_RESOURCE,
+            OsConstants.CAP_SYS_TIME,
+            OsConstants.CAP_SYS_TTY_CONFIG
+        );
         /* Hardcoded command line to start the system server */
         String args[] = {
             "--setuid=1000",
             "--setgid=1000",
             "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
-            "--capabilities=130104352,130104352",
+            "--capabilities=" + capabilities + "," + capabilities,
             "--runtime-init",
             "--nice-name=system_server",
             "com.android.server.SystemServer",
@@ -518,6 +532,20 @@
         return true;
     }
 
+    /**
+     * Gets the bit array representation of the provided list of POSIX capabilities.
+     */
+    private static long posixCapabilitiesAsBits(int... capabilities) {
+        long result = 0;
+        for (int capability : capabilities) {
+            if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
+                throw new IllegalArgumentException(String.valueOf(capability));
+            }
+            result |= (1L << capability);
+        }
+        return result;
+    }
+
     public static void main(String argv[]) {
         try {
             // Start profiling the zygote initialization.
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index d8f20c1..c1a8e92 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -151,7 +151,7 @@
 	$(call include-path-for, bluedroid) \
 	$(call include-path-for, libhardware)/hardware \
 	$(call include-path-for, libhardware_legacy)/hardware_legacy \
- $(TOP)/frameworks/av/include \
+	$(TOP)/frameworks/av/include \
 	external/skia/include/core \
 	external/skia/include/effects \
 	external/skia/include/images \
@@ -224,6 +224,7 @@
 
 LOCAL_MODULE:= libandroid_runtime
 
+include external/stlport/libstlport.mk
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 0a97f39..ca278cf 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -102,7 +102,7 @@
         return NULL;
     }
 
-    security_context_t tmp;
+    security_context_t tmp = NULL;
     int ret = getpeercon(fd, &tmp);
     Unique_SecurityContext context(tmp);
 
@@ -111,7 +111,7 @@
         contextStr.reset(env->NewStringUTF(context.get()));
     }
 
-    ALOGV("getPeerCon(%d) => %s", fd, contextStr.get());
+    ALOGV("getPeerCon(%d) => %s", fd, context.get());
     return contextStr.release();
 }
 
@@ -198,7 +198,7 @@
         return NULL;
     }
 
-    security_context_t tmp;
+    security_context_t tmp = NULL;
     int ret = getfilecon(path.c_str(), &tmp);
     Unique_SecurityContext context(tmp);
 
@@ -224,7 +224,7 @@
         return NULL;
     }
 
-    security_context_t tmp;
+    security_context_t tmp = NULL;
     int ret = getcon(&tmp);
     Unique_SecurityContext context(tmp);
 
@@ -251,7 +251,7 @@
         return NULL;
     }
 
-    security_context_t tmp;
+    security_context_t tmp = NULL;
     int ret = getpidcon(static_cast<pid_t>(pid), &tmp);
     Unique_SecurityContext context(tmp);
 
diff --git a/core/res/res/values-mcc202-mnc05/config.xml b/core/res/res/values-mcc202-mnc05/config.xml
new file mode 100644
index 0000000..ec5ecaf
--- /dev/null
+++ b/core/res/res/values-mcc202-mnc05/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">Vf Tethering,internet.vodafone.gr,,,,,,,,,202,05,,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc208-mnc01/config.xml b/core/res/res/values-mcc208-mnc01/config.xml
index c1489b1..3b84ff2 100644
--- a/core/res/res/values-mcc208-mnc01/config.xml
+++ b/core/res/res/values-mcc208-mnc01/config.xml
@@ -34,5 +34,6 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Orange Internet,orange.fr,,,,,,orange,orange,,208,01,,DUN</string>
+    <string translatable="false" name="config_tether_apndata">Orange Internet,orange.fr,,,orange,orange,,,,,208,01,1,DUN</string>
+
 </resources>
diff --git a/core/res/res/values-mcc208-mnc10/config.xml b/core/res/res/values-mcc208-mnc10/config.xml
index 99cc599..358bef6 100644
--- a/core/res/res/values-mcc208-mnc10/config.xml
+++ b/core/res/res/values-mcc208-mnc10/config.xml
@@ -33,6 +33,6 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">SFR Option Modem,websfr,,,,,,,,,208,10,,DUN"</string>
+    <string translatable="false" name="config_tether_apndata">SFR option modem,websfr,,,,,,,,,208,10,,DUN</string>
 
 </resources>
diff --git a/core/res/res/values-mcc214-mnc01/config.xml b/core/res/res/values-mcc214-mnc01/config.xml
new file mode 100644
index 0000000..1b7c462
--- /dev/null
+++ b/core/res/res/values-mcc214-mnc01/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">INTERNET,airtelnet.es,,,vodafone,vodafone,,,,,214,01,1,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc214-mnc03/config.xml b/core/res/res/values-mcc214-mnc03/config.xml
index 02f1475..4a51a2f 100644
--- a/core/res/res/values-mcc214-mnc03/config.xml
+++ b/core/res/res/values-mcc214-mnc03/config.xml
@@ -34,5 +34,6 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Orange Internet PC,internet,,,,,,orange,orange,,214,03,,DUN</string>
+    <string translatable="false" name="config_tether_apndata">Orange Internet PC,internet,,,orange,orange,,,,,214,03,1,DUN</string>
+
 </resources>
diff --git a/core/res/res/values-mcc214-mnc07/config.xml b/core/res/res/values-mcc214-mnc07/config.xml
index 4e3fa16..b49ad74 100644
--- a/core/res/res/values-mcc214-mnc07/config.xml
+++ b/core/res/res/values-mcc214-mnc07/config.xml
@@ -34,5 +34,6 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Conexión compartida,movistar.es,,,,,,MOVISTAR,MOVISTAR,,214,07,,DUN</string>
+    <string translatable="false" name="config_tether_apndata">Conexión Compartida,movistar.es,,,MOVISTAR,MOVISTAR,,,,,214,07,1,DUN</string>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml
index b1d363f..3d2ea75 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -34,5 +34,6 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Fido Tethering,isp.fido.apn,,,,,,,,,302,370,,DUN</string>
+    <string translatable="false" name="config_tether_apndata">Fido LTE Tethering,ltedata.apn,,,,,,,,,302,370,,DUN</string>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index 40ef939..680f1a3 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -34,5 +34,6 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Rogers Tethering,isp.apn,,,,,,,,,302,720,,DUN</string>
+    <string translatable="false" name="config_tether_apndata">Rogers LTE Tethering,ltedata.apn,,,,,,,,,302,720,,DUN</string>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc780/config.xml b/core/res/res/values-mcc302-mnc780/config.xml
new file mode 100644
index 0000000..42d4956
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc780/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,302,780,,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml
new file mode 100644
index 0000000..56a5d4e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">T-Mobile Tethering,pcweb.tmobile.com,,,,,,,,,310,260,,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc425-mnc01/config.xml b/core/res/res/values-mcc425-mnc01/config.xml
new file mode 100644
index 0000000..f4854da
--- /dev/null
+++ b/core/res/res/values-mcc425-mnc01/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">DUN,modem.orange.net.il,,,,,,,,,425,01,,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc425-mnc07/config.xml b/core/res/res/values-mcc425-mnc07/config.xml
new file mode 100644
index 0000000..890420e
--- /dev/null
+++ b/core/res/res/values-mcc425-mnc07/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">PC HOT mobile,pc.hotm,,,,,,,,,425,07,,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc454-mnc00/config.xml b/core/res/res/values-mcc454-mnc00/config.xml
new file mode 100644
index 0000000..c92b9c7
--- /dev/null
+++ b/core/res/res/values-mcc454-mnc00/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">1O1O tethering,lte.internet,,,,,,,,,454,00,3,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc454-mnc03/config.xml b/core/res/res/values-mcc454-mnc03/config.xml
new file mode 100644
index 0000000..c7dc960
--- /dev/null
+++ b/core/res/res/values-mcc454-mnc03/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">3 Share,share.lte.three.com.hk,,,,,,,,,454,03,1,DUN</string>
+
+</resources>
diff --git a/core/res/res/values-mcc505-mnc01/config.xml b/core/res/res/values-mcc505-mnc01/config.xml
new file mode 100644
index 0000000..f9d9ac7
--- /dev/null
+++ b/core/res/res/values-mcc505-mnc01/config.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">Telstra Tethering,telstra.internet,,,,,,,,,505,01,,DUN</string>
+
+</resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 8b395af..7804dd2 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -184,6 +184,6 @@
     <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
 
     <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) -->
-    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" />
+    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="87902" />
 
 </shortcodes>
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index b6b15c4..22fa7fc 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_DX_FLAGS := --core-library
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver guava littlemock
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
+LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
 
 LOCAL_CERTIFICATE := platform
diff --git a/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java b/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java
index 60c40db..04aa62a 100644
--- a/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java
+++ b/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java
@@ -25,7 +25,7 @@
 
 import junit.framework.TestCase;
 
-import org.apache.harmony.xnet.provider.jsse.TrustManagerImpl;
+import com.android.org.conscrypt.TrustManagerImpl;
 
 public class X509TrustManagerExtensionsTest extends TestCase {
 
diff --git a/docs/html/guide/topics/data/backup.jd b/docs/html/guide/topics/data/backup.jd
index 598b08a..4903852 100644
--- a/docs/html/guide/topics/data/backup.jd
+++ b/docs/html/guide/topics/data/backup.jd
@@ -680,7 +680,7 @@
 
 <pre>
 public class MyFileBackupAgent extends BackupAgentHelper {
-    // The name of the SharedPreferences file
+    // The name of the file
     static final String TOP_SCORES = "scores";
     static final String PLAYER_STATS = "stats";
 
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index c42001b..11afbf5 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -18,7 +18,7 @@
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
 
-import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
+import com.android.org.conscrypt.OpenSSLEngine;
 
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
@@ -49,10 +49,7 @@
  *
  * {@hide}
  */
-@SuppressWarnings("deprecation")
 public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
-    public static final String NAME = "AndroidKeyPairGenerator";
-
     private android.security.KeyStore mKeyStore;
 
     private AndroidKeyPairGeneratorSpec mSpec;
@@ -79,12 +76,21 @@
                     "Must call initialize with an AndroidKeyPairGeneratorSpec first");
         }
 
+        if (((mSpec.getFlags() & KeyStore.FLAG_ENCRYPTED) != 0)
+                && (mKeyStore.state() != KeyStore.State.UNLOCKED)) {
+            throw new IllegalStateException(
+                    "Android keystore must be in initialized and unlocked state "
+                            + "if encryption is required");
+        }
+
         final String alias = mSpec.getKeystoreAlias();
 
         Credentials.deleteAllTypesForAlias(mKeyStore, alias);
 
         final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
-        mKeyStore.generate(privateKeyAlias);
+        if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mSpec.getFlags())) {
+            throw new IllegalStateException("could not generate key in keystore");
+        }
 
         final PrivateKey privKey;
         final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
@@ -131,7 +137,8 @@
             throw new IllegalStateException("Can't get encoding of certificate", e);
         }
 
-        if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, certBytes)) {
+        if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, certBytes, KeyStore.UID_SELF,
+                mSpec.getFlags())) {
             Credentials.deleteAllTypesForAlias(mKeyStore, alias);
             throw new IllegalStateException("Can't store certificate in AndroidKeyStore");
         }
diff --git a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java b/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
index 83faf35..8d6bfa68 100644
--- a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
@@ -32,10 +32,9 @@
  * {@code KeyPairGenerator} that works with <a href="{@docRoot}
  * guide/topics/security/keystore.html">Android KeyStore facility</a>. The
  * Android KeyStore facility is accessed through a
- * {@link java.security.KeyPairGenerator} API using the
- * {@code AndroidKeyPairGenerator} provider. The {@code context} passed in may
- * be used to pop up some UI to ask the user to unlock or initialize the Android
- * keystore facility.
+ * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
+ * provider. The {@code context} passed in may be used to pop up some UI to ask
+ * the user to unlock or initialize the Android KeyStore facility.
  * <p>
  * After generation, the {@code keyStoreAlias} is used with the
  * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
@@ -47,12 +46,12 @@
  * Distinguished Name along with the other parameters specified with the
  * {@link Builder}.
  * <p>
- * The self-signed certificate may be replaced at a later time by a certificate
- * signed by a real Certificate Authority.
+ * The self-signed X.509 certificate may be replaced at a later time by a
+ * certificate signed by a real Certificate Authority.
  *
  * @hide
  */
-public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
+public final class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
     private final String mKeystoreAlias;
 
     private final Context mContext;
@@ -65,6 +64,8 @@
 
     private final Date mEndDate;
 
+    private final int mFlags;
+
     /**
      * Parameter specification for the "{@code AndroidKeyPairGenerator}"
      * instance of the {@link java.security.KeyPairGenerator} API. The
@@ -95,7 +96,8 @@
      * @hide should be built with AndroidKeyPairGeneratorSpecBuilder
      */
     public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias,
-            X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) {
+            X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate,
+            int flags) {
         if (context == null) {
             throw new IllegalArgumentException("context == null");
         } else if (TextUtils.isEmpty(keyStoreAlias)) {
@@ -118,48 +120,69 @@
         mSerialNumber = serialNumber;
         mStartDate = startDate;
         mEndDate = endDate;
+        mFlags = flags;
     }
 
     /**
-     * @hide
+     * Returns the alias that will be used in the {@code java.security.KeyStore}
+     * in conjunction with the {@code AndroidKeyStore}.
      */
-    String getKeystoreAlias() {
+    public String getKeystoreAlias() {
         return mKeystoreAlias;
     }
 
     /**
-     * @hide
+     * Gets the Android context used for operations with this instance.
      */
-    Context getContext() {
+    public Context getContext() {
         return mContext;
     }
 
     /**
-     * @hide
+     * Gets the subject distinguished name to be used on the X.509 certificate
+     * that will be put in the {@link java.security.KeyStore}.
      */
-    X500Principal getSubjectDN() {
+    public X500Principal getSubjectDN() {
         return mSubjectDN;
     }
 
     /**
-     * @hide
+     * Gets the serial number to be used on the X.509 certificate that will be
+     * put in the {@link java.security.KeyStore}.
      */
-    BigInteger getSerialNumber() {
+    public BigInteger getSerialNumber() {
         return mSerialNumber;
     }
 
     /**
-     * @hide
+     * Gets the start date to be used on the X.509 certificate that will be put
+     * in the {@link java.security.KeyStore}.
      */
-    Date getStartDate() {
+    public Date getStartDate() {
         return mStartDate;
     }
 
     /**
+     * Gets the end date to be used on the X.509 certificate that will be put in
+     * the {@link java.security.KeyStore}.
+     */
+    public Date getEndDate() {
+        return mEndDate;
+    }
+
+    /**
      * @hide
      */
-    Date getEndDate() {
-        return mEndDate;
+    int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Returns {@code true} if this parameter will require generated keys to be
+     * encrypted in the {@link java.security.KeyStore}.
+     */
+    public boolean isEncryptionRequired() {
+        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
     }
 
     /**
@@ -177,16 +200,17 @@
      * Calendar end = new Calendar();
      * end.add(1, Calendar.YEAR);
      *
-     * AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(mContext)
-     *         .setAlias("myKey")
-     *         .setSubject(new X500Principal("CN=myKey"))
-     *         .setSerial(BigInteger.valueOf(1337))
-     *         .setStartDate(start.getTime())
-     *         .setEndDate(end.getTime())
-     *         .build();
+     * AndroidKeyPairGeneratorSpec spec =
+     *         new AndroidKeyPairGeneratorSpec.Builder(mContext)
+     *                 .setAlias(&quot;myKey&quot;)
+     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;))
+     *                 .setSerial(BigInteger.valueOf(1337))
+     *                 .setStartDate(start.getTime())
+     *                 .setEndDate(end.getTime())
+     *                 .build();
      * </pre>
      */
-    public static class Builder {
+    public final static class Builder {
         private final Context mContext;
 
         private String mKeystoreAlias;
@@ -199,6 +223,14 @@
 
         private Date mEndDate;
 
+        private int mFlags;
+
+        /**
+         * Creates a new instance of the {@code Builder} with the given
+         * {@code context}. The {@code context} passed in may be used to pop up
+         * some UI to ask the user to unlock or initialize the Android KeyStore
+         * facility.
+         */
         public Builder(Context context) {
             if (context == null) {
                 throw new NullPointerException("context == null");
@@ -268,6 +300,17 @@
         }
 
         /**
+         * Indicates that this key must be encrypted at rest on storage. Note
+         * that enabling this will require that the user enable a strong lock
+         * screen (e.g., PIN, password) before creating or using the generated
+         * key is successful.
+         */
+        public Builder setEncryptionRequired() {
+            mFlags |= KeyStore.FLAG_ENCRYPTED;
+            return this;
+        }
+
+        /**
          * Builds the instance of the {@code AndroidKeyPairGeneratorSpec}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -275,7 +318,7 @@
          */
         public AndroidKeyPairGeneratorSpec build() {
             return new AndroidKeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
-                    mSerialNumber, mStartDate, mEndDate);
+                    mSerialNumber, mStartDate, mEndDate, mFlags);
         }
     }
 }
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index 8a9826b..cf715d6 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -16,8 +16,8 @@
 
 package android.security;
 
-import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder;
+import com.android.org.conscrypt.OpenSSLEngine;
+import com.android.org.conscrypt.OpenSSLKeyHolder;
 
 import android.util.Log;
 
@@ -27,6 +27,10 @@
 import java.io.OutputStream;
 import java.security.InvalidKeyException;
 import java.security.Key;
+import java.security.KeyStore.Entry;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStore.ProtectionParameter;
+import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.KeyStoreSpi;
 import java.security.NoSuchAlgorithmException;
@@ -198,14 +202,14 @@
         }
 
         if (key instanceof PrivateKey) {
-            setPrivateKeyEntry(alias, (PrivateKey) key, chain);
+            setPrivateKeyEntry(alias, (PrivateKey) key, chain, null);
         } else {
             throw new KeyStoreException("Only PrivateKeys are supported");
         }
     }
 
-    private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain)
-            throws KeyStoreException {
+    private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain,
+            AndroidKeyStoreParameter params) throws KeyStoreException {
         byte[] keyBytes = null;
 
         final String pkeyAlias;
@@ -317,15 +321,20 @@
             Credentials.deleteCertificateTypesForAlias(mKeyStore, alias);
         }
 
+        final int flags = (params == null) ? 0 : params.getFlags();
+
         if (shouldReplacePrivateKey
-                && !mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, keyBytes)) {
+                && !mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, keyBytes,
+                        android.security.KeyStore.UID_SELF, flags)) {
             Credentials.deleteAllTypesForAlias(mKeyStore, alias);
             throw new KeyStoreException("Couldn't put private key in keystore");
-        } else if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, userCertBytes)) {
+        } else if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, userCertBytes,
+                android.security.KeyStore.UID_SELF, flags)) {
             Credentials.deleteAllTypesForAlias(mKeyStore, alias);
             throw new KeyStoreException("Couldn't put certificate #1 in keystore");
         } else if (chainBytes != null
-                && !mKeyStore.put(Credentials.CA_CERTIFICATE + alias, chainBytes)) {
+                && !mKeyStore.put(Credentials.CA_CERTIFICATE + alias, chainBytes,
+                        android.security.KeyStore.UID_SELF, flags)) {
             Credentials.deleteAllTypesForAlias(mKeyStore, alias);
             throw new KeyStoreException("Couldn't put certificate chain in keystore");
         }
@@ -355,7 +364,8 @@
             throw new KeyStoreException(e);
         }
 
-        if (!mKeyStore.put(Credentials.CA_CERTIFICATE + alias, encoded)) {
+        if (!mKeyStore.put(Credentials.CA_CERTIFICATE + alias, encoded,
+                android.security.KeyStore.UID_SELF, android.security.KeyStore.FLAG_NONE)) {
             throw new KeyStoreException("Couldn't insert certificate; is KeyStore initialized?");
         }
     }
@@ -517,4 +527,37 @@
         mKeyStore = android.security.KeyStore.getInstance();
     }
 
+    @Override
+    public void engineSetEntry(String alias, Entry entry, ProtectionParameter param)
+            throws KeyStoreException {
+        if (entry == null) {
+            throw new KeyStoreException("entry == null");
+        }
+
+        if (engineContainsAlias(alias)) {
+            engineDeleteEntry(alias);
+        }
+
+        if (entry instanceof KeyStore.TrustedCertificateEntry) {
+            KeyStore.TrustedCertificateEntry trE = (KeyStore.TrustedCertificateEntry) entry;
+            engineSetCertificateEntry(alias, trE.getTrustedCertificate());
+            return;
+        }
+
+        if (param != null && !(param instanceof AndroidKeyStoreParameter)) {
+            throw new KeyStoreException("protParam should be AndroidKeyStoreParameter; was: "
+                    + param.getClass().getName());
+        }
+
+        if (entry instanceof PrivateKeyEntry) {
+            PrivateKeyEntry prE = (PrivateKeyEntry) entry;
+            setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(),
+                    (AndroidKeyStoreParameter) param);
+            return;
+        }
+
+        throw new KeyStoreException(
+                "Entry must be a PrivateKeyEntry or TrustedCertificateEntry; was " + entry);
+    }
+
 }
diff --git a/keystore/java/android/security/AndroidKeyStoreParameter.java b/keystore/java/android/security/AndroidKeyStoreParameter.java
new file mode 100644
index 0000000..4ce9f09
--- /dev/null
+++ b/keystore/java/android/security/AndroidKeyStoreParameter.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2013 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.security;
+
+import android.content.Context;
+import android.security.AndroidKeyPairGeneratorSpec.Builder;
+
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.KeyStore.ProtectionParameter;
+import java.security.cert.Certificate;
+
+/**
+ * This provides the optional parameters that can be specified for
+ * {@code KeyStore} entries that work with <a href="{@docRoot}
+ * guide/topics/security/keystore.html">Android KeyStore facility</a>. The
+ * Android KeyStore facility is accessed through a
+ * {@link java.security.KeyStore} API using the {@code AndroidKeyStore}
+ * provider. The {@code context} passed in may be used to pop up some UI to ask
+ * the user to unlock or initialize the Android KeyStore facility.
+ * <p>
+ * Any entries placed in the {@code KeyStore} may be retrieved later. Note that
+ * there is only one logical instance of the {@code KeyStore} per application
+ * UID so apps using the {@code sharedUid} facility will also share a
+ * {@code KeyStore}.
+ * <p>
+ * Keys may be generated using the {@link KeyPairGenerator} facility with a
+ * {@link AndroidKeyPairGeneratorSpec} to specify the entry's {@code alias}. A
+ * self-signed X.509 certificate will be attached to generated entries, but that
+ * may be replaced at a later time by a certificate signed by a real Certificate
+ * Authority.
+ *
+ * @hide
+ */
+public final class AndroidKeyStoreParameter implements ProtectionParameter {
+    private int mFlags;
+
+    private AndroidKeyStoreParameter(int flags) {
+        mFlags = flags;
+    }
+
+    /**
+     * @hide
+     */
+    public int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Returns {@code true} if this parameter requires entries to be encrypted
+     * on the disk.
+     */
+    public boolean isEncryptionRequired() {
+        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
+    }
+
+    /**
+     * Builder class for {@link AndroidKeyStoreParameter} objects.
+     * <p>
+     * This will build protection parameters for use with the <a
+     * href="{@docRoot} guide/topics/security/keystore.html">Android KeyStore
+     * facility</a>.
+     * <p>
+     * This can be used to require that KeyStore entries be stored encrypted.
+     * <p>
+     * Example:
+     *
+     * <pre class="prettyprint">
+     * AndroidKeyStoreParameter params =
+     *         new AndroidKeyStoreParameter.Builder(mContext).setEncryptionRequired().build();
+     * </pre>
+     */
+    public final static class Builder {
+        private int mFlags;
+
+        /**
+         * Creates a new instance of the {@code Builder} with the given
+         * {@code context}. The {@code context} passed in may be used to pop up
+         * some UI to ask the user to unlock or initialize the Android KeyStore
+         * facility.
+         */
+        public Builder(Context context) {
+            if (context == null) {
+                throw new NullPointerException("context == null");
+            }
+
+            // Context is currently not used, but will be in the future.
+        }
+
+        /**
+         * Indicates that this key must be encrypted at rest on storage. Note
+         * that enabling this will require that the user enable a strong lock
+         * screen (e.g., PIN, password) before creating or using the generated
+         * key is successful.
+         */
+        public Builder setEncryptionRequired() {
+            mFlags |= KeyStore.FLAG_ENCRYPTED;
+            return this;
+        }
+
+        /**
+         * Builds the instance of the {@code AndroidKeyPairGeneratorSpec}.
+         *
+         * @throws IllegalArgumentException if a required field is missing
+         * @return built instance of {@code AndroidKeyPairGeneratorSpec}
+         */
+        public AndroidKeyStoreParameter build() {
+            return new AndroidKeyStoreParameter(mFlags);
+        }
+    }
+}
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java
index 40d7e1a..8ca301e 100644
--- a/keystore/java/android/security/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/AndroidKeyStoreProvider.java
@@ -33,7 +33,6 @@
         put("KeyStore." + AndroidKeyStore.NAME, AndroidKeyStore.class.getName());
 
         // java.security.KeyPairGenerator
-        put("KeyPairGenerator." + AndroidKeyPairGenerator.NAME,
-                AndroidKeyPairGenerator.class.getName());
+        put("KeyPairGenerator." + AndroidKeyStore.NAME, AndroidKeyPairGenerator.class.getName());
     }
 }
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index d7119fff..0ad4d075 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -37,8 +37,8 @@
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
-import org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore;
+import com.android.org.conscrypt.OpenSSLEngine;
+import com.android.org.conscrypt.TrustedCertificateStore;
 
 /**
  * The {@code KeyChain} class provides access to private keys and
@@ -346,6 +346,8 @@
             List<X509Certificate> chain = store
                     .getCertificateChain(toCertificate(certificateBytes));
             return chain.toArray(new X509Certificate[chain.size()]);
+        } catch (CertificateException e) {
+            throw new KeyChainException(e);
         } catch (RemoteException e) {
             throw new KeyChainException(e);
         } catch (RuntimeException e) {
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 852f0bb..45385ee 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -40,6 +40,13 @@
     public static final int UNDEFINED_ACTION = 9;
     public static final int WRONG_PASSWORD = 10;
 
+    // Used for UID field to indicate the calling UID.
+    public static final int UID_SELF = -1;
+
+    // Flags for "put" "import" and "generate"
+    public static final int FLAG_NONE = 0;
+    public static final int FLAG_ENCRYPTED = 1;
+
     // States
     public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
 
@@ -87,17 +94,21 @@
         }
     }
 
-    public boolean put(String key, byte[] value, int uid) {
+    public boolean put(String key, byte[] value, int uid, int flags) {
         try {
-            return mBinder.insert(key, value, uid) == NO_ERROR;
+            return mBinder.insert(key, value, uid, flags) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
         }
     }
 
+    public boolean put(String key, byte[] value, int uid) {
+        return put(key, value, uid, FLAG_ENCRYPTED);
+    }
+
     public boolean put(String key, byte[] value) {
-        return put(key, value, -1);
+        return put(key, value, UID_SELF);
     }
 
     public boolean delete(String key, int uid) {
@@ -110,7 +121,7 @@
     }
 
     public boolean delete(String key) {
-        return delete(key, -1);
+        return delete(key, UID_SELF);
     }
 
     public boolean contains(String key, int uid) {
@@ -123,7 +134,7 @@
     }
 
     public boolean contains(String key) {
-        return contains(key, -1);
+        return contains(key, UID_SELF);
     }
 
     public String[] saw(String prefix, int uid) {
@@ -136,7 +147,7 @@
     }
 
     public String[] saw(String prefix) {
-        return saw(prefix, -1);
+        return saw(prefix, UID_SELF);
     }
 
     public boolean reset() {
@@ -185,30 +196,38 @@
         }
     }
 
-    public boolean generate(String key, int uid) {
+    public boolean generate(String key, int uid, int flags) {
         try {
-            return mBinder.generate(key, uid) == NO_ERROR;
+            return mBinder.generate(key, uid, flags) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
         }
     }
 
+    public boolean generate(String key, int uid) {
+        return generate(key, uid, FLAG_ENCRYPTED);
+    }
+
     public boolean generate(String key) {
-        return generate(key, -1);
+        return generate(key, UID_SELF);
     }
 
-    public boolean importKey(String keyName, byte[] key, int uid) {
+    public boolean importKey(String keyName, byte[] key, int uid, int flags) {
         try {
-            return mBinder.import_key(keyName, key, uid) == NO_ERROR;
+            return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
         }
     }
 
+    public boolean importKey(String keyName, byte[] key, int uid) {
+        return importKey(keyName, key, uid, FLAG_ENCRYPTED);
+    }
+
     public boolean importKey(String keyName, byte[] key) {
-        return importKey(keyName, key, -1);
+        return importKey(keyName, key, UID_SELF);
     }
 
     public byte[] getPubkey(String key) {
@@ -230,7 +249,7 @@
     }
 
     public boolean delKey(String key) {
-        return delKey(key, -1);
+        return delKey(key, UID_SELF);
     }
 
     public byte[] sign(String key, byte[] data) {
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
index 61cf640..35388d7 100644
--- a/keystore/tests/Android.mk
+++ b/keystore/tests/Android.mk
@@ -5,7 +5,7 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
 
-LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle
+LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java
index 3d275cd..5d4ab9c 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java
@@ -39,8 +39,9 @@
     private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
 
     public void testConstructor_Success() throws Exception {
-        AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec(getContext(),
-                TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW, NOW_PLUS_10_YEARS);
+        AndroidKeyPairGeneratorSpec spec =
+                new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
+                        NOW, NOW_PLUS_10_YEARS, 0);
 
         assertEquals("Context should be the one specified", getContext(), spec.getContext());
 
@@ -60,6 +61,7 @@
                 .setSerialNumber(SERIAL_1)
                 .setStartDate(NOW)
                 .setEndDate(NOW_PLUS_10_YEARS)
+                .setEncryptionRequired()
                 .build();
 
         assertEquals("Context should be the one specified", getContext(), spec.getContext());
@@ -71,12 +73,14 @@
         assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
 
         assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate());
+
+        assertEquals("encryption flag should be on", KeyStore.FLAG_ENCRYPTED, spec.getFlags());
     }
 
     public void testConstructor_NullContext_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS);
+                    NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when context is null");
         } catch (IllegalArgumentException success) {
         }
@@ -85,7 +89,7 @@
     public void testConstructor_NullKeystoreAlias_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(getContext(), null, TEST_DN_1, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS);
+                    NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when keystoreAlias is null");
         } catch (IllegalArgumentException success) {
         }
@@ -94,7 +98,7 @@
     public void testConstructor_NullSubjectDN_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, null, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS);
+                    NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when subjectDN is null");
         } catch (IllegalArgumentException success) {
         }
@@ -103,7 +107,7 @@
     public void testConstructor_NullSerial_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, null, NOW,
-                    NOW_PLUS_10_YEARS);
+                    NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when startDate is null");
         } catch (IllegalArgumentException success) {
         }
@@ -112,7 +116,7 @@
     public void testConstructor_NullStartDate_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, null,
-                    NOW_PLUS_10_YEARS);
+                    NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when startDate is null");
         } catch (IllegalArgumentException success) {
         }
@@ -121,7 +125,7 @@
     public void testConstructor_NullEndDate_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
-                    null);
+                    null, 0);
             fail("Should throw IllegalArgumentException when keystoreAlias is null");
         } catch (IllegalArgumentException success) {
         }
@@ -130,7 +134,7 @@
     public void testConstructor_EndBeforeStart_Failure() throws Exception {
         try {
             new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
-                    NOW_PLUS_10_YEARS, NOW);
+                    NOW_PLUS_10_YEARS, NOW, 0);
             fail("Should throw IllegalArgumentException when end is before start");
         } catch (IllegalArgumentException success) {
         }
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
index 69007c4..c5cf514 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
@@ -27,6 +27,7 @@
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 
 import javax.security.auth.x500.X500Principal;
@@ -64,22 +65,34 @@
 
         assertFalse(mAndroidKeyStore.isUnlocked());
 
+        mGenerator = java.security.KeyPairGenerator.getInstance("AndroidKeyStore");
+    }
+
+    private void setupPassword() {
         assertTrue(mAndroidKeyStore.password("1111"));
         assertTrue(mAndroidKeyStore.isUnlocked());
 
         String[] aliases = mAndroidKeyStore.saw("");
         assertNotNull(aliases);
         assertEquals(0, aliases.length);
-
-        mGenerator = java.security.KeyPairGenerator.getInstance(AndroidKeyPairGenerator.NAME);
     }
 
-    public void testKeyPairGenerator_Initialize_Params_Success() throws Exception {
-        mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
-                TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS));
+    public void testKeyPairGenerator_Initialize_Params_Encrypted_Success() throws Exception {
+        setupPassword();
+
+        mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .setEncryptionRequired()
+                .build());
     }
 
-    public void testKeyPairGenerator_Initialize_KeySize_Failure() throws Exception {
+    public void testKeyPairGenerator_Initialize_KeySize_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         try {
             mGenerator.initialize(1024);
             fail("KeyPairGenerator should not support setting the key size");
@@ -87,7 +100,10 @@
         }
     }
 
-    public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Failure() throws Exception {
+    public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Encrypted_Failure()
+            throws Exception {
+        setupPassword();
+
         try {
             mGenerator.initialize(1024, new SecureRandom());
             fail("KeyPairGenerator should not support setting the key size");
@@ -95,14 +111,48 @@
         }
     }
 
-    public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Failure() throws Exception {
-        mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
-                TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS), new SecureRandom());
+    public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Encrypted_Failure()
+            throws Exception {
+        setupPassword();
+
+        mGenerator.initialize(
+                new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                        .setAlias(TEST_ALIAS_1)
+                        .setSubject(TEST_DN_1)
+                        .setSerialNumber(TEST_SERIAL_1)
+                        .setStartDate(NOW)
+                        .setEndDate(NOW_PLUS_10_YEARS)
+                        .setEncryptionRequired()
+                        .build(),
+                new SecureRandom());
     }
 
-    public void testKeyPairGenerator_GenerateKeyPair_Success() throws Exception {
-        mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
-                TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS));
+    public void testKeyPairGenerator_GenerateKeyPair_Encrypted_Success() throws Exception {
+        setupPassword();
+
+        mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .setEncryptionRequired()
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_Unencrypted_Success() throws Exception {
+        mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
 
         final KeyPair pair = mGenerator.generateKeyPair();
         assertNotNull("The KeyPair returned should not be null", pair);
@@ -113,8 +163,13 @@
     public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
         // Generate the first key
         {
-            mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
-                    TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS));
+            mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                    .setAlias(TEST_ALIAS_1)
+                    .setSubject(TEST_DN_1)
+                    .setSerialNumber(TEST_SERIAL_1)
+                    .setStartDate(NOW)
+                    .setEndDate(NOW_PLUS_10_YEARS)
+                    .build());
             final KeyPair pair1 = mGenerator.generateKeyPair();
             assertNotNull("The KeyPair returned should not be null", pair1);
             assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
@@ -123,8 +178,13 @@
 
         // Replace the original key
         {
-            mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_2,
-                    TEST_DN_2, TEST_SERIAL_2, NOW, NOW_PLUS_10_YEARS));
+            mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                    .setAlias(TEST_ALIAS_2)
+                    .setSubject(TEST_DN_2)
+                    .setSerialNumber(TEST_SERIAL_2)
+                    .setStartDate(NOW)
+                    .setEndDate(NOW_PLUS_10_YEARS)
+                    .build());
             final KeyPair pair2 = mGenerator.generateKeyPair();
             assertNotNull("The KeyPair returned should not be null", pair2);
             assertKeyPairCorrect(pair2, TEST_ALIAS_2, TEST_DN_2, TEST_SERIAL_2, NOW,
@@ -132,6 +192,49 @@
         }
     }
 
+    public void testKeyPairGenerator_GenerateKeyPair_Replaced_UnencryptedToEncrypted_Success()
+            throws Exception {
+        // Generate the first key
+        {
+            mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                    .setAlias(TEST_ALIAS_1)
+                    .setSubject(TEST_DN_1)
+                    .setSerialNumber(TEST_SERIAL_1)
+                    .setStartDate(NOW)
+                    .setEndDate(NOW_PLUS_10_YEARS)
+                    .build());
+            final KeyPair pair1 = mGenerator.generateKeyPair();
+            assertNotNull("The KeyPair returned should not be null", pair1);
+            assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
+                    NOW_PLUS_10_YEARS);
+        }
+
+        // Attempt to replace previous key
+        {
+            mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+                    .setAlias(TEST_ALIAS_1)
+                    .setSubject(TEST_DN_2)
+                    .setSerialNumber(TEST_SERIAL_2)
+                    .setStartDate(NOW)
+                    .setEndDate(NOW_PLUS_10_YEARS)
+                    .setEncryptionRequired()
+                    .build());
+            try {
+                mGenerator.generateKeyPair();
+                fail("Should not be able to generate encrypted key while not initialized");
+            } catch (IllegalStateException expected) {
+            }
+
+            assertTrue(mAndroidKeyStore.password("1111"));
+            assertTrue(mAndroidKeyStore.isUnlocked());
+
+            final KeyPair pair2 = mGenerator.generateKeyPair();
+            assertNotNull("The KeyPair returned should not be null", pair2);
+            assertKeyPairCorrect(pair2, TEST_ALIAS_1, TEST_DN_2, TEST_SERIAL_2, NOW,
+                    NOW_PLUS_10_YEARS);
+        }
+    }
+
     private void assertKeyPairCorrect(KeyPair pair, String alias, X500Principal dn,
             BigInteger serial, Date start, Date end) throws Exception {
         final PublicKey pubKey = pair.getPublic();
@@ -163,10 +266,10 @@
         assertEquals("The Serial should be the one passed into the params", serial,
                 x509userCert.getSerialNumber());
 
-        assertEquals("The notBefore date should be the one passed into the params", start,
+        assertDateEquals("The notBefore date should be the one passed into the params", start,
                 x509userCert.getNotBefore());
 
-        assertEquals("The notAfter date should be the one passed into the params", end,
+        assertDateEquals("The notAfter date should be the one passed into the params", end,
                 x509userCert.getNotAfter());
 
         x509userCert.verify(pubKey);
@@ -178,4 +281,13 @@
         assertNotNull("The keystore should return the public key for the generated key",
                 pubKeyBytes);
     }
+
+    private static void assertDateEquals(String message, Date date1, Date date2) throws Exception {
+        SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
+
+        String result1 = formatter.format(date1);
+        String result2 = formatter.format(date2);
+
+        assertEquals(message, result1, result2);
+    }
 }
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index 8928e06..135f93f 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -18,7 +18,7 @@
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
 
-import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
+import com.android.org.conscrypt.OpenSSLEngine;
 
 import android.test.AndroidTestCase;
 
@@ -469,12 +469,14 @@
         assertTrue(mAndroidKeyStore.reset());
         assertFalse(mAndroidKeyStore.isUnlocked());
 
+        mKeyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+    }
+
+    private void setupPassword() {
         assertTrue(mAndroidKeyStore.password("1111"));
         assertTrue(mAndroidKeyStore.isUnlocked());
 
         assertEquals(0, mAndroidKeyStore.saw("").length);
-
-        mKeyStore = java.security.KeyStore.getInstance(AndroidKeyStore.NAME);
     }
 
     private void assertAliases(final String[] expectedAliases) throws KeyStoreException {
@@ -495,7 +497,9 @@
                 expectedAliases.length, count);
     }
 
-    public void testKeyStore_Aliases_Success() throws Exception {
+    public void testKeyStore_Aliases_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertAliases(new String[] {});
@@ -509,7 +513,9 @@
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
     }
 
-    public void testKeyStore_Aliases_NotInitialized_Failure() throws Exception {
+    public void testKeyStore_Aliases_NotInitialized_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         try {
             mKeyStore.aliases();
             fail("KeyStore should throw exception when not initialized");
@@ -517,7 +523,9 @@
         }
     }
 
-    public void testKeyStore_ContainsAliases_PrivateAndCA_Success() throws Exception {
+    public void testKeyStore_ContainsAliases_PrivateAndCA_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertAliases(new String[] {});
@@ -534,7 +542,9 @@
                 mKeyStore.containsAlias(TEST_ALIAS_3));
     }
 
-    public void testKeyStore_ContainsAliases_CAOnly_Success() throws Exception {
+    public void testKeyStore_ContainsAliases_CAOnly_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
@@ -542,13 +552,17 @@
         assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
     }
 
-    public void testKeyStore_ContainsAliases_NonExistent_Failure() throws Exception {
+    public void testKeyStore_ContainsAliases_NonExistent_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_DeleteEntry_Success() throws Exception {
+    public void testKeyStore_DeleteEntry_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         // TEST_ALIAS_1
@@ -578,14 +592,18 @@
         assertAliases(new String[] { });
     }
 
-    public void testKeyStore_DeleteEntry_EmptyStore_Success() throws Exception {
+    public void testKeyStore_DeleteEntry_EmptyStore_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         // Should not throw when a non-existent entry is requested for delete.
         mKeyStore.deleteEntry(TEST_ALIAS_1);
     }
 
-    public void testKeyStore_DeleteEntry_NonExistent_Success() throws Exception {
+    public void testKeyStore_DeleteEntry_NonExistent_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         // TEST_ALIAS_1
@@ -598,7 +616,9 @@
         mKeyStore.deleteEntry(TEST_ALIAS_2);
     }
 
-    public void testKeyStore_GetCertificate_Single_Success() throws Exception {
+    public void testKeyStore_GetCertificate_Single_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -618,14 +638,18 @@
         assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
     }
 
-    public void testKeyStore_GetCertificate_NonExist_Failure() throws Exception {
+    public void testKeyStore_GetCertificate_NonExist_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertNull("Certificate should not exist in keystore",
                 mKeyStore.getCertificate(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_GetCertificateAlias_CAEntry_Success() throws Exception {
+    public void testKeyStore_GetCertificateAlias_CAEntry_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -637,7 +661,10 @@
                 mKeyStore.getCertificateAlias(actual));
     }
 
-    public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Success() throws Exception {
+    public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Encrypted_Success()
+            throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -652,8 +679,10 @@
                 mKeyStore.getCertificateAlias(actual));
     }
 
-    public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Success()
+    public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Encrypted_Success()
             throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         // Insert TrustedCertificateEntry with CA name
@@ -672,7 +701,10 @@
                 mKeyStore.getCertificateAlias(actual));
     }
 
-    public void testKeyStore_GetCertificateAlias_NonExist_Empty_Failure() throws Exception {
+    public void testKeyStore_GetCertificateAlias_NonExist_Empty_Encrypted_Failure()
+            throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -682,7 +714,9 @@
                 mKeyStore.getCertificateAlias(actual));
     }
 
-    public void testKeyStore_GetCertificateAlias_NonExist_Failure() throws Exception {
+    public void testKeyStore_GetCertificateAlias_NonExist_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -694,7 +728,9 @@
                 mKeyStore.getCertificateAlias(userCert));
     }
 
-    public void testKeyStore_GetCertificateChain_SingleLength_Success() throws Exception {
+    public void testKeyStore_GetCertificateChain_SingleLength_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -720,14 +756,18 @@
                 mKeyStore.getCertificateChain(TEST_ALIAS_2));
     }
 
-    public void testKeyStore_GetCertificateChain_NonExist_Failure() throws Exception {
+    public void testKeyStore_GetCertificateChain_NonExist_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertNull("Stored certificate alias should not be found",
                 mKeyStore.getCertificateChain(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Success() throws Exception {
+    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -745,7 +785,29 @@
         assertTrue("Time should be close to current time", actual.after(expectedAfter));
     }
 
-    public void testKeyStore_GetCreationDate_CAEntry_Success() throws Exception {
+    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+
+        Date now = new Date();
+        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
+
+        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
+        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
+
+        assertTrue("Time should be close to current time", actual.before(expectedBefore));
+        assertTrue("Time should be close to current time", actual.after(expectedAfter));
+    }
+
+    public void testKeyStore_GetCreationDate_CAEntry_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -761,7 +823,9 @@
         assertTrue("Time should be close to current time", actual.after(expectedAfter));
     }
 
-    public void testKeyStore_GetEntry_NullParams_Success() throws Exception {
+    public void testKeyStore_GetEntry_NullParams_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -779,6 +843,26 @@
         assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
     }
 
+    public void testKeyStore_GetEntry_NullParams_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+
+        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+        assertNotNull("Entry should exist", entry);
+
+        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
+
+        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
+
+        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+    }
+
     @SuppressWarnings("unchecked")
     private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert,
             byte[] ca) throws Exception {
@@ -801,8 +885,9 @@
 
     private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
             Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
-        assertEquals("Returned PrivateKey should be what we inserted", expectedKey,
-                keyEntry.getPrivateKey());
+        assertEquals("Returned PrivateKey should be what we inserted",
+                ((RSAPrivateKey) expectedKey).getModulus(),
+                ((RSAPrivateKey) keyEntry.getPrivateKey()).getModulus());
 
         assertEquals("Returned Certificate should be what we inserted", expectedCert,
                 keyEntry.getCertificate());
@@ -823,14 +908,25 @@
         }
     }
 
-    public void testKeyStore_GetEntry_Nonexistent_NullParams_Failure() throws Exception {
+    public void testKeyStore_GetEntry_Nonexistent_NullParams_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertNull("A non-existent entry should return null",
                 mKeyStore.getEntry(TEST_ALIAS_1, null));
     }
 
-    public void testKeyStore_GetKey_NoPassword_Success() throws Exception {
+    public void testKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertNull("A non-existent entry should return null",
+                mKeyStore.getEntry(TEST_ALIAS_1, null));
+    }
+
+    public void testKeyStore_GetKey_NoPassword_Encrypted_Success() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -848,10 +944,37 @@
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
         PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
 
-        assertEquals("Inserted key should be same as retrieved key", actualKey, expectedKey);
+        assertEquals("Inserted key should be same as retrieved key",
+                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
     }
 
-    public void testKeyStore_GetKey_Certificate_Failure() throws Exception {
+    public void testKeyStore_GetKey_NoPassword_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+
+        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
+        assertNotNull("Key should exist", key);
+
+        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
+
+        RSAPrivateKey actualKey = (RSAPrivateKey) key;
+
+        KeyFactory keyFact = KeyFactory.getInstance("RSA");
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+        assertEquals("Inserted key should be same as retrieved key",
+                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
+    }
+
+    public void testKeyStore_GetKey_Certificate_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -859,21 +982,28 @@
         assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
     }
 
-    public void testKeyStore_GetKey_NonExistent_Failure() throws Exception {
+    public void testKeyStore_GetKey_NonExistent_Encrypted_Failure() throws Exception {
+        setupPassword();
+
         mKeyStore.load(null, null);
 
         assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
     }
 
-    public void testKeyStore_GetProvider_Success() throws Exception {
+    public void testKeyStore_GetProvider_Encrypted_Success() throws Exception {
+        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
+        setupPassword();
         assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
     }
 
-    public void testKeyStore_GetType_Success() throws Exception {
+    public void testKeyStore_GetType_Encrypted_Success() throws Exception {
+        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
+        setupPassword();
         assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
     }
 
-    public void testKeyStore_IsCertificateEntry_CA_Success() throws Exception {
+    public void testKeyStore_IsCertificateEntry_CA_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -882,7 +1012,8 @@
                 mKeyStore.isCertificateEntry(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_IsCertificateEntry_PrivateKey_Failure() throws Exception {
+    public void testKeyStore_IsCertificateEntry_PrivateKey_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -894,14 +1025,23 @@
                 mKeyStore.isCertificateEntry(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_IsCertificateEntry_NonExist_Failure() throws Exception {
+    public void testKeyStore_IsCertificateEntry_NonExist_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertFalse("Should return false for non-existent entry",
                 mKeyStore.isCertificateEntry(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_IsKeyEntry_PrivateKey_Success() throws Exception {
+    public void testKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertFalse("Should return false for non-existent entry",
+                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
+    }
+
+    public void testKeyStore_IsKeyEntry_PrivateKey_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -912,7 +1052,8 @@
         assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_IsKeyEntry_CA_Failure() throws Exception {
+    public void testKeyStore_IsKeyEntry_CA_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -920,17 +1061,19 @@
         assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_IsKeyEntry_NonExist_Failure() throws Exception {
+    public void testKeyStore_IsKeyEntry_NonExist_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertFalse("Should return false for non-existent entry",
                 mKeyStore.isKeyEntry(TEST_ALIAS_1));
     }
 
-    public void testKeyStore_SetCertificate_CA_Success() throws Exception {
+    public void testKeyStore_SetCertificate_CA_Encrypted_Success() throws Exception {
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
         final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
 
+        setupPassword();
         mKeyStore.load(null, null);
 
         mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
@@ -942,7 +1085,8 @@
                 retrieved);
     }
 
-    public void testKeyStore_SetCertificate_CAExists_Overwrite_Success() throws Exception {
+    public void testKeyStore_SetCertificate_CAExists_Overwrite_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -958,7 +1102,8 @@
         assertAliases(new String[] { TEST_ALIAS_1 });
     }
 
-    public void testKeyStore_SetCertificate_PrivateKeyExists_Failure() throws Exception {
+    public void testKeyStore_SetCertificate_PrivateKeyExists_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
@@ -978,7 +1123,8 @@
         }
     }
 
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Success() throws Exception {
+    public void testKeyStore_SetEntry_PrivateKeyEntry_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
@@ -1005,8 +1151,63 @@
         assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
     }
 
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Success()
+    public void testKeyStore_SetEntry_PrivateKeyEntry_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        KeyFactory keyFact = KeyFactory.getInstance("RSA");
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+        final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+        final Certificate[] expectedChain = new Certificate[2];
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
+
+        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
+
+        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+        assertNotNull("Retrieved entry should exist", actualEntry);
+
+        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+                actualEntry instanceof PrivateKeyEntry);
+
+        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+    }
+
+    public void testKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure() throws Exception {
+        mKeyStore.load(null, null);
+
+        KeyFactory keyFact = KeyFactory.getInstance("RSA");
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+        final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+        final Certificate[] expectedChain = new Certificate[2];
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+        PrivateKeyEntry entry = new PrivateKeyEntry(expectedKey, expectedChain);
+
+        try {
+            mKeyStore.setEntry(TEST_ALIAS_1, entry,
+                    new AndroidKeyStoreParameter.Builder(getContext())
+                    .setEncryptionRequired()
+                    .build());
+            fail("Shouldn't be able to insert encrypted entry when KeyStore uninitialized");
+        } catch (KeyStoreException expected) {
+        }
+
+        assertNull(mKeyStore.getEntry(TEST_ALIAS_1, null));
+    }
+
+    public void
+            testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()
             throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final KeyFactory keyFact = KeyFactory.getInstance("RSA");
@@ -1060,7 +1261,9 @@
         }
     }
 
-    public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Success() throws Exception {
+    public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()
+            throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1104,7 +1307,9 @@
         }
     }
 
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Success() throws Exception {
+    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Encrypted_Success()
+            throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1148,8 +1353,11 @@
         }
     }
 
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Success()
+    public
+            void
+            testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Encrypted_Success()
             throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1198,7 +1406,9 @@
         }
     }
 
-    public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Success() throws Exception {
+    public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Encrypted_Success()
+            throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1239,7 +1449,8 @@
         }
     }
 
-    public void testKeyStore_SetKeyEntry_ProtectedKey_Failure() throws Exception {
+    public void testKeyStore_SetKeyEntry_ProtectedKey_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1259,7 +1470,8 @@
         }
     }
 
-    public void testKeyStore_SetKeyEntry_Success() throws Exception {
+    public void testKeyStore_SetKeyEntry_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1285,7 +1497,8 @@
         assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
     }
 
-    public void testKeyStore_SetKeyEntry_Replaced_Success() throws Exception {
+    public void testKeyStore_SetKeyEntry_Replaced_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
@@ -1376,7 +1589,8 @@
         return cert;
     }
 
-    public void testKeyStore_SetKeyEntry_ReplacedChain_Success() throws Exception {
+    public void testKeyStore_SetKeyEntry_ReplacedChain_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         // Create key #1
@@ -1429,8 +1643,9 @@
         }
     }
 
-    public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Failure()
+    public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Encrypted_Failure()
             throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         // Create key #1
@@ -1472,7 +1687,48 @@
         }
     }
 
-    public void testKeyStore_Size_Success() throws Exception {
+    public void testKeyStore_SetKeyEntry_ReplacedChain_UnencryptedToEncrypted_Failure()
+            throws Exception {
+        mKeyStore.load(null, null);
+
+        // Create key #1
+        {
+            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
+            assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
+                    android.security.KeyStore.UID_SELF, android.security.KeyStore.FLAG_NONE));
+
+            X509Certificate cert =
+                    generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1, TEST_DN_1,
+                            NOW, NOW_PLUS_10_YEARS);
+
+            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
+                    cert.getEncoded(), android.security.KeyStore.UID_SELF,
+                    android.security.KeyStore.FLAG_NONE));
+        }
+
+        // Replace with one that requires encryption
+        {
+            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+
+            try {
+                mKeyStore.setEntry(TEST_ALIAS_1, entry, new AndroidKeyStoreParameter.Builder(
+                        getContext()).setEncryptionRequired().build());
+                fail("Should not allow setting of Entry without unlocked keystore");
+            } catch (KeyStoreException success) {
+            }
+
+            assertTrue(mAndroidKeyStore.password("1111"));
+            assertTrue(mAndroidKeyStore.isUnlocked());
+
+            mKeyStore.setEntry(TEST_ALIAS_1, entry,
+                    new AndroidKeyStoreParameter.Builder(getContext())
+                            .setEncryptionRequired()
+                            .build());
+        }
+    }
+
+    public void testKeyStore_Size_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
@@ -1501,7 +1757,8 @@
         assertAliases(new String[] { TEST_ALIAS_2 });
     }
 
-    public void testKeyStore_Store_LoadStoreParam_Failure() throws Exception {
+    public void testKeyStore_Store_LoadStoreParam_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         try {
@@ -1511,7 +1768,7 @@
         }
     }
 
-    public void testKeyStore_Load_InputStreamSupplied_Failure() throws Exception {
+    public void testKeyStore_Load_InputStreamSupplied_Encrypted_Failure() throws Exception {
         byte[] buf = "FAKE KEYSTORE".getBytes();
         ByteArrayInputStream is = new ByteArrayInputStream(buf);
 
@@ -1522,7 +1779,7 @@
         }
     }
 
-    public void testKeyStore_Load_PasswordSupplied_Failure() throws Exception {
+    public void testKeyStore_Load_PasswordSupplied_Encrypted_Failure() throws Exception {
         try {
             mKeyStore.load(null, "password".toCharArray());
             fail("Should throw IllegalArgumentException when password is supplied");
@@ -1530,7 +1787,8 @@
         }
     }
 
-    public void testKeyStore_Store_OutputStream_Failure() throws Exception {
+    public void testKeyStore_Store_OutputStream_Encrypted_Failure() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         OutputStream sink = new ByteArrayOutputStream();
@@ -1558,7 +1816,8 @@
                 cert.getEncoded()));
     }
 
-    public void testKeyStore_KeyOperations_Wrap_Success() throws Exception {
+    public void testKeyStore_KeyOperations_Wrap_Encrypted_Success() throws Exception {
+        setupPassword();
         mKeyStore.load(null, null);
 
         setupKey();
diff --git a/preloaded-classes b/preloaded-classes
index 126dd15..607c142 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1512,6 +1512,66 @@
 com.android.org.bouncycastle.util.encoders.HexEncoder
 com.android.org.bouncycastle.util.io.Streams
 com.android.org.bouncycastle.x509.ExtendedPKIXParameters
+com.android.org.conscrypt.AbstractSessionContext
+com.android.org.conscrypt.AbstractSessionContext$1
+com.android.org.conscrypt.ByteArray
+com.android.org.conscrypt.CertPinManager
+com.android.org.conscrypt.ClientSessionContext
+com.android.org.conscrypt.ClientSessionContext$HostAndPort
+com.android.org.conscrypt.DefaultSSLContextImpl
+com.android.org.conscrypt.FileClientSessionCache
+com.android.org.conscrypt.FileClientSessionCache$Impl
+com.android.org.conscrypt.JSSEProvider
+com.android.org.conscrypt.KeyManagerFactoryImpl
+com.android.org.conscrypt.KeyManagerImpl
+com.android.org.conscrypt.NativeCrypto
+com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
+com.android.org.conscrypt.OpenSSLCipherRSA
+com.android.org.conscrypt.OpenSSLCipherRSA$PKCS1
+com.android.org.conscrypt.OpenSSLCipherRSA$Raw
+com.android.org.conscrypt.OpenSSLContextImpl
+com.android.org.conscrypt.OpenSSLDSAKeyPairGenerator
+com.android.org.conscrypt.OpenSSLDSAPublicKey
+com.android.org.conscrypt.OpenSSLKey
+com.android.org.conscrypt.OpenSSLMessageDigestJDK
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA512
+com.android.org.conscrypt.OpenSSLProvider
+com.android.org.conscrypt.OpenSSLRSAKeyFactory
+com.android.org.conscrypt.OpenSSLRSAKeyPairGenerator
+com.android.org.conscrypt.OpenSSLRSAPublicKey
+com.android.org.conscrypt.OpenSSLRandom
+com.android.org.conscrypt.OpenSSLSessionImpl
+com.android.org.conscrypt.OpenSSLSignature
+com.android.org.conscrypt.OpenSSLSignature$EngineType
+com.android.org.conscrypt.OpenSSLSignature$MD5RSA
+com.android.org.conscrypt.OpenSSLSignature$SHA1DSA
+com.android.org.conscrypt.OpenSSLSignature$SHA1RSA
+com.android.org.conscrypt.OpenSSLSignature$SHA256RSA
+com.android.org.conscrypt.OpenSSLSignature$SHA384RSA
+com.android.org.conscrypt.OpenSSLSignature$SHA512RSA
+com.android.org.conscrypt.OpenSSLSignatureRawRSA
+com.android.org.conscrypt.OpenSSLSocketFactoryImpl
+com.android.org.conscrypt.OpenSSLSocketImpl
+com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream
+com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream
+com.android.org.conscrypt.OpenSSLSocketImplWrapper
+com.android.org.conscrypt.PinListEntry
+com.android.org.conscrypt.ProtocolVersion
+com.android.org.conscrypt.SSLClientSessionCache
+com.android.org.conscrypt.SSLContextImpl
+com.android.org.conscrypt.SSLParametersImpl
+com.android.org.conscrypt.ServerSessionContext
+com.android.org.conscrypt.TrustManagerFactoryImpl
+com.android.org.conscrypt.TrustManagerImpl
+com.android.org.conscrypt.TrustedCertificateIndex
+com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
+com.android.org.conscrypt.TrustedCertificateStore
+com.android.org.conscrypt.TrustedCertificateStore$1
+com.android.org.conscrypt.TrustedCertificateStore$2
+com.android.org.conscrypt.TrustedCertificateStore$3
+com.android.org.conscrypt.TrustedCertificateStore$CertSelector
 com.android.server.NetworkManagementSocketTagger
 com.android.server.NetworkManagementSocketTagger$1
 com.android.server.NetworkManagementSocketTagger$SocketTags
@@ -2273,66 +2333,6 @@
 org.apache.harmony.security.x509.Validity$1
 org.apache.harmony.xml.ExpatAttributes
 org.apache.harmony.xml.ExpatParser
-org.apache.harmony.xnet.provider.jsse.AbstractSessionContext
-org.apache.harmony.xnet.provider.jsse.AbstractSessionContext$1
-org.apache.harmony.xnet.provider.jsse.ByteArray
-org.apache.harmony.xnet.provider.jsse.CertPinManager
-org.apache.harmony.xnet.provider.jsse.ClientSessionContext
-org.apache.harmony.xnet.provider.jsse.ClientSessionContext$HostAndPort
-org.apache.harmony.xnet.provider.jsse.DefaultSSLContextImpl
-org.apache.harmony.xnet.provider.jsse.FileClientSessionCache
-org.apache.harmony.xnet.provider.jsse.FileClientSessionCache$Impl
-org.apache.harmony.xnet.provider.jsse.JSSEProvider
-org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl
-org.apache.harmony.xnet.provider.jsse.KeyManagerImpl
-org.apache.harmony.xnet.provider.jsse.NativeCrypto
-org.apache.harmony.xnet.provider.jsse.NativeCrypto$SSLHandshakeCallbacks
-org.apache.harmony.xnet.provider.jsse.OpenSSLCipherRSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLCipherRSA$PKCS1
-org.apache.harmony.xnet.provider.jsse.OpenSSLCipherRSA$Raw
-org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl
-org.apache.harmony.xnet.provider.jsse.OpenSSLDSAKeyPairGenerator
-org.apache.harmony.xnet.provider.jsse.OpenSSLDSAPublicKey
-org.apache.harmony.xnet.provider.jsse.OpenSSLKey
-org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK
-org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$MD5
-org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA1
-org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA512
-org.apache.harmony.xnet.provider.jsse.OpenSSLProvider
-org.apache.harmony.xnet.provider.jsse.OpenSSLRSAKeyFactory
-org.apache.harmony.xnet.provider.jsse.OpenSSLRSAKeyPairGenerator
-org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPublicKey
-org.apache.harmony.xnet.provider.jsse.OpenSSLRandom
-org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$EngineType
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$MD5RSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA1DSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA1RSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA256RSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA384RSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA512RSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSignatureRawRSA
-org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl
-org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
-org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream
-org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream
-org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImplWrapper
-org.apache.harmony.xnet.provider.jsse.PinListEntry
-org.apache.harmony.xnet.provider.jsse.ProtocolVersion
-org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache
-org.apache.harmony.xnet.provider.jsse.SSLContextImpl
-org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
-org.apache.harmony.xnet.provider.jsse.ServerSessionContext
-org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl
-org.apache.harmony.xnet.provider.jsse.TrustManagerImpl
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateIndex
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateKeyStoreSpi
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$1
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$2
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$3
-org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$CertSelector
 org.apache.http.ConnectionReuseStrategy
 org.apache.http.FormattedHeader
 org.apache.http.Header
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index a296d34..72aa203 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1493,7 +1493,9 @@
                 if (mStatusBar != null) {
                     mStatusBar.setImeWindowStatus(token, vis, backDisposition);
                 }
-                final boolean iconVisibility = (vis & InputMethodService.IME_ACTIVE) != 0;
+                final boolean iconVisibility = ((vis & (InputMethodService.IME_ACTIVE)) != 0)
+                        && (mWindowManagerService.isHardKeyboardAvailable()
+                                || (vis & (InputMethodService.IME_VISIBLE)) != 0);
                 final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
                 if (imi != null && iconVisibility && needsToShowImeSwitchOngoingNotification()) {
                     // Used to load label
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 27dd732..eafd09b 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -3623,7 +3623,9 @@
         }
 
         if (activityRemoved) {
-            resumeTopActivityLocked(null);
+            synchronized (mService) {
+                resumeTopActivityLocked(null);
+            }
         }
 
         return res;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index c16f0ee..92d1b89 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -8221,16 +8221,10 @@
                 mSettings.writeLPr();
             }
         }
-        // A user ID was deleted here. Go through all users and remove it from
-        // KeyStore.
-        final int appId = outInfo.removedAppId;
-        if (appId != -1) {
-            final KeyStore keyStore = KeyStore.getInstance();
-            if (keyStore != null) {
-                for (final int userId : sUserManager.getUserIds()) {
-                    keyStore.clearUid(UserHandle.getUid(userId, appId));
-                }
-            }
+        if (outInfo != null) {
+            // A user ID was deleted here. Go through all users and remove it
+            // from KeyStore.
+            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
         }
     }
 
@@ -8369,6 +8363,7 @@
                 outInfo.removedUsers = new int[] {removeUser};
             }
             mInstaller.clearUserData(packageName, removeUser);
+            removeKeystoreDataIfNeeded(removeUser, appId);
             schedulePackageCleaning(packageName, removeUser, false);
             return true;
         }
@@ -8520,29 +8515,34 @@
         }
         PackageParser.Package p;
         boolean dataOnly = false;
+        final int appId;
         synchronized (mPackages) {
             p = mPackages.get(packageName);
-            if(p == null) {
+            if (p == null) {
                 dataOnly = true;
                 PackageSetting ps = mSettings.mPackages.get(packageName);
-                if((ps == null) || (ps.pkg == null)) {
-                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
+                if ((ps == null) || (ps.pkg == null)) {
+                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
                     return false;
                 }
                 p = ps.pkg;
             }
-        }
-
-        if (!dataOnly) {
-            //need to check this only for fully installed applications
-            if (p == null) {
-                Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
-                return false;
+            if (!dataOnly) {
+                // need to check this only for fully installed applications
+                if (p == null) {
+                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
+                    return false;
+                }
+                final ApplicationInfo applicationInfo = p.applicationInfo;
+                if (applicationInfo == null) {
+                    Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
+                    return false;
+                }
             }
-            final ApplicationInfo applicationInfo = p.applicationInfo;
-            if (applicationInfo == null) {
-                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
-                return false;
+            if (p != null && p.applicationInfo != null) {
+                appId = p.applicationInfo.uid;
+            } else {
+                appId = -1;
             }
         }
         int retCode = mInstaller.clearUserData(packageName, userId);
@@ -8551,9 +8551,33 @@
                     + packageName);
             return false;
         }
+        removeKeystoreDataIfNeeded(userId, appId);
         return true;
     }
 
+    /**
+     * Remove entries from the keystore daemon. Will only remove it if the
+     * {@code appId} is valid.
+     */
+    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
+        if (appId < 0) {
+            return;
+        }
+
+        final KeyStore keyStore = KeyStore.getInstance();
+        if (keyStore != null) {
+            if (userId == UserHandle.USER_ALL) {
+                for (final int individual : sUserManager.getUserIds()) {
+                    keyStore.clearUid(UserHandle.getUid(individual, appId));
+                }
+            } else {
+                keyStore.clearUid(UserHandle.getUid(userId, appId));
+            }
+        } else {
+            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
+        }
+    }
+
     public void deleteApplicationCacheFiles(final String packageName,
             final IPackageDataObserver observer) {
         mContext.enforceCallingOrSelfPermission(
diff --git a/services/java/com/android/server/pm/SELinuxMMAC.java b/services/java/com/android/server/pm/SELinuxMMAC.java
index 4bbdb5e..04f43d9 100644
--- a/services/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/java/com/android/server/pm/SELinuxMMAC.java
@@ -57,7 +57,7 @@
 
     // Locations of potential install policy files.
     private static final File[] INSTALL_POLICY_FILE = {
-        new File(Environment.getDataDirectory(), "system/mac_permissions.xml"),
+        new File(Environment.getDataDirectory(), "security/mac_permissions.xml"),
         new File(Environment.getRootDirectory(), "etc/security/mac_permissions.xml"),
         null};
 
diff --git a/tests/CoreTests/android/Android.mk b/tests/CoreTests/android/Android.mk
index 5abfc88..bc0e4e4 100644
--- a/tests/CoreTests/android/Android.mk
+++ b/tests/CoreTests/android/Android.mk
@@ -6,7 +6,7 @@
 LOCAL_SRC_FILES := \
 	$(call all-subdir-java-files)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle
+LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt
 
 LOCAL_PACKAGE_NAME := CoreTests
 
diff --git a/tests/CoreTests/android/core/SSLSocketTest.java b/tests/CoreTests/android/core/SSLSocketTest.java
index 03905e1..b06790b 100644
--- a/tests/CoreTests/android/core/SSLSocketTest.java
+++ b/tests/CoreTests/android/core/SSLSocketTest.java
@@ -18,10 +18,10 @@
 
 import junit.framework.TestCase;
 
+import com.android.org.conscrypt.FileClientSessionCache;
+import com.android.org.conscrypt.OpenSSLContextImpl;
+import com.android.org.conscrypt.SSLClientSessionCache;
 import org.apache.commons.codec.binary.Base64;
-import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index f398de0..74ffeb0 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -48,6 +48,7 @@
         "   List contents of Zip-compatible archive.\n\n", gProgName);
     fprintf(stderr,
         " %s d[ump] [--values] WHAT file.{apk} [asset [asset ...]]\n"
+        "   strings          Print the contents of the resource table string pool in the APK.\n"
         "   badging          Print the label and icon for the app declared in APK.\n"
         "   permissions      Print the permissions from the APK.\n"
         "   resources        Print the resource table from the APK.\n"
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index d1e9b67..055bfb4 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -42,6 +42,7 @@
     private WifiStateMachine mWifiStateMachine;
     private WifiConfigStore mWifiConfigStore;
     private int mAuthenticationFailuresCount = 0;
+    private int mAssociationRejectCount = 0;
     /* Indicates authentication failure in supplicant broadcast.
      * TODO: enhance auth failure reporting to include notification
      * for all type of failures: EAP, WPS & WPA networks */
@@ -50,6 +51,9 @@
     /* Maximum retries on a authentication failure notification */
     private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
 
+    /* Maximum retries on assoc rejection events */
+    private static final int MAX_RETRIES_ON_ASSOCIATION_REJECT = 4;
+
     /* Tracks if networks have been disabled during a connection */
     private boolean mNetworksDisabledDuringConnect = false;
 
@@ -85,14 +89,14 @@
         start();
     }
 
-    private void handleNetworkConnectionFailure(int netId) {
+    private void handleNetworkConnectionFailure(int netId, int disableReason) {
         /* If other networks disabled during connection, enable them */
         if (mNetworksDisabledDuringConnect) {
             mWifiConfigStore.enableAllNetworks();
             mNetworksDisabledDuringConnect = false;
         }
         /* Disable failed network */
-        mWifiConfigStore.disableNetwork(netId, WifiConfiguration.DISABLED_AUTH_FAILURE);
+        mWifiConfigStore.disableNetwork(netId, disableReason);
     }
 
     private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) {
@@ -178,6 +182,10 @@
                     break;
                 case WifiManager.CONNECT_NETWORK:
                     mNetworksDisabledDuringConnect = true;
+                    mAssociationRejectCount = 0;
+                    break;
+                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
+                    mAssociationRejectCount++;
                     break;
                 default:
                     Log.e(TAG, "Ignoring " + message);
@@ -222,9 +230,17 @@
              if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
                  Log.d(TAG, "Failed to authenticate, disabling network " +
                          stateChangeResult.networkId);
-                 handleNetworkConnectionFailure(stateChangeResult.networkId);
+                 handleNetworkConnectionFailure(stateChangeResult.networkId,
+                         WifiConfiguration.DISABLED_AUTH_FAILURE);
                  mAuthenticationFailuresCount = 0;
              }
+             else if (mAssociationRejectCount >= MAX_RETRIES_ON_ASSOCIATION_REJECT) {
+                 Log.d(TAG, "Association getting rejected, disabling network " +
+                         stateChangeResult.networkId);
+                 handleNetworkConnectionFailure(stateChangeResult.networkId,
+                         WifiConfiguration.DISABLED_ASSOCIATION_REJECT);
+                 mAssociationRejectCount = 0;
+            }
          }
     }
 
@@ -264,7 +280,8 @@
                         if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) {
                             Log.d(TAG, "Supplicant loop detected, disabling network " +
                                     stateChangeResult.networkId);
-                            handleNetworkConnectionFailure(stateChangeResult.networkId);
+                            handleNetworkConnectionFailure(stateChangeResult.networkId,
+                                    WifiConfiguration.DISABLED_AUTH_FAILURE);
                         }
                         mLoopDetectIndex = state.ordinal();
                         sendSupplicantStateChangedBroadcast(state,
@@ -287,6 +304,7 @@
              if (DBG) Log.d(TAG, getName() + "\n");
              /* Reset authentication failure count */
              mAuthenticationFailuresCount = 0;
+             mAssociationRejectCount = 0;
              if (mNetworksDisabledDuringConnect) {
                  mWifiConfigStore.enableAllNetworks();
                  mNetworksDisabledDuringConnect = false;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index bf82792..f1542e9 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -173,6 +173,8 @@
     public static final int DISABLED_DHCP_FAILURE                           = 2;
     /** @hide */
     public static final int DISABLED_AUTH_FAILURE                           = 3;
+    /** @hide */
+    public static final int DISABLED_ASSOCIATION_REJECT                     = 4;
 
     /**
      * The ID number that the supplicant uses to identify this
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 7313e7e..25272b9 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -87,6 +87,7 @@
     private static final String ENGINE_KEY          = "engine";
     private static final String ENGINE_ID_KEY       = "engine_id";
     private static final String PRIVATE_KEY_ID_KEY  = "key_id";
+    private static final String OPP_KEY_CACHING     = "proactive_key_caching";
 
     private HashMap<String, String> mFields = new HashMap<String, String>();
     private X509Certificate mCaCert;
@@ -258,6 +259,7 @@
             case Eap.TLS:
             case Eap.TTLS:
                 mFields.put(EAP_KEY, Eap.strings[eapMethod]);
+                mFields.put(OPP_KEY_CACHING, "1");
                 break;
             default:
                 throw new IllegalArgumentException("Unknown EAP method");
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 0b0d7388e..fe3c709 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -56,7 +56,8 @@
     private static final int TERMINATING  = 6;
     private static final int DRIVER_STATE = 7;
     private static final int EAP_FAILURE  = 8;
-    private static final int UNKNOWN      = 9;
+    private static final int ASSOC_REJECT = 9;
+    private static final int UNKNOWN      = 10;
 
     /** All events coming from the supplicant start with this prefix */
     private static final String EVENT_PREFIX_STR = "CTRL-EVENT-";
@@ -153,6 +154,11 @@
     private static final String EAP_AUTH_FAILURE_STR = "EAP authentication failed";
 
     /**
+     * This indicates an assoc reject event
+     */
+    private static final String ASSOC_REJECT_STR = "ASSOC-REJECT";
+
+    /**
      * Regex pattern for extracting an Ethernet-style MAC address from a string.
      * Matches a strings like the following:<pre>
      * CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]</pre>
@@ -328,6 +334,8 @@
     public static final int AP_STA_DISCONNECTED_EVENT            = BASE + 41;
     public static final int AP_STA_CONNECTED_EVENT               = BASE + 42;
 
+    /* Indicates assoc reject event */
+    public static final int ASSOCIATION_REJECTION_EVENT          = BASE + 43;
     /**
      * This indicates the supplicant connection for the monitor is closed
      */
@@ -429,6 +437,8 @@
                     event = DRIVER_STATE;
                 else if (eventName.equals(EAP_FAILURE_STR))
                     event = EAP_FAILURE;
+                else if (eventName.equals(ASSOC_REJECT_STR))
+                    event = ASSOC_REJECT;
                 else
                     event = UNKNOWN;
 
@@ -473,6 +483,8 @@
                     if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
                         mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
                     }
+                } else if (event == ASSOC_REJECT) {
+                        mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
                 } else {
                     handleEvent(event, eventData);
                 }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 2d9cc29..880040b 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1962,6 +1962,7 @@
                 case WifiMonitor.SCAN_RESULTS_EVENT:
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
+                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
                 case WifiMonitor.WPS_OVERLAP_EVENT:
                 case CMD_BLACKLIST_NETWORK:
                 case CMD_CLEAR_BLACKLIST:
@@ -2698,6 +2699,7 @@
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
+                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
                 case WifiMonitor.WPS_OVERLAP_EVENT:
                 case CMD_SET_SCAN_TYPE:
                 case CMD_SET_COUNTRY_CODE:
@@ -3092,6 +3094,9 @@
             if (DBG) log(getName() + message.toString() + "\n");
             StateChangeResult stateChangeResult;
             switch(message.what) {
+                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
+                    mSupplicantStateTracker.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT);
+                    break;
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
                     mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT);
                     break;
@@ -3786,6 +3791,9 @@
                     if (DBG) log("Network connection lost");
                     handleNetworkDisconnect();
                     break;
+                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
+                    if (DBG) log("Ignore Assoc reject event during WPS Connection");
+                    break;
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
                     // Disregard auth failure events during WPS connection. The
                     // EAP sequence is retried several times, and there might be
@@ -3983,6 +3991,7 @@
                     if (!isWifiTethered(stateChange.active)) {
                         loge("Tethering reports wifi as untethered!, shut down soft Ap");
                         setWifiApEnabled(null, false);
+                        setWifiApEnabled(null, true);
                     }
                     return HANDLED;
                 case CMD_STOP_AP:
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 532148e..3325b2b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -1312,6 +1312,11 @@
                          * TODO: Verify multi-channel scenarios and supplicant behavior are
                          * better before adding a time out in future
                          */
+                        //Set group idle timeout of 10 sec, to avoid GO beaconing incase of any
+                        //failure during 4-way Handshake.
+                        if (!mAutonomousGroup) {
+                            mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
+                        }
                         startDhcpServer(mGroup.getInterface());
                     } else {
                         mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
@@ -1507,6 +1512,8 @@
                 case WifiMonitor.AP_STA_CONNECTED_EVENT:
                     WifiP2pDevice device = (WifiP2pDevice) message.obj;
                     String deviceAddress = device.deviceAddress;
+                    // Clear timeout that was set when group was started.
+                    mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
                     if (deviceAddress != null) {
                         if (mSavedProvDiscDevice != null &&
                                 deviceAddress.equals(mSavedProvDiscDevice.deviceAddress)) {