UNPKG

7.42 kBtext/x-java-sourceView Raw
1/*
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18*/
19package org.apache.cordova.inappbrowser;
20
21import org.apache.cordova.CordovaWebView;
22import org.apache.cordova.LOG;
23import org.apache.cordova.PluginResult;
24import org.json.JSONArray;
25import org.json.JSONException;
26
27import android.annotation.TargetApi;
28import android.os.Build;
29import android.os.Message;
30import android.webkit.JsPromptResult;
31import android.webkit.WebChromeClient;
32import android.webkit.WebResourceRequest;
33import android.webkit.WebStorage;
34import android.webkit.WebView;
35import android.webkit.WebViewClient;
36import android.webkit.GeolocationPermissions.Callback;
37
38public class InAppChromeClient extends WebChromeClient {
39
40 private CordovaWebView webView;
41 private String LOG_TAG = "InAppChromeClient";
42 private long MAX_QUOTA = 100 * 1024 * 1024;
43
44 public InAppChromeClient(CordovaWebView webView) {
45 super();
46 this.webView = webView;
47 }
48 /**
49 * Handle database quota exceeded notification.
50 *
51 * @param url
52 * @param databaseIdentifier
53 * @param currentQuota
54 * @param estimatedSize
55 * @param totalUsedQuota
56 * @param quotaUpdater
57 */
58 @Override
59 public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
60 long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
61 {
62 LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
63 quotaUpdater.updateQuota(MAX_QUOTA);
64 }
65
66 /**
67 * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
68 *
69 * @param origin
70 * @param callback
71 */
72 @Override
73 public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
74 super.onGeolocationPermissionsShowPrompt(origin, callback);
75 callback.invoke(origin, true, false);
76 }
77
78 /**
79 * Tell the client to display a prompt dialog to the user.
80 * If the client returns true, WebView will assume that the client will
81 * handle the prompt dialog and call the appropriate JsPromptResult method.
82 *
83 * The prompt bridge provided for the InAppBrowser is capable of executing any
84 * oustanding callback belonging to the InAppBrowser plugin. Care has been
85 * taken that other callbacks cannot be triggered, and that no other code
86 * execution is possible.
87 *
88 * To trigger the bridge, the prompt default value should be of the form:
89 *
90 * gap-iab://<callbackId>
91 *
92 * where <callbackId> is the string id of the callback to trigger (something
93 * like "InAppBrowser0123456789")
94 *
95 * If present, the prompt message is expected to be a JSON-encoded value to
96 * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid.
97 *
98 * @param view
99 * @param url
100 * @param message
101 * @param defaultValue
102 * @param result
103 */
104 @Override
105 public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
106 // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute.
107 if (defaultValue != null && defaultValue.startsWith("gap")) {
108 if(defaultValue.startsWith("gap-iab://")) {
109 PluginResult scriptResult;
110 String scriptCallbackId = defaultValue.substring(10);
111 if (scriptCallbackId.matches("^InAppBrowser[0-9]{1,10}$")) {
112 if(message == null || message.length() == 0) {
113 scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray());
114 } else {
115 try {
116 scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message));
117 } catch(JSONException e) {
118 scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
119 }
120 }
121 this.webView.sendPluginResult(scriptResult, scriptCallbackId);
122 result.confirm("");
123 return true;
124 }
125 else {
126 // Anything else that doesn't look like InAppBrowser0123456789 should end up here
127 LOG.w(LOG_TAG, "InAppBrowser callback called with invalid callbackId : "+ scriptCallbackId);
128 result.cancel();
129 return true;
130 }
131 }
132 else {
133 // Anything else with a gap: prefix should get this message
134 LOG.w(LOG_TAG, "InAppBrowser does not support Cordova API calls: " + url + " " + defaultValue);
135 result.cancel();
136 return true;
137 }
138 }
139 return false;
140 }
141
142 /**
143 * The InAppWebBrowser WebView is configured to MultipleWindow mode to mitigate a security
144 * bug found in Chromium prior to version 83.0.4103.106.
145 * See https://bugs.chromium.org/p/chromium/issues/detail?id=1083819
146 *
147 * Valid Urls set to open in new window will be routed back to load in the original WebView.
148 *
149 * @param view
150 * @param isDialog
151 * @param isUserGesture
152 * @param resultMsg
153 * @return
154 */
155 @Override
156 public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
157 WebView inAppWebView = view;
158 final WebViewClient webViewClient =
159 new WebViewClient() {
160 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
161 @Override
162 public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
163 inAppWebView.loadUrl(request.getUrl().toString());
164 return true;
165 }
166
167 @Override
168 public boolean shouldOverrideUrlLoading(WebView view, String url) {
169 inAppWebView.loadUrl(url);
170 return true;
171 }
172 };
173
174 final WebView newWebView = new WebView(view.getContext());
175 newWebView.setWebViewClient(webViewClient);
176
177 final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
178 transport.setWebView(newWebView);
179 resultMsg.sendToTarget();
180
181 return true;
182 }
183}