diff options
| author | ARC <arjunrc@gmail.com> | 2015-05-13 14:58:25 -0400 |
|---|---|---|
| committer | ARC <arjunrc@gmail.com> | 2015-05-13 14:58:25 -0400 |
| commit | 73968ba1b3c3b5efeb92f70969e40d143eebf3d8 (patch) | |
| tree | 25f9d358356645c89c212f014f622d5c831e81d0 /plugins/cordova-plugin-crosswalk-webview | |
| parent | 1bef6ad92cafa215e3927d0a4d0a29147d52fe56 (diff) | |
Added plugin directory as well to make sure you have all you need to compile (hopefully)
Diffstat (limited to 'plugins/cordova-plugin-crosswalk-webview')
11 files changed, 1221 insertions, 0 deletions
diff --git a/plugins/cordova-plugin-crosswalk-webview/LICENSE b/plugins/cordova-plugin-crosswalk-webview/LICENSE new file mode 100644 index 00000000..578fa3bb --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/LICENSE @@ -0,0 +1,235 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/************************************************/ +This product bundles CordovaXWalkCoreExtensionBridge.java as well +as the XWalk.pak and the Crosswalk JSApi which is available under a +"3-clause BSD" license. For details, see below: + + Copyright (c) 2013 Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/cordova-plugin-crosswalk-webview/NOTICE b/plugins/cordova-plugin-crosswalk-webview/NOTICE new file mode 100644 index 00000000..81636de1 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/NOTICE @@ -0,0 +1,8 @@ +Apache Cordova +Copyright 2014 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org) + +This software includes software developed at Intel Corporation. +Copyright 2014 Intel Corporation diff --git a/plugins/cordova-plugin-crosswalk-webview/README.md b/plugins/cordova-plugin-crosswalk-webview/README.md new file mode 100644 index 00000000..c2b25f57 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/README.md @@ -0,0 +1,83 @@ + + +Apache Cordova Crosswalk Engine +=== + +Cordova Crosswalk Engine is a [Crosswalk WebView](https://crosswalk-project.org/) based engine to work with [Apache Cordova](http://cordova.apache.org/) for Android. This currently works with master branch of [Cordova Android](https://github.com/apache/cordova-android) on GitHub, and it will work with Apache Cordova Android 4.0.0 release. + +### Directions: +#### Android-only: +* Pull down the Cordova Android +``` +$ git clone https://github.com/apache/cordova-android.git +``` +* Generate a project, e.g creating HelloWorld +``` +$ /path/to/cordova-android/bin/create hello com.example.hello HelloWorld +``` +* Navigate to the project folder +``` +$ cd hello +``` +* Install Crosswalk engine plugin by plugman (version >= 0.22.17) +``` +$ plugman install --platform android --plugin https://github.com/MobileChromeApps/cordova-crosswalk-engine.git --project . +``` +* Build +``` +$ ./cordova/build +``` +The build script will automatically fetch the Crosswalk WebView libraries from Crosswalk project download site (https://download.01.org/crosswalk/releases/crosswalk/android/) and build for both X86 and ARM architectures. + +For example, building HelloWorld generates: + +``` +/path/to/hello/build/outputs/apk/hello-x86-debug.apk +/path/to/hello/build/outputs/apk/hello-armv7-debug.apk +``` + +#### Cordova CLI: +(It will be updated after cordova-android 4.0.0 release with CLI) + +* Install the latest version of the Cordova CLI from npm (version >= 4.2.0) +``` +$ npm install -g cordova +``` +* Create a project with cordova create, e.g creating HelloWorld +``` +$ cordova create hello com.example.hello HelloWorld +``` +* Navigate to the project folder +``` +$ cd hello +``` +* Add the Android platform @4.0.0-dev +``` +$ cordova platform add https://github.com/apache/cordova-android.git +``` +* Add the Crosswalk engine plugin +``` +$ cordova plugin add https://github.com/MobileChromeApps/cordova-crosswalk-engine.git +``` +* Build +``` +$ cordova build android +``` +The build script will automatically fetch the Crosswalk WebView libraries from Crosswalk project download site (https://download.01.org/crosswalk/releases/crosswalk/android/) and build for both X86 and ARM architectures. + +For example, building android with Crosswalk generates: + +``` +/path/to/hello/platforms/android/build/outputs/apk/hello-x86-debug.apk +/path/to/hello/platforms/android/build/outputs/apk/hello-armv7-debug.apk +``` + +Note that it is also possible to publish a multi-APK application on the Play Store that uses Crosswalk for Pre-L devices, and the (updatable) system webview for L+: + +To build Crosswalk-enabled apks, add this plugin and run: + + $ cordova build --release + +To build System-webview apk, remove this plugin and run: + + $ cordova build --release -- --android-minSdkVersion=21 diff --git a/plugins/cordova-plugin-crosswalk-webview/package.json b/plugins/cordova-plugin-crosswalk-webview/package.json new file mode 100644 index 00000000..e67c6413 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/package.json @@ -0,0 +1,40 @@ +{ + "name": "cordova-plugin-crosswalk-webview", + "version": "1.0.1-dev", + "description": "Changes the default WebView to CrossWalk", + "cordova": { + "id": "cordova-plugin-crosswalk-webview", + "platforms": [ + "android" + ] + }, + "repository": { + "type": "git", + "url": "https://github.com/MobileChromeApps/cordova-crosswalk-engine.git" + }, + "keywords": [ + "cordova", + "chromium", + "crosswalk", + "webview", + "engine", + "ecosystem:cordova", + "cordova-android" + ], + "engines": [ + { + "name": "cordova-android", + "version": ">=4" + }, + { + "name": "cordova-plugman", + "version": ">=4.2.0" + } + ], + "author": "", + "license": "Apache 2.0", + "bugs": { + "url": "https://github.com/MobileChromeApps/cordova-crosswalk-engine/issues" + }, + "homepage": "https://github.com/MobileChromeApps/cordova-crosswalk-engine" +} diff --git a/plugins/cordova-plugin-crosswalk-webview/plugin.xml b/plugins/cordova-plugin-crosswalk-webview/plugin.xml new file mode 100644 index 00000000..8fd3e478 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/plugin.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" + id="cordova-plugin-crosswalk-webview" + version="1.0.1-dev"> + + <name>Crosswalk WebView Engine</name> + <description>Changes the default WebView to CrossWalk</description> + <license>Apache 2.0</license> + <keywords>cordova,chromium,crosswalk,webview</keywords> + <repo>https://github.com/MobileChromeApps/cordova-crosswalk-engine.git</repo> + <issue>https://github.com/MobileChromeApps/cordova-crosswalk-engine/issues</issue> + + <engines> + <engine name="cordova-android" version=">=4" /> + <engine name="cordova-plugman" version=">=4.2.0" /><!-- needed for gradleReference support --> + </engines> + + <platform name="android"> + <config-file target="res/xml/config.xml" parent="/*"> + <preference name="webView" value="org.crosswalk.engine.XWalkWebViewEngine" /> + </config-file> + + <source-file src="src/android/XWalkWebViewEngine.java" target-dir="src/org/crosswalk/engine" /> + <source-file src="src/android/XWalkExposedJsApi.java" target-dir="src/org/crosswalk/engine" /> + <source-file src="src/android/XWalkCordovaResourceClient.java" target-dir="src/org/crosswalk/engine" /> + <source-file src="src/android/XWalkCordovaUiClient.java" target-dir="src/org/crosswalk/engine" /> + <source-file src="src/android/XWalkCordovaView.java" target-dir="src/org/crosswalk/engine" /> + <source-file src="src/android/XWalkCordovaCookieManager.java" target-dir="src/org/crosswalk/engine" /> + + <framework src="libs/xwalk_core_library" custom="true" /> + </platform> +</plugin> diff --git a/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaCookieManager.java b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaCookieManager.java new file mode 100644 index 00000000..43f170d2 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaCookieManager.java @@ -0,0 +1,53 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.crosswalk.engine; + +import org.apache.cordova.ICordovaCookieManager; +import org.xwalk.core.internal.XWalkCookieManager; + +class XWalkCordovaCookieManager implements ICordovaCookieManager { + + protected XWalkCookieManager cookieManager = null; + + public XWalkCordovaCookieManager() { + cookieManager = new XWalkCookieManager(); + } + + public void setCookiesEnabled(boolean accept) { + cookieManager.setAcceptCookie(accept); + } + + public void setCookie(final String url, final String value) { + cookieManager.setCookie(url, value); + } + + public String getCookie(final String url) { + return cookieManager.getCookie(url); + } + + public void clearCookies() { + cookieManager.removeAllCookie(); + } + + public void flush() { + cookieManager.flushCookieStore(); + } +}; + + diff --git a/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaResourceClient.java b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaResourceClient.java new file mode 100644 index 00000000..57d0b0f9 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaResourceClient.java @@ -0,0 +1,231 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.crosswalk.engine; + +import android.net.Uri; +import android.webkit.WebResourceResponse; + +import org.apache.cordova.CordovaResourceApi; +import org.apache.cordova.CordovaResourceApi.OpenForReadResult; +import org.apache.cordova.LOG; +import org.chromium.net.NetError; +import org.xwalk.core.XWalkResourceClient; +import org.xwalk.core.XWalkView; + +import java.io.FileNotFoundException; +import java.io.IOException; + +public class XWalkCordovaResourceClient extends XWalkResourceClient { + + private static final String TAG = "XWalkCordovaResourceClient"; + protected XWalkWebViewEngine parentEngine; + + // Success + public static final int ERROR_OK = 0; + // Generic error + public static final int ERROR_UNKNOWN = -1; + // Server or proxy hostname lookup failed + public static final int ERROR_HOST_LOOKUP = -2; + // Unsupported authentication scheme (not basic or digest) + public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3; + // User authentication failed on server + public static final int ERROR_AUTHENTICATION = -4; + // User authentication failed on proxy + public static final int ERROR_PROXY_AUTHENTICATION = -5; + // Failed to connect to the server + public static final int ERROR_CONNECT = -6; + // Failed to read or write to the server + public static final int ERROR_IO = -7; + // Connection timed out + public static final int ERROR_TIMEOUT = -8; + // Too many redirects + public static final int ERROR_REDIRECT_LOOP = -9; + // Unsupported URI scheme + public static final int ERROR_UNSUPPORTED_SCHEME = -10; + // Failed to perform SSL handshake + public static final int ERROR_FAILED_SSL_HANDSHAKE = -11; + // Malformed URL + public static final int ERROR_BAD_URL = -12; + // Generic file error + public static final int ERROR_FILE = -13; + // File not found + public static final int ERROR_FILE_NOT_FOUND = -14; + // Too many requests during this load + public static final int ERROR_TOO_MANY_REQUESTS = -15; + + public XWalkCordovaResourceClient(XWalkWebViewEngine parentEngine) { + super(parentEngine.webView); + this.parentEngine = parentEngine; + } + + // Map XWalk error code about loading a page to Android specific ones. + // XWalk shares the error code with chromium currently. + static int convertErrorCode(int netError) { + // Note: many NetError.Error constants don't have an obvious mapping. + // These will be handled by the default case, ERROR_UNKNOWN. + switch (netError) { + case NetError.ERR_UNSUPPORTED_AUTH_SCHEME: + return ERROR_UNSUPPORTED_AUTH_SCHEME; + + case NetError.ERR_INVALID_AUTH_CREDENTIALS: + case NetError.ERR_MISSING_AUTH_CREDENTIALS: + case NetError.ERR_MISCONFIGURED_AUTH_ENVIRONMENT: + return ERROR_AUTHENTICATION; + + case NetError.ERR_TOO_MANY_REDIRECTS: + return ERROR_REDIRECT_LOOP; + + case NetError.ERR_UPLOAD_FILE_CHANGED: + return ERROR_FILE_NOT_FOUND; + + case NetError.ERR_INVALID_URL: + return ERROR_BAD_URL; + + case NetError.ERR_DISALLOWED_URL_SCHEME: + case NetError.ERR_UNKNOWN_URL_SCHEME: + return ERROR_UNSUPPORTED_SCHEME; + + case NetError.ERR_IO_PENDING: + case NetError.ERR_NETWORK_IO_SUSPENDED: + return ERROR_IO; + + case NetError.ERR_CONNECTION_TIMED_OUT: + case NetError.ERR_TIMED_OUT: + return ERROR_TIMEOUT; + + case NetError.ERR_FILE_TOO_BIG: + return ERROR_FILE; + + case NetError.ERR_HOST_RESOLVER_QUEUE_TOO_LARGE: + case NetError.ERR_INSUFFICIENT_RESOURCES: + case NetError.ERR_OUT_OF_MEMORY: + return ERROR_TOO_MANY_REQUESTS; + + case NetError.ERR_CONNECTION_CLOSED: + case NetError.ERR_CONNECTION_RESET: + case NetError.ERR_CONNECTION_REFUSED: + case NetError.ERR_CONNECTION_ABORTED: + case NetError.ERR_CONNECTION_FAILED: + case NetError.ERR_SOCKET_NOT_CONNECTED: + return ERROR_CONNECT; + + case NetError.ERR_INTERNET_DISCONNECTED: + case NetError.ERR_ADDRESS_INVALID: + case NetError.ERR_ADDRESS_UNREACHABLE: + case NetError.ERR_NAME_NOT_RESOLVED: + case NetError.ERR_NAME_RESOLUTION_FAILED: + return ERROR_HOST_LOOKUP; + + case NetError.ERR_SSL_PROTOCOL_ERROR: + case NetError.ERR_SSL_CLIENT_AUTH_CERT_NEEDED: + case NetError.ERR_TUNNEL_CONNECTION_FAILED: + case NetError.ERR_NO_SSL_VERSIONS_ENABLED: + case NetError.ERR_SSL_VERSION_OR_CIPHER_MISMATCH: + case NetError.ERR_SSL_RENEGOTIATION_REQUESTED: + case NetError.ERR_CERT_ERROR_IN_SSL_RENEGOTIATION: + case NetError.ERR_BAD_SSL_CLIENT_AUTH_CERT: + case NetError.ERR_SSL_NO_RENEGOTIATION: + case NetError.ERR_SSL_DECOMPRESSION_FAILURE_ALERT: + case NetError.ERR_SSL_BAD_RECORD_MAC_ALERT: + case NetError.ERR_SSL_UNSAFE_NEGOTIATION: + case NetError.ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: + case NetError.ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: + case NetError.ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: + return ERROR_FAILED_SSL_HANDSHAKE; + + case NetError.ERR_PROXY_AUTH_UNSUPPORTED: + case NetError.ERR_PROXY_AUTH_REQUESTED: + case NetError.ERR_PROXY_CONNECTION_FAILED: + case NetError.ERR_UNEXPECTED_PROXY_AUTH: + return ERROR_PROXY_AUTHENTICATION; + + // The certificate errors are handled by onReceivedSslError + // and don't need to be reported here. + case NetError.ERR_CERT_COMMON_NAME_INVALID: + case NetError.ERR_CERT_DATE_INVALID: + case NetError.ERR_CERT_AUTHORITY_INVALID: + case NetError.ERR_CERT_CONTAINS_ERRORS: + case NetError.ERR_CERT_NO_REVOCATION_MECHANISM: + case NetError.ERR_CERT_UNABLE_TO_CHECK_REVOCATION: + case NetError.ERR_CERT_REVOKED: + case NetError.ERR_CERT_INVALID: + case NetError.ERR_CERT_WEAK_SIGNATURE_ALGORITHM: + case NetError.ERR_CERT_NON_UNIQUE_NAME: + return ERROR_OK; + + default: + return ERROR_UNKNOWN; + } + } + + /** + * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable). + * The errorCode parameter corresponds to one of the ERROR_* constants. + * + * @param view The WebView that is initiating the callback. + * @param errorCode The error code corresponding to an ERROR_* value. + * @param description A String describing the error. + * @param failingUrl The url that failed to load. + */ + @Override + public void onReceivedLoadError(XWalkView view, int errorCode, String description, + String failingUrl) { + LOG.d(TAG, "CordovaWebViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl); + + // Convert the XWalk error code to Cordova error code, which follows the Android spec, + // http://developer.android.com/reference/android/webkit/WebViewClient.html. + errorCode = XWalkCordovaResourceClient.convertErrorCode(errorCode); + parentEngine.client.onReceivedError(errorCode, description, failingUrl); + } + + @Override + public WebResourceResponse shouldInterceptLoadRequest(XWalkView view, String url) { + try { + // Check the against the white-list. + if (!parentEngine.pluginManager.shouldAllowRequest(url)) { + LOG.w(TAG, "URL blocked by whitelist: " + url); + // Results in a 404. + return new WebResourceResponse("text/plain", "UTF-8", null); + } + + CordovaResourceApi resourceApi = parentEngine.resourceApi; + Uri origUri = Uri.parse(url); + // Allow plugins to intercept WebView requests. + Uri remappedUri = resourceApi.remapUri(origUri); + + if (!origUri.equals(remappedUri)) { + OpenForReadResult result = resourceApi.openForRead(remappedUri, true); + return new WebResourceResponse(result.mimeType, "UTF-8", result.inputStream); + } + // If we don't need to special-case the request, let the browser load it. + return null; + } catch (IOException e) { + if (!(e instanceof FileNotFoundException)) { + LOG.e(TAG, "Error occurred while loading a file (returning a 404).", e); + } + // Results in a 404. + return new WebResourceResponse("text/plain", "UTF-8", null); + } + } + + @Override + public boolean shouldOverrideUrlLoading(XWalkView view, String url) { + return parentEngine.client.onNavigationAttempt(url); + } +} diff --git a/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaUiClient.java b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaUiClient.java new file mode 100644 index 00000000..a5a20b70 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaUiClient.java @@ -0,0 +1,193 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.crosswalk.engine; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; +import android.webkit.ValueCallback; + +import org.apache.cordova.CordovaDialogsHelper; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.LOG; +import org.xwalk.core.XWalkJavascriptResult; +import org.xwalk.core.XWalkUIClient; +import org.xwalk.core.XWalkView; + +public class XWalkCordovaUiClient extends XWalkUIClient { + private static final String TAG = "XWalkCordovaUiClient"; + protected final CordovaDialogsHelper dialogsHelper; + protected final XWalkWebViewEngine parentEngine; + + private static final int FILECHOOSER_RESULTCODE = 5173; + + public XWalkCordovaUiClient(XWalkWebViewEngine parentEngine) { + super(parentEngine.webView); + this.parentEngine = parentEngine; + dialogsHelper = new CordovaDialogsHelper(parentEngine.webView.getContext()); + } + + @Override + public boolean onJavascriptModalDialog(XWalkView view, JavascriptMessageType type, String url, + String message, String defaultValue, XWalkJavascriptResult result) { + switch (type) { + case JAVASCRIPT_ALERT: + return onJsAlert(view, url, message, result); + case JAVASCRIPT_CONFIRM: + return onJsConfirm(view, url, message, result); + case JAVASCRIPT_PROMPT: + return onJsPrompt(view, url, message, defaultValue, result); + case JAVASCRIPT_BEFOREUNLOAD: + // Reuse onJsConfirm to show the dialog. + return onJsConfirm(view, url, message, result); + default: + break; + } + assert (false); + return false; + } + + /** + * Tell the client to display a javascript alert dialog. + */ + private boolean onJsAlert(XWalkView view, String url, String message, + final XWalkJavascriptResult result) { + dialogsHelper.showAlert(message, new CordovaDialogsHelper.Result() { + @Override + public void gotResult(boolean success, String value) { + if (success) { + result.confirm(); + } else { + result.cancel(); + } + } + }); + return true; + } + + /** + * Tell the client to display a confirm dialog to the user. + */ + private boolean onJsConfirm(XWalkView view, String url, String message, + final XWalkJavascriptResult result) { + dialogsHelper.showConfirm(message, new CordovaDialogsHelper.Result() { + @Override + public void gotResult(boolean success, String value) { + if (success) { + result.confirm(); + } else { + result.cancel(); + } + } + }); + return true; + } + + /** + * Tell the client to display a prompt dialog to the user. + * If the client returns true, WebView will assume that the client will + * handle the prompt dialog and call the appropriate JsPromptResult method. + * <p/> + * Since we are hacking prompts for our own purposes, we should not be using them for + * this purpose, perhaps we should hack console.log to do this instead! + */ + private boolean onJsPrompt(XWalkView view, String origin, String message, String defaultValue, + final XWalkJavascriptResult result) { + // Unlike the @JavascriptInterface bridge, this method is always called on the UI thread. + String handledRet = parentEngine.bridge.promptOnJsPrompt(origin, message, defaultValue); + if (handledRet != null) { + result.confirmWithResult(handledRet); + } else { + dialogsHelper.showPrompt(message, defaultValue, new CordovaDialogsHelper.Result() { + @Override + public void gotResult(boolean success, String value) { + if (success) { + result.confirmWithResult(value); + } else { + result.cancel(); + } + } + }); + + } + return true; + } + + /** + * Notify the host application that a page has started loading. + * This method is called once for each main frame load so a page with iframes or framesets will call onPageStarted + * one time for the main frame. This also means that onPageStarted will not be called when the contents of an + * embedded frame changes, i.e. clicking a link whose target is an iframe. + * + * @param view The webView initiating the callback. + * @param url The url of the page. + */ + @Override + public void onPageLoadStarted(XWalkView view, String url) { + + // Only proceed if this is a top-level navigation + if (view.getUrl() != null && view.getUrl().equals(url)) { + // Flush stale messages. + parentEngine.client.onPageStarted(url); + parentEngine.bridge.reset(); + } + } + + /** + * Notify the host application that a page has stopped loading. + * This method is called only for main frame. When onPageLoadStopped() is called, the rendering picture may not be updated yet. + * + * @param view The webView initiating the callback. + * @param url The url of the page. + * @param status The load status of the webView, can be FINISHED, CANCELLED or FAILED. + */ + @Override + public void onPageLoadStopped(XWalkView view, String url, LoadStatus status) { + LOG.d(TAG, "onPageFinished(" + url + ")"); + if (status == LoadStatus.FINISHED) { + parentEngine.client.onPageFinishedLoading(url); + } else if (status == LoadStatus.FAILED) { + // TODO: Should this call parentEngine.client.onReceivedError()? + // Right now we call this from ResourceClient, but maybe that is just for sub-resources? + } + } + + // File Chooser + @Override + public void openFileChooser(XWalkView view, final ValueCallback<Uri> uploadFile, String acceptType, String capture) { + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType("*/*"); // TODO: wire this to acceptType. + Intent intent = Intent.createChooser(i, "File Browser"); + try { + parentEngine.cordova.startActivityForResult(new CordovaPlugin() { + @Override + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData(); + uploadFile.onReceiveValue(result); + } + }, intent, FILECHOOSER_RESULTCODE); + } catch (ActivityNotFoundException e) { + Log.w("No activity found to handle file chooser intent.", e); + uploadFile.onReceiveValue(null); + } + } +} diff --git a/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaView.java b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaView.java new file mode 100644 index 00000000..0be2e998 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkCordovaView.java @@ -0,0 +1,108 @@ +package org.crosswalk.engine; + +import org.apache.cordova.CordovaPreferences; +import org.xwalk.core.XWalkPreferences; +import org.xwalk.core.XWalkResourceClient; +import org.xwalk.core.XWalkUIClient; +import org.xwalk.core.XWalkView; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.util.AttributeSet; +import android.view.KeyEvent; + +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.CordovaWebViewEngine; + +public class XWalkCordovaView extends XWalkView implements CordovaWebViewEngine.EngineView { + protected XWalkCordovaResourceClient resourceClient; + protected XWalkCordovaUiClient uiClient; + protected XWalkWebViewEngine parentEngine; + + private static boolean hasSetStaticPref; + // This needs to run before the super's constructor. + private static Context setGlobalPrefs(Context context, CordovaPreferences preferences) { + if (!hasSetStaticPref) { + hasSetStaticPref = true; + ApplicationInfo ai = null; + try { + ai = context.getPackageManager().getApplicationInfo(context.getApplicationContext().getPackageName(), PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } + boolean prefAnimatable = preferences == null ? false : preferences.getBoolean("CrosswalkAnimatable", false); + boolean manifestAnimatable = ai.metaData == null ? false : ai.metaData.getBoolean("CrosswalkAnimatable"); + if (prefAnimatable || manifestAnimatable) { + // Slows it down a bit, but allows for it to be animated by Android View properties. + XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true); + } + if ((ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { + XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true); + } + XWalkPreferences.setValue(XWalkPreferences.JAVASCRIPT_CAN_OPEN_WINDOW, true); + XWalkPreferences.setValue(XWalkPreferences.ALLOW_UNIVERSAL_ACCESS_FROM_FILE, true); + } + return context; + } + + public XWalkCordovaView(Context context, CordovaPreferences preferences) { + super(setGlobalPrefs(context, preferences), (AttributeSet)null); + } + + public XWalkCordovaView(Context context, AttributeSet attrs) { + super(setGlobalPrefs(context, null), attrs); + } + + void init(XWalkWebViewEngine parentEngine) { + this.parentEngine = parentEngine; + if (resourceClient == null) { + setResourceClient(new XWalkCordovaResourceClient(parentEngine)); + } + if (uiClient == null) { + setUIClient(new XWalkCordovaUiClient(parentEngine)); + } + } + + @Override + public void setResourceClient(XWalkResourceClient client) { + // XWalk calls this method from its constructor. + if (client instanceof XWalkCordovaResourceClient) { + this.resourceClient = (XWalkCordovaResourceClient)client; + } + super.setResourceClient(client); + } + + @Override + public void setUIClient(XWalkUIClient client) { + // XWalk calls this method from its constructor. + if (client instanceof XWalkCordovaUiClient) { + this.uiClient = (XWalkCordovaUiClient)client; + } + super.setUIClient(client); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + Boolean ret = parentEngine.client.onDispatchKeyEvent(event); + if (ret != null) { + return ret.booleanValue(); + } + return super.dispatchKeyEvent(event); + } + + @Override + public void pauseTimers() { + // This is called by XWalkViewInternal.onActivityStateChange(). + // We don't want them paused by default though. + } + + public void pauseTimersForReal() { + super.pauseTimers(); + } + + @Override + public CordovaWebView getCordovaWebView() { + return parentEngine == null ? null : parentEngine.getCordovaWebView(); + } +} diff --git a/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkExposedJsApi.java b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkExposedJsApi.java new file mode 100644 index 00000000..25715216 --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkExposedJsApi.java @@ -0,0 +1,52 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.crosswalk.engine; + +import android.os.Looper; + +import org.apache.cordova.CordovaBridge; +import org.apache.cordova.ExposedJsApi; +import org.json.JSONException; +import org.xwalk.core.JavascriptInterface; + +class XWalkExposedJsApi implements ExposedJsApi { + private final CordovaBridge bridge; + + XWalkExposedJsApi(CordovaBridge bridge) { + this.bridge = bridge; + } + + @JavascriptInterface + public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + return bridge.jsExec(bridgeSecret, service, action, callbackId, arguments); + } + + @JavascriptInterface + public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException { + bridge.jsSetNativeToJsBridgeMode(bridgeSecret, value); + } + + @JavascriptInterface + public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException { + return bridge.jsRetrieveJsMessages(bridgeSecret, fromOnlineEvent); + } +} diff --git a/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkWebViewEngine.java b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkWebViewEngine.java new file mode 100644 index 00000000..7e5a4f1c --- /dev/null +++ b/plugins/cordova-plugin-crosswalk-webview/src/android/XWalkWebViewEngine.java @@ -0,0 +1,185 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +package org.crosswalk.engine; + +import android.content.Context; +import android.view.View; + +import org.apache.cordova.CordovaBridge; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPreferences; +import org.apache.cordova.CordovaResourceApi; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.CordovaWebViewEngine; +import org.apache.cordova.ICordovaCookieManager; +import org.apache.cordova.NativeToJsMessageQueue; +import org.apache.cordova.PluginManager; +import org.xwalk.core.XWalkNavigationHistory; +import org.xwalk.core.XWalkView; + +/** + * Glue class between CordovaWebView (main Cordova logic) and XWalkCordovaView (the actual View). + */ +public class XWalkWebViewEngine implements CordovaWebViewEngine { + + public static final String TAG = "XWalkWebViewEngine"; + + protected final XWalkCordovaView webView; + protected XWalkCordovaCookieManager cookieManager; + protected CordovaBridge bridge; + protected CordovaWebViewEngine.Client client; + protected CordovaWebView parentWebView; + protected CordovaInterface cordova; + protected PluginManager pluginManager; + protected CordovaResourceApi resourceApi; + protected NativeToJsMessageQueue nativeToJsMessageQueue; + + /** Used when created via reflection. */ + public XWalkWebViewEngine(Context context, CordovaPreferences preferences) { + this(new XWalkCordovaView(context, preferences)); + } + + public XWalkWebViewEngine(XWalkCordovaView webView) { + this.webView = webView; + cookieManager = new XWalkCordovaCookieManager(); + } + + // Use two-phase init so that the control will work with XML layouts. + + @Override + public void init(CordovaWebView parentWebView, CordovaInterface cordova, CordovaWebViewEngine.Client client, + CordovaResourceApi resourceApi, PluginManager pluginManager, + NativeToJsMessageQueue nativeToJsMessageQueue) { + if (this.cordova != null) { + throw new IllegalStateException(); + } + this.parentWebView = parentWebView; + this.cordova = cordova; + this.client = client; + this.resourceApi = resourceApi; + this.pluginManager = pluginManager; + this.nativeToJsMessageQueue = nativeToJsMessageQueue; + + webView.init(this); + initWebViewSettings(); + + nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() { + @Override + public void setNetworkAvailable(boolean value) { + webView.setNetworkAvailable(value); + } + @Override + public void runOnUiThread(Runnable r) { + XWalkWebViewEngine.this.cordova.getActivity().runOnUiThread(r); + } + })); + bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue); + exposeJsInterface(webView, bridge); + } + + @Override + public CordovaWebView getCordovaWebView() { + return parentWebView; + } + + @Override + public View getView() { + return webView; + } + + private void initWebViewSettings() { + webView.setVerticalScrollBarEnabled(false); + } + + private static void exposeJsInterface(XWalkView webView, CordovaBridge bridge) { + XWalkExposedJsApi exposedJsApi = new XWalkExposedJsApi(bridge); + webView.addJavascriptInterface(exposedJsApi, "_cordovaNative"); + } + + // TODO(ningxin): XWalkViewUIClient should provide onScrollChanged callback + /* + public void onScrollChanged(int l, int t, int oldl, int oldt) + { + super.onScrollChanged(l, t, oldl, oldt); + //We should post a message that the scroll changed + ScrollEvent myEvent = new ScrollEvent(l, t, oldl, oldt, this); + this.postMessage("onScrollChanged", myEvent); + } + */ + + @Override + public boolean canGoBack() { + return this.webView.getNavigationHistory().canGoBack(); + } + + @Override + public boolean goBack() { + if (this.webView.getNavigationHistory().canGoBack()) { + this.webView.getNavigationHistory().navigate(XWalkNavigationHistory.Direction.BACKWARD, 1); + return true; + } + return false; + } + + @Override + public void setPaused(boolean value) { + if (value) { + // TODO: I think this has been fixed upstream and we don't need to override pauseTimers() anymore. + webView.pauseTimersForReal(); + } else { + webView.resumeTimers(); + } + } + + @Override + public void destroy() { + webView.onDestroy(); + } + + @Override + public void clearHistory() { + this.webView.getNavigationHistory().clear(); + } + + @Override + public void stopLoading() { + this.webView.stopLoading(); + } + + @Override + public void clearCache() { + webView.clearCache(true); + } + + @Override + public String getUrl() { + return this.webView.getUrl(); + } + + @Override + public ICordovaCookieManager getCookieManager() { + return cookieManager; + } + + @Override + public void loadUrl(String url, boolean clearNavigationStack) { + webView.load(url, null); + } +} |
