Merge "Specifying -1 for both low and highwater marks would not actually do the right thing"
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 8c22da0..c8b67a8 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -471,6 +471,7 @@
 
     /**
      * We have received an SSL certificate for the main top-level page.
+     * Used by the Android HTTP stack only.
      */
     void certificate(SslCertificate certificate) {
         if (mIsMainFrame) {
@@ -1178,6 +1179,7 @@
 
         if (SslCertLookupTable.getInstance().isAllowed(sslError)) {
             nativeSslCertErrorProceed(handle);
+            mCallbackProxy.onProceededAfterSslError(sslError);
             return;
         }
 
@@ -1267,7 +1269,8 @@
     }
 
     /**
-     * Called by JNI when we load a page over SSL.
+     * Called by JNI when we recieve a certificate for the page's main resource.
+     * Used by the Chromium HTTP stack only.
      */
     private void setCertificate(byte cert_der[]) {
         try {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 5ee90a4..75ee338 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -77,53 +77,54 @@
     // Used to call startActivity during url override.
     private final Context mContext;
 
-    // Message Ids
-    private static final int PAGE_STARTED                        = 100;
-    private static final int RECEIVED_ICON                       = 101;
-    private static final int RECEIVED_TITLE                      = 102;
-    private static final int OVERRIDE_URL                        = 103;
-    private static final int AUTH_REQUEST                        = 104;
-    private static final int SSL_ERROR                           = 105;
-    private static final int PROGRESS                            = 106;
-    private static final int UPDATE_VISITED                      = 107;
-    private static final int LOAD_RESOURCE                       = 108;
-    private static final int CREATE_WINDOW                       = 109;
-    private static final int CLOSE_WINDOW                        = 110;
-    private static final int SAVE_PASSWORD                       = 111;
-    private static final int JS_ALERT                            = 112;
-    private static final int JS_CONFIRM                          = 113;
-    private static final int JS_PROMPT                           = 114;
-    private static final int JS_UNLOAD                           = 115;
-    private static final int ASYNC_KEYEVENTS                     = 116;
-    private static final int DOWNLOAD_FILE                       = 118;
-    private static final int REPORT_ERROR                        = 119;
-    private static final int RESEND_POST_DATA                    = 120;
-    private static final int PAGE_FINISHED                       = 121;
-    private static final int REQUEST_FOCUS                       = 122;
-    private static final int SCALE_CHANGED                       = 123;
-    private static final int RECEIVED_CERTIFICATE                = 124;
-    private static final int SWITCH_OUT_HISTORY                  = 125;
-    private static final int EXCEEDED_DATABASE_QUOTA             = 126;
-    private static final int REACHED_APPCACHE_MAXSIZE            = 127;
-    private static final int JS_TIMEOUT                          = 128;
-    private static final int ADD_MESSAGE_TO_CONSOLE              = 129;
-    private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT = 130;
-    private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT = 131;
-    private static final int RECEIVED_TOUCH_ICON_URL             = 132;
-    private static final int GET_VISITED_HISTORY                 = 133;
-    private static final int OPEN_FILE_CHOOSER                   = 134;
-    private static final int ADD_HISTORY_ITEM                    = 135;
-    private static final int HISTORY_INDEX_CHANGED               = 136;
-    private static final int AUTH_CREDENTIALS                    = 137;
-    private static final int SET_INSTALLABLE_WEBAPP              = 138;
-    private static final int NOTIFY_SEARCHBOX_LISTENERS          = 139;
-    private static final int AUTO_LOGIN                          = 140;
-    private static final int CLIENT_CERT_REQUEST                 = 141;
-    private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK     = 142;
-    private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK= 143;
+    // Message IDs
+    private static final int PAGE_STARTED                         = 100;
+    private static final int RECEIVED_ICON                        = 101;
+    private static final int RECEIVED_TITLE                       = 102;
+    private static final int OVERRIDE_URL                         = 103;
+    private static final int AUTH_REQUEST                         = 104;
+    private static final int SSL_ERROR                            = 105;
+    private static final int PROGRESS                             = 106;
+    private static final int UPDATE_VISITED                       = 107;
+    private static final int LOAD_RESOURCE                        = 108;
+    private static final int CREATE_WINDOW                        = 109;
+    private static final int CLOSE_WINDOW                         = 110;
+    private static final int SAVE_PASSWORD                        = 111;
+    private static final int JS_ALERT                             = 112;
+    private static final int JS_CONFIRM                           = 113;
+    private static final int JS_PROMPT                            = 114;
+    private static final int JS_UNLOAD                            = 115;
+    private static final int ASYNC_KEYEVENTS                      = 116;
+    private static final int DOWNLOAD_FILE                        = 118;
+    private static final int REPORT_ERROR                         = 119;
+    private static final int RESEND_POST_DATA                     = 120;
+    private static final int PAGE_FINISHED                        = 121;
+    private static final int REQUEST_FOCUS                        = 122;
+    private static final int SCALE_CHANGED                        = 123;
+    private static final int RECEIVED_CERTIFICATE                 = 124;
+    private static final int SWITCH_OUT_HISTORY                   = 125;
+    private static final int EXCEEDED_DATABASE_QUOTA              = 126;
+    private static final int REACHED_APPCACHE_MAXSIZE             = 127;
+    private static final int JS_TIMEOUT                           = 128;
+    private static final int ADD_MESSAGE_TO_CONSOLE               = 129;
+    private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT  = 130;
+    private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT  = 131;
+    private static final int RECEIVED_TOUCH_ICON_URL              = 132;
+    private static final int GET_VISITED_HISTORY                  = 133;
+    private static final int OPEN_FILE_CHOOSER                    = 134;
+    private static final int ADD_HISTORY_ITEM                     = 135;
+    private static final int HISTORY_INDEX_CHANGED                = 136;
+    private static final int AUTH_CREDENTIALS                     = 137;
+    private static final int SET_INSTALLABLE_WEBAPP               = 138;
+    private static final int NOTIFY_SEARCHBOX_LISTENERS           = 139;
+    private static final int AUTO_LOGIN                           = 140;
+    private static final int CLIENT_CERT_REQUEST                  = 141;
+    private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK      = 142;
+    private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK = 143;
+    private static final int PROCEEDED_AFTER_SSL_ERROR            = 144;
 
     // Message triggered by the client to resume execution
-    private static final int NOTIFY                              = 200;
+    private static final int NOTIFY                               = 200;
 
     // Result transportation object for returning results across thread
     // boundaries.
@@ -349,6 +350,13 @@
                 }
                 break;
 
+            case PROCEEDED_AFTER_SSL_ERROR:
+                if (mWebViewClient != null) {
+                    mWebViewClient.onProceededAfterSslError(mWebView,
+                            (SslError) msg.obj);
+                }
+                break;
+
             case CLIENT_CERT_REQUEST:
                 if (mWebViewClient != null) {
                     HashMap<String, Object> map =
@@ -1024,6 +1032,15 @@
         sendMessage(msg);
     }
 
+    public void onProceededAfterSslError(SslError error) {
+        if (mWebViewClient == null) {
+            return;
+        }
+        Message msg = obtainMessage(PROCEEDED_AFTER_SSL_ERROR);
+        msg.obj = error;
+        sendMessage(msg);
+    }
+
     public void onReceivedClientCertRequest(ClientCertRequestHandler handler, String host_and_port) {
         // Do an unsynchronized quick check to avoid posting if no callback has
         // been set.
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index d3be2bf..81de356 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -186,11 +186,11 @@
     }
 
     /**
-     * Notify the host application to handle a SSL certificate error request
-     * (display the error to the user and ask whether to proceed or not). The
-     * host application has to call either handler.cancel() or handler.proceed()
-     * as the connection is suspended and waiting for the response. The default
-     * behavior is to cancel the load.
+     * Notify the host application that an SSL error occurred while loading a
+     * resource. The host application must call either handler.cancel() or
+     * handler.proceed(). Note that the decision may be retained for use in
+     * response to future SSL errors. The default behavior is to cancel the
+     * load.
      *
      * @param view The WebView that is initiating the callback.
      * @param handler An SslErrorHandler object that will handle the user's
@@ -203,6 +203,15 @@
     }
 
     /**
+     * Notify the host application that an SSL error occurred while loading a
+     * resource, but the WebView but chose to proceed anyway based on a
+     * decision retained from a previous response to onReceivedSslError().
+     * @hide
+     */
+    public void onProceededAfterSslError(WebView view, SslError error) {
+    }
+
+    /**
      * Notify the host application to handle a SSL client certificate
      * request (display the request to the user and ask whether to
      * proceed with a client certificate or not). The host application
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 31544b3..c3ced4c2 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -80,24 +80,33 @@
 
 class CameraHardwareInterface : public virtual RefBase {
 public:
-    CameraHardwareInterface(hw_module_t *module, const char *name)
+    CameraHardwareInterface(const char *name)
     {
         mDevice = 0;
         mName = name;
-        LOGI("Opening camera %s, this %p", name, this);
-        int rc = module->methods->open(module, name,
-                                       (hw_device_t **)&mDevice);
-        if (rc != OK)
-            LOGE("Could not open camera %s: %d", name, rc);
-        initHalPreviewWindow();
     }
 
     ~CameraHardwareInterface()
     {
         LOGI("Destroying camera %s", mName.string());
-        int rc = mDevice->common.close(&mDevice->common);
-        if (rc != OK)
-            LOGE("Could not close camera %s: %d", mName.string(), rc);
+        if(mDevice) {
+            int rc = mDevice->common.close(&mDevice->common);
+            if (rc != OK)
+                LOGE("Could not close camera %s: %d", mName.string(), rc);
+        }
+    }
+
+    status_t initialize(hw_module_t *module)
+    {
+        LOGI("Opening camera %s", mName.string());
+        int rc = module->methods->open(module, mName.string(),
+                                       (hw_device_t **)&mDevice);
+        if (rc != OK) {
+            LOGE("Could not open camera %s: %d", mName.string(), rc);
+            return rc;
+        }
+        initHalPreviewWindow();
+        return rc;
     }
 
     /** Set the ANativeWindow to which preview frames are sent */
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 05e7bcf..f306e4a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -133,6 +133,8 @@
 sp<ICamera> CameraService::connect(
         const sp<ICameraClient>& cameraClient, int cameraId) {
     int callingPid = getCallingPid();
+    sp<CameraHardwareInterface> hardware = NULL;
+
     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
 
     if (!mModule) {
@@ -187,10 +189,13 @@
     char camera_device_name[10];
     snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
 
-    client = new Client(this, cameraClient,
-                new CameraHardwareInterface(&mModule->common,
-                                            camera_device_name),
-                cameraId, info.facing, callingPid);
+    hardware = new CameraHardwareInterface(camera_device_name);
+    if (hardware->initialize(&mModule->common) != OK) {
+        hardware.clear();
+        return NULL;
+    }
+
+    client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
     mClient[cameraId] = client;
     LOG1("CameraService::connect X");
     return client;