Merge "Set crop params to ANative Window during Initialization."
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index e40de26..c3a14ca 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -201,7 +201,7 @@
         public static final int CAMERA_FACING_FRONT = 1;
 
         /**
-         * The direction that the camera faces to. It should be
+         * The direction that the camera faces. It should be
          * CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
          */
         public int facing;
@@ -1055,9 +1055,9 @@
         /**
          * Notify the listener of the detected faces in the preview frame.
          *
-         * @param faces the detected faces. The list is sorted by the score.
-         *              The highest score is the first element.
-         * @param camera  the Camera service object
+         * @param faces The detected faces in a list sorted by the confidence score.
+         *              The highest scored face is the first element.
+         * @param camera  The {@link Camera} service object
          */
         void onFaceDetection(Face[] faces, Camera camera);
     }
@@ -1105,7 +1105,7 @@
     /**
      * Stops the face detection.
      *
-     * @see #startFaceDetection(int)
+     * @see #startFaceDetection()
      */
     public final void stopFaceDetection() {
         _stopFaceDetection();
@@ -1116,8 +1116,12 @@
     private native final void _stopFaceDetection();
 
     /**
-     * The information of a face from camera face detection.
+     * Information about a face identified through camera face detection.
+     * 
+     * <p>When face detection is used with a camera, the {@link FaceDetectionListener} returns a
+     * list of face objects for use in focusing and metering.</p>
      *
+     * @see FaceDetectionListener
      */
     public static class Face {
         /**
@@ -1138,15 +1142,15 @@
          * the sensor sees. The direction is not affected by the rotation or
          * mirroring of {@link #setDisplayOrientation(int)}.</p>
          *
-         * @see #startFaceDetection(int)
+         * @see #startFaceDetection()
          */
         public Rect rect;
 
         /**
-         * The confidence level of the face. The range is 1 to 100. 100 is the
+         * The confidence level for the detection of the face. The range is 1 to 100. 100 is the
          * highest confidence.
          *
-         * @see #startFaceDetection(int)
+         * @see #startFaceDetection()
          */
         public int score;
 
@@ -3144,7 +3148,7 @@
          * supported.
          *
          * @return the maximum number of detected face supported by the camera.
-         * @see #startFaceDetection(int)
+         * @see #startFaceDetection()
          */
         public int getMaxNumDetectedFaces() {
             return getInt(KEY_MAX_NUM_DETECTED_FACES_HW, 0);
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
index 68a1dc3..5998f5f 100644
--- a/core/java/android/net/http/SslError.java
+++ b/core/java/android/net/http/SslError.java
@@ -163,10 +163,6 @@
      * Gets the URL associated with this object.
      * @return The URL, non-null.
      */
-    // TODO: When the WebView constructs an instance of this object, we
-    // actually provide only the hostname, not the full URL. We should consider
-    // deprecating this method, adding a new getHost() method and updating the
-    // constructor arguments. See http://b/5410252.
     public String getUrl() {
         return mUrl;
     }
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 28f54aa..8c22da0 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -43,7 +43,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
-import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.charset.Charsets;
 import java.security.PrivateKey;
@@ -472,8 +471,6 @@
 
     /**
      * We have received an SSL certificate for the main top-level page.
-     *
-     * !!!Called from the network thread!!!
      */
     void certificate(SslCertificate certificate) {
         if (mIsMainFrame) {
@@ -1171,12 +1168,7 @@
         try {
             X509Certificate cert = new X509CertImpl(certDER);
             SslCertificate sslCert = new SslCertificate(cert);
-            if (JniUtil.useChromiumHttpStack()) {
-                sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert,
-                        new URL(url).getHost());
-            } else {
-                sslError = new SslError(certError, cert, url);
-            }
+            sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert, url);
         } catch (IOException e) {
             // Can't get the certificate, not much to do.
             Log.e(LOGTAG, "Can't get the certificate from WebKit, canceling");
@@ -1192,12 +1184,11 @@
         SslErrorHandler handler = new SslErrorHandler() {
             @Override
             public void proceed() {
-                SslCertLookupTable.getInstance().setIsAllowed(sslError, true);
+                SslCertLookupTable.getInstance().setIsAllowed(sslError);
                 nativeSslCertErrorProceed(handle);
             }
             @Override
             public void cancel() {
-                SslCertLookupTable.getInstance().setIsAllowed(sslError, false);
                 nativeSslCertErrorCancel(handle, certError);
             }
         };
diff --git a/core/java/android/webkit/SslCertLookupTable.java b/core/java/android/webkit/SslCertLookupTable.java
index 052244f..a06836c 100644
--- a/core/java/android/webkit/SslCertLookupTable.java
+++ b/core/java/android/webkit/SslCertLookupTable.java
@@ -19,10 +19,14 @@
 import android.os.Bundle;
 import android.net.http.SslError;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+
 /**
  * Stores the user's decision of whether to allow or deny an invalid certificate.
  *
- * This class is not threadsafe. It is used only on the WebCore thread.
+ * This class is not threadsafe. It is used only on the WebCore thread. Also, it
+ * is used only by the Chromium HTTP stack.
  */
 final class SslCertLookupTable {
     private static SslCertLookupTable sTable;
@@ -39,15 +43,33 @@
         table = new Bundle();
     }
 
-    public void setIsAllowed(SslError sslError, boolean allow) {
-        table.putBoolean(sslError.toString(), allow);
+    public void setIsAllowed(SslError sslError) {
+        // TODO: We should key on just the host. See http://b/5409251.
+        String errorString = sslErrorToString(sslError);
+        if (errorString != null) {
+            table.putBoolean(errorString, true);
+        }
     }
 
     public boolean isAllowed(SslError sslError) {
-        return table.getBoolean(sslError.toString());
+        // TODO: We should key on just the host. See http://b/5409251.
+        String errorString = sslErrorToString(sslError);
+        return errorString == null ? false : table.getBoolean(errorString);
     }
 
     public void clear() {
         table.clear();
     }
+
+    private static String sslErrorToString(SslError error) {
+        String host;
+        try {
+            host = new URL(error.getUrl()).getHost();
+        } catch(MalformedURLException e) {
+            return null;
+        }
+        return "primary error: " + error.getPrimaryError() +
+                " certificate: " + error.getCertificate() +
+                " on host: " + host;
+    }
 }
diff --git a/core/java/android/webkit/SslErrorHandlerImpl.java b/core/java/android/webkit/SslErrorHandlerImpl.java
index e029e37..82cd3e8 100644
--- a/core/java/android/webkit/SslErrorHandlerImpl.java
+++ b/core/java/android/webkit/SslErrorHandlerImpl.java
@@ -16,8 +16,6 @@
 
 package android.webkit;
 
-import junit.framework.Assert;
-
 import android.net.http.SslError;
 import android.os.Bundle;
 import android.os.Handler;
@@ -54,7 +52,7 @@
     private final SslErrorHandler mOriginHandler;
     private final LoadListener mLoadListener;
 
-    // Message id for handling the response
+    // Message id for handling the response from the client.
     private static final int HANDLE_RESPONSE = 100;
 
     @Override
@@ -130,7 +128,9 @@
     }
 
     /**
-     * Handles SSL error(s) on the way up to the user.
+     * Handles requests from the network stack about whether to proceed with a
+     * load given an SSL error(s). We may ask the client what to do, or use a
+     * cached response.
      */
     /* package */ synchronized void handleSslErrorRequest(LoadListener loader) {
         if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -147,8 +147,10 @@
     }
 
     /**
-     * Check the preference table for a ssl error that has already been shown
-     * to the user.
+     * Check the preference table to see if we already have a 'proceed' decision
+     * from the client for this host and for an error of equal or greater
+     * severity than the supplied error. If so, instruct the loader to proceed
+     * and return true. Otherwise return false.
      */
     /* package */ synchronized boolean checkSslPrefTable(LoadListener loader,
             SslError error) {
@@ -156,21 +158,22 @@
         final int primary = error.getPrimaryError();
 
         if (DebugFlags.SSL_ERROR_HANDLER) {
-            Assert.assertTrue(host != null && primary != 0);
+            assert host != null;
+            assert primary != 0;
         }
 
-        if (mSslPrefTable.containsKey(host)) {
-            if (primary <= mSslPrefTable.getInt(host)) {
-                handleSslErrorResponse(loader, error, true);
-                return true;
+        if (mSslPrefTable.containsKey(host) && primary <= mSslPrefTable.getInt(host)) {
+            if (!loader.cancelled()) {
+                loader.handleSslErrorResponse(true);
             }
+            return true;
         }
         return false;
     }
 
     /**
      * Processes queued SSL-error confirmation requests in
-     * a tight loop while there is no need to ask the user.
+     * a tight loop while there is no need to ask the client.
      */
     /* package */void fastProcessQueuedSslErrors() {
         while (processNextLoader());
@@ -195,19 +198,18 @@
             SslError error = loader.sslError();
 
             if (DebugFlags.SSL_ERROR_HANDLER) {
-                Assert.assertNotNull(error);
+                assert error != null;
             }
 
-            // checkSslPrefTable will handle the ssl error response if the
-            // answer is available. It does not remove the loader from the
-            // queue.
+            // checkSslPrefTable() will instruct the loader to proceed if we
+            // have a cached 'proceed' decision. It does not remove the loader
+            // from the queue.
             if (checkSslPrefTable(loader, error)) {
                 mLoaderQueue.remove(loader);
                 return true;
             }
 
-            // if we do not have information on record, ask
-            // the user (display a dialog)
+            // If we can not proceed based on a cached decision, ask the client.
             CallbackProxy proxy = loader.getFrame().getCallbackProxy();
             proxy.onReceivedSslError(new SslErrorHandlerImpl(this, loader), error);
         }
@@ -217,32 +219,31 @@
     }
 
     /**
-     * Proceed with the SSL certificate.
+     * Proceed with this load.
      */
     public void proceed() {
-        mOriginHandler.sendMessage(
-                mOriginHandler.obtainMessage(
-                        HANDLE_RESPONSE, 1, 0, mLoadListener));
+        mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
+                HANDLE_RESPONSE, 1, 0, mLoadListener));
     }
 
     /**
-     * Cancel this request and all pending requests for the WebView that had
-     * the error.
+     * Cancel this load and all pending loads for the WebView that had the
+     * error.
      */
     public void cancel() {
-        mOriginHandler.sendMessage(
-                mOriginHandler.obtainMessage(
-                        HANDLE_RESPONSE, 0, 0, mLoadListener));
+        mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
+                HANDLE_RESPONSE, 0, 0, mLoadListener));
     }
 
     /**
-     * Handles SSL error(s) on the way down from the user.
+     * Handles the response from the client about whether to proceed with this
+     * load. We save the response to be re-used in the future.
      */
     /* package */ synchronized void handleSslErrorResponse(LoadListener loader,
             SslError error, boolean proceed) {
         if (DebugFlags.SSL_ERROR_HANDLER) {
-            Assert.assertNotNull(loader);
-            Assert.assertNotNull(error);
+            assert loader != null;
+            assert error != null;
         }
 
         if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -253,16 +254,16 @@
 
         if (!loader.cancelled()) {
             if (proceed) {
-                // update the user's SSL error preference table
+                // Update the SSL error preference table
                 int primary = error.getPrimaryError();
                 String host = loader.host();
 
                 if (DebugFlags.SSL_ERROR_HANDLER) {
-                    Assert.assertTrue(host != null && primary != 0);
+                    assert host != null;
+                    assert primary != 0;
                 }
                 boolean hasKey = mSslPrefTable.containsKey(host);
-                if (!hasKey ||
-                    primary > mSslPrefTable.getInt(host)) {
+                if (!hasKey || primary > mSslPrefTable.getInt(host)) {
                     mSslPrefTable.putInt(host, primary);
                 }
             }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 5ca7aff..1e45f68 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -2597,6 +2597,15 @@
         public boolean processMessage(Message message) {
             if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
+                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
+                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+                    SupplicantState state = stateChangeResult.state;
+                    // A WEXT bug means that we can be back to driver started state
+                    // unexpectedly
+                    if (SupplicantState.isDriverActive(state)) {
+                        transitionTo(mDriverStartedState);
+                    }
+                    break;
                 case CMD_START_DRIVER:
                     mWakeLock.acquire();
                     WifiNative.startDriverCommand();
@@ -2667,8 +2676,18 @@
                     sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
                     break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    handleSupplicantStateChange(message);
-                   break;
+                    SupplicantState state = handleSupplicantStateChange(message);
+                    // Due to a WEXT bug, during the time of driver start/stop
+                    // we can go into a driver stopped state in an unexpected way.
+                    // The sequence eventually puts interface
+                    // up and we should be back to a connected state
+                    if (!SupplicantState.isDriverActive(state)) {
+                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
+                            handleNetworkDisconnect();
+                        }
+                        transitionTo(mDriverStoppedState);
+                    }
+                    break;
                     /* Do a redundant disconnect without transition */
                 case CMD_DISCONNECT:
                     WifiNative.disconnectCommand();