You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2017/04/15 01:10:32 UTC
[11/39] cordova-lib git commit: CB-11346: added tests for support of
3rd party platforms
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/da952e07/cordova-lib/spec-cordova/fixtures/platforms/atari/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/atari/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java b/cordova-lib/spec-cordova/fixtures/platforms/atari/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java
new file mode 100755
index 0000000..0fa0276
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/atari/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java
@@ -0,0 +1,350 @@
+/*
+ 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.apache.cordova.engine;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.os.Build;
+import android.view.View;
+import android.webkit.ValueCallback;
+import android.webkit.WebSettings;
+import android.webkit.WebSettings.LayoutAlgorithm;
+import android.webkit.WebView;
+
+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.LOG;
+import org.apache.cordova.NativeToJsMessageQueue;
+import org.apache.cordova.PluginManager;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+/**
+ * Glue class between CordovaWebView (main Cordova logic) and SystemWebView (the actual View).
+ * We make the Engine separate from the actual View so that:
+ * A) We don't need to worry about WebView methods clashing with CordovaWebViewEngine methods
+ * (e.g.: goBack() is void for WebView, and boolean for CordovaWebViewEngine)
+ * B) Separating the actual View from the Engine makes API surfaces smaller.
+ * Class uses two-phase initialization. However, CordovaWebView is responsible for calling .init().
+ */
+public class SystemWebViewEngine implements CordovaWebViewEngine {
+ public static final String TAG = "SystemWebViewEngine";
+
+ protected final SystemWebView webView;
+ protected final SystemCookieManager cookieManager;
+ protected CordovaPreferences preferences;
+ protected CordovaBridge bridge;
+ protected CordovaWebViewEngine.Client client;
+ protected CordovaWebView parentWebView;
+ protected CordovaInterface cordova;
+ protected PluginManager pluginManager;
+ protected CordovaResourceApi resourceApi;
+ protected NativeToJsMessageQueue nativeToJsMessageQueue;
+ private BroadcastReceiver receiver;
+
+ /** Used when created via reflection. */
+ public SystemWebViewEngine(Context context, CordovaPreferences preferences) {
+ this(new SystemWebView(context), preferences);
+ }
+
+ public SystemWebViewEngine(SystemWebView webView) {
+ this(webView, null);
+ }
+
+ public SystemWebViewEngine(SystemWebView webView, CordovaPreferences preferences) {
+ this.preferences = preferences;
+ this.webView = webView;
+ cookieManager = new SystemCookieManager(webView);
+ }
+
+ @Override
+ public void init(CordovaWebView parentWebView, CordovaInterface cordova, CordovaWebViewEngine.Client client,
+ CordovaResourceApi resourceApi, PluginManager pluginManager,
+ NativeToJsMessageQueue nativeToJsMessageQueue) {
+ if (this.cordova != null) {
+ throw new IllegalStateException();
+ }
+ // Needed when prefs are not passed by the constructor
+ if (preferences == null) {
+ preferences = parentWebView.getPreferences();
+ }
+ this.parentWebView = parentWebView;
+ this.cordova = cordova;
+ this.client = client;
+ this.resourceApi = resourceApi;
+ this.pluginManager = pluginManager;
+ this.nativeToJsMessageQueue = nativeToJsMessageQueue;
+ webView.init(this, cordova);
+
+ 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) {
+ SystemWebViewEngine.this.cordova.getActivity().runOnUiThread(r);
+ }
+ }));
+ if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2)
+ nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.EvalBridgeMode(this, cordova));
+ bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue);
+ exposeJsInterface(webView, bridge);
+ }
+
+ @Override
+ public CordovaWebView getCordovaWebView() {
+ return parentWebView;
+ }
+
+ @Override
+ public ICordovaCookieManager getCookieManager() {
+ return cookieManager;
+ }
+
+ @Override
+ public View getView() {
+ return webView;
+ }
+
+ @SuppressLint({"NewApi", "SetJavaScriptEnabled"})
+ @SuppressWarnings("deprecation")
+ private void initWebViewSettings() {
+ webView.setInitialScale(0);
+ webView.setVerticalScrollBarEnabled(false);
+ // Enable JavaScript
+ final WebSettings settings = webView.getSettings();
+ settings.setJavaScriptEnabled(true);
+ settings.setJavaScriptCanOpenWindowsAutomatically(true);
+ settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
+
+ // Set the nav dump for HTC 2.x devices (disabling for ICS, deprecated entirely for Jellybean 4.2)
+ try {
+ Method gingerbread_getMethod = WebSettings.class.getMethod("setNavDump", new Class[] { boolean.class });
+
+ String manufacturer = android.os.Build.MANUFACTURER;
+ LOG.d(TAG, "CordovaWebView is running on device made by: " + manufacturer);
+ if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB &&
+ android.os.Build.MANUFACTURER.contains("HTC"))
+ {
+ gingerbread_getMethod.invoke(settings, true);
+ }
+ } catch (NoSuchMethodException e) {
+ LOG.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8");
+ } catch (IllegalArgumentException e) {
+ LOG.d(TAG, "Doing the NavDump failed with bad arguments");
+ } catch (IllegalAccessException e) {
+ LOG.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore");
+ } catch (InvocationTargetException e) {
+ LOG.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore.");
+ }
+
+ //We don't save any form data in the application
+ settings.setSaveFormData(false);
+ settings.setSavePassword(false);
+
+ // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
+ // while we do this
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
+ settings.setAllowUniversalAccessFromFileURLs(true);
+ }
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ settings.setMediaPlaybackRequiresUserGesture(false);
+ }
+ // Enable database
+ // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
+ String databasePath = webView.getContext().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
+ settings.setDatabaseEnabled(true);
+ settings.setDatabasePath(databasePath);
+
+
+ //Determine whether we're in debug or release mode, and turn on Debugging!
+ ApplicationInfo appInfo = webView.getContext().getApplicationContext().getApplicationInfo();
+ if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 &&
+ android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+ enableRemoteDebugging();
+ }
+
+ settings.setGeolocationDatabasePath(databasePath);
+
+ // Enable DOM storage
+ settings.setDomStorageEnabled(true);
+
+ // Enable built-in geolocation
+ settings.setGeolocationEnabled(true);
+
+ // Enable AppCache
+ // Fix for CB-2282
+ settings.setAppCacheMaxSize(5 * 1048576);
+ settings.setAppCachePath(databasePath);
+ settings.setAppCacheEnabled(true);
+
+ // Fix for CB-1405
+ // Google issue 4641
+ String defaultUserAgent = settings.getUserAgentString();
+
+ // Fix for CB-3360
+ String overrideUserAgent = preferences.getString("OverrideUserAgent", null);
+ if (overrideUserAgent != null) {
+ settings.setUserAgentString(overrideUserAgent);
+ } else {
+ String appendUserAgent = preferences.getString("AppendUserAgent", null);
+ if (appendUserAgent != null) {
+ settings.setUserAgentString(defaultUserAgent + " " + appendUserAgent);
+ }
+ }
+ // End CB-3360
+
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ if (this.receiver == null) {
+ this.receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ settings.getUserAgentString();
+ }
+ };
+ webView.getContext().registerReceiver(this.receiver, intentFilter);
+ }
+ // end CB-1405
+ }
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ private void enableRemoteDebugging() {
+ try {
+ WebView.setWebContentsDebuggingEnabled(true);
+ } catch (IllegalArgumentException e) {
+ LOG.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! ");
+ e.printStackTrace();
+ }
+ }
+
+ private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
+ if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
+ LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
+ // Bug being that Java Strings do not get converted to JS strings automatically.
+ // This isn't hard to work-around on the JS side, but it's easier to just
+ // use the prompt bridge instead.
+ return;
+ }
+ SystemExposedJsApi exposedJsApi = new SystemExposedJsApi(bridge);
+ webView.addJavascriptInterface(exposedJsApi, "_cordovaNative");
+ }
+
+
+ /**
+ * Load the url into the webview.
+ */
+ @Override
+ public void loadUrl(final String url, boolean clearNavigationStack) {
+ webView.loadUrl(url);
+ }
+
+ @Override
+ public String getUrl() {
+ return webView.getUrl();
+ }
+
+ @Override
+ public void stopLoading() {
+ webView.stopLoading();
+ }
+
+ @Override
+ public void clearCache() {
+ webView.clearCache(true);
+ }
+
+ @Override
+ public void clearHistory() {
+ webView.clearHistory();
+ }
+
+ @Override
+ public boolean canGoBack() {
+ return webView.canGoBack();
+ }
+
+ /**
+ * Go to previous page in history. (We manage our own history)
+ *
+ * @return true if we went back, false if we are already at top
+ */
+ @Override
+ public boolean goBack() {
+ // Check webview first to see if there is a history
+ // This is needed to support curPage#diffLink, since they are added to parentEngine's history, but not our history url array (JQMobile behavior)
+ if (webView.canGoBack()) {
+ webView.goBack();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void setPaused(boolean value) {
+ if (value) {
+ webView.onPause();
+ webView.pauseTimers();
+ } else {
+ webView.onResume();
+ webView.resumeTimers();
+ }
+ }
+
+ @Override
+ public void destroy() {
+ webView.chromeClient.destroyLastDialog();
+ webView.destroy();
+ // unregister the receiver
+ if (receiver != null) {
+ try {
+ webView.getContext().unregisterReceiver(receiver);
+ } catch (Exception e) {
+ LOG.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ @Override
+ public void evaluateJavascript(String js, ValueCallback<String> callback) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ webView.evaluateJavascript(js, callback);
+ }
+ else
+ {
+ LOG.d(TAG, "This webview is using the old bridge");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/da952e07/cordova-lib/spec-cordova/fixtures/platforms/atari/package.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/atari/package.json b/cordova-lib/spec-cordova/fixtures/platforms/atari/package.json
new file mode 100644
index 0000000..00abaa0
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/atari/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "atari",
+ "version": "1.0.0",
+ "description": "platform test repo. Copy of cordova-android",
+ "bin": {
+ "create": "bin/create"
+ },
+ "main": "bin/templates/cordova/Api.js",
+ "repository": {
+ "type": "git",
+ "url": "https://git-wip-us.apache.org/repos/asf/cordova-android.git"
+ },
+ "keywords": [
+ "android",
+ "cordova",
+ "apache"
+ ],
+ "scripts": {
+ "test": "npm run jshint && jasmine",
+ "cover": "istanbul cover --root bin/templates/cordova --print detail jasmine",
+ "test-build": "jasmine --captureExceptions --color spec/e2e/*.spec.js",
+ "jshint": "jshint bin && jshint spec"
+ },
+ "author": "Apache Software Foundation",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "cordova-common": "^1.5.0",
+ "elementtree": "^0.1.6",
+ "nopt": "^3.0.1",
+ "properties-parser": "^0.2.3",
+ "q": "^1.4.1",
+ "shelljs": "^0.5.3"
+ },
+ "bundledDependencies": [
+ "cordova-common",
+ "elementtree",
+ "nopt",
+ "properties-parser",
+ "q",
+ "shelljs"
+ ],
+ "devDependencies": {
+ "istanbul": "^0.4.2",
+ "jasmine": "^2.5.2",
+ "jshint": "^2.6.0",
+ "promise-matchers": "~0",
+ "rewire": "^2.1.3"
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/da952e07/cordova-lib/spec-cordova/platform.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/platform.spec.js b/cordova-lib/spec-cordova/platform.spec.js
index 763ba9c..604d974 100644
--- a/cordova-lib/spec-cordova/platform.spec.js
+++ b/cordova-lib/spec-cordova/platform.spec.js
@@ -30,6 +30,7 @@ var helpers = require('./helpers'),
var projectRoot = 'C:\\Projects\\cordova-projects\\move-tracker';
var pluginsDir = path.join(__dirname, 'fixtures', 'plugins');
+var platDir = path.join(__dirname, 'fixtures', 'platforms');
describe('platform end-to-end', function () {
@@ -353,4 +354,65 @@ describe('plugin add and rm end-to-end --fetch', function () {
})
.fin(done);
}, 60000);
-});
\ No newline at end of file
+});
+
+
+describe('non-core platform add and rm end-to-end --fetch', function () {
+
+ var tmpDir = helpers.tmpDir('non-core-platform-test');
+ var project = path.join(tmpDir, 'hello');
+ var results;
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ events.on('results', function(res) { results = res; });
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('Test 009 : should add and remove 3rd party platforms', function(done) {
+
+ var installed;
+ cordova.raw.create('hello')
+ .then(function() {
+ process.chdir(project);
+ //add cordova-android instead of android
+ return cordova.raw.platform('add', 'cordova-android', {'fetch': true});
+ })
+ .then(function() {
+ //local 3rd party platform
+ return cordova.raw.platform('add', path.join(platDir, 'atari'), {'fetch': true});
+ })
+ .then(function() {
+ //3rd party platform from npm
+ return cordova.raw.platform('add', 'cordova-platform-test', {'fetch': true});
+ })
+
+ .then(function() {
+ expect(path.join(project, 'platforms', 'android')).toExist();
+ expect(path.join(project, 'platforms', 'cordova-platform-test')).toExist();
+ expect(path.join(project, 'platforms', 'atari')).toExist();
+ return cordova.raw.platform('ls');
+ })
+ .then(function() {
+ //use regex to grab installed platforms
+ installed = results.match(/Installed platforms:\n (.*)\n (.*)\n (.*)/);
+ expect(installed).toBeDefined();
+ expect(installed[1].indexOf('android')).toBeGreaterThan(-1);
+ expect(installed[3].indexOf('cordova-platform-test')).toBeGreaterThan(-1);
+ expect(installed[2].indexOf('atari')).toBeGreaterThan(-1);
+ return cordova.raw.platform('rm', 'atari', {'fetch':true});
+ })
+ .then(function() {
+ expect(path.join(project, 'platforms', 'atari')).not.toExist();
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 90000);
+});
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/da952e07/cordova-lib/spec-plugman/install.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/install.spec.js b/cordova-lib/spec-plugman/install.spec.js
index 4e486f0..081cc3c 100644
--- a/cordova-lib/spec-plugman/install.spec.js
+++ b/cordova-lib/spec-plugman/install.spec.js
@@ -437,13 +437,13 @@ describe('install', function() {
});
describe('failure', function() {
- it('Test 021 : should throw if platform is unrecognized', function(done) {
+ it('Test 021 : should throw if platform is unrecognized & is missing api.js', function(done) {
install('atari', project, 'SomePlugin')
.then(function() {
expect(false).toBe(true);
done();
}).fail(function err (errMsg) {
- expect(errMsg.toString()).toContain('atari not supported.');
+ expect(errMsg.toString()).toContain('It is missing API.js');
done();
}, 6000);
});
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org