1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_CLIENT_BRIDGE_H_
6 #define ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_CLIENT_BRIDGE_H_
7 
8 #include <memory>
9 
10 #include "android_webview/browser/network_service/aw_web_resource_request.h"
11 #include "android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.h"
12 #include "base/android/jni_weak_ref.h"
13 #include "base/android/scoped_java_ref.h"
14 #include "base/callback.h"
15 #include "base/containers/id_map.h"
16 #include "base/supports_user_data.h"
17 #include "components/security_interstitials/core/unsafe_resource.h"
18 #include "content/public/browser/certificate_request_result_type.h"
19 #include "content/public/browser/javascript_dialog_manager.h"
20 #include "content/public/browser/web_contents.h"
21 #include "net/http/http_response_headers.h"
22 
23 class GURL;
24 
25 namespace content {
26 class ClientCertificateDelegate;
27 class WebContents;
28 }
29 
30 namespace net {
31 class SSLCertRequestInfo;
32 class X509Certificate;
33 }
34 
35 namespace android_webview {
36 
37 // A class that handles the Java<->Native communication for the
38 // AwContentsClient. AwContentsClientBridge is created and owned by
39 // native AwContents class and it only has a weak reference to the
40 // its Java peer. Since the Java AwContentsClientBridge can have
41 // indirect refs from the Application (via callbacks) and so can outlive
42 // webview, this class notifies it before being destroyed and to nullify
43 // any references.
44 class AwContentsClientBridge {
45  public:
46   // Used to package up information needed by OnReceivedHttpError for transfer
47   // between IO and UI threads.
48   struct HttpErrorInfo {
49     HttpErrorInfo();
50     ~HttpErrorInfo();
51 
52     int status_code;
53     std::string status_text;
54     std::string mime_type;
55     std::string encoding;
56     std::vector<std::string> response_header_names;
57     std::vector<std::string> response_header_values;
58   };
59 
60   using CertErrorCallback =
61       base::OnceCallback<void(content::CertificateRequestResultType)>;
62   using SafeBrowsingActionCallback =
63       base::OnceCallback<void(AwUrlCheckerDelegateImpl::SafeBrowsingAction,
64                               bool)>;
65 
66   // Adds the handler to the UserData registry. Dissociate should be called
67   // before handler is deleted.
68   static void Associate(content::WebContents* web_contents,
69                         AwContentsClientBridge* handler);
70   // Removes any handlers associated to the UserData registry.
71   static void Dissociate(content::WebContents* web_contents);
72   static AwContentsClientBridge* FromWebContents(
73       content::WebContents* web_contents);
74   static AwContentsClientBridge* FromWebContentsGetter(
75       const content::WebContents::Getter& web_contents_getter);
76   static AwContentsClientBridge* FromID(int render_process_id,
77                                         int render_frame_id);
78   AwContentsClientBridge(JNIEnv* env,
79                          const base::android::JavaRef<jobject>& obj);
80   ~AwContentsClientBridge();
81 
82   // AwContentsClientBridge implementation
83   void AllowCertificateError(int cert_error,
84                              net::X509Certificate* cert,
85                              const GURL& request_url,
86                              CertErrorCallback callback,
87                              bool* cancel_request);
88   void SelectClientCertificate(
89       net::SSLCertRequestInfo* cert_request_info,
90       std::unique_ptr<content::ClientCertificateDelegate> delegate);
91   void RunJavaScriptDialog(
92       content::JavaScriptDialogType dialog_type,
93       const GURL& origin_url,
94       const base::string16& message_text,
95       const base::string16& default_prompt_text,
96       content::JavaScriptDialogManager::DialogClosedCallback callback);
97   void RunBeforeUnloadDialog(
98       const GURL& origin_url,
99       content::JavaScriptDialogManager::DialogClosedCallback callback);
100   bool ShouldOverrideUrlLoading(const base::string16& url,
101                                 bool has_user_gesture,
102                                 bool is_redirect,
103                                 bool is_main_frame,
104                                 bool* ignore_navigation);
105   void NewDownload(const GURL& url,
106                    const std::string& user_agent,
107                    const std::string& content_disposition,
108                    const std::string& mime_type,
109                    int64_t content_length);
110 
111   // Called when a new login request is detected. See the documentation for
112   // WebViewClient.onReceivedLoginRequest for arguments. Note that |account|
113   // may be empty.
114   void NewLoginRequest(const std::string& realm,
115                        const std::string& account,
116                        const std::string& args);
117 
118   // Called when a resource loading error has occured (e.g. an I/O error,
119   // host name lookup failure etc.)
120   void OnReceivedError(const AwWebResourceRequest& request,
121                        int error_code,
122                        bool safebrowsing_hit,
123                        bool should_omit_notifications_for_safebrowsing_hit);
124 
125   void OnSafeBrowsingHit(const AwWebResourceRequest& request,
126                          const safe_browsing::SBThreatType& threat_type,
127                          SafeBrowsingActionCallback callback);
128 
129   // Called when a response from the server is received with status code >= 400.
130   void OnReceivedHttpError(const AwWebResourceRequest& request,
131                            std::unique_ptr<HttpErrorInfo> error_info);
132 
133   // This should be called from IO thread.
134   static std::unique_ptr<HttpErrorInfo> ExtractHttpErrorInfo(
135       const net::HttpResponseHeaders* response_headers);
136 
137   // Methods called from Java.
138   void ProceedSslError(JNIEnv* env,
139                        const base::android::JavaRef<jobject>& obj,
140                        jboolean proceed,
141                        jint id);
142   void ProvideClientCertificateResponse(
143       JNIEnv* env,
144       const base::android::JavaRef<jobject>& object,
145       jint request_id,
146       const base::android::JavaRef<jobjectArray>& encoded_chain_ref,
147       const base::android::JavaRef<jobject>& private_key_ref);
148   void ConfirmJsResult(JNIEnv*,
149                        const base::android::JavaRef<jobject>&,
150                        int id,
151                        const base::android::JavaRef<jstring>& prompt);
152   void CancelJsResult(JNIEnv*, const base::android::JavaRef<jobject>&, int id);
153 
154   void TakeSafeBrowsingAction(JNIEnv*,
155                               const base::android::JavaRef<jobject>&,
156                               int action,
157                               bool reporting,
158                               int request_id);
159 
160  private:
161   JavaObjectWeakGlobalRef java_ref_;
162 
163   base::IDMap<std::unique_ptr<CertErrorCallback>> pending_cert_error_callbacks_;
164   base::IDMap<std::unique_ptr<SafeBrowsingActionCallback>>
165       safe_browsing_callbacks_;
166   base::IDMap<
167       std::unique_ptr<content::JavaScriptDialogManager::DialogClosedCallback>>
168       pending_js_dialog_callbacks_;
169   base::IDMap<std::unique_ptr<content::ClientCertificateDelegate>>
170       pending_client_cert_request_delegates_;
171 };
172 
173 }  // namespace android_webview
174 
175 #endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_CLIENT_BRIDGE_H_
176