cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject [04/16] cordova-lib git commit: CB-11346: added tests for support of 3rd party platforms
Date Tue, 21 Mar 2017 20:19:20 GMT
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


Mime
View raw message