Compare commits

...

13 Commits

Author SHA1 Message Date
Erisu
2143045d4e release(android-v13.0.0): updated version and RELEASENOTES.md 2024-05-15 19:35:44 +09:00
エリス
3c5df42df5 dep: bump npm dependencies 20240515 (#1713)
* dep: bump android-versions@2.0.0
* dep: bump properties-parser@0.6.0
* dep: bump which@4.0.0
* chore: rebuilt package-lock w/ lockfileVersion 3
* dep(dev): bump @cordova/eslint-config@5.1.0
* dep: bump dedent@1.5.3
* dep: bump fast-glob@3.3.2
* dep: bump fs-extra@11.2.0
* dep(dev): bump jasmine@5.1.0
* dep(dev): bump nopt@7.2.1
* dep(dev): bump rewire@7.0.0
* dep: bump semver@7.6.2
* chore: rebuilt package-lock after package updates
2024-05-15 18:01:22 +09:00
エリス
c2f315c0ff feat: bump kotlin 1.9.24 & drop kotlin-android-extensions when kotlin >= 1.8.0 (#1543)
* feat: bump kotlin 1.9.24 & don't apply kotlin-android-extensions when kotlin >= 1.8.0
2024-05-13 23:32:49 +09:00
Norman Breau
89a0a72da5 feat!: API 34 Support (#1678)
* feat!: Upgrade to Gradle and AGP 8

* java 17

* feat!: API 34 Support

API 34: Upgrade AGP from 8.2.0-rc01 to 8.2.0-rc02

API 34: Upgrade AGP from 8.2.0-rc02 to 8.2.0-rc03

API 34: Upgrade AGP from 8.2.0-rc03 to 8.2.0

feat: add AndroidKotlinJVMTarget preference to set the kotlin JVM target
This is in addition to the java source / target compatibility preferences.
AndroidKotlinJVMTarget is only affective if Kotlin is enabled.

chore: Upgrade Gradle from 8.4 to 8.5

AGP 8.2.0 -> 8.2.1

Gradle 8.5 -> 8.7

fix: Add --validate-url to gradle wrapper commands

AGP 8.4.0

* fix(test): ProjectBuilder using Gradle 8.3, no longer supported version

* API 34: Change Kotlin JVM Target default.

The new default value is null. When null, it will by default
to the Java Target compatibility. Updating AndroidJavaTargetCompatibility
will also influence the Kotlin JVM target, unless if AndroidKotlinJVMTarget
is also explicitly defined.

* removed leftover debug prints

* API 34: Gradle Wrapper

* API 34: ratignore generated gradle wrapper files

* fix gradle wrapper jar via git attributes

* fix(test): normalise gradle paths

* fix(windows): Gradle paths

* fix(windows): Keep CRLF endings for bat files

* chore: Updated license for Gradle Wrapper 8.7 pointer

* API 34 Support Gradle Tools project

* API 34: omit --validate-url on installing the wrapper

* revert: LICENSE notice on bundling the gradle wrapper jar

* Revert: AGP 8.4 -> 8.3

* test(ci): Added NodeJS 22 to the test matrix

---------

Co-authored-by: jcesarmobile <jcesarmobile@gmail.com>
2024-05-13 10:28:57 -03:00
エリス
ed8e5d2f0a ci: Set up CodeQL analysis w/ fixes (#1711)
* ci: Set up CodeQL analysis
* spec: disable allowBackup in testing
* ci: do not check cordova.js - convered in cordova-js repo
* chore: add missing @Override annotation
2024-05-13 10:24:04 +09:00
Darryl Pogue
7fa4a65d0a feat(splash): Support SplashScreenBackgroundColor preference (#1700) 2024-05-09 15:57:04 +09:00
Ken Corbett
b773ae48f4 feat: add camera intent with file input capture (#1609)
* Allow image file input to be from camera
* Reverting some irrellevant formatting changes
* Removing the openFileChooser functions as they are no longer necessary
* Update templates/project/res/xml/opener_paths.xml
* Code review feedback
* Adding license to provider paths xml file
* Adding a comment describing the proper use of the core cordova file provider
* Adding the ability to query the android.media.action.IMAGE_CAPTURE intent action
* Only including a cache path
* Applying code review feedback

---------

Co-authored-by: Ken Corbett <ken@truepic.com>
Co-authored-by: エリス <erisu@users.noreply.github.com>
2024-05-09 13:30:49 +09:00
jcesarmobile
ebf0b105a3 feat: Add ResolveServiceWorkerRequests preference (#1696)
* feat: Add ResolveServiceWorkerRequests preference
* Change default to true
2024-05-08 20:53:09 +09:00
エリス
9261b29cf2 ci(release-audit): add license header and dependency checker (#1687)
* ci(release-audit): add license header and dependency checker
* chore: add Apache license headers
* chore: add new line to .ratignore
2024-05-08 15:07:52 +09:00
エリス
90e74befc7 chore: bump version 13.0.0-dev (#1708) 2024-05-08 01:51:15 +09:00
エリス
97806db463 ci: update codecov@v4 w/ token (#1703) 2024-04-13 18:31:55 +09:00
dependabot[bot]
4742358601 chore(deps-dev): bump @babel/traverse from 7.22.10 to 7.23.2 (#1677)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.10 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-20 17:36:12 -03:00
Erisu
e61e271f5b chore: bump version 12.0.2-dev 2023-08-23 18:39:28 +09:00
55 changed files with 1901 additions and 4983 deletions

3
.gitattributes vendored
View File

@@ -23,7 +23,7 @@
*.scm text
*.sql text
*.sh text
*.bat text
*.bat text eol=crlf
# templates
*.ejs text
@@ -92,3 +92,4 @@ AUTHORS text
*.woff binary
*.pyc binary
*.pdf binary
*.jar binary

View File

@@ -27,22 +27,19 @@ jobs:
strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
node-version: [16.x, 18.x, 20.x, 22.x]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: set up JDK 11
uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'
- name: Environment Information
run: |
@@ -50,6 +47,21 @@ jobs:
npm --version
gradle --version
# "bin/templates/platform_www/cordova.js" is ignored because it is a generated file.
# It contains mixed content from the npm package "cordova-js" and "./cordova-js-src".
# The report might not be resolvable because of the external package.
# If the report is related to this repository, it would be detected when scanning "./cordova-js-src".
- uses: github/codeql-action/init@v3
with:
languages: javascript, java-kotlin
queries: security-and-quality
config: |
paths-ignore:
- coverage
- node_modules
- templates/project/assets/www/cordova.js
- test/androidx/app/src/main/assets/www/cordova.js
- name: npm install and test
run: |
npm i
@@ -57,8 +69,11 @@ jobs:
env:
CI: true
- name: upload coverage
- uses: github/codeql-action/analyze@v3
- uses: codecov/codecov-action@v4
if: success()
uses: codecov/codecov-action@v3
with:
name: ${{ runner.os }} node.js ${{ matrix.node-version }}
token: ${{ secrets.CORDOVA_CODECOV_TOKEN }}
fail_ci_if_error: false

45
.github/workflows/release-audit.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
# 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.
name: Release Auditing
on: [push, pull_request]
jobs:
test:
name: Audit Licenses
runs-on: ubuntu-latest
steps:
# Checkout project
- uses: actions/checkout@v4
# Check license headers
- uses: erisu/apache-rat-action@555ae80334a535eb6c1f8920b121563a5a985a75
# Setup environment with node
- uses: actions/setup-node@v4
with:
node-version: 20
# Install node packages
- name: npm install packages
run: npm i
# Check node package licenses
- uses: erisu/license-checker-action@e929758f9416f30234ac454fc9054ca4b803871d
with:
license-config: 'licence_checker.yml'

6
.gitignore vendored
View File

@@ -29,12 +29,8 @@ example
**/assets/www/cordova.js
/test/.externalNativeBuild
/test/androidx/gradle
/test/androidx/gradlew
/test/androidx/gradlew.bat
/test/androidx/cdv-gradle-config.json
/test/androidx/tools
/test/assets/www/.tmp*
/test/assets/www/cordova.js
/test/bin

View File

@@ -1,8 +1,13 @@
*.properties
templates
gen
proguard-project.txt
spec
framework/build
ic_launcher.png
build
\.(.*)
(.*).txt
coverage
fixtures
generated
gitignore
intermediates
reports
test-results
node_modules
gradle
gradlew
gradlew.bat

View File

@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2015-2020 Apache Cordova
Copyright 2015-2024 Apache Cordova
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -200,3 +200,4 @@
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.

View File

@@ -20,6 +20,38 @@
-->
## Release Notes for Cordova (Android)
### 13.0.0 (May 15, 2024)
**Breaking Changes:**
* [GH-1678](https://github.com/apache/cordova-android/pull/1678) feat!: API 34 Support
* [GH-1543](https://github.com/apache/cordova-android/pull/1543) feat!: bump `kotlin@1.9.24` & drop `kotlin-android-extensions` when kotlin `>=1.8.0`
**Features:**
* [GH-1700](https://github.com/apache/cordova-android/pull/1700) feat(splash): Support `SplashScreenBackgroundColor` preference
* [GH-1609](https://github.com/apache/cordova-android/pull/1609) feat: add camera intent with file input capture
* [GH-1696](https://github.com/apache/cordova-android/pull/1696) feat: Add `ResolveServiceWorkerRequests` preference
**Chores, Dependencies & CI:**
* [GH-1677](https://github.com/apache/cordova-android/pull/1677) chore(deps-dev): bump `@babel/traverse` from `7.22.10` to `7.23.2`
* [GH-1713](https://github.com/apache/cordova-android/pull/1713) dep: bump npm dependencies 20240515
* `semver@7.6.2`
* `rewire@7.0.0`
* `nopt@7.2.1`
* `jasmine@5.1.0`
* `fs-extra@11.2.0`
* `fast-glob@3.3.2`
* `dedent@1.5.3`
* `@cordova/eslint-config@5.1.0`
* `which@4.0.0`
* `properties-parser@0.6.0`
* `android-versions@2.0.0`
* [GH-1711](https://github.com/apache/cordova-android/pull/1711) ci: Set up CodeQL analysis w/ fixes
* [GH-1687](https://github.com/apache/cordova-android/pull/1687) ci(release-audit): add license header and dependency checker
* [GH-1703](https://github.com/apache/cordova-android/pull/1703) ci: update `codecov@v4` w/ token
### 12.0.1 (Aug 23, 2023)
* [GH-1632](https://github.com/apache/cordova-android/pull/1632) fix(android): `monochrome` checks

View File

@@ -50,8 +50,8 @@ android {
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaLanguageVersion.of(cordovaConfig.JAVA_SOURCE_COMPATIBILITY)
targetCompatibility JavaLanguageVersion.of(cordovaConfig.JAVA_TARGET_COMPATIBILITY)
}
// For the Android Cordova Lib, we allow changing the minSdkVersion, but it is at the users own risk

View File

@@ -1,16 +1,19 @@
{
"MIN_SDK_VERSION": 24,
"SDK_VERSION": 33,
"SDK_VERSION": 34,
"COMPILE_SDK_VERSION": null,
"GRADLE_VERSION": "7.6",
"MIN_BUILD_TOOLS_VERSION": "33.0.2",
"AGP_VERSION": "7.4.2",
"KOTLIN_VERSION": "1.7.21",
"GRADLE_VERSION": "8.7",
"MIN_BUILD_TOOLS_VERSION": "34.0.0",
"AGP_VERSION": "8.3.0",
"KOTLIN_VERSION": "1.9.24",
"ANDROIDX_APP_COMPAT_VERSION": "1.6.1",
"ANDROIDX_WEBKIT_VERSION": "1.6.0",
"ANDROIDX_CORE_SPLASHSCREEN_VERSION": "1.0.0",
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.15",
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false,
"PACKAGE_NAMESPACE": "io.cordova.helloCordova"
"PACKAGE_NAMESPACE": "io.cordova.helloCordova",
"JAVA_SOURCE_COMPATIBILITY": 8,
"JAVA_TARGET_COMPATIBILITY": 8,
"KOTLIN_JVM_TARGET": null
}

View File

@@ -43,6 +43,10 @@ Boolean isVersionValid(version) {
return !(new Version(version)).isEqual('0.0.0')
}
Boolean isVersionGreaterThanEqual(versionX, versionY) {
return (new Version(versionX)) >= (new Version(versionY))
}
String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
def buildToolsDirContents
try {

View File

@@ -1,3 +1,20 @@
# 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.
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:

View File

@@ -1,3 +1,20 @@
# 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.
#Thu Nov 09 10:50:25 PST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists

View File

@@ -1,3 +1,20 @@
# 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.
# GENERATED FILE! DO NOT EDIT!
# This file was originally created by the Android Tools, but is now

View File

@@ -391,6 +391,7 @@ public class CordovaActivity extends AppCompatActivity {
if ((errorUrl != null) && (!failingUrl.equals(errorUrl)) && (appView != null)) {
// Load URL on UI thread
me.runOnUiThread(new Runnable() {
@Override
public void run() {
me.appView.showWebPage(errorUrl, false, true, null);
}
@@ -400,6 +401,7 @@ public class CordovaActivity extends AppCompatActivity {
else {
final boolean exit = !(errorCode == WebViewClient.ERROR_HOST_LOOKUP);
me.runOnUiThread(new Runnable() {
@Override
public void run() {
if (exit) {
me.appView.getView().setVisibility(View.GONE);
@@ -416,6 +418,7 @@ public class CordovaActivity extends AppCompatActivity {
public void displayError(final String title, final String message, final String button, final boolean exit) {
final CordovaActivity me = this;
me.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
AlertDialog.Builder dlg = new AlertDialog.Builder(me);
@@ -424,6 +427,7 @@ public class CordovaActivity extends AppCompatActivity {
dlg.setCancelable(false);
dlg.setPositiveButton(button,
new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (exit) {
@@ -488,6 +492,7 @@ public class CordovaActivity extends AppCompatActivity {
return null;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
cordovaInterface.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);

View File

@@ -41,6 +41,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* Cancel this request
*/
@SuppressLint("NewApi")
@Override
public void cancel()
{
request.cancel();
@@ -50,6 +51,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* Returns the host name of the server requesting the certificate.
*/
@SuppressLint("NewApi")
@Override
public String getHost()
{
return request.getHost();
@@ -59,6 +61,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* Returns the acceptable types of asymmetric keys (can be null).
*/
@SuppressLint("NewApi")
@Override
public String[] getKeyTypes()
{
return request.getKeyTypes();
@@ -68,6 +71,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* Returns the port number of the server requesting the certificate.
*/
@SuppressLint("NewApi")
@Override
public int getPort()
{
return request.getPort();
@@ -77,6 +81,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* Returns the acceptable certificate issuers for the certificate matching the private key (can be null).
*/
@SuppressLint("NewApi")
@Override
public Principal[] getPrincipals()
{
return request.getPrincipals();
@@ -86,6 +91,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* Ignore the request for now. Do not remember user's choice.
*/
@SuppressLint("NewApi")
@Override
public void ignore()
{
request.ignore();
@@ -98,6 +104,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* @param chain The certificate chain
*/
@SuppressLint("NewApi")
@Override
public void proceed(PrivateKey privateKey, X509Certificate[] chain)
{
request.proceed(privateKey, chain);

View File

@@ -43,18 +43,21 @@ public class CordovaDialogsHelper {
dlg.setCancelable(true);
dlg.setPositiveButton(android.R.string.ok,
new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.gotResult(true, null);
}
});
dlg.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
result.gotResult(false, null);
}
});
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
//DO NOTHING
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK)
{
@@ -75,24 +78,28 @@ public class CordovaDialogsHelper {
dlg.setCancelable(true);
dlg.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.gotResult(true, null);
}
});
dlg.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.gotResult(false, null);
}
});
dlg.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
result.gotResult(false, null);
}
});
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
//DO NOTHING
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK)
{
@@ -126,6 +133,7 @@ public class CordovaDialogsHelper {
dlg.setCancelable(false);
dlg.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String userText = input.getText().toString();
result.gotResult(true, userText);
@@ -133,6 +141,7 @@ public class CordovaDialogsHelper {
});
dlg.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.gotResult(false, null);
}

View File

@@ -35,6 +35,7 @@ public class CordovaHttpAuthHandler implements ICordovaHttpAuthHandler {
/**
* Instructs the WebView to cancel the authentication request.
*/
@Override
public void cancel () {
this.handler.cancel();
}
@@ -45,6 +46,7 @@ public class CordovaHttpAuthHandler implements ICordovaHttpAuthHandler {
* @param username
* @param password
*/
@Override
public void proceed (String username, String password) {
this.handler.proceed(username, password);
}

View File

@@ -223,18 +223,21 @@ public class CordovaInterfaceImpl implements CordovaInterface {
}
}
@Override
public void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
String[] permissions = new String [1];
permissions[0] = permission;
requestPermissions(plugin, requestCode, permissions);
}
@SuppressLint("NewApi")
@SuppressLint("NewApi")
@Override
public void requestPermissions(CordovaPlugin plugin, int requestCode, String [] permissions) {
int mappedRequestCode = permissionResultCallbacks.registerCallback(plugin, requestCode);
getActivity().requestPermissions(permissions, mappedRequestCode);
}
@Override
public boolean hasPermission(String permission)
{
return PackageManager.PERMISSION_GRANTED == activity.checkSelfPermission(permission);

View File

@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
* are not expected to implement it.
*/
public interface CordovaWebView {
public static final String CORDOVA_VERSION = "12.0.1";
public static final String CORDOVA_VERSION = "13.0.0";
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);

View File

@@ -149,6 +149,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
// Timeout error method
final Runnable loadError = new Runnable() {
@Override
public void run() {
stopLoading();
LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
@@ -168,6 +169,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
// Timeout timer method
final Runnable timeoutCheck = new Runnable() {
@Override
public void run() {
try {
synchronized (this) {
@@ -189,6 +191,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
if (cordova.getActivity() != null) {
final boolean _recreatePlugins = recreatePlugins;
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (loadUrlTimeoutValue > 0) {
cordova.getThreadPool().execute(timeoutCheck);
@@ -579,11 +582,13 @@ public class CordovaWebViewImpl implements CordovaWebView {
// Make app visible after 2 sec in case there was a JS error and Cordova JS never initialized correctly
if (engine.getView().getVisibility() != View.VISIBLE) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
if (cordova.getActivity() != null) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
pluginManager.postMessage("spinner", "stop");
}

View File

@@ -73,6 +73,7 @@ public class CoreAndroid extends CordovaPlugin {
* @param callbackContext The callback context from which we were invoked.
* @return A PluginResult object with a status and message.
*/
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
PluginResult.Status status = PluginResult.Status.OK;
String result = "";
@@ -86,6 +87,7 @@ public class CoreAndroid extends CordovaPlugin {
// I recommend we change the name of the Message as spinner/stop is not
// indicative of what this actually does (shows the webview).
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
webView.getPluginManager().postMessage("spinner", "stop");
}
@@ -144,6 +146,7 @@ public class CoreAndroid extends CordovaPlugin {
*/
public void clearCache() {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
webView.clearCache();
}
@@ -215,6 +218,7 @@ public class CoreAndroid extends CordovaPlugin {
*/
public void clearHistory() {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
webView.clearHistory();
}
@@ -227,6 +231,7 @@ public class CoreAndroid extends CordovaPlugin {
*/
public void backHistory() {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
webView.backHistory();
}
@@ -353,6 +358,7 @@ public class CoreAndroid extends CordovaPlugin {
* Unregister the receiver
*
*/
@Override
public void onDestroy()
{
webView.getContext().unregisterReceiver(this.telephonyReceiver);

View File

@@ -302,6 +302,7 @@ public class NativeToJsMessageQueue {
@Override
public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String js = queue.popAndEncodeAsJs();
if (js != null) {
@@ -330,6 +331,7 @@ public class NativeToJsMessageQueue {
@Override
public void reset() {
delegate.runOnUiThread(new Runnable() {
@Override
public void run() {
online = false;
// If the following call triggers a notifyOfFlush, then ignore it.
@@ -342,6 +344,7 @@ public class NativeToJsMessageQueue {
@Override
public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) {
delegate.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!queue.isEmpty()) {
ignoreNextFlush = false;
@@ -372,6 +375,7 @@ public class NativeToJsMessageQueue {
@Override
public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String js = queue.popAndEncodeAsJs();
if (js != null) {

View File

@@ -41,22 +41,27 @@ class SystemCookieManager implements ICordovaCookieManager {
cookieManager.setAcceptFileSchemeCookies(true);
}
@Override
public void setCookiesEnabled(boolean accept) {
cookieManager.setAcceptCookie(accept);
}
@Override
public void setCookie(final String url, final String value) {
cookieManager.setCookie(url, value);
}
@Override
public String getCookie(final String url) {
return cookieManager.getCookie(url);
}
@Override
public void clearCookies() {
cookieManager.removeAllCookies(null);
}
@Override
public void flush() {
cookieManager.flush();
}

View File

@@ -37,16 +37,19 @@ class SystemExposedJsApi implements ExposedJsApi {
}
@JavascriptInterface
@Override
public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
return bridge.jsExec(bridgeSecret, service, action, callbackId, arguments);
}
@JavascriptInterface
@Override
public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
bridge.jsSetNativeToJsBridgeMode(bridgeSecret, value);
}
@JavascriptInterface
@Override
public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
return bridge.jsRetrieveJsMessages(bridgeSecret, fromOnlineEvent);
}

View File

@@ -18,18 +18,22 @@
*/
package org.apache.cordova.engine;
import java.io.IOException;
import java.io.File;
import java.util.Arrays;
import android.annotation.TargetApi;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
@@ -41,6 +45,7 @@ import android.webkit.PermissionRequest;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import androidx.core.content.FileProvider;
import org.apache.cordova.CordovaDialogsHelper;
import org.apache.cordova.CordovaPlugin;
@@ -212,52 +217,110 @@ public class SystemWebChromeClient extends WebChromeClient {
}
@Override
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback,
final WebChromeClient.FileChooserParams fileChooserParams) {
Intent fileIntent = fileChooserParams.createIntent();
// Check if multiple-select is specified
Boolean selectMultiple = false;
if (fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) {
selectMultiple = true;
}
Intent intent = fileChooserParams.createIntent();
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, selectMultiple);
fileIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, selectMultiple);
// Uses Intent.EXTRA_MIME_TYPES to pass multiple mime types.
String[] acceptTypes = fileChooserParams.getAcceptTypes();
if (acceptTypes.length > 1) {
intent.setType("*/*"); // Accept all, filter mime types by Intent.EXTRA_MIME_TYPES.
intent.putExtra(Intent.EXTRA_MIME_TYPES, acceptTypes);
fileIntent.setType("*/*"); // Accept all, filter mime types by Intent.EXTRA_MIME_TYPES.
fileIntent.putExtra(Intent.EXTRA_MIME_TYPES, acceptTypes);
}
// Image from camera intent
Uri tempUri = null;
Intent captureIntent = null;
if (fileChooserParams.isCaptureEnabled()) {
captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Context context = parentEngine.getView().getContext();
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
&& captureIntent.resolveActivity(context.getPackageManager()) != null) {
try {
File tempFile = createTempFile(context);
LOG.d(LOG_TAG, "Temporary photo capture file: " + tempFile);
tempUri = createUriForFile(context, tempFile);
LOG.d(LOG_TAG, "Temporary photo capture URI: " + tempUri);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
} catch (IOException e) {
LOG.e(LOG_TAG, "Unable to create temporary file for photo capture", e);
captureIntent = null;
}
} else {
LOG.w(LOG_TAG, "Device does not support photo capture");
captureIntent = null;
}
}
final Uri captureUri = tempUri;
// Chooser intent
Intent chooserIntent = Intent.createChooser(fileIntent, null);
if (captureIntent != null) {
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { captureIntent });
}
try {
LOG.i(LOG_TAG, "Starting intent for file chooser");
parentEngine.cordova.startActivityForResult(new CordovaPlugin() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// Handle result
Uri[] result = null;
if (resultCode == Activity.RESULT_OK && intent != null) {
if (intent.getClipData() != null) {
// handle multiple-selected files
final int numSelectedFiles = intent.getClipData().getItemCount();
result = new Uri[numSelectedFiles];
for (int i = 0; i < numSelectedFiles; i++) {
result[i] = intent.getClipData().getItemAt(i).getUri();
LOG.d(LOG_TAG, "Receive file chooser URL: " + result[i]);
if (resultCode == Activity.RESULT_OK) {
List<Uri> uris = new ArrayList<Uri>();
if (intent != null && intent.getData() != null) { // single file
LOG.v(LOG_TAG, "Adding file (single): " + intent.getData());
uris.add(intent.getData());
} else if (captureUri != null) { // camera
LOG.v(LOG_TAG, "Adding camera capture: " + captureUri);
uris.add(captureUri);
} else if (intent != null && intent.getClipData() != null) { // multiple files
ClipData clipData = intent.getClipData();
int count = clipData.getItemCount();
for (int i = 0; i < count; i++) {
Uri uri = clipData.getItemAt(i).getUri();
LOG.v(LOG_TAG, "Adding file (multiple): " + uri);
if (uri != null) {
uris.add(uri);
}
}
}
else if (intent.getData() != null) {
// handle single-selected file
result = WebChromeClient.FileChooserParams.parseResult(resultCode, intent);
LOG.d(LOG_TAG, "Receive file chooser URL: " + result);
if (!uris.isEmpty()) {
LOG.d(LOG_TAG, "Receive file chooser URL: " + uris.toString());
result = uris.toArray(new Uri[uris.size()]);
}
}
filePathsCallback.onReceiveValue(result);
}
}, intent, FILECHOOSER_RESULTCODE);
}, chooserIntent, FILECHOOSER_RESULTCODE);
} catch (ActivityNotFoundException e) {
LOG.w("No activity found to handle file chooser intent.", e);
LOG.w(LOG_TAG, "No activity found to handle file chooser intent.", e);
filePathsCallback.onReceiveValue(null);
}
return true;
}
private File createTempFile(Context context) throws IOException {
// Create an image file name
File tempFile = File.createTempFile("temp", ".jpg", context.getCacheDir());
return tempFile;
}
private Uri createUriForFile(Context context, File tempFile) throws IOException {
String appId = context.getPackageName();
Uri uri = FileProvider.getUriForFile(context, appId + ".cdv.core.file.provider", tempFile);
return uri;
}
@Override
public void onPermissionRequest(final PermissionRequest request) {
LOG.d(LOG_TAG, "onPermissionRequest: " + Arrays.toString(request.getResources()));

View File

@@ -29,6 +29,8 @@ import android.webkit.ClientCertRequest;
import android.webkit.HttpAuthHandler;
import android.webkit.MimeTypeMap;
import android.webkit.RenderProcessGoneDetail;
import android.webkit.ServiceWorkerClient;
import android.webkit.ServiceWorkerController;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
@@ -116,6 +118,18 @@ public class SystemWebViewClient extends WebViewClient {
});
this.assetLoader = assetLoaderBuilder.build();
boolean setAsServiceWorkerClient = parentEngine.preferences.getBoolean("ResolveServiceWorkerRequests", true);
ServiceWorkerController controller = null;
if (setAsServiceWorkerClient) {
controller = ServiceWorkerController.getInstance();
controller.setServiceWorkerClient(new ServiceWorkerClient(){
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
return assetLoader.shouldInterceptRequest(request.getUrl());
}
});
}
}
/**

View File

@@ -25,7 +25,7 @@ const events = require('cordova-common').events;
const CordovaError = require('cordova-common').CordovaError;
const check_reqs = require('../check_reqs');
const PackageType = require('../PackageType');
const { compareByAll } = require('../utils');
const { compareByAll, isWindows } = require('../utils');
const { createEditor } = require('properties-parser');
const CordovaGradleConfigParserFactory = require('../config/CordovaGradleConfigParserFactory');
@@ -85,9 +85,7 @@ class ProjectBuilder {
}
getArgs (cmd, opts) {
let args = [
'-b', path.join(this.root, 'build.gradle')
];
let args = [];
if (opts.extraArgs) {
args = args.concat(opts.extraArgs);
}
@@ -116,16 +114,27 @@ class ProjectBuilder {
return args;
}
/*
* This returns a promise
*/
runGradleWrapper (gradle_cmd) {
const gradlePath = path.join(this.root, 'gradlew');
const wrapperGradle = path.join(this.root, 'wrapper.gradle');
if (fs.existsSync(gradlePath)) {
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
getGradleWrapperPath () {
let wrapper = path.join(this.root, 'tools', 'gradlew');
if (isWindows()) {
wrapper += '.bat';
}
return wrapper;
}
/**
* Installs/updates the gradle wrapper
* @param {string} gradleVersion The gradle version to install. Ignored if CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL environment variable is defined
* @returns {Promise<void>}
*/
async installGradleWrapper (gradleVersion) {
if (process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL) {
events.emit('verbose', `Overriding Gradle Version via CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL (${process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL})`);
await execa('gradle', ['-p', path.join(this.root, 'tools'), 'wrapper', '--gradle-distribution-url', process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL], { stdio: 'inherit' });
} else {
return execa(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], { stdio: 'inherit' });
await execa('gradle', ['-p', path.join(this.root, 'tools'), 'wrapper', '--gradle-version', gradleVersion], { stdio: 'inherit' });
}
}
@@ -275,23 +284,14 @@ class ProjectBuilder {
prepEnv (opts) {
const self = this;
const config = this._getCordovaConfig();
return check_reqs.check_gradle()
.then(function (gradlePath) {
return self.runGradleWrapper(gradlePath);
.then(function () {
events.emit('verbose', `Using Gradle: ${config.GRADLE_VERSION}`);
return self.installGradleWrapper(config.GRADLE_VERSION);
}).then(function () {
return self.prepBuildFiles();
}).then(() => {
const config = this._getCordovaConfig();
// update/set the distributionUrl in the gradle-wrapper.properties
const gradleWrapperPropertiesPath = path.join(self.root, 'gradle/wrapper/gradle-wrapper.properties');
const gradleWrapperProperties = createEditor(gradleWrapperPropertiesPath);
const distributionUrl = process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL || `https://services.gradle.org/distributions/gradle-${config.GRADLE_VERSION}-all.zip`;
gradleWrapperProperties.set('distributionUrl', distributionUrl);
gradleWrapperProperties.save();
events.emit('verbose', `Gradle Distribution URL: ${distributionUrl}`);
})
.then(() => {
const signingPropertiesPath = path.join(self.root, `${opts.buildType}${SIGNING_PROPERTIES}`);
if (fs.existsSync(signingPropertiesPath)) fs.removeSync(signingPropertiesPath);
@@ -317,7 +317,7 @@ class ProjectBuilder {
* Returns a promise.
*/
async build (opts) {
const wrapper = path.join(this.root, 'gradlew');
const wrapper = this.getGradleWrapperPath();
const args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
events.emit('verbose', `Running Gradle Build: ${wrapper} ${args.join(' ')}`);
@@ -338,7 +338,7 @@ class ProjectBuilder {
}
clean (opts) {
const wrapper = path.join(this.root, 'gradlew');
const wrapper = this.getGradleWrapperPath();
const args = this.getArgs('clean', opts);
return execa(wrapper, args, { stdio: 'inherit', cwd: path.resolve(this.root) })
.then(() => {

View File

@@ -113,20 +113,15 @@ function prepBuildFiles (projectPath) {
buildModule.getBuilder(projectPath).prepBuildFiles();
}
function copyBuildRules (projectPath, isLegacy) {
function copyBuildRules (projectPath) {
const srcDir = path.join(ROOT, 'templates', 'project');
if (isLegacy) {
// The project's build.gradle is identical to the earlier build.gradle, so it should still work
fs.copySync(path.join(srcDir, 'legacy', 'build.gradle'), path.join(projectPath, 'legacy', 'build.gradle'));
fs.copySync(path.join(srcDir, 'wrapper.gradle'), path.join(projectPath, 'wrapper.gradle'));
} else {
fs.copySync(path.join(srcDir, 'build.gradle'), path.join(projectPath, 'build.gradle'));
fs.copySync(path.join(srcDir, 'app', 'build.gradle'), path.join(projectPath, 'app', 'build.gradle'));
fs.copySync(path.join(srcDir, 'app', 'repositories.gradle'), path.join(projectPath, 'app', 'repositories.gradle'));
fs.copySync(path.join(srcDir, 'repositories.gradle'), path.join(projectPath, 'repositories.gradle'));
fs.copySync(path.join(srcDir, 'wrapper.gradle'), path.join(projectPath, 'wrapper.gradle'));
}
fs.copySync(path.join(srcDir, 'build.gradle'), path.join(projectPath, 'build.gradle'));
fs.copySync(path.join(srcDir, 'app', 'build.gradle'), path.join(projectPath, 'app', 'build.gradle'));
fs.copySync(path.join(srcDir, 'app', 'repositories.gradle'), path.join(projectPath, 'app', 'repositories.gradle'));
fs.copySync(path.join(srcDir, 'repositories.gradle'), path.join(projectPath, 'repositories.gradle'));
copyGradleTools(projectPath);
}
function copyScripts (projectPath) {
@@ -176,6 +171,12 @@ function validateProjectName (project_name) {
return Promise.resolve();
}
function copyGradleTools (projectPath) {
const srcDir = path.join(ROOT, 'templates', 'project');
fs.copySync(path.resolve(srcDir, 'tools'), path.resolve(projectPath, 'tools'));
}
/**
* Creates an android application with the given options.
*

View File

@@ -110,7 +110,10 @@ function getUserGradleConfig (configXml) {
{ xmlKey: 'AndroidXWebKitVersion', gradleKey: 'ANDROIDX_WEBKIT_VERSION', type: String },
{ xmlKey: 'GradlePluginGoogleServicesVersion', gradleKey: 'GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION', type: String },
{ xmlKey: 'GradlePluginGoogleServicesEnabled', gradleKey: 'IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED', type: Boolean },
{ xmlKey: 'GradlePluginKotlinEnabled', gradleKey: 'IS_GRADLE_PLUGIN_KOTLIN_ENABLED', type: Boolean }
{ xmlKey: 'GradlePluginKotlinEnabled', gradleKey: 'IS_GRADLE_PLUGIN_KOTLIN_ENABLED', type: Boolean },
{ xmlKey: 'AndroidJavaSourceCompatibility', gradleKey: 'JAVA_SOURCE_COMPATIBILITY', type: Number },
{ xmlKey: 'AndroidJavaTargetCompatibility', gradleKey: 'JAVA_TARGET_COMPATIBILITY', type: Number },
{ xmlKey: 'AndroidKotlinJVMTarget', gradleKey: 'KOTLIN_JVM_TARGET', type: String }
];
return configXmlToGradleMapping.reduce((config, mapping) => {
@@ -378,10 +381,24 @@ function updateProjectSplashScreen (platformConfig, locations) {
const themes = xmlHelpers.parseElementtreeSync(locations.themes);
const splashScreenTheme = themes.find('style[@name="Theme.App.SplashScreen"]');
let splashBg = platformConfig.getPreference('AndroidWindowSplashScreenBackground', this.platform);
if (!splashBg) {
splashBg = platformConfig.getPreference('SplashScreenBackgroundColor', this.platform);
}
if (!splashBg) {
splashBg = platformConfig.getPreference('BackgroundColor', this.platform);
}
// use the user defined value for "colors.xml"
updateProjectSplashScreenBackgroundColor(splashBg, locations);
// force the themes value to `@color/cdv_splashscreen_background`
const splashBgNode = splashScreenTheme.find('item[@name="windowSplashScreenBackground"]');
splashBgNode.text = '@color/cdv_splashscreen_background';
[
'windowSplashScreenAnimatedIcon',
'windowSplashScreenAnimationDuration',
'windowSplashScreenBackground',
'android:windowSplashScreenBrandingImage',
'windowSplashScreenIconBackgroundColor',
'postSplashScreenTheme'
@@ -392,14 +409,6 @@ function updateProjectSplashScreen (platformConfig, locations) {
let themeTargetNode = splashScreenTheme.find(`item[@name="${themeKey}"]`);
switch (themeKey) {
case 'windowSplashScreenBackground':
// use the user defined value for "colors.xml"
updateProjectSplashScreenBackgroundColor(cdvConfigPrefValue, locations);
// force the themes value to `@color/cdv_splashscreen_background`
themeTargetNode.text = '@color/cdv_splashscreen_background';
break;
case 'windowSplashScreenAnimatedIcon':
// handle here the cases of "png" vs "xml" (drawable)
// If "png":

60
licence_checker.yml Normal file
View File

@@ -0,0 +1,60 @@
# 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.
# Compiled list of allowed 3RD PARTY LICENSES from:
#
# ASF CATEGORY A: WHAT CAN WE INCLUDE IN AN ASF PROJECT
# https://www.apache.org/legal/resolved.html#category-a
#
# Licenses converted into the SPDX standardized short identifier format.
# https://spdx.org/licenses/
allowed-licenses:
- 0BSD
- AFL-3.0
- Apache-1.1
- Apache-2.0
- APAFML
- BlueOak-1.0.0
- BSD-2-Clause
- BSD-3-Clause
- BSD-3-Clause-LBNL
- BSL-1.0
- CC-PDDC
- CC0-1.0
- EPICS
- HPND
- ICU
- ISC
- MIT
- MIT-0
- MS-PL
- MulanPSL-2.0
- NCSA
- OGL-UK-3.0
- PHP-3.01
- PostgreSQL
- PSF-2.0
- SMLNJ
- Unicode-DFS-2016
- Unlicense
- UPL-1.0
- W3C
- WTFPL
- X11
- Xnet
- Zlib
- ZPL-2.0

5922
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "cordova-android",
"version": "12.0.1",
"version": "13.0.0",
"description": "cordova-android release",
"types": "./types/index.d.ts",
"main": "lib/Api.js",
@@ -19,34 +19,33 @@
"unit-tests": "jasmine --config=spec/unit/jasmine.json",
"cover": "nyc jasmine --config=spec/coverage.json",
"e2e-tests": "jasmine --config=spec/e2e/jasmine.json",
"java-unit-tests": "node test/run_java_unit_tests.js",
"clean:java-unit-tests": "node test/clean.js"
"java-unit-tests": "node test/run_java_unit_tests.js"
},
"author": "Apache Software Foundation",
"license": "Apache-2.0",
"dependencies": {
"android-versions": "^1.8.1",
"android-versions": "^2.0.0",
"cordova-common": "^5.0.0",
"dedent": "^1.0.1",
"dedent": "^1.5.3",
"execa": "^5.1.1",
"fast-glob": "^3.2.12",
"fs-extra": "^11.1.1",
"fast-glob": "^3.3.2",
"fs-extra": "^11.2.0",
"is-path-inside": "^3.0.3",
"nopt": "^7.1.0",
"properties-parser": "^0.3.1",
"semver": "^7.3.8",
"nopt": "^7.2.1",
"properties-parser": "^0.6.0",
"semver": "^7.6.2",
"string-argv": "^0.3.1",
"untildify": "^4.0.0",
"which": "^3.0.0"
"which": "^4.0.0"
},
"devDependencies": {
"@cordova/eslint-config": "^5.0.0",
"@cordova/eslint-config": "^5.1.0",
"cordova-js": "^6.1.0",
"elementtree": "^0.1.7",
"jasmine": "^4.6.0",
"jasmine": "^5.1.0",
"jasmine-spec-reporter": "^7.0.0",
"nyc": "^15.1.0",
"rewire": "^6.0.0"
"rewire": "^7.0.0"
},
"engines": {
"node": ">=16.13.0"

View File

@@ -3,7 +3,7 @@
package="com.example.anis.myapplication">
<application
android:allowBackup="true"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"

View File

@@ -1,3 +1,20 @@
# 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.
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists

View File

@@ -20,6 +20,7 @@
const fs = require('fs-extra');
const path = require('path');
const rewire = require('rewire');
const { isWindows } = require('../../../lib/utils');
describe('ProjectBuilder', () => {
const rootDir = '/root';
@@ -128,19 +129,24 @@ describe('ProjectBuilder', () => {
});
});
describe('runGradleWrapper', () => {
it('should run the provided gradle command if a gradle wrapper does not already exist', () => {
spyOn(fs, 'existsSync').and.returnValue(false);
builder.runGradleWrapper('/my/sweet/gradle');
expect(execaSpy).toHaveBeenCalledWith('/my/sweet/gradle', jasmine.any(Array), jasmine.any(Object));
describe('installGradleWrapper', () => {
beforeEach(() => {
execaSpy.and.resolveTo();
});
it('should do nothing if a gradle wrapper exists in the project directory', () => {
spyOn(fs, 'existsSync').and.returnValue(true);
builder.runGradleWrapper('/my/sweet/gradle');
expect(execaSpy).not.toHaveBeenCalledWith('/my/sweet/gradle', jasmine.any(Array), jasmine.any(Object));
it('should run gradle wrapper 8.7', async () => {
await builder.installGradleWrapper('8.7');
expect(execaSpy).toHaveBeenCalledWith('gradle', ['-p', path.normalize('/root/tools'), 'wrapper', '--gradle-version', '8.7'], jasmine.any(Object));
});
it('CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL should override gradle version', async () => {
process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL = 'https://dist.local';
await builder.installGradleWrapper('8.7');
delete process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL;
expect(execaSpy).toHaveBeenCalledWith('gradle', ['-p', path.normalize('/root/tools'), 'wrapper', '--gradle-distribution-url', 'https://dist.local'], jasmine.any(Object));
});
});
describe('build', () => {
beforeEach(() => {
spyOn(builder, 'getArgs');
@@ -170,7 +176,12 @@ describe('ProjectBuilder', () => {
builder.build({});
expect(execaSpy).toHaveBeenCalledWith(path.join(rootDir, 'gradlew'), testArgs, jasmine.anything());
let gradle = path.join(rootDir, 'tools', 'gradlew');
if (isWindows()) {
gradle += '.bat';
}
expect(execaSpy).toHaveBeenCalledWith(gradle, testArgs, jasmine.anything());
});
it('should reject if the spawn fails', () => {
@@ -227,8 +238,13 @@ describe('ProjectBuilder', () => {
const gradleArgs = ['test', 'args', '-f'];
builder.getArgs.and.returnValue(gradleArgs);
let gradle = path.join(rootDir, 'tools', 'gradlew');
if (isWindows()) {
gradle += '.bat';
}
return builder.clean(opts).then(() => {
expect(execaSpy).toHaveBeenCalledWith(path.join(rootDir, 'gradlew'), gradleArgs, jasmine.anything());
expect(execaSpy).toHaveBeenCalledWith(gradle, gradleArgs, jasmine.anything());
});
});

View File

@@ -46,5 +46,14 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.cdv.core.file.provider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/cdv_core_file_provider_paths" />
</provider>
</application>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
</manifest>

View File

@@ -21,7 +21,11 @@ apply plugin: 'com.android.application'
if (cordovaConfig.IS_GRADLE_PLUGIN_KOTLIN_ENABLED) {
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
if(!cdvHelpers.isVersionGreaterThanEqual(cordovaConfig.KOTLIN_VERSION, '1.8.0')) {
println "Kotlin version < 1.8.0 detected. Applying kotlin-android-extensions plugin."
apply plugin: 'kotlin-android-extensions'
}
}
buildscript {
@@ -181,6 +185,10 @@ task cdvPrintProps {
android {
namespace cordovaConfig.PACKAGE_NAMESPACE
buildFeatures {
buildConfig true
}
defaultConfig {
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
applicationId cordovaConfig.PACKAGE_NAMESPACE
@@ -248,8 +256,39 @@ android {
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaLanguageVersion.of(cordovaConfig.JAVA_SOURCE_COMPATIBILITY)
targetCompatibility JavaLanguageVersion.of(cordovaConfig.JAVA_TARGET_COMPATIBILITY)
}
if (cordovaConfig.IS_GRADLE_PLUGIN_KOTLIN_ENABLED) {
if (cordovaConfig.KOTLIN_JVM_TARGET == null) {
// If the value is null, fallback to JAVA_TARGET_COMPATIBILITY,
// as they generally should be equal
def javaTarget = JavaLanguageVersion.of(cordovaConfig.JAVA_TARGET_COMPATIBILITY)
// check if javaTarget is <= 8; if so, we need to prefix it with "1."
// Starting with 9 and later, the value can be used as is.
if (javaTarget.compareTo(JavaLanguageVersion.of(8)) <= 0) {
javaTarget = "1." + javaTarget
}
cordovaConfig.KOTLIN_JVM_TARGET = javaTarget
}
// Similar to above, check if kotlin target is <= 8, if so prefix it.
// This allows the user to use consistent set of values in config.xml
// Rather than having to be aware whether the "1."" prefix is needed.
// This check is only done if the value isn't already prefixed with 1.
if (
!cordovaConfig.KOTLIN_JVM_TARGET.startsWith("1.") &&
JavaLanguageVersion.of(cordovaConfig.KOTLIN_JVM_TARGET).compareTo(JavaLanguageVersion.of(8)) <= 0
) {
cordovaConfig.KOTLIN_JVM_TARGET = "1." + cordovaConfig.KOTLIN_JVM_TARGET
}
kotlinOptions {
jvmTarget = cordovaConfig.KOTLIN_JVM_TARGET
}
}
if (cdvReleaseSigningPropertiesFile) {

View File

@@ -1,3 +1,21 @@
# 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.
# This file was originally created by the Android Tools, but is now
# used by cordova-android to manage the state of the various third party
# libraries used in your application

View File

@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />

View File

@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />

View File

@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />

View File

@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />

View File

@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />

View File

@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />

View File

@@ -1,4 +1,5 @@
/*
<?xml version="1.0" encoding="utf-8"?>
<!--
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
@@ -15,18 +16,15 @@
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
-->
<!--
Note: This File provider should only be used by the Cordova core
itself and should not be used for responding to Intents because
it will expose the app's private data folders.
const fs = require('fs-extra');
const path = require('path');
/**
* This script is to be run manually (e.g. by npm run clean:java-unit-tests) if
* you want to upgrade gradlew or test its proper generation.
*/
for (const variant of ['androidx']) {
for (const file of ['gradlew', 'gradlew.bat']) {
fs.removeSync(path.join(__dirname, variant, file));
}
}
For more information about FileProviders see:
https://developer.android.com/reference/androidx/core/content/FileProvider
-->
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache" path="." />
</paths>

View File

@@ -0,0 +1,29 @@
/*
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.
*/
// This is an empty project used to provide Gradle Tooling
// Using the main project which loads AGP will enforce a minimum version
// requirement on the end-user, requiring a gradle install that satisfies AGP
// version requirements.
// To avoid that, we utilise this empty project of which we can
// freely run the gradle wrapper task against to obtain the
// wrapper at the desired version, without being restricted by AGP's version
// requirements.
// Of course, the installed wrapper must still be of at least the minimum
// required version of AGP for the build to work correctly.

View File

@@ -1 +0,0 @@
//This file is intentionally just a comment

View File

@@ -69,30 +69,35 @@ public class BackButtonMultipageTest {
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
webInterface.sendJavascript("window.location = 'sample2.html';");
}
});
assertPageSample(SAMPLE2_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
webInterface.sendJavascript("window.location = 'sample3.html';");
}
});
assertPageSample(SAMPLE3_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertPageSample(SAMPLE2_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertFalse(webInterface.backHistory());
}
@@ -105,30 +110,35 @@ public class BackButtonMultipageTest {
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
webInterface.loadUrl(SAMPLE2_URL);
}
});
assertPageSample(SAMPLE2_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
webInterface.loadUrl(SAMPLE3_URL);
}
});
assertPageSample(SAMPLE3_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertPageSample(SAMPLE2_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertFalse(webInterface.backHistory());
}
@@ -141,12 +151,14 @@ public class BackButtonMultipageTest {
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
webInterface.loadUrl(SAMPLE2_URL);
}
});
assertPageSample(SAMPLE2_URL);
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
webInterface.loadUrl(SAMPLE3_URL);
}

View File

@@ -60,6 +60,7 @@ public class ErrorUrlTest {
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
assertEquals(ERROR_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(ERROR_URL, mActivity.getWebInterface().getUrl());
}

View File

@@ -79,6 +79,7 @@ public class MessageChannelMultipageTest {
//load a page - this resets the plugin manager and nulls cordovaWebViewImpl.appPlugin
//(previously this resets plugin manager but did not null cordovaWebViewImpl.appPlugin, leading to the issue)
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
cordovaWebView.loadUrl(START_URL);
}

View File

@@ -20,7 +20,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"

View File

@@ -93,6 +93,7 @@ public class EmbeddedWebViewActivity extends AppCompatActivity {
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
try

View File

@@ -1,3 +1,20 @@
# 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.
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:

View File

@@ -1,22 +0,0 @@
/* 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.
*/
wrapper {
apply from: '../../framework/cordova.gradle'
gradleVersion = cordovaConfig.GRADLE_VERSION
}

View File

@@ -28,7 +28,7 @@ class AndroidTestRunner {
constructor (testTitle, projectDir) {
this.testTitle = testTitle;
this.projectDir = projectDir;
this.gradleWrapper = path.join(this.projectDir, 'gradlew');
this.gradleWrapper = path.join(this.projectDir, 'tools/gradlew');
}
_gradlew (...args) {
@@ -42,8 +42,18 @@ class AndroidTestRunner {
);
}
_getGradleVersion () {
const config = JSON.parse(
fs.readFileSync(path.resolve(this.projectDir, '../../framework/cdv-gradle-config-defaults.json'), {
encoding: 'utf-8'
})
);
return config.GRADLE_VERSION;
}
_createProjectBuilder () {
return new ProjectBuilder(this.projectDir).runGradleWrapper('gradle');
return new ProjectBuilder(this.projectDir).installGradleWrapper(this._getGradleVersion());
}
run () {
@@ -52,15 +62,16 @@ class AndroidTestRunner {
.then(_ => {
// TODO we should probably not only copy these files, but instead create a new project from scratch
fs.copyFileSync(path.resolve(this.projectDir, '../../framework/cdv-gradle-config-defaults.json'), path.resolve(this.projectDir, 'cdv-gradle-config.json'));
fs.copySync(path.resolve(this.projectDir, '../../templates/project/tools'), path.resolve(this.projectDir, 'tools'));
fs.copyFileSync(
path.join(__dirname, '../templates/project/assets/www/cordova.js'),
path.join(this.projectDir, 'app/src/main/assets/www/cordova.js')
);
})
.then(_ => this._createProjectBuilder())
.then(_ => this._gradlew('--version'))
.then(_ => this._gradlew(['--version']))
.then(_ => console.log(`[${this.testTitle}] Gradle wrapper is ready. Running tests now.`))
.then(_ => this._gradlew('test'))
.then(_ => this._gradlew(['test']))
.then(_ => console.log(`[${this.testTitle}] Java unit tests completed successfully`));
}
}