OSDN Git Service

b/3347670 Support installing online certs to the system keystore.
authorHuahui Wu <hwu@google.com>
Thu, 27 Jan 2011 05:55:20 +0000 (21:55 -0800)
committerHuahui Wu <hwu@google.com>
Thu, 27 Jan 2011 20:54:16 +0000 (12:54 -0800)
Requires another CL in framework.
    https://android-git.corp.google.com/g/#change,93329

Change-Id: Ie623b55b6580d9761cc7de6b1b1708fbb2f0c633

WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
WebKit/android/jni/WebCoreFrameBridge.cpp
WebKit/android/jni/WebCoreFrameBridge.h

index 1c21c3c..864dc30 100644 (file)
@@ -100,6 +100,7 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHand
     : m_webFrame(webFrame)
     , m_resourceHandle(resourceHandle)
     , m_isMainResource(false)
+    , m_isCertMimeType(false)
     , m_cancelling(false)
     , m_sync(false)
     , m_finished(false)
@@ -199,12 +200,35 @@ bool WebUrlLoaderClient::start(bool isMainResource, bool sync, WebRequestContext
     return true;
 }
 
+namespace {
+// Check if the mime type is for certificate installation.
+// The items must be consistent with the sCertificateTypeMap
+// in frameworks/base/core/java/android/webkit/CertTool.java.
+bool isMimeTypeForCert(const std::string& mimeType)
+{
+    static std::hash_set<std::string> sCertificateTypeSet;
+    if (sCertificateTypeSet.empty()) {
+        sCertificateTypeSet.insert("application/x-x509-ca-cert");
+        sCertificateTypeSet.insert("application/x-x509-user-cert");
+        sCertificateTypeSet.insert("application/x-pkcs12");
+    }
+    return sCertificateTypeSet.find(mimeType) != sCertificateTypeSet.end();
+}
+}
+
 void WebUrlLoaderClient::downloadFile()
 {
     if (m_response) {
         std::string contentDisposition;
         m_response->getHeader("content-disposition", &contentDisposition);
         m_webFrame->downloadStart(m_request->getUrl(), m_request->getUserAgent(), contentDisposition, m_response->getMimeType(), m_response->getExpectedSize());
+
+        m_isCertMimeType = isMimeTypeForCert(m_response->getMimeType());
+        // Currently, only certificate mime type needs to receive the data.
+        // Other mime type, e.g. wav, will send the url to other application
+        // which will load the data by url.
+        if (!m_isCertMimeType)
+            cancel();
     } else {
         LOGE("Unexpected call to downloadFile() before didReceiveResponse(). URL: %s", m_request->getUrl().c_str());
         // TODO: Turn off asserts crashing before release
@@ -362,6 +386,10 @@ void WebUrlLoaderClient::didReceiveResponse(PassOwnPtr<WebResponse> webResponse)
 
 void WebUrlLoaderClient::didReceiveData(scoped_refptr<net::IOBuffer> buf, int size)
 {
+    if (m_isMainResource && m_isCertMimeType) {
+        m_webFrame->didReceiveData(buf->data(), size);
+    }
+
     if (!isActive() || !size)
         return;
 
@@ -425,6 +453,10 @@ void WebUrlLoaderClient::didFinishLoading()
     if (isActive())
         m_resourceHandle->client()->didFinishLoading(m_resourceHandle.get(), 0);
 
+    if (m_isMainResource && m_isCertMimeType) {
+        m_webFrame->didFinishLoading();
+    }
+
     // Always finish a request, if not it will leak
     finish();
 }
index bf53c00..59ec28b 100644 (file)
@@ -104,6 +104,7 @@ private:
     WebFrame* m_webFrame;
     RefPtr<WebCore::ResourceHandle> m_resourceHandle;
     bool m_isMainResource;
+    bool m_isCertMimeType;
     bool m_cancelling;
     bool m_sync;
     volatile bool m_finished;
index 476f017..9780d2d 100644 (file)
@@ -217,6 +217,8 @@ struct WebFrame::JavaBrowserFrame
     jmethodID   mDidReceiveAuthenticationChallenge;
     jmethodID   mReportSslCertError;
     jmethodID   mDownloadStart;
+    jmethodID   mDidReceiveData;
+    jmethodID   mDidFinishLoading;
     jmethodID   mSetCertificate;
     AutoJObject frame(JNIEnv* env) {
         return getRealObject(env, mObj);
@@ -286,6 +288,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
     mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[B)V");
     mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V");
+    mJavaFrame->mDidReceiveData = env->GetMethodID(clazz, "didReceiveData", "([BI)V");
+    mJavaFrame->mDidFinishLoading = env->GetMethodID(clazz, "didFinishLoading", "()V");
     mJavaFrame->mSetCertificate = env->GetMethodID(clazz, "setCertificate",
             "(Ljava/lang/String;Ljava/lang/String;JJ)V");
     env->DeleteLocalRef(clazz);
@@ -315,6 +319,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
     LOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge");
     LOG_ASSERT(mJavaFrame->mReportSslCertError, "Could not find method reportSslCertError");
     LOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart");
+    LOG_ASSERT(mJavaFrame->mDidReceiveData, "Could not find method didReceiveData");
+    LOG_ASSERT(mJavaFrame->mDidFinishLoading, "Could not find method didFinishLoading");
     LOG_ASSERT(mJavaFrame->mSetCertificate, "Could not find method setCertificate");
 
     mUserAgent = WTF::String();
@@ -912,6 +918,35 @@ WebFrame::downloadStart(const std::string& url, const std::string& userAgent, co
     env->DeleteLocalRef(jMimetype);
     checkException(env);
 }
+
+void
+WebFrame::didReceiveData(const char* data, int size) {
+#ifdef ANDROID_INSTRUMENT
+    TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
+#endif
+    JNIEnv* env = getJNIEnv();
+
+    jbyteArray jData = env->NewByteArray(size);
+    jbyte* bytes = env->GetByteArrayElements(jData, NULL);
+    memcpy(reinterpret_cast<char*>(bytes), data, size);
+
+    env->CallVoidMethod(mJavaFrame->frame(env).get(),
+            mJavaFrame->mDidReceiveData, jData, size);
+    env->DeleteLocalRef(jData);
+    checkException(env);
+}
+
+void
+WebFrame::didFinishLoading() {
+#ifdef ANDROID_INSTRUMENT
+    TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
+#endif
+    JNIEnv* env = getJNIEnv();
+
+    env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidFinishLoading);
+    checkException(env);
+}
+
 #endif
 
 #if USE(CHROME_NETWORK_STACK)
index 11e9e72..ae62835 100644 (file)
@@ -119,6 +119,10 @@ class WebFrame : public WebCoreRefObject {
 
     void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength);
 
+    void didReceiveData(const char* data, int size);
+
+    void didFinishLoading();
+
     void maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request);
 
     void setCertificate(const std::string& issuedTo, const std::string& issuedBy, long long validNotBeforeMillis, long long validNotAfterMillis);