Compare commits

...

73 Commits

Author SHA1 Message Date
Erisu
a9171c3db6 android-v10.0.1 Updated version and RELEASENOTES.md for release 10.0.1 2021-07-27 22:50:34 +09:00
エリス
90271301fb fix: maven-publish setup (#1295) 2021-07-27 21:03:14 +09:00
Norman Breau
c11fcc10e8 fix: gradle build tools config (#1293) 2021-07-26 13:26:42 -03:00
Norman Breau
5e50c1d611 fix: automatic latest build tools finding (#1294) 2021-07-26 13:17:25 -03:00
エリス
38ca895459 fix: add missing release notes (#1291)
* CB-14203 Update RELEASENOTES & version for 7.1.1
* Update RELEASENOTES & version for v7.1.2
* Update VERSION & RELEASENOTES for 7.1.3
* Update VERSION & RELEASENOTES for 7.1.4

Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
Co-authored-by: Darryl Pogue <darryl@dpogue.ca>
2021-07-24 21:44:17 +09:00
エリス
0ce66249da fix: Google Services Gradle Plugin version check failure (#1287) 2021-07-20 17:49:21 +09:00
エリス
291edcd24e chore: update readme requirements (#1286) 2021-07-20 17:49:13 +09:00
エリス
4f44036d0a chore: set version for patch release (#1285) 2021-07-20 17:49:04 +09:00
Erisu
6081cc7442 Set VERSION to 10.1.0-dev (via coho) 2021-07-17 16:24:18 +09:00
Erisu
7572fc4912 android-v10.0.0 Updated version and RELEASENOTES.md for release 10.0.0 2021-07-17 13:56:20 +09:00
エリス
9286496378 fix: add missing apache-license header to getASPath.bat (#1283) 2021-07-16 17:59:30 +09:00
エリス
9d3d8d0521 chore!: bump all dependencies (#1279)
* chore: bump jasmine@^3.8.0
* chore!: bump release dependencies

- android-versions@^1.7.0
- execa@^5.1.1
- fast-glob@^3.2.7
- fs-extra@^10.0.0

* chore: rebuilt package-lock.json
2021-07-15 21:02:32 +09:00
エリス
636136c88e chore!: drop node 10 support (#1278) 2021-07-15 12:32:56 +09:00
Niklas Merz
bedb4427f4 fix: add WebViewAssetloader to default allow list (#1275) 2021-07-14 22:29:15 +09:00
Raphael von der Grün
35f0d07521 build: build cordova.js during npm prepare (#1271) 2021-07-14 10:25:34 +02:00
エリス
b94409ffe0 Remove gradle.daemon from default forced settings (#1276)
Co-authored-by: Fernando Serboncini <fserb@fserb.com.br>
2021-07-14 17:22:11 +09:00
エリス
adc380cf9f cleanup!: remove deprecated settings & add todo comments (#1274)
* chore: add todo task for setSaveFormData
* cleanup!: remove deprecated setSavePassword
* cleanup!: remove deprecated setDatabasePath
* chore: add todo task for setGeolocationDatabasePath
2021-07-14 15:37:12 +09:00
エリス
7da531ced5 chore: remove old VERSION file (#1273) 2021-07-14 15:34:27 +09:00
Dominik Hendrix
3e870e3a04 fix: request focus after custom view hided (#1216)
Co-authored-by: Dominik Hendrix <hendrix@schaffrath-digital.de>
2021-07-14 11:42:19 +09:00
エリス
f15fec81cf cleanup: delete old ANT & Eclipse files (#1272) 2021-07-14 11:38:40 +09:00
Raphael von der Grün
53d60dd707 refactor(Api)!: use version from package.json (#1270) 2021-07-13 12:27:25 +02:00
hiepxanh
68a302e9d2 fix(build): support tilde expansion on windows (#563)
Co-authored-by: Raphael von der Grün <raphinesse@gmail.com>
2021-07-13 19:02:09 +09:00
Raphael von der Grün
16ff6e1b2f refactor!: do not copy JS lib to platform project (#1269) 2021-07-13 11:01:50 +02:00
エリス
f6d1deeff6 feat!: release build defaults to aab package type (#1268) 2021-07-13 16:34:38 +09:00
Raphael von der Grün
1f0ea173b0 refactor: do not infer project root from script location (#1265)
* fix(Api): do not infer project root from script location

* fix(builders): do not infer project root from script location

* fix(target): do not infer project root from script location

* test(e2e): cleanup and extend E2E tests

- Renames the file with the only existing E2E test
- Makes existing test use the API instance returned by
  `Api.createPlatform`
- Adds another test that ensures we can still require the API from
  `platformProjectPath/cordova/Api.js`

* fix(check_reqs): do not infer project root from script location
2021-07-13 08:51:20 +02:00
Raphael von der Grün
70a1eff705 refactor: use target SDK of built APK to determine best emulator (#1267)
* refactor(emulator): require emulatorId in emulator.run

* refactor: use effective targetSdk to find best emulator
2021-07-12 09:48:36 +02:00
Raphael von der Grün
fb36e03aeb refactor(run)!: cleanup run method (#1266)
* refactor(run)!: get rid of emit-and-throw & throw-literal antipatterns

* refactor(run)!: convert run method to async/await

* refactor(run): require build module in advance

* refactor(run): minor cleanup

* refactor(run): drop always-undefined option arch

`parseBuildOptions` only sets `arch` if something truthy is passed for
parameter `resolvedTarget` to which we pass `null`.

* refactor(run): destructure buildOptions
2021-07-11 15:47:07 +02:00
jcesarmobile
8a9cb8f6b7 feat: remove java 1.8 version check (#1241) 2021-07-07 13:19:09 +02:00
エリス
b31e024dbb fix: missing super.onRequestPermissionsResult error (MissingSuperCall) (#1264) 2021-07-07 19:57:33 +09:00
エリス
422ce4f6bf feat: bump appcompat@1.3.0 (#1262) 2021-07-07 11:17:05 +09:00
エリス
b8d32d7c60 feat: bump gradle@7.1.1 (#1257) 2021-07-07 11:11:24 +09:00
エリス
83b3998801 feat: bump android-gradle-plugin@4.2.2 (#1255) 2021-07-07 11:08:03 +09:00
エリス
180a1a39f0 feat: bump kotlin@1.5.20 (#1256)
* feat: bump kotlin@1.5.10
* fix: kotlin@1.5.20 (applied suggestion)

Co-authored-by: jcesarmobile <jcesarmobile@gmail.com>
2021-07-07 10:55:47 +09:00
エリス
a1ed525a0b feat: bump android.webkit@1.4.0 (#1258) 2021-07-07 10:55:17 +09:00
Raphael von der Grün
2037b62f99 test(check_reqs): do not hardcode DEFAULT_TARGET_API (#1263)
Should have been part of #1212
2021-07-06 18:12:00 +02:00
エリス
21f64806c0 feat: support webkit version override (#1254) 2021-07-06 23:39:12 +09:00
エリス
e8cbeaaa1b refactor: gradle cleanup (#1253)
* refactor: move androidx.webkit version to cdv-gradle-config-defaults
* chore: remove unnecessary cordova.gradle apply
* refactor: maven publish to use version info from package.json
* refactor: separate framwork publishing outside of app dev scope
2021-07-06 22:38:16 +09:00
Raphael von der Grün
facffb0809 refactor!: remove most platform binaries (#1100)
* Remove binaries cordova/lib/*

* Remove binary bin/android_sdk_version

* Remove binary bin/update script

* Remove binary bin/check_reqs

* Remove binary bin/create script

* Remove binary cordova/build

* Remove binary cordova/run

* Remove binary cordova/clean

* Remove binary cordova/log

* Remove unused module cordova/loggingHelper

* Update README

* Restore target-listing binaries used by CLI

Usage: cordova-lib/src/cordova/targets.js

* Restore binary bin/android_sdk_version for CLI compatibility

This is used in CLI to implement an Android SDK version check for plugins.
See https://cordova.apache.org/docs/en/latest/plugin_ref/spec.html#engines-and-engine

* Remove version.bat
2021-07-06 15:37:46 +02:00
Raphael von der Grün
6f35d0b2b7 refactor(check_reqs): drop originalError param from check_android_target (#1260) 2021-07-06 13:33:26 +02:00
Raphael von der Grün
334d02d26e tests(prepare): factor out common vars (#1259) 2021-07-06 13:01:37 +02:00
エリス
69b24dbf6a feat!: drop abandoned com.github.dcendents:android-maven-gradle-plugin (#1252)
* feat: use maven-publish plugin (mavenCentral)
* fix: Apache License url
* fix: framework build failure without useAndroidX
* fix: add aar build artifact
2021-07-06 15:57:40 +09:00
Norman Breau
510596f515 feat!: unify & fix gradle library/tooling overrides (#1212)
* enhancement: Control SDK versions and other default projects in one place
* fix: target/compile sdk usage
* refactor: cleanup gradle process
* chore: cleanup and remove unused changes
* chore: remove more unneeded FILE_PATH
* chore: fix lint error
* revert change intended to be part of a different PR
* chore: apply changes to revert to fit new changes
* fix: Ensure proper types
* breaking: Removed TempateFile class
  * Replaced the one and only usage of it with the properties-parser editor.
  * Breaking change because we are converting a method into an asynchronous method.
* refactor: Use the sync version of properties editor
* Gh 1178 fix sdk use gradlearg fix (#2)
* fix: readd gradleArg support
* fix: variable name
* refactor: remove unused mock variables
* Update bin/templates/cordova/lib/builders/ProjectBuilder.js
* Update bin/lib/create.js
* fix: const naming (review suggestion)
* fix: use defaults for framework building
* chore: apply review suggestion
* chore: rename config.json & defaults.json (review suggestions)
* refactor: updateUserProjectGradleConfig method
* refactor: minor changes in updateUserProjectGradleConfig
* refactor: major changes in updateUserProjectGradleConfig
* fix: wrong handling of missing preferences
* fix: usage of undefined this
* fix(create.spec): mocking of getPreference
* test(check_reqs): reduce diff size
* refactor: add wrapper to load gradle config defaults
* fix(check_reqs): get_target
  * Reads default SDK from default gradle config now
* fix(check_reqs.spec): return correct types from mocks
* revert to using get_target in create
* fix: e2e test

Co-authored-by: Erisu <ellis.bryan@gmail.com>
Co-authored-by: Raphael von der Grün <raphinesse@gmail.com>
2021-07-06 15:38:28 +09:00
エリス
47aa116b1d breaking: drop jcenter & update dependencies (#1251) 2021-07-03 13:04:13 +09:00
エリス
015db819ae feat(allow-list)!: integrate and refactor core plugin (#1138)
* refactor!: naming to allow list
* feat(allow-list): integrate core plugin
* refactor(allow-list): cleanup
* refactor: drop deprecated launch-external case for CustomConfigParser::handleStartTag
* fix: apply review comments
2021-07-02 11:52:05 +09:00
jcesarmobile
01569ce71a feat!: upgrade android gradle plugin to 4.2.1 (#1232) 2021-07-01 16:50:39 +09:00
Raphael von der Grün
0f13f4a5ac refactor(env/java): improve tests and implementation (#1246)
This basically fixes up the changes from #1220.

* test(env/java): replace test that duplicates implementation
* test(env/java): stub _ensure to focus on unit under test
* test(env/java): add test for invalid output
* refactor(env/java): keep try block small
* refactor(env/java): shorten excessive comment
2021-06-23 18:22:04 +02:00
Norman Breau
6d803e2f72 Bugfix/java checks (#1228)
* fix: Java version parsing if java executable prints out additional information with --version

* fix: Ensure JAVA_HOME path comes first in the PATH environment

* refactor: Removed redundent code in favour of keeping a change introduced from another PR
2021-05-09 17:52:35 -03:00
Norman Breau
ae4dba2bb8 feat: CORDOVA_JAVA_HOME env variable (#1229)
* feat: CORDOVA_JAVA_HOME env variable

* refactor: Improve CORDOVA_JAVA_HOME env test

* fix(test) path separator issue
2021-05-09 17:02:25 -03:00
David
a45804329b fix(requirements check): use regex to get java version from javac output (#1220)
* fix(requirements check): use regex to get java version from javac output

* fix(lint): format code

* fix(node 10): remove optional chaining from version check
2021-05-09 09:33:08 -03:00
Raphael von der Grün
1b7874607e fix(prepare): delete splash screens if none are used (#1227)
Currently, we copy default splash screens to the platform folder during platform creation, but then we do not delete them when the user uses no splash screens at all. This causes #1226 and what is described in #689.

The new implementation does not return early when updating splashes and none are defined. Instead, we let the cleanup map we create initially take care of deleting all unused splash screens. This also deletes the default splashes during the first prepare after platform creation.

Fixes #1226
2021-05-06 09:30:19 +02:00
Niklas Merz
ff1ae2125a feat: add backwards compatibility mode for WebViewAssetLoader (#1222) 2021-05-06 08:17:58 +02:00
Norman Breau
f9e8ce8fab ci: Add Node16 to CI matrix (#1218) 2021-04-26 12:47:22 -03:00
Niklas Merz
5e7be8e1d6 breaking: implement WebViewAssetLoader (#1137)
Implement AndroidX WebViewAssetLoader with hook for plugins


Co-authored-by: エリス <erisu@users.noreply.github.com>
2021-04-22 14:32:14 +02:00
Jakub Blejder
b2d9d639b4 feat: overload PluginEntry constructor to set onload property (#1166)
Co-authored-by: Erisu <ellis.bryan@gmail.com>
2021-04-19 07:51:18 +09:00
エリス
8d407708d4 feat: allow appcompat version to be configurable (#1208) 2021-04-19 07:30:06 +09:00
エリス
19bbf1e8c1 test(AndroidManifest): update theme to Theme.AppCompat.NoActionBar (#1207) 2021-04-16 18:32:46 +09:00
Hans Krywalsky
2a84d7c44d breaking: only support androidx (#1052)
* GH-841 only support androix
2021-04-16 06:52:14 +09:00
エリス
eeb645c886 chore! (npm): update all dependencies (#1205) 2021-04-15 08:23:41 +09:00
Mosab A
676f98d82d feat!: upgrade kotlin@1.4.32 (#1204) 2021-04-14 11:29:09 +09:00
Raphael von der Grün
9c3195c1ee refactor!: drop support for android SDK tool (#1083)
* refactor(emulator)!: remove support for legacy `android` binary
`emulator.list_images` now always uses the `avdmanager` binary.
* refactor(android_sdk)!: remove support for legacy `android` binary
`android_sdk.list_targets` now always uses the `avdmanager` binary.
* refactor(check_reqs)!: do not look for legacy `android` binary
* refactor: replace installation instructions involving `android` binary
2021-04-13 19:16:43 +09:00
Niklas Merz
2a92c77772 remove app cache settings (#1141) 2021-04-13 19:14:37 +09:00
Norman Breau
eefa91b3ea breaking: remove keystore password prompt (#1048) 2021-04-13 19:13:01 +09:00
Norman Breau
6b33772613 feat: Deprecated onRequestPermissionResult in favour for onRequestPermissionsResult for consistency (#1047) 2021-04-13 18:56:04 +09:00
エリス
cab9840a03 feat!: upgrade jfrog gradle-bintray-plugin@1.8.5 (#1201)
* breaking: upgrade jfrog gradle-bintray-plugin@1.8.5
* original contribution PR: #1079

Co-authored-by: Mosab A <47486787+mosabab@users.noreply.github.com>
2021-04-13 18:10:07 +09:00
エリス
63b2356575 feat!: upgrade kotlin@1.4.31 (#1200)
* feat: upgrade kotlin@1.4.31 (#1176)

Co-authored-by: Mosab A <47486787+mosabab@users.noreply.github.com>
2021-04-13 17:50:05 +09:00
エリス
a9ee9196bd feat!: upgrade Google Services Gradle Plugin@4.3.5 (#1199)
* feat: upgrade Google Services Gradle Plugin google-services@4.3.5 (#1177)

Co-authored-by: Mosab A <47486787+mosabab@users.noreply.github.com>
2021-04-13 17:20:54 +09:00
エリス
6588994586 feat!: upgrade android gradle plugin@4.1.3 (#1198)
* feat: upgrade gradle-plugin@4.1.3 (#1175)

Co-authored-by: Mosab A <47486787+mosabab@users.noreply.github.com>
2021-04-13 16:43:30 +09:00
エリス
46d4d924cc feat!: upgrade gradle@6.8.3 (#1197)
* [Frequent Updates] Gradle 6.6.1 & Android Gradle Plugin 4.0.1 & com.jfrog.bintray.gradle 1.8.5 (#1079)
* Update ProjectBuilder.js
* Update build.gradle
* Update wrapper.gradle
* chore: remove non-gradle wrapper changes
* feat: upgrade gradle@6.8.3 (#1174)

Co-authored-by: Mosab A <47486787+mosabab@users.noreply.github.com>
2021-04-13 15:35:34 +09:00
エリス
dc8854d16c feat: target sdk 30 w/ build-tool 30.0.3 (#1182) 2021-04-13 15:34:21 +09:00
エリス
a33044921d feat: bump version to 10.0.0-dev (#1181) 2021-04-13 15:34:00 +09:00
Erisu
9c165cb94f chore: set package-lock.json to 9.2.0-dev 2021-04-10 01:55:22 +09:00
Erisu
e0d5d14895 Update JS snapshot to version 9.2.0-dev (via coho) 2021-04-10 00:26:30 +09:00
Erisu
35bc354531 Set VERSION to 9.2.0-dev (via coho) 2021-04-10 00:26:26 +09:00
231 changed files with 1933 additions and 11605 deletions

View File

@@ -1,3 +1,3 @@
bin/templates/project/assets/www/cordova.js
templates/project/assets/www/cordova.js
test/android/app
test/androidx/app

View File

@@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [12.x, 14.x, 16.x]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:

7
.gitignore vendored
View File

@@ -25,14 +25,15 @@ example
/framework/libs
/framework/javadoc-public
/framework/javadoc-private
**/assets/www/cordova.js
/test/.externalNativeBuild
/test/android/gradle
/test/android/gradlew
/test/android/gradlew.bat
/test/androidx/gradle
/test/androidx/gradlew
/test/androidx/gradlew.bat
/test/androidx/cdv-gradle-config.json
/test/assets/www/.tmp*
/test/assets/www/cordova.js

View File

@@ -3,3 +3,4 @@ coverage
test
spec
framework/build
cordova-js-src

View File

@@ -1,5 +1,5 @@
*.properties
bin
templates
gen
proguard-project.txt
spec

View File

@@ -30,28 +30,14 @@ Cordova Android is an Android application library that allows for Cordova-based
[Apache Cordova](https://cordova.apache.org) is a project of The Apache Software Foundation (ASF).
## Requires
## Requirements
- Java JDK 1.8
- Android SDK [http://developer.android.com](https://developer.android.com/)
- Java Development Kit (JDK) 11
- [Android SDK](https://developer.android.com/)
## Cordova Android Developer Tools
We recommend using the [Cordova command-line tool](https://www.npmjs.com/package/cordova) to create projects and be able to easily install plugins.
However, the following scripts can be used instead:
./bin/create [path package activity] ... creates the ./example app or a cordova android project
./bin/check_reqs ....................... checks that your environment is set up for cordova-android development
./bin/update [path] .................... updates an existing cordova-android project to the version of the framework
These commands live in a generated Cordova Android project. Any interactions with the emulator require you to have an AVD defined.
./cordova/clean ........................ cleans the project
./cordova/build ........................ calls `clean` then compiles the project
./cordova/log ........................ streams device or emulator logs to STDOUT
./cordova/run ........................ calls `build` then deploys to a connected Android device. If no Android device is detected, will launch an emulator and deploy to it.
./cordova/version ...................... returns the cordova-android version of the current project
Use the [Cordova command-line tool](https://www.npmjs.com/package/cordova) to create projects and install plugins.
## Using Android Studio

View File

@@ -20,6 +20,99 @@
-->
## Release Notes for Cordova (Android)
### 10.0.1 (Jul 27, 2021)
**Fixes:**
* [GH-1295](https://github.com/apache/cordova-android/pull/1295) fix: `maven-publish` setup
* [GH-1293](https://github.com/apache/cordova-android/pull/1293) fix: `gradle` build tools config
* [GH-1294](https://github.com/apache/cordova-android/pull/1294) fix: automatic latest build tools finding
* [GH-1287](https://github.com/apache/cordova-android/pull/1287) fix: Google Services Gradle Plugin version check failure
**Chores:**
* [GH-1291](https://github.com/apache/cordova-android/pull/1291) chore: add missing release notes
* [GH-1286](https://github.com/apache/cordova-android/pull/1286) chore: update `README` requirements
### 10.0.0 (Jul 17, 2021)
**Breaking:**
* [GH-1052](https://github.com/apache/cordova-android/pull/1052) feat!: only support `AndroidX`
* [GH-1137](https://github.com/apache/cordova-android/pull/1137) feat!: implement `WebViewAssetLoader`
* [GH-1268](https://github.com/apache/cordova-android/pull/1268) feat!: release build defaults to `aab` package type
* [GH-1182](https://github.com/apache/cordova-android/pull/1182) feat!: bump `target sdk@30` w/ `build-tool@30.0.3`
* [GH-1257](https://github.com/apache/cordova-android/pull/1257) feat!: upgrade `gradle@7.1.1`
* [GH-1197](https://github.com/apache/cordova-android/pull/1197) feat!: upgrade `gradle@6.8.3`
* [GH-1256](https://github.com/apache/cordova-android/pull/1256) feat!: upgrade `kotlin@1.5.20`
* [GH-1204](https://github.com/apache/cordova-android/pull/1204) feat!: upgrade `kotlin@1.4.32`
* [GH-1200](https://github.com/apache/cordova-android/pull/1200) feat!: upgrade `kotlin@1.4.31`
* [GH-1255](https://github.com/apache/cordova-android/pull/1255) feat!: upgrade `android-gradle-plugin@4.2.2`
* [GH-1232](https://github.com/apache/cordova-android/pull/1232) feat!: upgrade `android-gradle-plugin@4.2.1`
* [GH-1198](https://github.com/apache/cordova-android/pull/1198) feat!: upgrade `android-gradle-plugin@4.1.3`
* [GH-1199](https://github.com/apache/cordova-android/pull/1199) feat!: upgrade `Google Services Gradle Plugin@4.3.5`
* [GH-1262](https://github.com/apache/cordova-android/pull/1262) feat!: bump `appcompat@1.3.0`
* [GH-1258](https://github.com/apache/cordova-android/pull/1258) feat!: bump `android.webkit@1.4.0`
* [GH-1252](https://github.com/apache/cordova-android/pull/1252) feat!: drop abandoned `com.github.dcendents:android-maven-gradle-plugin`
* [GH-1212](https://github.com/apache/cordova-android/pull/1212) feat!: unify & fix gradle library/tooling overrides
* [GH-1138](https://github.com/apache/cordova-android/pull/1138) feat(allow-list)!: integrate and refactor core plugin
* [GH-1201](https://github.com/apache/cordova-android/pull/1201) feat!: upgrade jfrog `gradle-bintray-plugin@1.8.5`
* [GH-1279](https://github.com/apache/cordova-android/pull/1279) chore!: bump all dependencies
* [GH-1278](https://github.com/apache/cordova-android/pull/1278) chore!: drop `node` 10 support
* [GH-1205](https://github.com/apache/cordova-android/pull/1205) chore! (`npm`): update all dependencies
* [GH-1274](https://github.com/apache/cordova-android/pull/1274) cleanup!: remove deprecated settings & add todo comments
* [GH-1048](https://github.com/apache/cordova-android/pull/1048) cleanup!: remove `keystore` password prompt
* [GH-1251](https://github.com/apache/cordova-android/pull/1251) cleanup!: drop `jcenter` & update dependencies
* [GH-1269](https://github.com/apache/cordova-android/pull/1269) refactor!: do not copy JS lib to platform project
* [GH-1270](https://github.com/apache/cordova-android/pull/1270) refactor(Api)!: use version from `package.json`
* [GH-1266](https://github.com/apache/cordova-android/pull/1266) refactor(run)!: `run` method
* [GH-1083](https://github.com/apache/cordova-android/pull/1083) refactor!: drop support for `android` SDK tool
* [GH-1100](https://github.com/apache/cordova-android/pull/1100) refactor!: remove most platform binaries
**Features:**
* [GH-1241](https://github.com/apache/cordova-android/pull/1241) feat: remove `java` 1.8 version check
* [GH-1254](https://github.com/apache/cordova-android/pull/1254) feat: support `webkit` version override
* [GH-1229](https://github.com/apache/cordova-android/pull/1229) feat: `CORDOVA_JAVA_HOME` env variable
* [GH-1222](https://github.com/apache/cordova-android/pull/1222) feat: add backwards compatibility mode for `WebViewAssetLoader`
* [GH-1166](https://github.com/apache/cordova-android/pull/1166) feat: overload `PluginEntry` constructor to set onload property
* [GH-1208](https://github.com/apache/cordova-android/pull/1208) feat: allow `appcompat` version to be configurable
* [GH-1047](https://github.com/apache/cordova-android/pull/1047) feat: Deprecated `onRequestPermissionResult` in favour for `onRequestPermissionsResult` for consistency
**Fixes:**
* [GH-1283](https://github.com/apache/cordova-android/pull/1283) fix: add missing apache-license header to `getASPath.bat`
* [GH-1275](https://github.com/apache/cordova-android/pull/1275) fix: add `WebViewAssetloader` to default allow list
* [GH-1216](https://github.com/apache/cordova-android/pull/1216) fix: request focus after custom view hided
* [GH-1264](https://github.com/apache/cordova-android/pull/1264) fix: missing `super.onRequestPermissionsResult` error (`MissingSuperCall`)
* [GH-563](https://github.com/apache/cordova-android/pull/563) fix(build): support tilde expansion on Windows
* [GH-1220](https://github.com/apache/cordova-android/pull/1220) fix(`requirements` check): use regex to get java version from javac output
* [GH-1227](https://github.com/apache/cordova-android/pull/1227) fix(prepare): delete splash screens if none are used
* [GH-1228](https://github.com/apache/cordova-android/pull/1228) fix: java checks
* [GH-1276](https://github.com/apache/cordova-android/pull/1276) fix: remove forced default `gradle.daemon` setting
**Refactors:**
* [GH-1265](https://github.com/apache/cordova-android/pull/1265) refactor: do not infer project root from script location
* [GH-1267](https://github.com/apache/cordova-android/pull/1267) refactor: use target SDK of built APK to determine best emulator
* [GH-1253](https://github.com/apache/cordova-android/pull/1253) refactor: `gradle` cleanup
* [GH-1260](https://github.com/apache/cordova-android/pull/1260) refactor(`check_reqs`): drop `originalError` param from `check_android_target`
* [GH-1246](https://github.com/apache/cordova-android/pull/1246) refactor(`env/java`): improve tests and implementation
**Chores & Cleanup:**
* [GH-1273](https://github.com/apache/cordova-android/pull/1273) chore: remove old `VERSION` file
* [GH-1272](https://github.com/apache/cordova-android/pull/1272) cleanup: delete old ANT & Eclipse files
* [GH-1141](https://github.com/apache/cordova-android/pull/1141) cleanup: remove app cache settings
**CI, Build & Testing:**
* [GH-1218](https://github.com/apache/cordova-android/pull/1218) ci: Add `Node16` to CI matrix
* [GH-1271](https://github.com/apache/cordova-android/pull/1271) build: build `cordova.js` during npm prepare
* [GH-1207](https://github.com/apache/cordova-android/pull/1207) test(`AndroidManifest`): update theme to `Theme.AppCompat.NoActionBar`
* [GH-1263](https://github.com/apache/cordova-android/pull/1263) test(`check_reqs`): do not hardcode `DEFAULT_TARGET_API`
* [GH-1259](https://github.com/apache/cordova-android/pull/1259) test(`prepare`): factor out common vars
### 9.1.0 (Apr 09, 2021)
**Features:**
@@ -233,6 +326,38 @@
* [CB-13830](https://issues.apache.org/jira/browse/CB-13830) Add handlers for plugins that use non-Java source files, such as Camera
* [CB-13923](https://issues.apache.org/jira/browse/CB-13923) Fix -1 length for compressed files
### 7.1.4 (Nov 22, 2018)
* Update android-versions to `1.4.0`, with added support for Android Pie ([#573](https://github.com/apache/cordova-android/pull/573))
* Output current package name if package name can't be validated ([#567](https://github.com/apache/cordova-android/pull/567))
* Resolve issue with plugin `target-dir="*app*"` subdirs ([#572](https://github.com/apache/cordova-android/pull/572))
### 7.1.3 (Nov 19, 2018)
* [GH-495](https://github.com/apache/cordova-android/pull/495) Incorrect default sdk version issue fix
* [GH-496](https://github.com/apache/cordova-android/pull/496) update comments in `build.gradle`
* [GH-539](https://github.com/apache/cordova-android/pull/539) Fix dest overwrite, in case of of plugin `source-file` element with `target-dir` that does not need remapping
* [GH-540](https://github.com/apache/cordova-android/issues/540) support plugin `source-file` element with any app `target-dir` value
* [GH-547](https://github.com/apache/cordova-android/issues/547) Compatibility of old plugins with non-Java `source-file` entries (individual files)
* [GH-551](https://github.com/apache/cordova-android/pull/551) add missing cast for cdvMinSdkVersion to `build.gradle`
* [GH-552](https://github.com/apache/cordova-android/issues/552) check for `build-extras.gradle` in the parent app directory
### 7.1.2 (Nov 08, 2018)
* [CB-14127](https://issues.apache.org/jira/browse/CB-14127): Always put the Google repo above jcenter
* [CB-14165](https://issues.apache.org/jira/browse/CB-14165): Emulator: handle "device still connecting" error (#457)
* [CB-14125](https://issues.apache.org/jira/browse/CB-14125): Increase old plugin compatibility
* [CB-13830](https://issues.apache.org/jira/browse/CB-13830): Add handlers for plugins that use non-Java source files, such as Camera
* [CB-14038](https://issues.apache.org/jira/browse/CB-14038): fix false positive detecting project type
### 7.1.1 (Jul 11, 2018)
* Fix unsafe property access in run.js (#445)
* Emit log event instead of logging directly (#452)
* [CB-14101](https://issues.apache.org/jira/browse/CB-14101) Fix Java version check for Java >= 9 (#446)
* [CB-14127](https://issues.apache.org/jira/browse/CB-14127) (android) Move google maven repo ahead of jcenter
* [CB-13923](https://issues.apache.org/jira/browse/CB-13923) (android) fix -1 length for compressed files
* [CB-14145](https://issues.apache.org/jira/browse/CB-14145) use cordova-common@2.2.5 and update other dependencies to resolve `npm audit` warnings
* [CB-9366](https://issues.apache.org/jira/browse/CB-9366) log error.stack in cordova.js
### 7.1.0 (Feb 20, 2018)
* [CB-13879](https://issues.apache.org/jira/browse/CB-13879) updated gradle tools dependency to 3.0.1 for project template
* [CB-13831](https://issues.apache.org/jira/browse/CB-13831) Update `android-versions` to 1.3.0 to support SDK 27.

View File

@@ -1 +0,0 @@
9.1.0-dev

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0android_sdk_version"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'android_sdk_version' script in 'bin' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0check_reqs"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,61 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var path = require('path');
var ConfigParser = require('cordova-common').ConfigParser;
var Api = require('./templates/cordova/Api');
var argv = require('nopt')({
help: Boolean,
cli: Boolean,
shared: Boolean,
link: Boolean,
'activity-name': [String, undefined]
}, { d: '--verbose' });
if (argv.help || argv.argv.remain.length === 0) {
console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' <path_to_new_project> <package_name> <project_name> [<template_path>] [--activity-name <activity_name>] [--link]');
console.log(' <path_to_new_project>: Path to your new Cordova Android project');
console.log(' <package_name>: Package name, following reverse-domain style convention');
console.log(' <project_name>: Project name');
console.log(' <template_path>: Path to a custom application template to use');
console.log(' --activity-name <activity_name>: Activity name');
console.log(' --link will use the CordovaLib project directly instead of making a copy.');
process.exit(1);
}
var config = new ConfigParser(path.resolve(__dirname, 'templates/project/res/xml/config.xml'));
if (argv.argv.remain[1]) config.setPackageName(argv.argv.remain[1]);
if (argv.argv.remain[2]) config.setName(argv.argv.remain[2]);
if (argv['activity-name']) config.setName(argv['activity-name']);
var options = {
link: argv.link || argv.shared,
customTemplate: argv.argv.remain[3],
activityName: argv['activity-name']
};
require('./templates/cordova/loggingHelper').adjustLoggerLevel(argv);
Api.createPlatform(argv.argv.remain[0], config, options).catch(err => {
console.error(err);
process.exitCode = 1;
});

View File

@@ -1,51 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var args = process.argv;
var Api = require('./Api');
var nopt = require('nopt');
var path = require('path');
// Support basic help commands
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[2]) >= 0) {
require('./lib/build').help();
}
// Do some basic argument parsing
var buildOpts = nopt({
verbose: Boolean,
silent: Boolean,
debug: Boolean,
release: Boolean,
nobuild: Boolean,
buildConfig: path
}, { d: '--verbose' });
// Make buildOptions compatible with PlatformApi build method spec
buildOpts.argv = buildOpts.argv.original;
require('./loggingHelper').adjustLoggerLevel(buildOpts);
new Api().build(buildOpts)
.catch(function (err) {
console.error(err.stack);
process.exit(2);
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0build"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'build' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,51 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var Api = require('./Api');
var path = require('path');
var nopt = require('nopt');
// Support basic help commands
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]));
console.log('Cleans the project directory.');
process.exit(0);
}
// Do some basic argument parsing
var opts = nopt({
verbose: Boolean,
silent: Boolean
}, { d: '--verbose' });
// Make buildOptions compatible with PlatformApi clean method spec
opts.argv = opts.argv.original;
// Skip cleaning prepared files when not invoking via cordova CLI.
opts.noPrepare = true;
require('./loggingHelper').adjustLoggerLevel(opts);
new Api().clean(opts)
.catch(function (err) {
console.error(err.stack);
process.exit(2);
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0clean"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'clean' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,3 +0,0 @@
@ECHO OFF
for /f "tokens=2*" %%a in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio" /v Path') do set "ASPath=%%~b"
ECHO %ASPath%

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
const { resolve, install } = require('./target');
var args = process.argv;
const targetSpec = { type: 'device' };
if (args.length > 2) {
if (args[2].substring(0, 9) === '--target=') {
targetSpec.id = args[2].substring(9, args[2].length);
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
resolve(targetSpec).then(install).catch(err => {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0install-device"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
const { resolve, install } = require('./target');
var args = process.argv;
const targetSpec = { type: 'emulator' };
if (args.length > 2) {
if (args[2].substring(0, 9) === '--target=') {
targetSpec.id = args[2].substring(9, args[2].length);
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
resolve(targetSpec).then(install).catch(err => {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0install-emulator"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0list-devices"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0list-emulator-images"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-emulator-images' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var emulators = require('./emulator');
// Usage support for when args are given
require('./check_reqs').check_android().then(function () {
emulators.list_started().then(function (emulator_list) {
emulator_list && emulator_list.forEach(function (emu) {
console.log(emu);
});
}, function (err) {
console.error('ERROR: ' + err);
process.exit(2);
});
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0list-started-emulators"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,45 +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.
*/
var path = require('path');
var os = require('os');
var execa = require('execa');
var ROOT = path.join(__dirname, '..', '..');
/*
* Starts running logcat in the shell.
* Returns a promise.
*/
module.exports.run = function () {
var adb = execa('adb', ['logcat'], { cwd: os.tmpdir(), stderr: 'inherit' });
adb.stdout.on('data', function (data) {
var lines = data ? data.toString().split('\n') : [];
var out = lines.filter(function (x) { return x.indexOf('nativeGetEnabledTags') < 0; });
console.log(out.join('\n'));
});
return adb;
};
module.exports.help = function () {
console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'log')));
console.log('Gives the logcat output on the command line.');
process.exit(0);
};

View File

@@ -1,99 +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.
*/
var path = require('path');
var emulator = require('./emulator');
const target = require('./target');
var PackageType = require('./PackageType');
const { events } = require('cordova-common');
/**
* Builds a target spec from a runOptions object
*
* @param {{target?: string, device?: boolean, emulator?: boolean}} runOptions
* @return {target.TargetSpec}
*/
function buildTargetSpec (runOptions) {
const spec = {};
if (runOptions.target) {
spec.id = runOptions.target;
} else if (runOptions.device) {
spec.type = 'device';
} else if (runOptions.emulator) {
spec.type = 'emulator';
}
return spec;
}
function formatResolvedTarget ({ id, type }) {
return `${type} ${id}`;
}
/**
* Runs the application on a device if available. If no device is found, it will
* use a started emulator. If no started emulators are found it will attempt
* to start an avd. If no avds are found it will error out.
*
* @param {Object} runOptions various run/build options. See Api.js build/run
* methods for reference.
*
* @return {Promise}
*/
module.exports.run = function (runOptions) {
runOptions = runOptions || {};
var self = this;
const spec = buildTargetSpec(runOptions);
return target.resolve(spec).then(function (resolvedTarget) {
events.emit('log', `Deploying to ${formatResolvedTarget(resolvedTarget)}`);
return new Promise((resolve) => {
const buildOptions = require('./build').parseBuildOptions(runOptions, null, self.root);
// Android app bundles cannot be deployed directly to the device
if (buildOptions.packageType === PackageType.BUNDLE) {
const packageTypeErrorMessage = 'Package type "bundle" is not supported during cordova run.';
events.emit('error', packageTypeErrorMessage);
throw packageTypeErrorMessage;
}
resolve(self._builder.fetchBuildResults(buildOptions.buildType, buildOptions.arch));
}).then(async function (buildResults) {
if (resolvedTarget.type === 'emulator') {
await emulator.wait_for_boot(resolvedTarget.id);
}
return target.install(resolvedTarget, buildResults);
});
});
};
module.exports.help = function () {
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]) + ' [options]');
console.log('Build options :');
console.log(' --debug : Builds project in debug mode');
console.log(' --release : Builds project in release mode');
console.log(' --nobuild : Runs the currently built project without recompiling');
console.log('Deploy options :');
console.log(' --device : Will deploy the built project to a device');
console.log(' --emulator : Will deploy the built project to an emulator if one exists');
console.log(' --target=<target_id> : Installs to the target with the specified id.');
process.exit(0);
};

View File

@@ -1,38 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var emulator = require('./emulator');
var args = process.argv;
var install_target;
if (args.length > 2) {
if (args[2].substring(0, 9) === '--target=') {
install_target = args[2].substring(9, args[2].length);
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
emulator.start(install_target).catch(function (err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0start-emulator"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,36 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var log = require('./lib/log');
var reqs = require('./lib/check_reqs');
var args = process.argv;
// Usage support for when args are given
if (args.length > 2) {
log.help();
} else {
reqs.run().then(function () {
return log.run();
}, function (err) {
console.error('ERROR: ' + err);
process.exit(2);
});
}

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0log"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'log' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,18 +0,0 @@
var CordovaLogger = require('cordova-common').CordovaLogger;
module.exports = {
adjustLoggerLevel: function (opts) {
if (opts instanceof Array) {
opts.silent = opts.indexOf('--silent') !== -1;
opts.verbose = opts.indexOf('--verbose') !== -1;
}
if (opts.silent) {
CordovaLogger.get().setLevel('error');
}
if (opts.verbose) {
CordovaLogger.get().setLevel('verbose');
}
}
};

View File

@@ -1,54 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var Api = require('./Api');
var nopt = require('nopt');
var path = require('path');
// Support basic help commands
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
require('./lib/run').help();
}
// Do some basic argument parsing
var runOpts = nopt({
verbose: Boolean,
silent: Boolean,
debug: Boolean,
release: Boolean,
nobuild: Boolean,
buildConfig: path,
archs: String,
device: Boolean,
emulator: Boolean,
target: String
}, { d: '--verbose' });
// Make runOptions compatible with PlatformApi run method spec
runOpts.argv = runOpts.argv.remain;
require('./loggingHelper').adjustLoggerLevel(runOpts);
new Api().run(runOpts)
.catch(function (err) {
console.error(err, err.stack);
process.exit(2);
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0run"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'run' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0version"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'version' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

File diff suppressed because it is too large Load Diff

View File

@@ -1,49 +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.
*/
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.50'
apply from: 'repositories.gradle'
repositories repos
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
apply from: 'repositories.gradle'
repositories repos
//This replaces project.properties w.r.t. build settings
project.ext {
defaultBuildToolsVersion="29.0.2" //String
defaultMinSdkVersion=22 //Integer - Minimum requirement is Android 5.1
defaultTargetSdkVersion=29 //Integer - We ALWAYS target the latest by default
defaultCompileSdkVersion=29 //Integer - We ALWAYS compile with the latest by default
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -1,40 +0,0 @@
#!/usr/bin/env node
/*
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.
*/
var path = require('path');
var Api = require('./templates/cordova/Api');
var args = require('nopt')({
link: Boolean,
shared: Boolean,
help: Boolean
}, { d: '--verbose' });
if (args.help || args.argv.remain.length === 0) {
console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'update')) + ' <path_to_project> [--link]');
console.log(' --link will use the CordovaLib project directly instead of making a copy.');
process.exit(1);
}
require('./templates/cordova/loggingHelper').adjustLoggerLevel(args);
Api.updatePlatform(args.argv.remain[0], { link: (args.link || args.shared) }).catch(err => {
console.error(err);
process.exitCode = 1;
});

View File

@@ -1,26 +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.
@ECHO OFF
SET script_path="%~dp0update"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'update' script in 'bin' folder, aborting...>&2
EXIT /B 1
)

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@@ -1,4 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.6

View File

@@ -1,34 +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.
#
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

View File

@@ -16,28 +16,15 @@
under the License.
*/
ext {
apply from: 'cordova.gradle'
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
if (project.hasProperty('cdvMinSdkVersion') && cdvMinSdkVersion.isInteger()) {
cdvMinSdkVersion = cdvMinSdkVersion as int
println '[Cordova] cdvMinSdkVersion is overridden, try it at your own risk.'
} else {
cdvMinSdkVersion = 22; // current Cordova's default
}
}
buildscript {
apply from: 'cordova.gradle'
apply from: 'repositories.gradle'
repositories repos
dependencies {
// The gradle plugin and the maven plugin have to be updated after each version of Android
// studio comes out
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
// Android Gradle Plugin (AGP) Build Tools
classpath "com.android.tools.build:gradle:${cordovaConfig.AGP_VERSION}"
}
}
@@ -47,15 +34,10 @@ allprojects {
}
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
group = 'org.apache.cordova'
version = '9.1.0-dev'
android {
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
compileSdkVersion cordovaConfig.SDK_VERSION
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -64,7 +46,7 @@ android {
// For the Android Cordova Lib, we allow changing the minSdkVersion, but it is at the users own risk
defaultConfig {
minSdkVersion cdvMinSdkVersion
minSdkVersion cordovaConfig.MIN_SDK_VERSION
}
sourceSets {
@@ -87,64 +69,17 @@ android {
}
}
install {
repositories.mavenInstaller {
pom {
project {
packaging 'aar'
name 'Cordova'
url 'https://cordova.apache.org'
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id 'stevengill'
name 'Steve Gill'
}
}
scm {
connection 'scm:git:https://github.com/apache/cordova-android.git'
developerConnection 'scm:git:git@github.com:apache/cordova-android.git'
url 'https://github.com/apache/cordova-android'
}
}
}
}
dependencies {
implementation "androidx.appcompat:appcompat:${cordovaConfig.ANDROIDX_APP_COMPAT_VERSION}"
implementation "androidx.webkit:webkit:${cordovaConfig.ANDROIDX_WEBKIT_VERSION}"
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
bintray {
user = System.getenv('BINTRAY_USER')
key = System.getenv('BINTRAY_KEY')
configurations = ['archives']
pkg {
repo = 'maven'
name = 'cordova-android'
userOrg = 'cordova'
licenses = ['Apache-2.0']
vcsUrl = 'https://github.com/apache/cordova-android'
websiteUrl = 'https://cordova.apache.org'
issueTrackerUrl = 'https://github.com/apache/cordova-android/issues'
publicDownloadNumbers = true
licenses = ['Apache-2.0']
labels = ['android', 'cordova', 'phonegap']
version {
name = '9.1.0-dev'
released = new Date()
vcsTag = '9.1.0-dev'
}
}
/**
* In a project created though CLI, the `cordova-publish.gradle` file is not copied to the `framework` dir.
* App development (CLI) projects can not and should not publish our framework.
* In this case, there is no need for the gradle build process to know about the publish process.
*/
def cordovaPublishGradle = './cordova-publish.gradle'
if(file(cordovaPublishGradle).exists()) {
apply from: cordovaPublishGradle
}

View File

@@ -1,192 +0,0 @@
<?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.
-->
<project name="Cordova" default="jar">
<!-- LOAD VERSION -->
<loadfile property="version" srcFile="../VERSION">
<filterchain>
<striplinebreaks/>
</filterchain>
</loadfile>
<!-- check that the version of ant is at least 1.8.0 -->
<antversion property="thisantversion" atleast="1.8.0" />
<fail message="The required minimum version of ant is 1.8.0, you have ${ant.version}"
unless="thisantversion" />
<!-- The local.properties file is created and updated by the 'android'
tool. (For example "sdkdir/tools/android update project -p ." inside
of this directory where the AndroidManifest.xml file exists. This
properties file that gets built contains the path to the SDK. It
should *NOT* be checked into Version Control Systems since it holds
data about the local machine. -->
<available file="local.properties" property="exists.local.properties" />
<fail message="You need to create the file 'local.properties' by running 'android update project -p .' here."
unless="exists.local.properties" />
<loadproperties srcFile="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'"
unless="sdk.dir"
/>
<!-- version-tag: custom -->
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
/* This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir} */
<target name="-post-compile">
</target>
-->
<target name="-pre-clean">
<!-- delete generated javadoc -->
<delete dir="javadoc-public" failonerror="false" />
<delete dir="javadoc-private" failonerror="false" />
<!-- delete generated jar -->
<delete file="cordova-${version}.jar" failonerror="false" />
</target>
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<import file="${sdk.dir}/tools/ant/build.xml" />
<!-- Build Cordova jar file that includes all native code, and Cordova JS file
that includes all JavaScript code.
-->
<target name="jar" depends="-compile">
<jar
basedir="bin/classes"
excludes="org/apache/cordova/R.class,org/apache/cordova/R$*.class"
jarfile="cordova-${version}.jar" />
</target>
<target name="javadoc">
<delete dir="javadoc-public" failonerror="false" />
<javadoc
access="public"
destdir="javadoc-public"
classpath="${sdk.dir}/platforms/${target}/android.jar">
<packageset dir="src">
<include name="org/apache/cordova/**" />
</packageset>
</javadoc>
<delete dir="javadoc-private" failonerror="false" />
<javadoc
access="private"
destdir="javadoc-private"
classpath="${sdk.dir}/platforms/${target}/android.jar">
<packageset dir="src">
<include name="org/apache/cordova/**" />
</packageset>
</javadoc>
</target>
<!-- tests for Java files -->
<property name="test.dir" location="test/org/apache/cordova" />
<path id="test.classpath">
<!-- requires both junit and cordova -->
<pathelement location="libs/junit-4.10.jar" />
<pathelement location="cordova-${version}.jar" />
<pathelement location="${test.dir}" />
</path>
<target name="compile-test">
<javac srcdir="${test.dir}" >
<classpath refid="test.classpath" />
</javac>
</target>
<target name="test" depends="jar, compile-test">
<junit showoutput="true">
<classpath refid="test.classpath" />
<formatter type="brief" usefile="false" />
<batchtest fork="yes">
<fileset dir="${test.dir}">
<include name="*Test.java" />
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
</target>
<target name="cordova_debug" depends="debug">
</target>
<target name="cordova_release" depends="release">
</target>
</project>

View File

@@ -0,0 +1,13 @@
{
"MIN_SDK_VERSION": 22,
"SDK_VERSION": 30,
"GRADLE_VERSION": "7.1.1",
"MIN_BUILD_TOOLS_VERSION": "30.0.3",
"AGP_VERSION": "4.2.2",
"KOTLIN_VERSION": "1.5.20",
"ANDROIDX_APP_COMPAT_VERSION": "1.3.0",
"ANDROIDX_WEBKIT_VERSION": "1.4.0",
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.5",
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false
}

View File

@@ -0,0 +1,125 @@
/*
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.
*/
apply plugin: 'maven-publish'
apply plugin: 'signing'
String getCordovaAndroidVersion() {
// Fetch Data from Cordova-Android package.json (Used only by framework build/publishing)
def cordovaAndroidRepoPackageJson = "$projectDir/../package.json"
if(file(cordovaAndroidRepoPackageJson).exists()) {
def packageJsonFile = new File(cordovaAndroidRepoPackageJson)
def packageJson = new groovy.json.JsonSlurper().parseText(packageJsonFile.text)
return packageJson.version
}
}
// Enable signing by default when keyId and secretKeyRingFile is defined.
ext.cdvEnableSigning = project.hasProperty('signing.keyId') && project.hasProperty('signing.secretKeyRingFile')
if (cdvEnableSigning) {
logger.debug('[Cordova] Signing has been enabled by default because the signing keyId & secretKeyRingFile has been defined.')
}
if (project.hasProperty('signEnabled')) {
if(!cdvEnableSigning && Boolean.valueOf(signEnabled)) {
logger.debug("[Cordova] The \"signEnabled\" override can not be set to \"true\" when the signing properties are missing.")
} else {
// Override the default setting with the "signEnabled" property. (In this case it should only accept false)
logger.debug("[Cordova] The \"signEnabled\" property has been detected and forcing enabled signing to \"$signEnabled\".")
cdvEnableSigning = signEnabled
}
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'org.apache.cordova'
artifactId = 'framework'
version = getCordovaAndroidVersion()
artifact(sourcesJar)
artifact("$buildDir/outputs/aar/framework-release.aar")
pom {
name = 'Cordova'
description = 'A library to build Cordova-based projects for the Android platform.'
url = 'https://cordova.apache.org'
licenses {
license {
name = 'Apache License, Version 2.0'
url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'stevengill'
name = 'Steve Gill'
}
developer {
id = 'erisu'
name = 'Bryan Ellis'
email = 'erisu@apache.org'
}
}
scm {
connection = 'scm:git:https://github.com/apache/cordova-android.git'
developerConnection = 'scm:git:git@github.com:apache/cordova-android.git'
url = 'https://github.com/apache/cordova-android'
}
}
}
}
repositories {
maven {
def releasesRepoUrl = 'https://repository.apache.org/content/repositories/releases'
def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots'
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
if (project.hasProperty('apacheUsername') && project.hasProperty('apachePassword')) {
username apacheUsername
password apachePassword
}
}
}
}
signing {
if (Boolean.valueOf(cdvEnableSigning)) {
sign publishing.publications.mavenJava
}
}
}
tasks.whenTaskAdded {task ->
if(task.name.contains('sign')) {
logger.debug("[Cordova] The task \"${task.name}\" is enabled? ${cdvEnableSigning}")
task.enabled = cdvEnableSigning
}
}

View File

@@ -18,8 +18,7 @@
*/
import java.util.regex.Pattern
import groovy.swing.SwingBuilder
import com.g00fy2.versioncompare.Version
import io.github.g00fy2.versioncompare.Version
String doEnsureValueExists(filePath, props, key) {
if (props.get(key) == null) {
@@ -54,10 +53,13 @@ String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
throw e
}
def minBuildToolsVersion = new Version(minBuildToolsVersionString)
def maxVersion = new Version((minBuildToolsVersion.getMajor() + 1) + ".0.0")
def highestBuildToolsVersion = buildToolsDirContents
.collect { new Version(it) }
// Invalid inputs will be handled as 0.0.0
.findAll { it.isHigherThan('0.0.0') }
.findAll { it.isHigherThan('0.0.0') && it.isLowerThan(maxVersion) }
.max()
if (highestBuildToolsVersion == null) {
@@ -69,7 +71,7 @@ String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
if (highestBuildToolsVersion.isLowerThan(minBuildToolsVersionString)) {
throw new RuntimeException("""
No usable Android build tools found. Highest installed version is
No usable Android build tools found. Highest ${minBuildToolsVersion.getMajor()}.x installed version is
${highestBuildToolsVersion.getOriginalString()}; minimum version
required is ${minBuildToolsVersionString}.
""".replaceAll(/\s+/, ' ').trim())
@@ -131,30 +133,6 @@ def doExtractStringFromManifest(name) {
return matcher.group(1)
}
def doPromptForPassword(msg) {
if (System.console() == null) {
def ret = null
new SwingBuilder().edt {
dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {
vbox {
label(text: msg)
def input = passwordField()
button(defaultButton: true, text: 'OK', actionPerformed: {
ret = input.password;
dispose();
})
}
}
}
if (!ret) {
throw new GradleException('User canceled build')
}
return new String(ret)
} else {
return System.console().readPassword('\n' + msg);
}
}
def doGetConfigXml() {
def xml = file("src/main/res/xml/config.xml").getText()
// Disable namespace awareness since Cordova doesn't use them properly
@@ -175,15 +153,72 @@ def doGetConfigPreference(name, defaultValue) {
return ret
}
def doApplyCordovaConfigCustomization() {
// Apply user overide properties that comes from the "--gradleArg=-P" parameters
if (project.hasProperty('cdvMinSdkVersion')) {
cordovaConfig.MIN_SDK_VERSION = Integer.parseInt('' + cdvMinSdkVersion)
}
if (project.hasProperty('cdvSdkVersion')) {
cordovaConfig.SDK_VERSION = Integer.parseInt('' + cdvSdkVersion)
}
if (project.hasProperty('cdvMaxSdkVersion')) {
cordovaConfig.MAX_SDK_VERSION = Integer.parseInt('' + cdvMaxSdkVersion)
}
if (project.hasProperty('cdvBuildToolsVersion')) {
cordovaConfig.BUILD_TOOLS_VERSION = cdvBuildToolsVersion
}
if (project.hasProperty('cdvAndroidXAppCompatVersion')) {
cordovaConfig.ANDROIDX_APP_COMPAT_VERSION = cdvAndroidXAppCompatVersion
}
if (project.hasProperty('cdvAndroidXWebKitVersion')) {
cordovaConfig.ANDROIDX_WEBKIT_VERSION = cdvAndroidXWebKitVersion
}
if (!cordovaConfig.BUILD_TOOLS_VERSION) {
cordovaConfig.BUILD_TOOLS_VERSION = doFindLatestInstalledBuildTools(
cordovaConfig.MIN_BUILD_TOOLS_VERSION
)
}
// Ensure the configured build tools version is at least our declared minimum
def buildToolsVersion = new Version(cordovaConfig.BUILD_TOOLS_VERSION)
if (buildToolsVersion.isLowerThan(cordovaConfig.MIN_BUILD_TOOLS_VERSION)) {
throw new RuntimeException("""
Expected Android Build Tools version >= ${cordovaConfig.MIN_BUILD_TOOLS_VERSION},
but got Android Build Tools version ${cordovaConfig.BUILD_TOOLS_VERSION}. Please use version ${cordovaConfig.MIN_BUILD_TOOLS_VERSION} or later.
""".replaceAll(/\s+/, ' ').trim())
}
}
// Properties exported here are visible to all plugins.
ext {
def defaultsFilePath = './cdv-gradle-config-defaults.json'
def projectConfigFilePath = "$rootDir/cdv-gradle-config.json"
def targetConfigFilePath = null
/**
* Check if the project config file path exists. This file will exist if coming from CLI project.
* If this file does not exist, falls back onto the default file.
* This scenario can occur if building the framework's AAR package for publishing.
*/
if(file(projectConfigFilePath).exists()) {
targetConfigFilePath = projectConfigFilePath
} else {
targetConfigFilePath = defaultsFilePath
}
def jsonFile = new File(targetConfigFilePath)
cordovaConfig = new groovy.json.JsonSlurper().parseText(jsonFile.text)
// Apply Gradle Properties
doApplyCordovaConfigCustomization()
// These helpers are shared, but are not guaranteed to be stable / unchanged.
privateHelpers = {}
privateHelpers.getProjectTarget = { doGetProjectTarget() }
privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') }
privateHelpers.applyCordovaConfigCustomization = { doApplyCordovaConfigCustomization() }
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) }
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
// These helpers can be used by plugins / projects and will not change.
@@ -196,10 +231,11 @@ ext {
buildscript {
repositories {
jcenter()
google()
mavenCentral()
}
dependencies {
classpath 'com.g00fy2:versioncompare:1.3.4@jar'
classpath 'io.github.g00fy2:versioncompare:1.4.1@jar'
}
}

View File

@@ -1,14 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-14
apk-configurations=

View File

@@ -10,6 +10,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
android.enableJetifier=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit

View File

@@ -3,4 +3,3 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

View File

@@ -1,3 +1,5 @@
# GENERATED FILE! DO NOT EDIT!
# This file was originally created by the Android Tools, but is now
# used by cordova-android to manage the project configuration.
@@ -5,7 +7,6 @@
split.density=false
# Project target.
target=android-29
apk-configurations=
renderscript.opt.level=O0
android.library=true

View File

@@ -18,5 +18,5 @@
ext.repos = {
google()
jcenter()
mavenCentral()
}

View File

@@ -28,7 +28,7 @@ import org.apache.cordova.LOG;
import android.net.Uri;
public class Whitelist {
public class AllowList {
private static class URLPattern {
public Pattern scheme;
public Pattern host;
@@ -92,12 +92,12 @@ public class Whitelist {
}
}
private ArrayList<URLPattern> whiteList;
private ArrayList<URLPattern> allowList;
public static final String TAG = "Whitelist";
public static final String TAG = "CordovaAllowList";
public Whitelist() {
this.whiteList = new ArrayList<URLPattern>();
public AllowList() {
this.allowList = new ArrayList<URLPattern>();
}
/* Match patterns (from http://developer.chrome.com/extensions/match_patterns.html)
@@ -111,13 +111,13 @@ public class Whitelist {
* the scheme to be omitted for backwards compatibility. (Also host is not required
* to begin with a "*" or "*.".)
*/
public void addWhiteListEntry(String origin, boolean subdomains) {
if (whiteList != null) {
public void addAllowListEntry(String origin, boolean subdomains) {
if (allowList != null) {
try {
// Unlimited access to network resources
if (origin.compareTo("*") == 0) {
LOG.d(TAG, "Unlimited access to network resources");
whiteList = null;
allowList = null;
}
else { // specific access
Pattern parts = Pattern.compile("^((\\*|[A-Za-z-]+):(//)?)?(\\*|((\\*\\.)?[^*/:]+))?(:(\\d+))?(/.*)?");
@@ -131,10 +131,10 @@ public class Whitelist {
String path = m.group(9);
if (scheme == null) {
// XXX making it stupid friendly for people who forget to include protocol/SSL
whiteList.add(new URLPattern("http", host, port, path));
whiteList.add(new URLPattern("https", host, port, path));
allowList.add(new URLPattern("http", host, port, path));
allowList.add(new URLPattern("https", host, port, path));
} else {
whiteList.add(new URLPattern(scheme, host, port, path));
allowList.add(new URLPattern(scheme, host, port, path));
}
}
}
@@ -149,15 +149,15 @@ public class Whitelist {
* Determine if URL is in approved list of URLs to load.
*
* @param uri
* @return true if wide open or whitelisted
* @return true if wide open or allow listed
*/
public boolean isUrlWhiteListed(String uri) {
// If there is no whitelist, then it's wide open
if (whiteList == null) return true;
public boolean isUrlAllowListed(String uri) {
// If there is no allowList, then it's wide open
if (allowList == null) return true;
Uri parsedUri = Uri.parse(uri);
// Look for match in white list
Iterator<URLPattern> pit = whiteList.iterator();
// Look for match in allow list
Iterator<URLPattern> pit = allowList.iterator();
while (pit.hasNext()) {
URLPattern p = pit.next();
if (p.matches(parsedUri)) {

View File

@@ -0,0 +1,165 @@
/*
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;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.ConfigXmlParser;
import org.apache.cordova.LOG;
import org.apache.cordova.AllowList;
import org.apache.cordova.CordovaPreferences;
import org.xmlpull.v1.XmlPullParser;
import android.content.Context;
public class AllowListPlugin extends CordovaPlugin {
public static final String PLUGIN_NAME = "CordovaAllowListPlugin";
protected static final String LOG_TAG = "CordovaAllowListPlugin";
private AllowList allowedNavigations;
private AllowList allowedIntents;
private AllowList allowedRequests;
// Used when instantiated via reflection by PluginManager
public AllowListPlugin() { }
// These can be used by embedders to allow Java-configuration of an allow list.
public AllowListPlugin(Context context) {
this(new AllowList(), new AllowList(), null);
new CustomConfigXmlParser().parse(context);
}
public AllowListPlugin(XmlPullParser xmlParser) {
this(new AllowList(), new AllowList(), null);
new CustomConfigXmlParser().parse(xmlParser);
}
public AllowListPlugin(AllowList allowedNavigations, AllowList allowedIntents, AllowList allowedRequests) {
if (allowedRequests == null) {
allowedRequests = new AllowList();
allowedRequests.addAllowListEntry("file:///*", false);
allowedRequests.addAllowListEntry("data:*", false);
}
this.allowedNavigations = allowedNavigations;
this.allowedIntents = allowedIntents;
this.allowedRequests = allowedRequests;
}
@Override
public void pluginInitialize() {
if (this.allowedNavigations == null) {
this.allowedNavigations = new AllowList();
this.allowedIntents = new AllowList();
this.allowedRequests = new AllowList();
new CustomConfigXmlParser().parse(webView.getContext());
}
}
private class CustomConfigXmlParser extends ConfigXmlParser {
private CordovaPreferences prefs = new CordovaPreferences();
@Override
public void handleStartTag(XmlPullParser xml) {
String strNode = xml.getName();
if (strNode.equals("content")) {
String startPage = xml.getAttributeValue(null, "src");
allowedNavigations.addAllowListEntry(startPage, false);
// Allow origin for WebViewAssetLoader
if (!this.prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
allowedNavigations.addAllowListEntry("https://" + this.prefs.getString("hostname", "localhost"), false);
}
} else if (strNode.equals("allow-navigation")) {
String origin = xml.getAttributeValue(null, "href");
if ("*".equals(origin)) {
allowedNavigations.addAllowListEntry("http://*/*", false);
allowedNavigations.addAllowListEntry("https://*/*", false);
allowedNavigations.addAllowListEntry("data:*", false);
} else {
allowedNavigations.addAllowListEntry(origin, false);
}
} else if (strNode.equals("allow-intent")) {
String origin = xml.getAttributeValue(null, "href");
allowedIntents.addAllowListEntry(origin, false);
} else if (strNode.equals("access")) {
String origin = xml.getAttributeValue(null, "origin");
if (origin != null) {
if ("*".equals(origin)) {
allowedRequests.addAllowListEntry("http://*/*", false);
allowedRequests.addAllowListEntry("https://*/*", false);
} else {
String subdomains = xml.getAttributeValue(null, "subdomains");
allowedRequests.addAllowListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
}
}
}
}
@Override
public void handleEndTag(XmlPullParser xml) { }
}
@Override
public Boolean shouldAllowNavigation(String url) {
return this.allowedNavigations.isUrlAllowListed(url)
? true
: null; // default policy
}
@Override
public Boolean shouldAllowRequest(String url) {
return (this.shouldAllowNavigation(url) || this.allowedRequests.isUrlAllowListed(url))
? true
: null; // default policy
}
@Override
public Boolean shouldOpenExternalUrl(String url) {
return (this.allowedIntents.isUrlAllowListed(url))
? true
: null; // default policy
}
public AllowList getAllowedNavigations() {
return this.allowedNavigations;
}
public void setAllowedNavigations(AllowList allowedNavigations) {
this.allowedNavigations = allowedNavigations;
}
public AllowList getAllowedIntents() {
return this.allowedIntents;
}
public void setAllowedIntents(AllowList allowedIntents) {
this.allowedIntents = allowedIntents;
}
public AllowList getAllowedRequests() {
return this.allowedRequests;
}
public void setAllowedRequests(AllowList allowedRequests) {
this.allowedRequests = allowedRequests;
}
}

View File

@@ -23,7 +23,7 @@ import java.util.List;
import android.app.Activity;
@Deprecated // Use Whitelist, CordovaPrefences, etc. directly.
@Deprecated // Use AllowList, CordovaPrefences, etc. directly.
public class Config {
private static final String TAG = "Config";

View File

@@ -33,7 +33,7 @@ import android.content.Context;
public class ConfigXmlParser {
private static String TAG = "ConfigXmlParser";
private String launchUrl = "file:///android_asset/www/index.html";
private String launchUrl = null;
private CordovaPreferences prefs = new CordovaPreferences();
private ArrayList<PluginEntry> pluginEntries = new ArrayList<PluginEntry>(20);
@@ -46,6 +46,14 @@ public class ConfigXmlParser {
}
public String getLaunchUrl() {
if (launchUrl == null) {
launchUrl = "https://" + this.prefs.getString("hostname", "localhost");
}
if (this.prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
launchUrl = "file:///android_asset/www/index.html";
}
return launchUrl;
}
@@ -60,6 +68,15 @@ public class ConfigXmlParser {
return;
}
}
pluginEntries.add(
new PluginEntry(
AllowListPlugin.PLUGIN_NAME,
"org.apache.cordova.AllowListPlugin",
true
)
);
parse(action.getResources().getXml(id));
}
@@ -139,7 +156,11 @@ public class ConfigXmlParser {
if (src.charAt(0) == '/') {
src = src.substring(1);
}
launchUrl = "file:///android_asset/www/" + src;
if (this.prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
launchUrl = "file:///android_asset/www/" + src;
} else {
launchUrl = "https://" + this.prefs.getString("hostname", "localhost") + "/" + src;
}
}
}
}

View File

@@ -24,7 +24,6 @@ import java.util.Locale;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
@@ -32,7 +31,6 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
@@ -43,6 +41,8 @@ import android.view.WindowManager;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import androidx.appcompat.app.AppCompatActivity;
/**
* This class is the main Android activity that represents the Cordova
* application. It should be extended by the user to load the specific
@@ -74,7 +74,7 @@ import android.widget.FrameLayout;
* deprecated in favor of the config.xml file.
*
*/
public class CordovaActivity extends Activity {
public class CordovaActivity extends AppCompatActivity {
public static String TAG = "CordovaActivity";
// The webview for our app
@@ -513,6 +513,8 @@ public class CordovaActivity extends Activity {
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
try
{
cordovaInterface.onRequestPermissionResult(requestCode, permissions, grantResults);

View File

@@ -18,11 +18,10 @@
*/
package org.apache.cordova;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import org.apache.cordova.CordovaPlugin;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.ExecutorService;
@@ -56,7 +55,7 @@ public interface CordovaInterface {
*
* @return the Activity
*/
public abstract Activity getActivity();
public abstract AppCompatActivity getActivity();
/**
* Get the Android context.

View File

@@ -20,7 +20,6 @@
package org.apache.cordova;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -28,6 +27,8 @@ import android.os.Build;
import android.os.Bundle;
import android.util.Pair;
import androidx.appcompat.app.AppCompatActivity;
import org.json.JSONException;
import org.json.JSONObject;
@@ -39,7 +40,7 @@ import java.util.concurrent.Executors;
*/
public class CordovaInterfaceImpl implements CordovaInterface {
private static final String TAG = "CordovaInterfaceImpl";
protected Activity activity;
protected AppCompatActivity activity;
protected ExecutorService threadPool;
protected PluginManager pluginManager;
@@ -51,11 +52,11 @@ public class CordovaInterfaceImpl implements CordovaInterface {
protected boolean activityWasDestroyed = false;
protected Bundle savedPluginState;
public CordovaInterfaceImpl(Activity activity) {
public CordovaInterfaceImpl(AppCompatActivity activity) {
this(activity, Executors.newCachedThreadPool());
}
public CordovaInterfaceImpl(Activity activity, ExecutorService threadPool) {
public CordovaInterfaceImpl(AppCompatActivity activity, ExecutorService threadPool) {
this.activity = activity;
this.threadPool = threadPool;
this.permissionResultCallbacks = new CallbackMap();
@@ -76,13 +77,13 @@ public class CordovaInterfaceImpl implements CordovaInterface {
public void setActivityResultCallback(CordovaPlugin plugin) {
// Cancel any previously pending activity.
if (activityResultCallback != null) {
activityResultCallback.onActivityResult(activityResultRequestCode, Activity.RESULT_CANCELED, null);
activityResultCallback.onActivityResult(activityResultRequestCode, AppCompatActivity.RESULT_CANCELED, null);
}
activityResultCallback = plugin;
}
@Override
public Activity getActivity() {
public AppCompatActivity getActivity() {
return activity;
}

View File

@@ -414,9 +414,32 @@ public class CordovaPlugin {
* @param requestCode
* @param permissions
* @param grantResults
*
* @deprecated Use {@link #onRequestPermissionsResult} instead.
*/
@Deprecated
public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {
}
/**
* Called by the system when the user grants permissions
*
* @param requestCode
* @param permissions
* @param grantResults
*/
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {
}
/**
* Allow plugins to supply a PathHandler for the WebViewAssetHandler
* @return a CordovaPluginPathHandler which listen for paths and returns a response
*/
public CordovaPluginPathHandler getPathHandler() {
return null;
}
}

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,14 +17,22 @@
under the License.
*/
var check_reqs = require('./templates/cordova/lib/check_reqs');
package org.apache.cordova;
check_reqs.run().then(
function success () {
console.log('Looks like your environment fully supports cordova-android development!');
},
function fail (err) {
console.log(err);
process.exit(2);
import androidx.webkit.WebViewAssetLoader;
/**
* Wrapper class for path and handler
*/
public class CordovaPluginPathHandler {
private final WebViewAssetLoader.PathHandler handler;
public CordovaPluginPathHandler(WebViewAssetLoader.PathHandler handler) {
this.handler = handler;
}
);
public WebViewAssetLoader.PathHandler getPathHandler() {
return handler;
}
}

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 = "9.1.0-dev";
public static final String CORDOVA_VERSION = "10.0.1";
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
@@ -94,7 +94,7 @@ public interface CordovaWebView {
/**
* Load the specified URL in the Cordova webview or a new browser instance.
*
* NOTE: If openExternal is false, only whitelisted URLs can be loaded.
* NOTE: If openExternal is false, only allow listed URLs can be loaded.
*
* @param url The url to load.
* @param openExternal Load url in browser instead of Cordova webview.

View File

@@ -117,7 +117,6 @@ public class CordovaWebViewImpl implements CordovaWebView {
pluginManager.addService(CoreAndroid.PLUGIN_NAME, "org.apache.cordova.CoreAndroid");
pluginManager.init();
}
@Override
@@ -219,19 +218,19 @@ public class CordovaWebViewImpl implements CordovaWebView {
// If loading into our webview
if (!openExternal) {
// Make sure url is in whitelist
// Make sure url is in allow list
if (pluginManager.shouldAllowNavigation(url)) {
// TODO: What about params?
// Load new URL
loadUrlIntoView(url, true);
return;
} else {
LOG.w(TAG, "showWebPage: Refusing to load URL into webview since it is not in the <allow-navigation> whitelist. URL=" + url);
LOG.w(TAG, "showWebPage: Refusing to load URL into webview since it is not in the <allow-navigation> allow list. URL=" + url);
return;
}
}
if (!pluginManager.shouldOpenExternalUrl(url)) {
LOG.w(TAG, "showWebPage: Refusing to send intent for URL since it is not in the <allow-intent> whitelist. URL=" + url);
LOG.w(TAG, "showWebPage: Refusing to send intent for URL since it is not in the <allow-intent> allow list. URL=" + url);
return;
}
@@ -339,6 +338,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
// Show the content view.
engine.getView().setVisibility(View.VISIBLE);
engine.getView().requestFocus();
}
@Override

View File

@@ -79,7 +79,9 @@ public class PermissionHelper {
Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);
try {
// This one is deprecated - see https://github.com/apache/cordova-android/issues/592
plugin.onRequestPermissionResult(requestCode, permissions, requestResults);
plugin.onRequestPermissionsResult(requestCode, permissions, requestResults);
} catch (JSONException e) {
LOG.e(LOG_TAG, "JSONException when delivering permissions results", e);
}

View File

@@ -47,11 +47,23 @@ public final class PluginEntry {
/**
* Constructs with a CordovaPlugin already instantiated.
*
* @param service The name of the service
* @param pluginClass The plugin class name
*/
public PluginEntry(String service, CordovaPlugin plugin) {
this(service, plugin.getClass().getName(), true, plugin);
}
/**
* @param service The name of the service
* @param plugin The CordovaPlugin already instantiated
* @param onload Create plugin object when HTML page is loaded
*/
public PluginEntry(String service, CordovaPlugin plugin, boolean onload) {
this(service, plugin.getClass().getName(), onload, plugin);
}
/**
* @param service The name of the service
* @param pluginClass The plugin class name
@@ -61,6 +73,12 @@ public final class PluginEntry {
this(service, pluginClass, onload, null);
}
/**
* @param service The name of the service
* @param pluginClass The plugin class name
* @param onload Create plugin object when HTML page is loaded
* @param plugin The CordovaPlugin already instantiated
*/
private PluginEntry(String service, String pluginClass, boolean onload, CordovaPlugin plugin) {
this.service = service;
this.pluginClass = pluginClass;

View File

@@ -18,6 +18,7 @@
*/
package org.apache.cordova;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -577,4 +578,19 @@ public class PluginManager {
}
return state;
}
/**
* Collect all plugins PathHandlers
*
* @return list of PathHandlers in no particular order
*/
public ArrayList<CordovaPluginPathHandler> getPluginPathHandlers() {
ArrayList<CordovaPluginPathHandler> handlers = new ArrayList<CordovaPluginPathHandler>();
for (CordovaPlugin plugin : this.pluginMap.values()) {
if (plugin != null && plugin.getPathHandler() != null) {
handlers.add(plugin.getPathHandler());
}
}
return handlers;
}
}

View File

@@ -27,7 +27,7 @@
<script type="text/javascript" charset="utf-8" src="../main.js"></script>
</head>
<body onload="init();" id="stage" class="theme">
<h1>Whitelist Page 1</h1>
<h1>Allow List Page 1</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>

View File

@@ -27,7 +27,7 @@
<script type="text/javascript" charset="utf-8" src="../main.js"></script>
</head>
<body onload="init();" id="stage" class="theme">
<h1>Whitelist Page 2</h1>
<h1>Allow List Page 2</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>

View File

@@ -18,17 +18,18 @@
*/
package org.apache.cordova.engine;
import android.annotation.TargetApi;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.webkit.ClientCertRequest;
import android.webkit.HttpAuthHandler;
import android.webkit.MimeTypeMap;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -36,14 +37,17 @@ import android.webkit.WebViewClient;
import org.apache.cordova.AuthenticationToken;
import org.apache.cordova.CordovaClientCertRequest;
import org.apache.cordova.CordovaHttpAuthHandler;
import org.apache.cordova.CordovaPluginPathHandler;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.LOG;
import org.apache.cordova.PluginManager;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import androidx.webkit.WebViewAssetLoader;
/**
* This class is the WebViewClient that implements callbacks for our web view.
@@ -56,6 +60,7 @@ public class SystemWebViewClient extends WebViewClient {
private static final String TAG = "SystemWebViewClient";
protected final SystemWebViewEngine parentEngine;
private final WebViewAssetLoader assetLoader;
private boolean doClearHistory = false;
boolean isCurrentlyLoading;
@@ -64,6 +69,52 @@ public class SystemWebViewClient extends WebViewClient {
public SystemWebViewClient(SystemWebViewEngine parentEngine) {
this.parentEngine = parentEngine;
WebViewAssetLoader.Builder assetLoaderBuilder = new WebViewAssetLoader.Builder()
.setDomain(parentEngine.preferences.getString("hostname", "localhost"))
.setHttpAllowed(true);
assetLoaderBuilder.addPathHandler("/", path -> {
try {
// Check if there a plugins with pathHandlers
PluginManager pluginManager = this.parentEngine.pluginManager;
if (pluginManager != null) {
for (CordovaPluginPathHandler handler : pluginManager.getPluginPathHandlers()) {
if (handler.getPathHandler() != null) {
WebResourceResponse response = handler.getPathHandler().handle(path);
if (response != null) {
return response;
}
};
}
}
if (path.isEmpty()) {
path = "index.html";
}
InputStream is = parentEngine.webView.getContext().getAssets().open("www/" + path, AssetManager.ACCESS_STREAMING);
String mimeType = "text/html";
String extension = MimeTypeMap.getFileExtensionFromUrl(path);
if (extension != null) {
if (path.endsWith(".js") || path.endsWith(".mjs")) {
// Make sure JS files get the proper mimetype to support ES modules
mimeType = "application/javascript";
} else if (path.endsWith(".wasm")) {
mimeType = "application/wasm";
} else {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
}
return new WebResourceResponse(mimeType, null, is);
} catch (Exception e) {
e.printStackTrace();
LOG.e(TAG, e.getMessage());
}
return null;
});
this.assetLoader = assetLoaderBuilder.build();
}
/**
@@ -320,10 +371,10 @@ public class SystemWebViewClient extends WebViewClient {
@SuppressWarnings("deprecation")
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
try {
// Check the against the whitelist and lock out access to the WebView directory
// Check the against the allow list and lock out access to the WebView directory
// Changing this will cause problems for your application
if (!parentEngine.pluginManager.shouldAllowRequest(url)) {
LOG.w(TAG, "URL blocked by whitelist: " + url);
LOG.w(TAG, "URL blocked by allow list: " + url);
// Results in a 404.
return new WebResourceResponse("text/plain", "UTF-8", null);
}
@@ -366,4 +417,9 @@ public class SystemWebViewClient extends WebViewClient {
return false;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return this.assetLoader.shouldInterceptRequest(request.getUrl());
}
}

View File

@@ -152,33 +152,27 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
/**
* https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess(boolean)
*
* SDK >= 30 has recently set this value to false by default.
* It is recommended to turn off this settings To prevent possible security issues targeting Build.VERSION_CODES.Q and earlier.
* For existing functionality, this setting is set to true. In a future release, this should be defaulted to false.
*/
settings.setAllowFileAccess(true);
String manufacturer = android.os.Build.MANUFACTURER;
LOG.d(TAG, "CordovaWebView is running on device made by: " + manufacturer);
//We don't save any form data in the application
// We don't save any form data in the application
// @todo remove when Cordova drop API level 26 support
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
settings.setAllowUniversalAccessFromFileURLs(true);
if (preferences.getBoolean("AndroidInsecureFileModeEnabled", false)) {
//These settings are deprecated and loading content via file:// URLs is generally discouraged,
//but we allow this for compatibility reasons
LOG.d(TAG, "Enabled insecure file access");
settings.setAllowFileAccess(true);
settings.setAllowUniversalAccessFromFileURLs(true);
}
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();
@@ -186,6 +180,7 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
enableRemoteDebugging();
}
// @todo remove when Cordova drop API level 24 support
settings.setGeolocationDatabasePath(databasePath);
// Enable DOM storage
@@ -194,12 +189,6 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
// 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();

View File

@@ -17,26 +17,18 @@
under the License.
*/
/**
* @todo update coho to update this line.
* @todo use `package.json` instead but first
* figure out how this fit in with the platform-centered workflow structure.
* This workflow would not have the `package.json` file.
*/
// Coho updates this line
const VERSION = '9.1.0-dev';
var path = require('path');
var AndroidProject = require('./lib/AndroidProject');
var AndroidProject = require('./AndroidProject');
var PluginManager = require('cordova-common').PluginManager;
var CordovaLogger = require('cordova-common').CordovaLogger;
var selfEvents = require('cordova-common').events;
var ConfigParser = require('cordova-common').ConfigParser;
const prepare = require('./lib/prepare').prepare;
const prepare = require('./prepare').prepare;
var PLATFORM = 'android';
const VERSION = require('../package').version;
function setupEvents (externalEventEmitter) {
if (externalEventEmitter) {
@@ -66,7 +58,7 @@ function setupEvents (externalEventEmitter) {
class Api {
constructor (platform, platformRootDir, events) {
this.platform = PLATFORM;
this.root = path.resolve(__dirname, '..');
this.root = platformRootDir;
setupEvents(events);
@@ -86,7 +78,7 @@ class Api {
javaSrc: path.join(appMain, 'java')
};
this._builder = require('./lib/builders/builders').getBuilder(this.root);
this._builder = require('./builders/builders').getBuilder(this.root);
}
/**
@@ -249,8 +241,8 @@ class Api {
build (buildOptions) {
var self = this;
return require('./lib/check_reqs').run().then(function () {
return require('./lib/build').run.call(self, buildOptions);
return require('./check_reqs').run().then(function () {
return require('./build').run.call(self, buildOptions);
}).then(function (buildResults) {
// Cast build result to array of build artifacts
return buildResults.paths.map(function (apkPath) {
@@ -278,8 +270,8 @@ class Api {
*/
run (runOptions) {
var self = this;
return require('./lib/check_reqs').run().then(function () {
return require('./lib/run').run.call(self, runOptions);
return require('./check_reqs').run().then(function () {
return require('./run').run.call(self, runOptions);
});
}
@@ -297,10 +289,10 @@ class Api {
cleanOptions = {};
}
return require('./lib/check_reqs').run().then(function () {
return require('./lib/build').runClean.call(self, cleanOptions);
return require('./check_reqs').run().then(function () {
return require('./build').runClean.call(self, cleanOptions);
}).then(function () {
return require('./lib/prepare').clean.call(self, cleanOptions);
return require('./prepare').clean.call(self, cleanOptions);
});
}
@@ -313,7 +305,7 @@ class Api {
* objects for current platform.
*/
requirements () {
return require('./lib/check_reqs').check_all();
return require('./check_reqs').check_all(this.root);
}
/**
@@ -338,7 +330,7 @@ class Api {
events = setupEvents(events);
var result;
try {
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
result = require('./create').create(destination, config, options, events).then(function (destination) {
return new Api(PLATFORM, destination, events);
});
} catch (e) {

View File

@@ -76,23 +76,12 @@ function parse_targets (output) {
return targets;
}
module.exports.list_targets_with_android = function () {
return execa('android', ['list', 'target']).then(result => parse_targets(result.stdout));
};
module.exports.list_targets_with_avdmanager = function () {
return execa('avdmanager', ['list', 'target']).then(result => parse_targets(result.stdout));
};
module.exports.list_targets = function () {
return module.exports.list_targets_with_avdmanager().catch(function (err) {
// If there's an error, like avdmanager could not be found, we can try
// as a last resort, to run `android`, in case this is a super old
// SDK installation.
if (err && (err.code === 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
return module.exports.list_targets_with_android();
} else throw err;
}).then(function (targets) {
return module.exports.list_targets_with_avdmanager().then(function (targets) {
if (targets.length === 0) {
return Promise.reject(new Error('No android targets (SDKs) installed!'));
}

View File

@@ -20,6 +20,7 @@
var path = require('path');
var fs = require('fs');
var nopt = require('nopt');
const untildify = require('untildify');
var Adb = require('./Adb');
@@ -82,9 +83,7 @@ function parseOpts (options, resolvedTarget, projectRoot) {
if (config.android && config.android[ret.buildType]) {
var androidInfo = config.android[ret.buildType];
if (androidInfo.keystore && !packageArgs.keystore) {
if (androidInfo.keystore.substr(0, 1) === '~') {
androidInfo.keystore = process.env.HOME + androidInfo.keystore.substr(1);
}
androidInfo.keystore = untildify(androidInfo.keystore);
packageArgs.keystore = path.resolve(path.dirname(buildConfig), androidInfo.keystore);
events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
}
@@ -130,7 +129,11 @@ function parseOpts (options, resolvedTarget, projectRoot) {
ret.packageType = packageArgs.packageType;
}
} else {
ret.packageType = PackageType.APK;
if (ret.buildType === 'release') {
ret.packageType = PackageType.BUNDLE;
} else {
ret.packageType = PackageType.APK;
}
}
return ret;
@@ -241,26 +244,3 @@ PackageInfo.prototype = {
propertiesParser.save();
}
};
module.exports.help = function () {
console.log('Usage: ' + path.relative(process.cwd(), path.join('../build')) + ' [flags] [Signed APK flags]');
console.log('Flags:');
console.log(' \'--debug\': will build project in debug mode (default)');
console.log(' \'--release\': will build project for release');
console.log(' \'--nobuild\': will skip build process (useful when using run command)');
console.log(' \'--prepenv\': don\'t build, but copy in build scripts where necessary');
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs.');
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build.');
console.log(' \'--maxSdkVersion=#\': Override maxSdkVersion for this build. (Not Recommended)');
console.log(' \'--targetSdkVersion=#\': Override targetSdkVersion for this build.');
console.log(' \'--gradleArg=<gradle command line arg>\': Extra args to pass to the gradle command. Use one flag per arg. Ex. --gradleArg=-PcdvBuildMultipleApks=true');
console.log(' \'--packageType=<apk|bundle>\': Builds an APK or a bundle');
console.log('');
console.log('Signed APK flags (overwrites debug/release-signing.proprties) :');
console.log(' \'--keystore=<path to keystore>\': Key store used to build a signed archive. (Required)');
console.log(' \'--alias=\': Alias for the key store. (Required)');
console.log(' \'--storePassword=\': Password for the key store. (Optional - prompted)');
console.log(' \'--password=\': Password for the key. (Optional - prompted)');
console.log(' \'--keystoreType\': Type of the keystore. (Optional)');
process.exit(0);
};

View File

@@ -78,7 +78,7 @@ function findOutputFiles (bundleType, buildType, { arch } = {}) {
class ProjectBuilder {
constructor (rootDirectory) {
this.root = rootDirectory || path.resolve(__dirname, '../../..');
this.root = rootDirectory;
this.apkDir = path.join(this.root, 'app', 'build', 'outputs', 'apk');
this.aabDir = path.join(this.root, 'app', 'build', 'outputs', 'bundle');
}
@@ -160,7 +160,7 @@ class ProjectBuilder {
// Makes the project buildable, minus the gradle wrapper.
prepBuildFiles () {
// Update the version of build.gradle in each dependent library.
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
var pluginBuildGradle = path.join(__dirname, 'plugin-build.gradle');
var propertiesObj = this.readProjectProperties();
var subProjects = propertiesObj.libs;
@@ -265,10 +265,11 @@ class ProjectBuilder {
}).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-6.5-all.zip';
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();
@@ -287,25 +288,35 @@ class ProjectBuilder {
});
}
/**
* @private
* @returns The user defined configs
*/
_getCordovaConfig () {
return fs.readJSONSync(path.join(this.root, 'cdv-gradle-config.json'));
}
/*
* Builds the project with gradle.
* Returns a promise.
*/
build (opts) {
async build (opts) {
var wrapper = path.join(this.root, 'gradlew');
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
return execa(wrapper, args, { stdio: 'inherit', cwd: path.resolve(this.root) })
.catch(function (error) {
if (error.toString().indexOf('failed to find target with hash string') >= 0) {
return check_reqs.check_android_target(error).then(function () {
// If due to some odd reason - check_android_target succeeds
// we should still fail here.
throw error;
});
try {
return await execa(wrapper, args, { stdio: 'inherit', cwd: path.resolve(this.root) });
} catch (error) {
if (error.toString().includes('failed to find target with hash string')) {
// Add hint from check_android_target to error message
try {
await check_reqs.check_android_target(this.root);
} catch (checkAndroidTargetError) {
error.message += '\n' + checkAndroidTargetError.message;
}
throw error;
});
}
throw error;
}
}
clean (opts) {

View File

@@ -21,7 +21,7 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
// Switch the Android Gradle plugin version requirement depending on the
@@ -42,8 +42,8 @@ dependencies {
}
android {
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
compileSdkVersion cordovaConfig.SDK_VERSION
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6

View File

@@ -22,58 +22,44 @@ var path = require('path');
var fs = require('fs-extra');
const { forgivingWhichSync, isWindows, isDarwin } = require('./utils');
const java = require('./env/java');
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
var PROJECT_ROOT = path.join(__dirname, '..', '..');
const { CordovaError, ConfigParser, events } = require('cordova-common');
var android_sdk = require('./android_sdk');
const { createEditor } = require('properties-parser');
const semver = require('semver');
const EXPECTED_JAVA_VERSION = '1.8.x';
const { SDK_VERSION } = require('./gradle-config-defaults');
// Re-exporting these for backwards compatibility and for unit testing.
// TODO: Remove uses and use the ./utils module directly.
Object.assign(module.exports, { isWindows, isDarwin });
/**
* @description Get valid target from framework/project.properties if run from this repo
* Otherwise get target from project.properties file within a generated cordova-android project
* @param {string} projectRoot
* @returns {string} The android target in format "android-${target}"
*/
module.exports.get_target = function () {
const projectPropertiesPaths = [
path.join(REPO_ROOT, 'framework', 'project.properties'),
path.join(PROJECT_ROOT, 'project.properties')
];
module.exports.get_target = function (projectRoot) {
const userTargetSdkVersion = getUserTargetSdkVersion(projectRoot);
// Get the minimum required target API from the framework.
let target = projectPropertiesPaths.filter(filePath => fs.existsSync(filePath))
.map(filePath => createEditor(filePath).get('target'))
.pop();
if (!target) {
throw new Error(`We could not locate the target from the "project.properties" at either "${projectPropertiesPaths.join('", "')}".`);
if (userTargetSdkVersion && userTargetSdkVersion < SDK_VERSION) {
events.emit('warn', `android-targetSdkVersion should be greater than or equal to ${SDK_VERSION}.`);
}
return `android-${Math.max(userTargetSdkVersion, SDK_VERSION)}`;
};
/**
* @param {string} projectRoot
* @returns {number} target sdk or 0 if undefined
*/
function getUserTargetSdkVersion (projectRoot) {
// If the repo config.xml file exists, find the desired targetSdkVersion.
const configFile = path.join(REPO_ROOT, 'config.xml');
if (!fs.existsSync(configFile)) return target;
// We need to use the cordova project's config.xml here, since the platform
// project's config.xml does not yet have the user's preferences when this
// function is called during `Api.createPlatform`.
const configFile = path.join(projectRoot, '../../config.xml');
if (!fs.existsSync(configFile)) return 0;
const configParser = new ConfigParser(configFile);
const desiredAPI = parseInt(configParser.getPreference('android-targetSdkVersion', 'android'), 10);
if (!isNaN(desiredAPI)) {
const minimumAPI = parseInt(target.split('-').pop(), 10);
if (desiredAPI >= minimumAPI) {
target = `android-${desiredAPI}`;
} else {
events.emit('warn', `android-targetSdkVersion should be greater than or equal to ${minimumAPI}.`);
}
}
return target;
};
const targetSdkVersion = parseInt(configParser.getPreference('android-targetSdkVersion', 'android'), 10);
return isNaN(targetSdkVersion) ? 0 : targetSdkVersion;
}
module.exports.get_gradle_wrapper = function () {
var androidStudioPath;
@@ -140,14 +126,6 @@ module.exports.check_gradle = function () {
*/
module.exports.check_java = async function () {
const javaVersion = await java.getVersion();
if (!semver.satisfies(javaVersion.version, EXPECTED_JAVA_VERSION)) {
throw new CordovaError(
`Requirements check failed for JDK ${EXPECTED_JAVA_VERSION}! Detected version: ${javaVersion.version}\n` +
'Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.'
);
}
return javaVersion;
};
@@ -161,7 +139,6 @@ module.exports.check_android = function () {
}
}
var androidCmdPath = forgivingWhichSync('android');
var adbInPath = forgivingWhichSync('adb');
var avdmanagerInPath = forgivingWhichSync('avdmanager');
var hasAndroidHome = false;
@@ -172,7 +149,7 @@ module.exports.check_android = function () {
// First ensure ANDROID_HOME is set
// If we have no hints (nothing in PATH), try a few default locations
if (!hasAndroidHome && !androidCmdPath && !adbInPath && !avdmanagerInPath) {
if (!hasAndroidHome && !adbInPath && !avdmanagerInPath) {
if (process.env.ANDROID_HOME) {
// Fallback to deprecated `ANDROID_HOME` variable
maybeSetAndroidHome(path.join(process.env.ANDROID_HOME));
@@ -222,17 +199,6 @@ module.exports.check_android = function () {
if (!hasAndroidHome) {
// If we dont have ANDROID_SDK_ROOT, but we do have some tools on the PATH, try to infer from the tooling PATH.
var parentDir, grandParentDir;
if (androidCmdPath) {
parentDir = path.dirname(androidCmdPath);
grandParentDir = path.dirname(parentDir);
if (path.basename(parentDir) === 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
maybeSetAndroidHome(grandParentDir);
} else {
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
}
}
if (adbInPath) {
parentDir = path.dirname(adbInPath);
grandParentDir = path.dirname(parentDir);
@@ -265,9 +231,6 @@ module.exports.check_android = function () {
'\nTry update it manually to point to valid SDK directory.');
}
// Next let's make sure relevant parts of the SDK tooling is in our PATH
if (hasAndroidHome && !androidCmdPath) {
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'tools');
}
if (hasAndroidHome && !adbInPath) {
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'platform-tools');
}
@@ -278,40 +241,18 @@ module.exports.check_android = function () {
});
};
// TODO: is this actually needed?
module.exports.getAbsoluteAndroidCmd = function () {
var cmd = forgivingWhichSync('android');
if (cmd.length === 0) {
cmd = forgivingWhichSync('sdkmanager');
}
if (module.exports.isWindows()) {
return '"' + cmd + '"';
}
return cmd.replace(/(\s)/g, '\\$1');
};
module.exports.check_android_target = function (originalError) {
module.exports.check_android_target = function (projectRoot) {
// valid_target can look like:
// android-19
// android-L
// Google Inc.:Google APIs:20
// Google Inc.:Glass Development Kit Preview:20
var desired_api_level = module.exports.get_target();
var desired_api_level = module.exports.get_target(projectRoot);
return android_sdk.list_targets().then(function (targets) {
if (targets.indexOf(desired_api_level) >= 0) {
return targets;
}
var androidCmd = module.exports.getAbsoluteAndroidCmd();
var msg = 'Please install Android target / API level: "' + desired_api_level + '".\n\n' +
'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
'You will require:\n' +
'1. "SDK Platform" for API level ' + desired_api_level + '\n' +
'2. "Android SDK Platform-tools (latest)\n' +
'3. "Android SDK Build-tools" (latest)';
if (originalError) {
msg = originalError + '\n' + msg;
}
throw new CordovaError(msg);
throw new CordovaError(`Please install the Android SDK Platform "platforms;${desired_api_level}"`);
});
};
@@ -351,9 +292,10 @@ var Requirement = function (id, name, version, installed) {
* Methods that runs all checks one by one and returns a result of checks
* as an array of Requirement objects. This method intended to be used by cordova-lib check_reqs method
*
* @param {string} projectRoot
* @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
*/
module.exports.check_all = function () {
module.exports.check_all = function (projectRoot) {
var requirements = [
new Requirement('java', 'Java JDK'),
new Requirement('androidSdk', 'Android SDK'),
@@ -364,7 +306,7 @@ module.exports.check_all = function () {
var checkFns = [
this.check_java,
this.check_android,
this.check_android_target,
this.check_android_target.bind(this, projectRoot),
this.check_gradle
];

View File

@@ -30,15 +30,12 @@ class GradlePropertiesParser {
*/
constructor (platformDir) {
this._defaults = {
// 10 seconds -> 6 seconds
'org.gradle.daemon': 'true',
// to allow dex in process
'org.gradle.jvmargs': '-Xmx2048m',
// Android X
'android.useAndroidX': 'false',
'android.enableJetifier': 'false'
'android.useAndroidX': 'true',
'android.enableJetifier': 'true'
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
// 'org.gradle.parallel': 'true'

View File

@@ -19,12 +19,13 @@
var path = require('path');
var fs = require('fs-extra');
var utils = require('../templates/cordova/lib/utils');
var check_reqs = require('./../templates/cordova/lib/check_reqs');
var ROOT = path.join(__dirname, '..', '..');
var utils = require('./utils');
var check_reqs = require('./check_reqs');
var ROOT = path.join(__dirname, '..');
const { createEditor } = require('properties-parser');
var CordovaError = require('cordova-common').CordovaError;
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
var AndroidManifest = require('./AndroidManifest');
// Export all helper functions, and make sure internally within this module, we
// reference these methods via the `exports` object - this helps with testing
@@ -42,16 +43,12 @@ function getFrameworkDir (projectPath, shared) {
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
}
function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) {
function copyJsAndLibrary (projectPath, shared, projectName, targetAPI) {
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
var srcCordovaJsPath = path.join(ROOT, 'templates', 'project', 'assets', 'www', 'cordova.js');
var app_path = path.join(projectPath, 'app', 'src', 'main');
const platform_www = path.join(projectPath, 'platform_www');
if (isLegacy) {
app_path = projectPath;
}
fs.copySync(srcCordovaJsPath, path.join(app_path, 'assets', 'www', 'cordova.js'));
// Copy the cordova.js file to platforms/<platform>/platform_www/
@@ -59,21 +56,20 @@ function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) {
fs.ensureDirSync(platform_www);
fs.copySync(srcCordovaJsPath, path.join(platform_www, 'cordova.js'));
// Copy cordova-js-src directory into platform_www directory.
// We need these files to build cordova.js if using browserify method.
fs.copySync(path.join(ROOT, 'cordova-js-src'), path.join(platform_www, 'cordova-js-src'));
if (shared) {
var relativeFrameworkPath = path.relative(projectPath, getFrameworkDir(projectPath, true));
fs.symlinkSync(relativeFrameworkPath, nestedCordovaLibPath, 'dir');
} else {
fs.ensureDirSync(nestedCordovaLibPath);
fs.copySync(path.join(ROOT, 'framework', 'AndroidManifest.xml'), path.join(nestedCordovaLibPath, 'AndroidManifest.xml'));
fs.copySync(path.join(ROOT, 'framework', 'project.properties'), path.join(nestedCordovaLibPath, 'project.properties'));
const propertiesEditor = createEditor(path.join(ROOT, 'framework', 'project.properties'));
propertiesEditor.set('target', targetAPI);
propertiesEditor.save(path.join(nestedCordovaLibPath, 'project.properties'));
fs.copySync(path.join(ROOT, 'framework', 'build.gradle'), path.join(nestedCordovaLibPath, 'build.gradle'));
fs.copySync(path.join(ROOT, 'framework', 'cordova.gradle'), path.join(nestedCordovaLibPath, 'cordova.gradle'));
fs.copySync(path.join(ROOT, 'framework', 'repositories.gradle'), path.join(nestedCordovaLibPath, 'repositories.gradle'));
fs.copySync(path.join(ROOT, 'framework', 'src'), path.join(nestedCordovaLibPath, 'src'));
fs.copySync(path.join(ROOT, 'framework', 'cdv-gradle-config-defaults.json'), path.join(projectPath, 'cdv-gradle-config.json'));
}
}
@@ -89,7 +85,7 @@ function extractSubProjectPaths (data) {
function writeProjectProperties (projectPath, target_api) {
var dstPath = path.join(projectPath, 'project.properties');
var templatePath = path.join(ROOT, 'bin', 'templates', 'project', 'project.properties');
var templatePath = path.join(ROOT, 'templates', 'project', 'project.properties');
var srcPath = fs.existsSync(dstPath) ? dstPath : templatePath;
var data = fs.readFileSync(srcPath, 'utf8');
@@ -113,12 +109,12 @@ function writeProjectProperties (projectPath, target_api) {
// This makes no sense, what if you're building with a different build system?
function prepBuildFiles (projectPath) {
var buildModule = require('../templates/cordova/lib/builders/builders');
var buildModule = require('./builders/builders');
buildModule.getBuilder(projectPath).prepBuildFiles();
}
function copyBuildRules (projectPath, isLegacy) {
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
var 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
@@ -134,33 +130,12 @@ function copyBuildRules (projectPath, isLegacy) {
}
function copyScripts (projectPath) {
var bin = path.join(ROOT, 'bin');
var srcScriptsDir = path.join(bin, 'templates', 'cordova');
var srcScriptsDir = path.join(ROOT, 'templates', 'cordova');
var destScriptsDir = path.join(projectPath, 'cordova');
// Delete old scripts directory if this is an update.
fs.removeSync(destScriptsDir);
// Copy in the new ones.
fs.copySync(srcScriptsDir, destScriptsDir);
const nodeModulesDir = path.join(ROOT, 'node_modules');
if (fs.existsSync(nodeModulesDir)) fs.copySync(nodeModulesDir, path.join(destScriptsDir, 'node_modules'));
fs.copySync(path.join(bin, 'check_reqs'), path.join(destScriptsDir, 'check_reqs'));
fs.copySync(path.join(bin, 'check_reqs.bat'), path.join(destScriptsDir, 'check_reqs.bat'));
fs.copySync(path.join(bin, 'android_sdk_version'), path.join(destScriptsDir, 'android_sdk_version'));
fs.copySync(path.join(bin, 'android_sdk_version.bat'), path.join(destScriptsDir, 'android_sdk_version.bat'));
var check_reqs = path.join(destScriptsDir, 'check_reqs');
var android_sdk_version = path.join(destScriptsDir, 'android_sdk_version');
// TODO: the two files being edited on-the-fly here are shared between
// platform and project-level commands. the below is updating the
// `require` path for the two libraries. if there's a better way to share
// modules across both the repo and generated projects, we should make sure
// to remove/update this.
const templatesCordovaRegex = /templates\/cordova\//;
utils.replaceFileContents(android_sdk_version, templatesCordovaRegex, '');
utils.replaceFileContents(check_reqs, templatesCordovaRegex, '');
}
/**
@@ -247,7 +222,7 @@ exports.create = function (project_path, config, options, events) {
? config.name().replace(/[^\w.]/g, '_') : 'CordovaExample';
var safe_activity_name = config.android_activityName() || options.activityName || 'MainActivity';
var target_api = check_reqs.get_target();
var target_api = check_reqs.get_target(project_path);
// Make the package conform to Java package types
return exports.validatePackageName(package_name)
@@ -264,7 +239,7 @@ exports.create = function (project_path, config, options, events) {
events.emit('verbose', 'Copying android template project to ' + project_path);
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
var project_template_dir = options.customTemplate || path.join(ROOT, 'templates', 'project');
var app_path = path.join(project_path, 'app', 'src', 'main');
// copy project template
@@ -277,7 +252,7 @@ exports.create = function (project_path, config, options, events) {
fs.ensureDirSync(path.join(app_path, 'libs'));
// copy cordova.js, cordova.jar
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name, target_api);
// Set up ther Android Studio paths
var java_path = path.join(app_path, 'java');
@@ -317,7 +292,7 @@ exports.create = function (project_path, config, options, events) {
};
function generateDoneMessage (type, link) {
var pkg = require('../../package');
var pkg = require('../package');
var msg = 'Android project ' + (type === 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
if (link) {
msg += ' and has a linked CordovaLib';

View File

@@ -25,7 +25,6 @@ var Adb = require('./Adb');
var events = require('cordova-common').events;
var CordovaError = require('cordova-common').CordovaError;
var android_sdk = require('./android_sdk');
var check_reqs = require('./check_reqs');
var which = require('which');
// constants
@@ -99,48 +98,6 @@ module.exports.list_images_using_avdmanager = function () {
});
};
module.exports.list_images_using_android = function () {
return execa('android', ['list', 'avd']).then(({ stdout: output }) => {
var response = output.split('\n');
var emulator_list = [];
for (var i = 1; i < response.length; i++) {
// To return more detailed information use img_obj
var img_obj = {};
if (response[i].match(/Name:\s/)) {
img_obj.name = response[i].split('Name: ')[1].replace('\r', '');
if (response[i + 1].match(/Device:\s/)) {
i++;
img_obj.device = response[i].split('Device: ')[1].replace('\r', '');
}
if (response[i + 1].match(/Path:\s/)) {
i++;
img_obj.path = response[i].split('Path: ')[1].replace('\r', '');
}
if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) {
i++;
var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : '';
img_obj.target = (response[i] + secondLine).split('Target: ')[1].replace('\r', '');
}
if (response[i + 1].match(/ABI:\s/)) {
i++;
img_obj.abi = response[i].split('ABI: ')[1].replace('\r', '');
}
if (response[i + 1].match(/Skin:\s/)) {
i++;
img_obj.skin = response[i].split('Skin: ')[1].replace('\r', '');
}
emulator_list.push(img_obj);
}
/* To just return a list of names use this
if (response[i].match(/Name:\s/)) {
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
} */
}
return emulator_list;
});
};
/**
* Returns a Promise for a list of emulator images in the form of objects
* {
@@ -156,10 +113,8 @@ module.exports.list_images = function () {
return Promise.resolve().then(function () {
if (forgivingWhichSync('avdmanager')) {
return module.exports.list_images_using_avdmanager();
} else if (forgivingWhichSync('android')) {
return module.exports.list_images_using_android();
} else {
return Promise.reject(new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?'));
return Promise.reject(new CordovaError('Could not find `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?'));
}
}).then(function (avds) {
// In case we're missing the Android OS version string from the target description, add it.
@@ -179,18 +134,19 @@ module.exports.list_images = function () {
};
/**
* Will return the closest avd to the projects target
* Returns the best image (if any) for given target.
*
* @param {Number} project_target Android targetSDK API level
* @return {{name: string} | undefined} the closest avd to the given target
* or undefined if no avds exist.
* Returns a promise.
*/
module.exports.best_image = function () {
module.exports.best_image = function (project_target) {
return this.list_images().then(function (images) {
// Just return undefined if there is no images
if (images.length === 0) return;
var closest = 9999;
var best = images[0];
var project_target = parseInt(check_reqs.get_target().replace('android-', ''));
for (var i in images) {
var target = images[i].target;
if (target && target.indexOf('API level') > -1) {
@@ -233,32 +189,19 @@ module.exports.get_available_port = function () {
/*
* Starts an emulator with the given ID,
* and returns the started ID of that emulator.
* If no ID is given it will use the first image available,
* if no image is available it will error out (maybe create one?).
* If no boot timeout is given or the value is negative it will wait forever for
* the emulator to boot
*
* Returns a promise.
*/
module.exports.start = function (emulator_ID, boot_timeout) {
module.exports.start = function (emulatorId, boot_timeout) {
var self = this;
return Promise.resolve().then(function () {
if (emulator_ID) return Promise.resolve(emulator_ID);
if (!emulatorId) {
throw new CordovaError('No emulator ID given');
}
return self.best_image().then(function (best) {
if (best && best.name) {
events.emit('warn', 'No emulator specified, defaulting to ' + best.name);
return best.name;
}
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
return Promise.reject(new CordovaError('No emulator images (avds) found.\n' +
'1. Download desired System Image by running: ' + androidCmd + ' sdk\n' +
'2. Create an AVD by running: ' + androidCmd + ' avd\n' +
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'));
});
}).then(function (emulatorId) {
return self.get_available_port().then(function (port) {
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
// Workaround for https://code.google.com/p/android/issues/detail?id=235461

View File

@@ -41,9 +41,9 @@ const java = {
await java._ensure(process.env);
// Java <= 8 writes version info to stderr, Java >= 9 to stdout
let version = null;
let javacOutput;
try {
version = (await execa('javac', ['-version'], { all: true })).all;
javacOutput = (await execa('javac', ['-version'], { all: true })).all;
} catch (ex) {
events.emit('verbose', ex.shortMessage);
@@ -58,7 +58,11 @@ const java = {
throw new CordovaError(msg);
}
return semver.coerce(version);
// We have to filter the output, because javac prints _JAVA_OPTIONS
// before printing the version which causes semver.coerce to fail to get
// the correct version if those options contain any numbers.
const match = /javac\s+([\d.]+)/i.exec(javacOutput);
return semver.coerce(match && match[1]);
},
/**
@@ -72,14 +76,15 @@ const java = {
return;
}
const javacPath = utils.forgivingWhichSync('javac');
const hasJavaHome = !!environment.JAVA_HOME;
if (hasJavaHome) {
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
if (!javacPath) {
environment.PATH += path.delimiter + path.join(environment.JAVA_HOME, 'bin');
}
const javaHome = environment.CORDOVA_JAVA_HOME || environment.JAVA_HOME;
if (javaHome) {
// Ensure that CORDOVA_JAVA_HOME overrides
environment.JAVA_HOME = javaHome;
// Ensure that the JAVA_HOME bin path is before anything else
// to cover cases where different Java versions is in the PATH
environment.PATH = path.join(environment.JAVA_HOME, 'bin') + path.delimiter + environment.PATH;
} else {
const javacPath = utils.forgivingWhichSync('javac');
if (javacPath) {
// OS X has a command for finding JAVA_HOME.
const find_java = '/usr/libexec/java_home';

View File

@@ -16,11 +16,5 @@
:: under the License.
@ECHO OFF
SET script_path="%~dp0create"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'create' script in 'bin' folder, aborting...>&2
EXIT /B 1
)
for /f "tokens=2*" %%a in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio" /v Path') do set "ASPath=%%~b"
ECHO %ASPath%

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.
*/
const ABS_MODULE_PATH = '/framework/cdv-gradle-config-defaults.json';
try {
// Try relative require first, …
module.exports = require('..' + ABS_MODULE_PATH);
} catch (error) {
// … then fall back to installed-package require
if (error.code !== 'MODULE_NOT_FOUND') throw error;
module.exports = require('cordova-android' + ABS_MODULE_PATH);
}

View File

@@ -32,6 +32,7 @@ var PlatformJson = require('cordova-common').PlatformJson;
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
const utils = require('./utils');
const gradleConfigDefaults = require('./gradle-config-defaults');
const GradlePropertiesParser = require('./config/GradlePropertiesParser');
@@ -55,31 +56,11 @@ module.exports.prepare = function (cordovaProject, options) {
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
// Get the min SDK version from config.xml
const minSdkVersion = this._config.getPreference('android-minSdkVersion', 'android');
const maxSdkVersion = this._config.getPreference('android-maxSdkVersion', 'android');
const targetSdkVersion = this._config.getPreference('android-targetSdkVersion', 'android');
const androidXEnabled = this._config.getPreference('AndroidXEnabled', 'android');
const isGradlePluginKotlinEnabled = this._config.getPreference('GradlePluginKotlinEnabled', 'android');
const gradlePluginKotlinCodeStyle = this._config.getPreference('GradlePluginKotlinCodeStyle', 'android');
// Update Gradle cdv-gradle-config.json
updateUserProjectGradleConfig(this);
const gradlePropertiesUserConfig = {};
if (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion;
if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
if (args.jvmargs) gradlePropertiesUserConfig['org.gradle.jvmargs'] = args.jvmargs;
if (isGradlePluginKotlinEnabled) {
gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
}
// Both 'useAndroidX' and 'enableJetifier' are linked together.
if (androidXEnabled) {
gradlePropertiesUserConfig['android.useAndroidX'] = androidXEnabled;
gradlePropertiesUserConfig['android.enableJetifier'] = androidXEnabled;
}
const gradlePropertiesParser = new GradlePropertiesParser(this.locations.root);
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
// Update Project's Gradle Properties
updateUserProjectGradlePropertiesConfig(this, args);
// Update own www dir with project's www assets and plugins' assets and js-files
return Promise.resolve(updateWww(cordovaProject, this.locations)).then(function () {
@@ -94,6 +75,77 @@ module.exports.prepare = function (cordovaProject, options) {
});
};
/** @param {PlatformApi} project */
function updateUserProjectGradleConfig (project) {
// Generate project gradle config
const projectGradleConfig = {
...gradleConfigDefaults,
...getUserGradleConfig(project._config)
};
// Write out changes
const projectGradleConfigPath = path.join(project.root, 'cdv-gradle-config.json');
fs.writeJSONSync(projectGradleConfigPath, projectGradleConfig, { spaces: 2 });
}
function getUserGradleConfig (configXml) {
const configXmlToGradleMapping = [
{ xmlKey: 'android-minSdkVersion', gradleKey: 'MIN_SDK_VERSION', type: Number },
{ xmlKey: 'android-maxSdkVersion', gradleKey: 'MAX_SDK_VERSION', type: Number },
{ xmlKey: 'android-targetSdkVersion', gradleKey: 'SDK_VERSION', type: Number },
{ xmlKey: 'android-buildToolsVersion', gradleKey: 'BUILD_TOOLS_VERSION', type: String },
{ xmlKey: 'GradleVersion', gradleKey: 'GRADLE_VERSION', type: String },
{ xmlKey: 'AndroidGradlePluginVersion', gradleKey: 'AGP_VERSION', type: String },
{ xmlKey: 'GradlePluginKotlinVersion', gradleKey: 'KOTLIN_VERSION', type: String },
{ xmlKey: 'AndroidXAppCompatVersion', gradleKey: 'ANDROIDX_APP_COMPAT_VERSION', type: String },
{ 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 }
];
return configXmlToGradleMapping.reduce((config, mapping) => {
const rawValue = configXml.getPreference(mapping.xmlKey, 'android');
// ignore missing preferences (which occur as '')
if (rawValue) {
config[mapping.gradleKey] = parseStringAsType(rawValue, mapping.type);
}
return config;
}, {});
}
/** Converts given string to given type */
function parseStringAsType (value, type) {
switch (type) {
case String:
return String(value);
case Number:
return parseFloat(value);
case Boolean:
return value.toLowerCase() === 'true';
default:
throw new CordovaError('Invalid type: ' + type);
}
}
function updateUserProjectGradlePropertiesConfig (project, args) {
const gradlePropertiesUserConfig = {};
// Get the min SDK version from config.xml
if (args.jvmargs) gradlePropertiesUserConfig['org.gradle.jvmargs'] = args.jvmargs;
const isGradlePluginKotlinEnabled = project._config.getPreference('GradlePluginKotlinEnabled', 'android');
if (isGradlePluginKotlinEnabled) {
const gradlePluginKotlinCodeStyle = project._config.getPreference('GradlePluginKotlinCodeStyle', 'android');
gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
}
const gradlePropertiesParser = new GradlePropertiesParser(project.root);
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
}
module.exports.clean = function (options) {
// A cordovaProject isn't passed into the clean() function, because it might have
// been called from the platform shell script rather than the CLI. Check for the
@@ -330,10 +382,13 @@ function makeSplashCleanupMap (projectRoot, resourcesDir) {
function updateSplashes (cordovaProject, platformResourcesDir) {
var resources = cordovaProject.projectConfig.getSplashScreens('android');
// if there are "splash" elements in config.xml
// if there are no "splash" elements in config.xml
if (resources.length === 0) {
events.emit('verbose', 'This app does not have splash screens defined');
return;
// We must not return here!
// If the user defines no splash screens, the cleanup map will cause any
// existing splash screen images (e.g. the defaults that we copy into a
// new app) to be removed from the app folder, which is what we want.
}
// Build an initial resource map that deletes all existing splash screens

83
lib/run.js Normal file
View File

@@ -0,0 +1,83 @@
/*
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.
*/
var emulator = require('./emulator');
const target = require('./target');
const build = require('./build');
const PackageType = require('./PackageType');
const AndroidManifest = require('./AndroidManifest');
const { CordovaError, events } = require('cordova-common');
/**
* Builds a target spec from a runOptions object
*
* @param {{target?: string, device?: boolean, emulator?: boolean}} runOptions
* @return {target.TargetSpec}
*/
function buildTargetSpec (runOptions) {
const spec = {};
if (runOptions.target) {
spec.id = runOptions.target;
} else if (runOptions.device) {
spec.type = 'device';
} else if (runOptions.emulator) {
spec.type = 'emulator';
}
return spec;
}
function formatResolvedTarget ({ id, type }) {
return `${type} ${id}`;
}
/**
* Runs the application on a device if available. If no device is found, it will
* use a started emulator. If no started emulators are found it will attempt
* to start an avd. If no avds are found it will error out.
*
* @param {Object} runOptions various run/build options. See Api.js build/run
* methods for reference.
*
* @return {Promise}
*/
module.exports.run = async function (runOptions = {}) {
const { packageType, buildType } = build.parseBuildOptions(runOptions, null, this.root);
// Android app bundles cannot be deployed directly to the device
if (packageType === PackageType.BUNDLE) {
throw new CordovaError('Package type "bundle" is not supported during cordova run.');
}
const buildResults = this._builder.fetchBuildResults(buildType);
if (buildResults.apkPaths.length === 0) {
throw new CordovaError('Could not find any APKs to deploy');
}
const targetSpec = buildTargetSpec(runOptions);
const resolvedTarget = await target.resolve(targetSpec, buildResults);
events.emit('log', `Deploying to ${formatResolvedTarget(resolvedTarget)}`);
if (resolvedTarget.type === 'emulator') {
await emulator.wait_for_boot(resolvedTarget.id);
}
const manifest = new AndroidManifest(this.locations.manifest);
return target.install(resolvedTarget, { manifest, buildResults });
};

View File

@@ -17,12 +17,11 @@
under the License.
*/
const path = require('path');
const { inspect } = require('util');
const execa = require('execa');
const Adb = require('./Adb');
const build = require('./build');
const emulator = require('./emulator');
const AndroidManifest = require('./AndroidManifest');
const { compareBy } = require('./utils');
const { retryPromise } = require('./retry');
const { events, CordovaError } = require('cordova-common');
@@ -35,6 +34,7 @@ const EXEC_KILL_SIGNAL = 'SIGKILL';
* @typedef { 'device' | 'emulator' } TargetType
* @typedef { { id: string, type: TargetType } } Target
* @typedef { { id?: string, type?: TargetType } } TargetSpec
* @typedef { { apkPaths: string[] } } BuildResults
*/
/**
@@ -73,30 +73,49 @@ async function isEmulatorName (name) {
}
/**
* @param {TargetSpec?} spec
* @param {TargetSpec} spec
* @param {BuildResults} buildResults
* @return {Promise<Target>}
*/
async function resolveToOfflineEmulator (spec = {}) {
if (spec.type === 'device') return null;
if (spec.id && !(await isEmulatorName(spec.id))) return null;
async function resolveToOfflineEmulator ({ id: avdName, type }, { apkPaths }) {
if (type === 'device') return null;
// try to start an emulator with name spec.id
// if spec.id is undefined, picks best match regarding target API
const emulatorId = await emulator.start(spec.id);
if (avdName) {
if (!await isEmulatorName(avdName)) return null;
} else {
events.emit('verbose', 'Looking for emulator image that best matches the target API');
const targetSdk = await getTargetSdkFromApk(apkPaths[0]);
const bestImage = await emulator.best_image(targetSdk);
if (!bestImage) return null;
avdName = bestImage.name;
}
// try to start an emulator with name avdName
const emulatorId = await emulator.start(avdName);
return { id: emulatorId, type: 'emulator' };
}
async function getTargetSdkFromApk (apkPath) {
const { stdout: targetSdkStr } = await execa('apkanalyzer', [
'manifest', 'target-sdk', apkPath
]);
return Number(targetSdkStr);
}
/**
* @param {TargetSpec?} spec
* @param {BuildResults} buildResults
* @return {Promise<Target & {arch: string}>}
*/
exports.resolve = async (spec = {}) => {
exports.resolve = async (spec, buildResults) => {
events.emit('verbose', `Trying to find target matching ${inspect(spec)}`);
const resolvedTarget =
(await resolveToOnlineTarget(spec)) ||
(await resolveToOfflineEmulator(spec));
(await resolveToOfflineEmulator(spec, buildResults));
if (!resolvedTarget) {
throw new CordovaError(`Could not find target matching ${inspect(spec)}`);
@@ -108,9 +127,8 @@ exports.resolve = async (spec = {}) => {
};
};
exports.install = async function ({ id: target, arch, type }, buildResults) {
exports.install = async function ({ id: target, arch, type }, { manifest, buildResults }) {
const apk_path = build.findBestApkForArchitecture(buildResults, arch);
const manifest = new AndroidManifest(path.join(__dirname, '../../app/src/main/AndroidManifest.xml'));
const pkgName = manifest.getPackageId();
const launchName = pkgName + '/.' + manifest.getActivity().getName();

863
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,8 @@
{
"name": "cordova-android",
"version": "9.1.0",
"version": "10.0.1",
"description": "cordova-android release",
"bin": {
"create": "bin/create"
},
"main": "bin/templates/cordova/Api.js",
"main": "lib/Api.js",
"repository": "github:apache/cordova-android",
"bugs": "https://github.com/apache/cordova-android/issues",
"keywords": [
@@ -14,8 +11,9 @@
"apache"
],
"scripts": {
"prepare": "cordova-js build > templates/project/assets/www/cordova.js",
"test": "npm run lint && npm run cover && npm run java-unit-tests",
"lint": "eslint . \"bin/**/!(*.*|gitignore)\"",
"lint": "eslint lib spec test \"templates/cordova/**/!(*.*)\"",
"unit-tests": "jasmine --config=spec/unit/jasmine.json",
"cover": "nyc jasmine --config=spec/coverage.json",
"e2e-tests": "jasmine --config=spec/e2e/jasmine.json",
@@ -25,31 +23,32 @@
"author": "Apache Software Foundation",
"license": "Apache-2.0",
"dependencies": {
"android-versions": "^1.5.0",
"cordova-common": "^4.0.1",
"execa": "^4.0.2",
"fast-glob": "^3.2.4",
"fs-extra": "^9.0.1",
"is-path-inside": "^3.0.2",
"nopt": "^4.0.3",
"android-versions": "^1.7.0",
"cordova-common": "^4.0.2",
"execa": "^5.1.1",
"fast-glob": "^3.2.7",
"fs-extra": "^10.0.0",
"is-path-inside": "^3.0.3",
"nopt": "^5.0.0",
"properties-parser": "^0.3.1",
"semver": "^7.3.4",
"semver": "^7.3.5",
"untildify": "^4.0.0",
"which": "^2.0.2"
},
"devDependencies": {
"@cordova/eslint-config": "^3.0.0",
"jasmine": "^3.5.0",
"jasmine-spec-reporter": "^5.0.2",
"cordova-js": "^6.1.0",
"jasmine": "^3.8.0",
"jasmine-spec-reporter": "^7.0.0",
"nyc": "^15.1.0",
"rewire": "^5.0.0"
},
"engines": {
"node": ">=10.10.0"
"node": ">=12.0.0"
},
"nyc": {
"include": [
"bin/lib/**",
"bin/templates/cordova/**"
"lib"
],
"reporter": [
"lcov",

74
spec/e2e/e2e.spec.js Normal file
View File

@@ -0,0 +1,74 @@
/*
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.
*/
const os = require('os');
const fs = require('fs-extra');
const path = require('path');
const { EventEmitter } = require('events');
const { ConfigParser, PluginInfoProvider } = require('cordova-common');
const Api = require('../../lib/Api');
function makeTempDir () {
const tmpDirTemplate = path.join(os.tmpdir(), 'cordova-android-test-');
return fs.realpathSync(fs.mkdtempSync(tmpDirTemplate));
}
async function makeProject (projectPath) {
const configXmlPath = path.join(__dirname, '../../templates/project/res/xml/config.xml');
const config = new ConfigParser(configXmlPath);
config.setPackageName('io.cordova.testapp');
config.setName('TestApp');
const noopEvents = new EventEmitter();
return Api.createPlatform(projectPath, config, {}, noopEvents);
}
describe('E2E', function () {
let tmpDir, projectPath, api;
beforeEach(async () => {
tmpDir = makeTempDir();
projectPath = path.join(tmpDir, 'project');
api = await makeProject(projectPath);
});
afterEach(() => {
fs.removeSync(tmpDir);
});
it('loads the API from a project directory', async () => {
// Allow test project to find the `cordova-android` module
fs.ensureSymlinkSync(
path.join(__dirname, '../..'),
path.join(tmpDir, 'node_modules/cordova-android'),
'junction'
);
expect(() => {
require(path.join(projectPath, 'cordova/Api.js'));
}).not.toThrow();
});
it('adds a plugin with framework', async () => {
const fakePluginPath = path.join(__dirname, 'fixtures/cordova-plugin-fake');
const pluginInfo = new PluginInfoProvider().get(fakePluginPath);
await expectAsync(api.addPlugin(pluginInfo)).toBeResolved();
});
});

View File

@@ -1,53 +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.
*/
const os = require('os');
const fs = require('fs-extra');
const path = require('path');
const execa = require('execa');
const { PluginInfoProvider } = require('cordova-common');
const createBin = path.join(__dirname, '../../bin/create');
const fakePluginPath = path.join(__dirname, 'fixtures/cordova-plugin-fake');
describe('plugin add', function () {
let tmpDir;
beforeEach(() => {
const tmpDirTemplate = path.join(os.tmpdir(), 'cordova-android-test-');
tmpDir = fs.realpathSync(fs.mkdtempSync(tmpDirTemplate));
});
afterEach(() => {
fs.removeSync(tmpDir);
});
it('Test#001 : create project and add a plugin with framework', function () {
const projectname = 'testpluginframework';
const projectid = 'com.test.plugin.framework';
const projectPath = path.join(tmpDir, projectname);
const pluginInfo = new PluginInfoProvider().get(fakePluginPath);
return Promise.resolve()
.then(() => execa(createBin, [projectPath, projectid, projectname]))
.then(() => {
const Api = require(path.join(projectPath, 'cordova/Api.js'));
return new Api('android', projectPath).addPlugin(pluginInfo);
});
}, 90000);
});

View File

@@ -1,13 +1,13 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example.anis.myapplication"
minSdkVersion 21
targetSdkVersion 29
targetSdkVersion 30
versionCode 1
versionName "1.0"
}

View File

@@ -3,10 +3,10 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:4.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -16,7 +16,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip

View File

@@ -1,7 +0,0 @@
Available Android Virtual Devices:
Name: QWR
Device: Nexus 5 (Google)
Path: /Users/shazron/.android/avd/QWR.avd
Target: Android 7.1.1 (API level 25)
Tag/ABI: google_apis/x86_64
Skin: 1080x1920

Some files were not shown because too many files have changed in this diff Show More