Compare commits
322 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaca570cb6 | ||
|
|
76bac55fba | ||
|
|
6b76757c80 | ||
|
|
fb562f4ed0 | ||
|
|
eaf875b0d6 | ||
|
|
d7afba0ad0 | ||
|
|
ebe6890dee | ||
|
|
172b8448af | ||
|
|
655aa0a5fb | ||
|
|
52578ae770 | ||
|
|
360be21ea5 | ||
|
|
5bca218e5b | ||
|
|
eb5fe4fbda | ||
|
|
46af3114b8 | ||
|
|
76aa938002 | ||
|
|
7d7f511023 | ||
|
|
488c498733 | ||
|
|
e4457f7fdb | ||
|
|
8742cfe4a6 | ||
|
|
af1ae68a97 | ||
|
|
56afb70894 | ||
|
|
1204a79378 | ||
|
|
bf0ba3dd5e | ||
|
|
c2cf589d84 | ||
|
|
0190d2e33a | ||
|
|
df36c7a2c4 | ||
|
|
b79232612b | ||
|
|
60d2842024 | ||
|
|
cab5c5b7ec | ||
|
|
484c60e483 | ||
|
|
72e7148884 | ||
|
|
36bee66493 | ||
|
|
4dcfc361d2 | ||
|
|
c25ed27828 | ||
|
|
d8f6f37737 | ||
|
|
f0e8885693 | ||
|
|
5dc9c72821 | ||
|
|
7a47fe01dc | ||
|
|
08b8a95416 | ||
|
|
6024465814 | ||
|
|
6b8e819f21 | ||
|
|
00744c4f71 | ||
|
|
872d98876e | ||
|
|
855fab238c | ||
|
|
2ffe68ab17 | ||
|
|
f697ca7dec | ||
|
|
1d82a3b52f | ||
|
|
688d2cf5ad | ||
|
|
f6e384a9ea | ||
|
|
839f9b878b | ||
|
|
d4eca414e3 | ||
|
|
5da9bd6d9d | ||
|
|
2258d33a72 | ||
|
|
ca4caf3fc1 | ||
|
|
7ab18487cf | ||
|
|
ff11f659f0 | ||
|
|
aad36fe565 | ||
|
|
7f9529408b | ||
|
|
bb4f86e7b9 | ||
|
|
d0b59863ac | ||
|
|
7544fdf1ed | ||
|
|
8f458b042b | ||
|
|
eb0f002112 | ||
|
|
e012478537 | ||
|
|
b623311efa | ||
|
|
1f349f2984 | ||
|
|
9f5518000f | ||
|
|
92116dee48 | ||
|
|
34220ae0e3 | ||
|
|
1fe44d71c5 | ||
|
|
58c2e3ae15 | ||
|
|
ea045dee63 | ||
|
|
cee7b0b8ac | ||
|
|
6f0efd3a0d | ||
|
|
dff2fc6331 | ||
|
|
1347e48d14 | ||
|
|
5a2c50d1ed | ||
|
|
5eddc460e4 | ||
|
|
3503bfa31b | ||
|
|
d281727113 | ||
|
|
172e947d18 | ||
|
|
2143045d4e | ||
|
|
3c5df42df5 | ||
|
|
c2f315c0ff | ||
|
|
89a0a72da5 | ||
|
|
ed8e5d2f0a | ||
|
|
7fa4a65d0a | ||
|
|
b773ae48f4 | ||
|
|
ebf0b105a3 | ||
|
|
9261b29cf2 | ||
|
|
90e74befc7 | ||
|
|
97806db463 | ||
|
|
4742358601 | ||
|
|
e61e271f5b | ||
|
|
0c805a0a8e | ||
|
|
a7cd4227a4 | ||
|
|
c9e7c59986 | ||
|
|
94234d988e | ||
|
|
b104554877 | ||
|
|
7da13ccf77 | ||
|
|
cb48147398 | ||
|
|
6f6717afbd | ||
|
|
3343c3bb34 | ||
|
|
a62f699380 | ||
|
|
7efe90faac | ||
|
|
5b546a27e6 | ||
|
|
2252c09a49 | ||
|
|
3a9c87d3b8 | ||
|
|
a9d4d4ebd2 | ||
|
|
841710edf7 | ||
|
|
016018513e | ||
|
|
a78fad1783 | ||
|
|
b91639dbb5 | ||
|
|
c2013439bc | ||
|
|
d4bfd5079b | ||
|
|
dbddbf253b | ||
|
|
04723eb8f3 | ||
|
|
862d33694e | ||
|
|
fe3940a73c | ||
|
|
81c678c58d | ||
|
|
bfe086a2d7 | ||
|
|
8fb707567a | ||
|
|
992a60a434 | ||
|
|
2318ef58ad | ||
|
|
968bd85cc3 | ||
|
|
9ef3ee9539 | ||
|
|
5347054efb | ||
|
|
3340e98519 | ||
|
|
ce19a3b445 | ||
|
|
d02f8eafe8 | ||
|
|
56d4b8312b | ||
|
|
80f232aa79 | ||
|
|
954d3e0e75 | ||
|
|
8a1ffeeafd | ||
|
|
7793db97cc | ||
|
|
248257bd37 | ||
|
|
60e3803c67 | ||
|
|
d828785435 | ||
|
|
e5b7e8ab26 | ||
|
|
f38e8eb3d0 | ||
|
|
98895f7d78 | ||
|
|
e968cac0b9 | ||
|
|
861fec2cc7 | ||
|
|
273d1bdecd | ||
|
|
606e9c4826 | ||
|
|
2d2ad4cb81 | ||
|
|
26b21219f7 | ||
|
|
8d6e41fd77 | ||
|
|
262a314c72 | ||
|
|
bf9e4d8aab | ||
|
|
4916e1db51 | ||
|
|
68a9a3181a | ||
|
|
ba032df665 | ||
|
|
53d39fb135 | ||
|
|
4744bfe6bf | ||
|
|
cb494ff9b1 | ||
|
|
bd0c8ce639 | ||
|
|
e73000023b | ||
|
|
087e9e6178 | ||
|
|
a2bb7f1173 | ||
|
|
62ed71c539 | ||
|
|
5704ef9ea5 | ||
|
|
adcd9d9ff8 | ||
|
|
f3c75a89b5 | ||
|
|
21e7c2f661 | ||
|
|
f12080b7e2 | ||
|
|
51291f8985 | ||
|
|
112f0a61a8 | ||
|
|
6d3ce211dd | ||
|
|
f100809bf3 | ||
|
|
a1ed1c0af7 | ||
|
|
05e3e3cf8d | ||
|
|
8a957fb9c9 | ||
|
|
e188c61c86 | ||
|
|
ca19084b1c | ||
|
|
aea6b7f6f4 | ||
|
|
7a67e00b9f | ||
|
|
dc4e065f61 | ||
|
|
c3fd6bca4a | ||
|
|
13bd3f4a9f | ||
|
|
09c75237d9 | ||
|
|
b5e79b5a4d | ||
|
|
5db850890d | ||
|
|
b6c5db3e37 | ||
|
|
cba3410b17 | ||
|
|
565ac9c7b1 | ||
|
|
1636d70f25 | ||
|
|
4e5892c5ed | ||
|
|
e69ab6a687 | ||
|
|
a9171c3db6 | ||
|
|
90271301fb | ||
|
|
c11fcc10e8 | ||
|
|
5e50c1d611 | ||
|
|
38ca895459 | ||
|
|
0ce66249da | ||
|
|
291edcd24e | ||
|
|
4f44036d0a | ||
|
|
6081cc7442 | ||
|
|
7572fc4912 | ||
|
|
9286496378 | ||
|
|
9d3d8d0521 | ||
|
|
636136c88e | ||
|
|
bedb4427f4 | ||
|
|
35f0d07521 | ||
|
|
b94409ffe0 | ||
|
|
adc380cf9f | ||
|
|
7da531ced5 | ||
|
|
3e870e3a04 | ||
|
|
f15fec81cf | ||
|
|
53d60dd707 | ||
|
|
68a302e9d2 | ||
|
|
16ff6e1b2f | ||
|
|
f6d1deeff6 | ||
|
|
1f0ea173b0 | ||
|
|
70a1eff705 | ||
|
|
fb36e03aeb | ||
|
|
8a9cb8f6b7 | ||
|
|
b31e024dbb | ||
|
|
422ce4f6bf | ||
|
|
b8d32d7c60 | ||
|
|
83b3998801 | ||
|
|
180a1a39f0 | ||
|
|
a1ed525a0b | ||
|
|
2037b62f99 | ||
|
|
21f64806c0 | ||
|
|
e8cbeaaa1b | ||
|
|
facffb0809 | ||
|
|
6f35d0b2b7 | ||
|
|
334d02d26e | ||
|
|
69b24dbf6a | ||
|
|
510596f515 | ||
|
|
47aa116b1d | ||
|
|
015db819ae | ||
|
|
01569ce71a | ||
|
|
0f13f4a5ac | ||
|
|
6d803e2f72 | ||
|
|
ae4dba2bb8 | ||
|
|
a45804329b | ||
|
|
1b7874607e | ||
|
|
ff1ae2125a | ||
|
|
f9e8ce8fab | ||
|
|
5e7be8e1d6 | ||
|
|
b2d9d639b4 | ||
|
|
8d407708d4 | ||
|
|
19bbf1e8c1 | ||
|
|
2a84d7c44d | ||
|
|
eeb645c886 | ||
|
|
676f98d82d | ||
|
|
9c3195c1ee | ||
|
|
2a92c77772 | ||
|
|
eefa91b3ea | ||
|
|
6b33772613 | ||
|
|
cab9840a03 | ||
|
|
63b2356575 | ||
|
|
a9ee9196bd | ||
|
|
6588994586 | ||
|
|
46d4d924cc | ||
|
|
dc8854d16c | ||
|
|
a33044921d | ||
|
|
9c165cb94f | ||
|
|
e0d5d14895 | ||
|
|
35bc354531 | ||
|
|
ac4d3d1d45 | ||
|
|
be9abf5f91 | ||
|
|
c04ea9b1c0 | ||
|
|
c774bf3311 | ||
|
|
9071d5131a | ||
|
|
c676ca98ff | ||
|
|
690ff3f364 | ||
|
|
04b0106bca | ||
|
|
31233089f1 | ||
|
|
1f5426f939 | ||
|
|
1ec87634d4 | ||
|
|
d22af021ee | ||
|
|
c9ab33eded | ||
|
|
6dcd67a902 | ||
|
|
cb1cf4dc8e | ||
|
|
6cbf69d109 | ||
|
|
e8ec3b1e37 | ||
|
|
f927014d06 | ||
|
|
19a5feb875 | ||
|
|
9dcf3eb68b | ||
|
|
11364918b2 | ||
|
|
1430304d36 | ||
|
|
2a92c2e595 | ||
|
|
fe4d4aeff0 | ||
|
|
23a1710557 | ||
|
|
774de78691 | ||
|
|
3081e5e6e9 | ||
|
|
7428bd3a7f | ||
|
|
55feadff05 | ||
|
|
97e2d15634 | ||
|
|
b245337501 | ||
|
|
bb7d733cde | ||
|
|
aa679ea1d6 | ||
|
|
0e8234abfd | ||
|
|
d5b9029a23 | ||
|
|
671e1fd1c6 | ||
|
|
c144c08112 | ||
|
|
aada3e813d | ||
|
|
335b0f2575 | ||
|
|
b1f01d7a65 | ||
|
|
3b56160d38 | ||
|
|
39e315628e | ||
|
|
e125ab1b9a | ||
|
|
5d3591b853 | ||
|
|
206238893b | ||
|
|
33476b4754 | ||
|
|
2c888f418b | ||
|
|
565106fc1f | ||
|
|
a45217e6b9 | ||
|
|
d7790ca8bc | ||
|
|
8ef8d994df | ||
|
|
80ad635348 | ||
|
|
ec944cf068 | ||
|
|
ba5781c3bf | ||
|
|
d86cb99dd5 | ||
|
|
3204b9804b | ||
|
|
ce735256d3 | ||
|
|
cccf812454 | ||
|
|
f7e1979665 | ||
|
|
49fc5da207 |
24
.asf.yaml
@@ -15,6 +15,30 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
github:
|
||||
description: Apache Cordova Android
|
||||
homepage: https://cordova.apache.org/
|
||||
|
||||
labels:
|
||||
- cordova
|
||||
- cordova-platform
|
||||
- android
|
||||
- java
|
||||
- mobile
|
||||
- javascript
|
||||
- nodejs
|
||||
- hacktoberfest
|
||||
|
||||
features:
|
||||
wiki: false
|
||||
issues: true
|
||||
projects: true
|
||||
|
||||
enabled_merge_buttons:
|
||||
squash: true
|
||||
merge: false
|
||||
rebase: false
|
||||
|
||||
notifications:
|
||||
commits: commits@cordova.apache.org
|
||||
issues: issues@cordova.apache.org
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
bin/templates/project/assets/www/cordova.js
|
||||
test/android/app
|
||||
test/androidx/app
|
||||
20
.gitattributes
vendored
@@ -1,3 +1,20 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
* text eol=lf
|
||||
|
||||
# source code
|
||||
@@ -23,7 +40,7 @@
|
||||
*.scm text
|
||||
*.sql text
|
||||
*.sh text
|
||||
*.bat text
|
||||
*.bat text eol=crlf
|
||||
|
||||
# templates
|
||||
*.ejs text
|
||||
@@ -92,3 +109,4 @@ AUTHORS text
|
||||
*.woff binary
|
||||
*.pyc binary
|
||||
*.pdf binary
|
||||
*.jar binary
|
||||
|
||||
57
.github/workflows/ci.yml
vendored
@@ -6,18 +6,28 @@
|
||||
# "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
|
||||
# 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
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
name: Node CI
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -27,21 +37,19 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
node-version: [20.x, 22.x, 24.x]
|
||||
os: [ubuntu-latest, windows-latest, macos-15]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: 1.8
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: Environment Information
|
||||
run: |
|
||||
@@ -49,6 +57,21 @@ jobs:
|
||||
npm --version
|
||||
gradle --version
|
||||
|
||||
# "bin/templates/platform_www/cordova.js" is ignored because it is a generated file.
|
||||
# It contains mixed content from the npm package "cordova-js" and "./cordova-js-src".
|
||||
# The report might not be resolvable because of the external package.
|
||||
# If the report is related to this repository, it would be detected when scanning "./cordova-js-src".
|
||||
- uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: javascript, java-kotlin
|
||||
queries: security-and-quality
|
||||
config: |
|
||||
paths-ignore:
|
||||
- coverage
|
||||
- node_modules
|
||||
- templates/project/assets/www/cordova.js
|
||||
- test/androidx/app/src/main/assets/www/cordova.js
|
||||
|
||||
- name: npm install and test
|
||||
run: |
|
||||
npm i
|
||||
@@ -56,6 +79,12 @@ jobs:
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- uses: codecov/codecov-action@v1
|
||||
- uses: github/codeql-action/analyze@v3
|
||||
|
||||
# v4.6.0
|
||||
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238
|
||||
if: success()
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
name: ${{ runner.os }} node.js ${{ matrix.node-version }}
|
||||
token: ${{ secrets.CORDOVA_CODECOV_TOKEN }}
|
||||
fail_ci_if_error: false
|
||||
|
||||
55
.github/workflows/release-audit.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
name: Release Auditing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Audit Licenses
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout project
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Check license headers (v2.0.0)
|
||||
- uses: erisu/apache-rat-action@46fb01ce7d8f76bdcd7ab10e7af46e1ea95ca01c
|
||||
|
||||
# Setup environment with node
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
# Install node packages
|
||||
- name: npm install packages
|
||||
run: npm ci
|
||||
|
||||
# Check node package licenses (v2.0.1)
|
||||
- uses: erisu/license-checker-action@99cffa11264fe545fd0baa6c13bca5a00ae608f2
|
||||
with:
|
||||
license-config: 'licence_checker.yml'
|
||||
include-asf-category-a: true
|
||||
34
.gitignore
vendored
@@ -1,3 +1,20 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
.DS_Store
|
||||
.gradle
|
||||
.metadata
|
||||
@@ -25,15 +42,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/androidx/repositories.gradle
|
||||
/test/androidx/app/repositories.gradle
|
||||
/test/androidx/tools
|
||||
/test/androidx/build
|
||||
/test/assets/www/.tmp*
|
||||
/test/assets/www/cordova.js
|
||||
/test/bin
|
||||
@@ -49,7 +66,6 @@ tmp/**/*
|
||||
npm-debug.log
|
||||
node_modules/
|
||||
coverage/
|
||||
.nyc_output/
|
||||
# Eclipse Buildship files
|
||||
.project
|
||||
.settings
|
||||
|
||||
18
.npmignore
@@ -1,5 +1,23 @@
|
||||
# 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.
|
||||
|
||||
.*
|
||||
coverage
|
||||
test
|
||||
spec
|
||||
framework/build
|
||||
cordova-js-src
|
||||
|
||||
@@ -15,13 +15,4 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
extends: '@cordova/eslint-config/node'
|
||||
|
||||
overrides:
|
||||
- files: [spec/**/*.js]
|
||||
extends: '@cordova/eslint-config/node-tests'
|
||||
rules:
|
||||
prefer-promise-reject-errors: off
|
||||
|
||||
- files: [cordova-js-src/**/*.js]
|
||||
extends: '@cordova/eslint-config/browser'
|
||||
registry=https://registry.npmjs.org
|
||||
35
.ratignore
@@ -1,8 +1,27 @@
|
||||
*.properties
|
||||
bin
|
||||
gen
|
||||
proguard-project.txt
|
||||
spec
|
||||
framework/build
|
||||
ic_launcher.png
|
||||
build
|
||||
# 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.
|
||||
|
||||
.git/
|
||||
coverage/
|
||||
framework/build/
|
||||
node_modules/
|
||||
spec/fixtures/
|
||||
templates/project/gitignore
|
||||
test/androidx/app/.gitignore
|
||||
test/androidx/app/build/
|
||||
test/androidx/build/
|
||||
test/androidx/tools/
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#
|
||||
# Settings for post-review (used for uploading diffs to reviews.apache.org).
|
||||
#
|
||||
|
||||
66
LICENSE
@@ -187,7 +187,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2015-2020 Apache Cordova
|
||||
Copyright 2015-2024 Apache Cordova
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -201,67 +201,3 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
ADDITIONAL LICENSES:
|
||||
|
||||
================================================================================
|
||||
bin/node_modules/q
|
||||
================================================================================
|
||||
|
||||
Copyright 2009–2017 Kristopher Michael Kowal. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
================================================================================
|
||||
bin/node_modules/nopt
|
||||
================================================================================
|
||||
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
================================================================================
|
||||
bin/node_modules/which
|
||||
================================================================================
|
||||
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
64
README.md
@@ -28,36 +28,58 @@
|
||||
|
||||
Cordova Android is an Android application library that allows for Cordova-based projects to be built for the Android Platform. Cordova based applications are, at the core, applications written with web technology: HTML, CSS and JavaScript.
|
||||
|
||||
[Apache Cordova](https://cordova.apache.org) is a project of The Apache Software Foundation (ASF).
|
||||
[Apache Cordova](https://cordova.apache.org/) is a project of [The Apache Software Foundation (ASF)](https://apache.org/).
|
||||
|
||||
## Requires
|
||||
## Requirements
|
||||
|
||||
- Java JDK 1.8
|
||||
- Android SDK [http://developer.android.com](https://developer.android.com/)
|
||||
* Java Development Kit (JDK) 17
|
||||
* [Android SDK](https://developer.android.com/)
|
||||
* [Node.js](https://nodejs.org)
|
||||
|
||||
## Cordova Android Developer Tools
|
||||
## Create a Cordova project
|
||||
|
||||
We recommend using the [Cordova command-line tool](https://www.npmjs.com/package/cordova) to create projects and be able to easily install plugins.
|
||||
Follow the instructions in the [**Create your first Cordova app**](https://cordova.apache.org/docs/en/latest/guide/cli/index.html) section of [Apache Cordova Docs](https://cordova.apache.org/docs/en/latest/)
|
||||
|
||||
However, the following scripts can be used instead:
|
||||
To use a **shared framework**, for example in development, link the appropriate cordova-android platform folder path:
|
||||
|
||||
./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
|
||||
```bash
|
||||
cordova platform add --link /path/to/cordova-android
|
||||
```
|
||||
|
||||
These commands live in a generated Cordova Android project. Any interactions with the emulator require you to have an AVD defined.
|
||||
## Updating a Cordova project
|
||||
|
||||
./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
|
||||
When you install a new version of the [`Cordova CLI`](https://www.npmjs.com/package/cordova) that pins a new version of the [`Cordova-Android`](https://www.npmjs.com/package/cordova-android) platform, you can follow these simple upgrade steps within your project:
|
||||
|
||||
## Using Android Studio
|
||||
```bash
|
||||
cordova platform rm android
|
||||
cordova platform add android
|
||||
```
|
||||
|
||||
1. Create a project
|
||||
2. Import it via "Non-Android Studio Project"
|
||||
## Debugging in Android Studio
|
||||
|
||||
## Running the Native Tests
|
||||
Import project in Android Studio through _File > Open_ and targeting `/path/to/your-cdv-project/platforms/android/`.
|
||||
|
||||
The `test/` directory in this project contains an Android test project that can be used to run different kinds of native tests. Check out the [README contained therein](test/README.md) for more details!
|
||||
## How to Test Repo Development
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm test
|
||||
```
|
||||
|
||||
## Install Nightly Build
|
||||
|
||||
```bash
|
||||
cordova platform add android@nightly
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
Nightly builds are **not recommended for production apps**. They are intended for testing purposes. This allows users either to check if recent changes in the main branch have fixed existing issues or to identify new bugs before an official release.
|
||||
|
||||
Nightly builds are generated daily and may be **unstable**.
|
||||
|
||||
See [Apache Cordova - Nightly Builds](https://cordova.apache.org/contribute/nightly_builds.html) for more details.
|
||||
|
||||
## Further reading
|
||||
|
||||
* [Apache Cordova](https://cordova.apache.org/)
|
||||
|
||||
412
RELEASENOTES.md
@@ -20,6 +20,386 @@
|
||||
-->
|
||||
## Release Notes for Cordova (Android)
|
||||
|
||||
### 14.0.1 (Apr 24, 2025)
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1795](https://github.com/apache/cordova-android/pull/1795) fix: configure gradle `java.home`
|
||||
* [GH-1793](https://github.com/apache/cordova-android/pull/1793) fix(windows): get gradle path with `which` command
|
||||
|
||||
### 14.0.0 (Mar 23, 2025)
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
* [GH-1788](https://github.com/apache/cordova-android/pull/1788) dep!: bump npm packages
|
||||
* nyc@17.1.0
|
||||
* which@5.0.0
|
||||
* semver@7.7.1
|
||||
* jasmine@5.6.0
|
||||
* android-versions@2.1.0
|
||||
* cordova-common@5.0.1
|
||||
* fast-glob@3.3.3
|
||||
* nopt@8.1.0
|
||||
* [GH-1789](https://github.com/apache/cordova-android/pull/1789) feat!: bump node engine requirement `>=20.5.0`
|
||||
* [GH-1784](https://github.com/apache/cordova-android/pull/1784) feat!: bump java default targets to 11
|
||||
* [GH-1771](https://github.com/apache/cordova-android/pull/1771) feat!: deprecate CordovaPlugin's method initialize
|
||||
* [GH-1767](https://github.com/apache/cordova-android/pull/1767) feat!: use kotlin-stdlib instead of kotlin-stdlib-jdk*
|
||||
* [GH-1763](https://github.com/apache/cordova-android/pull/1763) feat!: SDK 35 Support
|
||||
|
||||
**Features:**
|
||||
|
||||
* [GH-1785](https://github.com/apache/cordova-android/pull/1785) feat: bump gradle to 8.13
|
||||
* [GH-1779](https://github.com/apache/cordova-android/pull/1779) feat: add `AndroidEdgeToEdge` preference & theme flag
|
||||
* [GH-1778](https://github.com/apache/cordova-android/pull/1778) feat: Account for Node security patch
|
||||
* [GH-1768](https://github.com/apache/cordova-android/pull/1768) feat: `androidx.core:core-splashscreen@1.0.1`
|
||||
* [GH-1766](https://github.com/apache/cordova-android/pull/1766) feat: `com.google.gms:google-services@4.4.2`
|
||||
* [GH-1765](https://github.com/apache/cordova-android/pull/1765) feat: `androidx.webkit:webkit@1.12.1`
|
||||
* [GH-1764](https://github.com/apache/cordova-android/pull/1764) feat: `androidx.appcompat:appcompat@1.7.0`
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1790](https://github.com/apache/cordova-android/pull/1790) fix: replace fs-extra.ensureFileSync with fs.writeFileSync
|
||||
* [GH-1781](https://github.com/apache/cordova-android/pull/1781) fix: copy gradle wrapper from tools to platform root dir
|
||||
* [GH-1770](https://github.com/apache/cordova-android/pull/1770) fix: creation of cdv-gradle-config.json w/ --link flag
|
||||
* [GH-1739](https://github.com/apache/cordova-android/pull/1739) fix(docs): Incorrect JDK requirement stated in README
|
||||
* [GH-1718](https://github.com/apache/cordova-android/pull/1718) fix: app restart when BT keyboard is connected in some devices
|
||||
|
||||
**Chores & Refactoring:**
|
||||
|
||||
* [GH-1786](https://github.com/apache/cordova-android/pull/1786) chore: add AndroidX build test to gitignore
|
||||
* [GH-1774](https://github.com/apache/cordova-android/pull/1774) style: update & resolve doc block warnings
|
||||
* [GH-1772](https://github.com/apache/cordova-android/pull/1772) refactor: replace fs-extra with node:fs
|
||||
* [GH-1769](https://github.com/apache/cordova-android/pull/1769) refactor: prefix node:*
|
||||
* [GH-1748](https://github.com/apache/cordova-android/pull/1748) chore(deps): bump cross-spawn from 7.0.3 to 7.0.6
|
||||
* [GH-1750](https://github.com/apache/cordova-android/pull/1750) chore(ci): Fix dependabot PR failures
|
||||
* [GH-1736](https://github.com/apache/cordova-android/pull/1736) chore(deps): bump micromatch from 4.0.5 to 4.0.8
|
||||
* [GH-1716](https://github.com/apache/cordova-android/pull/1716) chore(deps): bump braces from 3.0.2 to 3.0.3
|
||||
|
||||
### 13.0.0 (May 15, 2024)
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
* [GH-1678](https://github.com/apache/cordova-android/pull/1678) feat!: API 34 Support
|
||||
* [GH-1543](https://github.com/apache/cordova-android/pull/1543) feat!: bump `kotlin@1.9.24` & drop `kotlin-android-extensions` when kotlin `>=1.8.0`
|
||||
|
||||
**Features:**
|
||||
|
||||
* [GH-1700](https://github.com/apache/cordova-android/pull/1700) feat(splash): Support `SplashScreenBackgroundColor` preference
|
||||
* [GH-1609](https://github.com/apache/cordova-android/pull/1609) feat: add camera intent with file input capture
|
||||
* [GH-1696](https://github.com/apache/cordova-android/pull/1696) feat: Add `ResolveServiceWorkerRequests` preference
|
||||
|
||||
**Chores, Dependencies & CI:**
|
||||
|
||||
* [GH-1677](https://github.com/apache/cordova-android/pull/1677) chore(deps-dev): bump `@babel/traverse` from `7.22.10` to `7.23.2`
|
||||
* [GH-1713](https://github.com/apache/cordova-android/pull/1713) dep: bump npm dependencies 20240515
|
||||
* `semver@7.6.2`
|
||||
* `rewire@7.0.0`
|
||||
* `nopt@7.2.1`
|
||||
* `jasmine@5.1.0`
|
||||
* `fs-extra@11.2.0`
|
||||
* `fast-glob@3.3.2`
|
||||
* `dedent@1.5.3`
|
||||
* `@cordova/eslint-config@5.1.0`
|
||||
* `which@4.0.0`
|
||||
* `properties-parser@0.6.0`
|
||||
* `android-versions@2.0.0`
|
||||
* [GH-1711](https://github.com/apache/cordova-android/pull/1711) ci: Set up CodeQL analysis w/ fixes
|
||||
* [GH-1687](https://github.com/apache/cordova-android/pull/1687) ci(release-audit): add license header and dependency checker
|
||||
* [GH-1703](https://github.com/apache/cordova-android/pull/1703) ci: update `codecov@v4` w/ token
|
||||
|
||||
### 12.0.1 (Aug 23, 2023)
|
||||
|
||||
* [GH-1632](https://github.com/apache/cordova-android/pull/1632) fix(android): `monochrome` checks
|
||||
* [GH-1649](https://github.com/apache/cordova-android/pull/1649) chore: rebuild `package-lock` w/ lint corrections
|
||||
|
||||
### 12.0.0 (May 20, 2023)
|
||||
|
||||
**Breaking:**
|
||||
|
||||
* [GH-1605](https://github.com/apache/cordova-android/pull/1605) fix!: Make `CoreAndroid` plugin instantiate on load
|
||||
* [GH-1539](https://github.com/apache/cordova-android/pull/1539) feat!: bump Gradle 7.6 & AGP 7.4.2
|
||||
* [GH-1571](https://github.com/apache/cordova-android/pull/1571) feat!: bump min SDK to 24
|
||||
* [GH-1538](https://github.com/apache/cordova-android/pull/1538) feat!: bump target sdk & build tools for SDK 33 support
|
||||
* [GH-1540](https://github.com/apache/cordova-android/pull/1540) feat!: bump node engine requirement `>=16.13.0`
|
||||
* [GH-1597](https://github.com/apache/cordova-android/pull/1597) deprecate: `CoreAndroid.getBuildConfigValue`
|
||||
* [GH-1541](https://github.com/apache/cordova-android/pull/1541) dep(npm)!: bump acceptable modules w/ rebuilt `package-lock`
|
||||
* [GH-1566](https://github.com/apache/cordova-android/pull/1566) dep(npm)!: bump `cordova-common@5.0.0`
|
||||
|
||||
**Features:**
|
||||
|
||||
* [GH-1602](https://github.com/apache/cordova-android/pull/1602) feat: add `listTarget` api
|
||||
* [GH-1574](https://github.com/apache/cordova-android/pull/1574) feat: add plugin hooks for `WebViewClient.onRenderProcessGone`
|
||||
* [GH-1594](https://github.com/apache/cordova-android/pull/1594) feat: bump default `kotlin` to version 1.7.21
|
||||
* [GH-1550](https://github.com/apache/cordova-android/pull/1550) feat: add `monochrome` app icon support
|
||||
* [GH-1589](https://github.com/apache/cordova-android/pull/1589) feat: `InspectableWebview` preference
|
||||
* [GH-1568](https://github.com/apache/cordova-android/pull/1568) feat: bump `androidx.appcompat.appcompat` 1.6.1
|
||||
* [GH-1567](https://github.com/apache/cordova-android/pull/1567) feat: bump `androidx.webkit.webkit` 1.6.0
|
||||
* [GH-1545](https://github.com/apache/cordova-android/pull/1545) feat: bump `androidx.webkit.webkit` 1.5.0
|
||||
* [GH-1547](https://github.com/apache/cordova-android/pull/1547) feat: bump `com.google.gms.google-services` 4.3.15
|
||||
* [GH-1546](https://github.com/apache/cordova-android/pull/1546) feat: bump `androidx.core.core-splashscreen` 1.0.0
|
||||
* [GH-1544](https://github.com/apache/cordova-android/pull/1544) feat: bump `androidx.appcompat.appcompat` 1.5.1
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1606](https://github.com/apache/cordova-android/pull/1606) fix: Gradle Args parsing
|
||||
* [GH-1575](https://github.com/apache/cordova-android/pull/1575) fix(`BuildHelper`): get package name from `ApplicationInfo`
|
||||
* [GH-1595](https://github.com/apache/cordova-android/pull/1595) fix(test): Native test namespace refactor
|
||||
* [GH-1471](https://github.com/apache/cordova-android/pull/1471) fix: `ANDROID_HOME` is the new default, to check first and give advice
|
||||
* [GH-1573](https://github.com/apache/cordova-android/pull/1573) fix(GH-1432): Default `content` `src` when content tag is missing
|
||||
* [GH-1506](https://github.com/apache/cordova-android/pull/1506) fix: only do fadeout animation if `FadeSplashScreen` is true
|
||||
* [GH-1505](https://github.com/apache/cordova-android/pull/1505) fix: correctly flag API dependency on `AppCompat` for Maven
|
||||
* [GH-1487](https://github.com/apache/cordova-android/pull/1487) fix: Add **Android** prefix to `WindowSplashScreenBrandingImage`
|
||||
* [GH-1489](https://github.com/apache/cordova-android/pull/1489) fix: import type definitions from obsolete `cordova-plugin-splashscreen`
|
||||
|
||||
**Chores, Refactor, Dependencies & CI:**
|
||||
|
||||
* [GH-1493](https://github.com/apache/cordova-android/pull/1493) chore: add `lint:fix` script for fixing lint errors
|
||||
* [GH-1491](https://github.com/apache/cordova-android/pull/1491) chore: Use gradle 7.4.2 distribution url
|
||||
* [GH-1588](https://github.com/apache/cordova-android/pull/1588) refactor: Removed obsolete version code checks
|
||||
* [GH-1492](https://github.com/apache/cordova-android/pull/1492) refactor: replace deprecated `Handler` constructor
|
||||
* [GH-1587](https://github.com/apache/cordova-android/pull/1587) dep: bump npm dependencies
|
||||
* `fs-extra@11.1.1`
|
||||
* `nopt@7.1.0`
|
||||
* `@cordova/eslint-config@5.0.0`
|
||||
* `jasmine@4.6.0`
|
||||
* [GH-1607](https://github.com/apache/cordova-android/pull/1607) ci: Added NodeJS 20.x to the workflow matrix
|
||||
* [GH-1542](https://github.com/apache/cordova-android/pull/1542) ci(workflow): update `codecov/codecov-action@v3`
|
||||
* [GH-1532](https://github.com/apache/cordova-android/pull/1532) ci: update `codecov/codecov-action` reporting format
|
||||
|
||||
### 11.0.0 (Jul 04, 2022)
|
||||
|
||||
**Breaking:**
|
||||
|
||||
* [GH-1441](https://github.com/apache/cordova-android/pull/1441) feat!: **Android** 12 splash screen
|
||||
* [GH-1427](https://github.com/apache/cordova-android/pull/1427) feat!: API 32 support
|
||||
* [GH-1410](https://github.com/apache/cordova-android/pull/1410) feat!: API 31 support
|
||||
* [GH-1444](https://github.com/apache/cordova-android/pull/1444) fix!: set & use `ANDROID_HOME` as default
|
||||
* [GH-1411](https://github.com/apache/cordova-android/pull/1411) chore!: Drop Node 12 support
|
||||
|
||||
**Features:**
|
||||
|
||||
* [GH-1448](https://github.com/apache/cordova-android/pull/1448) feat: Update `androidx.appcompat` version
|
||||
* [GH-1446](https://github.com/apache/cordova-android/pull/1446) feat: Update gradle plugin version
|
||||
* [GH-1447](https://github.com/apache/cordova-android/pull/1447) feat: Update google services pluging
|
||||
* [GH-1431](https://github.com/apache/cordova-android/pull/1431) feat: support custom `compileSdk` setting
|
||||
* [GH-1311](https://github.com/apache/cordova-android/pull/1311) feat: added support for BoM imports
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1455](https://github.com/apache/cordova-android/pull/1455) fix(`prepare`): `destFile` path separator
|
||||
* [GH-1453](https://github.com/apache/cordova-android/pull/1453) fix: support installing platfrom from local git checkout
|
||||
* [GH-1449](https://github.com/apache/cordova-android/pull/1449) fix: accept file cookies only if `AndroidInsecureFileModeEnabled`
|
||||
* [GH-1443](https://github.com/apache/cordova-android/pull/1443) fix: force `hostname` to lowercase
|
||||
* [GH-1434](https://github.com/apache/cordova-android/pull/1434) fix: restore `checkReqs` in `prepare.js`
|
||||
* [GH-1154](https://github.com/apache/cordova-android/pull/1154) fix: move `MainActivity.java` to folder that tracks the app package name (widget id)
|
||||
|
||||
**Chores, Dependencies & CI:**
|
||||
|
||||
* [GH-1451](https://github.com/apache/cordova-android/pull/1451) chore: display warning on deprecated `<splash>` tag usage
|
||||
* [GH-1430](https://github.com/apache/cordova-android/pull/1430) chore: remove unneeded deprecated annotation
|
||||
* [GH-1421](https://github.com/apache/cordova-android/pull/1421) chore(npm): bump `@cordova/eslint-config@^4.0.0`
|
||||
* [GH-1420](https://github.com/apache/cordova-android/pull/1420) chore(npm): bump dependencies
|
||||
* [GH-1452](https://github.com/apache/cordova-android/pull/1452) dep: bump `jasmine@4.2.1` w/ `package-lock` rebuild
|
||||
* [GH-1439](https://github.com/apache/cordova-android/pull/1439) ci: update github action workflow
|
||||
* [GH-1424](https://github.com/apache/cordova-android/pull/1424) ci: Added Node 18 to test matrix
|
||||
|
||||
### 10.1.2 (Apr 11, 2022)
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1372](https://github.com/apache/cordova-android/pull/1372) fix(`AndroidManifest`): explicitly define the `activity` attribute `android:exported`
|
||||
* [GH-1406](https://github.com/apache/cordova-android/pull/1406) fix: detect `JAVA_HOME` with Java 11
|
||||
* [GH-1401](https://github.com/apache/cordova-android/pull/1401) fix(GH-1391): Reword minimum build tools version to make it more clear what is actually required.
|
||||
* [GH-1384](https://github.com/apache/cordova-android/pull/1384) fix: escape `strings.xml` app name
|
||||
|
||||
**Chores:**
|
||||
|
||||
* [GH-1413](https://github.com/apache/cordova-android/pull/1413) chore: update `package-lock` to satisfy `npm audit`
|
||||
* [GH-1348](https://github.com/apache/cordova-android/pull/1348) chore: `npmrc`
|
||||
|
||||
### 10.1.1 (Sep 13, 2021)
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1349](https://github.com/apache/cordova-android/pull/1349) fix(`PluginManager`): `AllowNavigation` default policy to handle scheme & hostname
|
||||
* [GH-1342](https://github.com/apache/cordova-android/pull/1342) fix(`AllowListPlugin`): Safely handle default allow navigation policy in allow request
|
||||
* [GH-1332](https://github.com/apache/cordova-android/pull/1332) fix(`PluginManager`): `AllowBridgeAccess` default policy to handle scheme & hostname
|
||||
|
||||
### 10.1.0 (Aug 13, 2021)
|
||||
|
||||
**Features:**
|
||||
|
||||
* [GH-1213](https://github.com/apache/cordova-android/pull/1213) feat: unify `create` default values & stop project name transform
|
||||
* [GH-1306](https://github.com/apache/cordova-android/pull/1306) feat: bump `ANDROIDX_APP_COMPAT@1.3.1`
|
||||
* [GH-1303](https://github.com/apache/cordova-android/pull/1303) feat: bump `Google Services Gradle Plugin@4.3.8`
|
||||
* [GH-1302](https://github.com/apache/cordova-android/pull/1302) feat: bump `kotlin@1.5.21`
|
||||
* [GH-1298](https://github.com/apache/cordova-android/pull/1298) feat: support `http` w/ `content` `src` fix
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1214](https://github.com/apache/cordova-android/pull/1214) fix: display project name in Android Studio
|
||||
* [GH-1300](https://github.com/apache/cordova-android/pull/1300) fix: fall back to project root `repositories.gradle`
|
||||
|
||||
**Docs:**
|
||||
|
||||
* [GH-1308](https://github.com/apache/cordova-android/pull/1308) doc: update `README` about development & testing
|
||||
|
||||
### 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:**
|
||||
|
||||
* [GH-1104](https://github.com/apache/cordova-android/pull/1104) feat: support `gzip` encoding requests & use `GZIPInputStream`
|
||||
* [GH-1167](https://github.com/apache/cordova-android/pull/1167) feat: handle `intent://` scheme links with `browser_fallback_url` param
|
||||
* [GH-1179](https://github.com/apache/cordova-android/pull/1179) feat: add `repositories` support
|
||||
* [GH-1173](https://github.com/apache/cordova-android/pull/1173) feat(android-studio): display app name as project name
|
||||
* [GH-1113](https://github.com/apache/cordova-android/pull/1113) feat: `webp` support for splashscreen
|
||||
* [GH-1125](https://github.com/apache/cordova-android/pull/1125) feat(Adb): list `devices` _and_ `emulators` in one go
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1186](https://github.com/apache/cordova-android/pull/1186) fix: copy `repositories.gradle` to project on create
|
||||
* [GH-1184](https://github.com/apache/cordova-android/pull/1184) fix: unit-test failure
|
||||
* [GH-733](https://github.com/apache/cordova-android/pull/733) fix(splashscreen): nav & title bar showing in fullscreen mode
|
||||
* [GH-1157](https://github.com/apache/cordova-android/pull/1157) fix: restore key event handlers when DOM element is fullscreen
|
||||
* [GH-1073](https://github.com/apache/cordova-android/pull/1073) fix(android): Avoid Crash Report: ConcurrentModificationException
|
||||
* [GH-1148](https://github.com/apache/cordova-android/pull/1148) fix: add not null checks to prevent running on destroyed activity
|
||||
* [GH-1091](https://github.com/apache/cordova-android/pull/1091) fix: concurrent modification exception (#924)
|
||||
* [GH-1153](https://github.com/apache/cordova-android/pull/1153) fix: optional arch parameter
|
||||
* [GH-1136](https://github.com/apache/cordova-android/pull/1136) fix(prepare): `mapImageResources` always returning `[]`
|
||||
* [GH-1111](https://github.com/apache/cordova-android/pull/1111) fix(android): allow file access for existing behavior
|
||||
* [GH-1045](https://github.com/apache/cordova-android/pull/1045) fix: Reflect minimum required NodeJS
|
||||
* [GH-1084](https://github.com/apache/cordova-android/pull/1084) fix(prepare): fix pattern used to collect image resources
|
||||
* [GH-1014](https://github.com/apache/cordova-android/pull/1014) fix(`pluginHandlers`): properly check if path is inside another
|
||||
* [GH-1018](https://github.com/apache/cordova-android/pull/1018) fix: gradle ignore properties
|
||||
* [GH-1185](https://github.com/apache/cordova-android/pull/1185) fix(regression): Cannot read version of undefined caused by Java refactor
|
||||
* [GH-1117](https://github.com/apache/cordova-android/pull/1117) fix: allow changing min sdk version
|
||||
|
||||
**Refactors:**
|
||||
|
||||
* [GH-1101](https://github.com/apache/cordova-android/pull/1101) refactor: unify target resolution for devices & emulators
|
||||
* [GH-1130](https://github.com/apache/cordova-android/pull/1130) refactor: java checks
|
||||
* [GH-1099](https://github.com/apache/cordova-android/pull/1099) refactor(`ProjectBuilder`): clean up output file collection code
|
||||
* [GH-1123](https://github.com/apache/cordova-android/pull/1123) refactor: unify installation on devices & emulators
|
||||
* [GH-1102](https://github.com/apache/cordova-android/pull/1102) refactor(`check_reqs`): cleanup default Java location detection on **Windows**
|
||||
* [GH-1103](https://github.com/apache/cordova-android/pull/1103) refactor: do not kill adb on UNIX-like systems
|
||||
* [GH-1086](https://github.com/apache/cordova-android/pull/1086) refactor(retry): simplify retryPromise using modern JS
|
||||
* [GH-1085](https://github.com/apache/cordova-android/pull/1085) refactor(utils): reduce number of utils
|
||||
* [GH-1046](https://github.com/apache/cordova-android/pull/1046) refactor: Stop suppressing un-needed TruelyRandom lints
|
||||
* [GH-1016](https://github.com/apache/cordova-android/pull/1016) refactor: save `ProjectBuilder` instance in Api instance
|
||||
* [GH-1108](https://github.com/apache/cordova-android/pull/1108) refactor: remove copied Adb.install from `emulator.install`
|
||||
|
||||
**Chores:**
|
||||
|
||||
* [GH-1196](https://github.com/apache/cordova-android/pull/1196) chore: add missing header license
|
||||
* chore(asf): Update GitHub repo metadata
|
||||
* [GH-1183](https://github.com/apache/cordova-android/pull/1183) chore: rebuilt package-lock
|
||||
* [GH-1015](https://github.com/apache/cordova-android/pull/1015) chore: remove unnecessary stuff
|
||||
* [GH-1081](https://github.com/apache/cordova-android/pull/1081) chore(pkg): remove deprecated `no-op` field `"engineStrict"`
|
||||
* [GH-1019](https://github.com/apache/cordova-android/pull/1019) chore: remove unused `emulator.create_image` and its dependencies
|
||||
|
||||
**Tests & CI:**
|
||||
|
||||
* [GH-1017](https://github.com/apache/cordova-android/pull/1017) test(java): fix, improve and move clean script
|
||||
* [GH-1012](https://github.com/apache/cordova-android/pull/1012) test: fix missing stack traces in jasmine output
|
||||
* [GH-1013](https://github.com/apache/cordova-android/pull/1013) test(`pluginHandlers/common`): better setup & teardown
|
||||
* [GH-1094](https://github.com/apache/cordova-android/pull/1094) test: fix unit test failures for certain random orders
|
||||
* [GH-1094](https://github.com/apache/cordova-android/pull/1094) test: ensure single top-level describe block in test file
|
||||
* [GH-1129](https://github.com/apache/cordova-android/pull/1129) test(java): remove duplicate code in `BackButtonMultipageTest`
|
||||
* [GH-975](https://github.com/apache/cordova-android/pull/975) ci: Added Node 14.x
|
||||
|
||||
### 9.0.0 (Jun 23, 2020)
|
||||
|
||||
* [GH-1005](https://github.com/apache/cordova-android/pull/1005) chore: set AndroidX off by default
|
||||
@@ -170,6 +550,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.
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
)
|
||||
@@ -1,28 +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 fs = require('fs');
|
||||
|
||||
if (fs.existsSync('./test/gradlew')) {
|
||||
fs.unlinkSync('./test/gradlew');
|
||||
}
|
||||
|
||||
if (fs.existsSync('./test/gradlew.bat')) {
|
||||
fs.unlinkSync('./test/gradlew.bat');
|
||||
}
|
||||
61
bin/create
@@ -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;
|
||||
});
|
||||
@@ -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="%~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
|
||||
)
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
380
bin/templates/cordova/lib/builders/ProjectBuilder.js
vendored
@@ -1,380 +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 fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
const execa = require('execa');
|
||||
var events = require('cordova-common').events;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var check_reqs = require('../check_reqs');
|
||||
var PackageType = require('../PackageType');
|
||||
const { createEditor } = require('properties-parser');
|
||||
|
||||
const MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
||||
const SIGNING_PROPERTIES = '-signing.properties';
|
||||
const TEMPLATE =
|
||||
'# This file is automatically generated.\n' +
|
||||
'# Do not modify this file -- ' + MARKER + '\n';
|
||||
|
||||
const archSpecificRegex = /-x86|-arm/;
|
||||
const unsignedBuildRegex = /-unsigned/;
|
||||
|
||||
const fileSorter = (filePathA, filePathB) => {
|
||||
const archSpecificA = archSpecificRegex.test(filePathA);
|
||||
const archSpecificB = archSpecificRegex.test(filePathB);
|
||||
|
||||
// If they are not equal, then sort by specific archs after generic ones
|
||||
if (archSpecificA !== archSpecificB) {
|
||||
return archSpecificA < archSpecificB ? -1 : 1;
|
||||
}
|
||||
|
||||
// Otherwise, move onto the next sort item, which is by sorting unsigned bulds after signed ones
|
||||
const unsignedA = unsignedBuildRegex.test(filePathA);
|
||||
const unsignedB = unsignedBuildRegex.test(filePathB);
|
||||
|
||||
if (unsignedA !== unsignedB) {
|
||||
return unsignedA < unsignedB ? -1 : 1;
|
||||
}
|
||||
|
||||
// Then, sort by modification time, latest first
|
||||
const modTimeA = fs.statSync(filePathA).mtime.getTime();
|
||||
const modTimeB = fs.statSync(filePathB).mtime.getTime();
|
||||
|
||||
if (modTimeA !== modTimeB) {
|
||||
return modTimeA < modTimeB ? 1 : -1;
|
||||
}
|
||||
|
||||
// Finally, if all above is the same, sort by file name length, ascending
|
||||
return filePathB.length < filePathA.length ? -1 : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* If the provided directory does not exist or extension is missing, return an empty array.
|
||||
* If the director exists, loop the directories and collect list of files matching the extension.
|
||||
*
|
||||
* @param {String} dir Directory to scan
|
||||
* @param {String} extension
|
||||
*/
|
||||
function recursivelyFindFiles (dir, extension) {
|
||||
if (!fs.existsSync(dir) || !extension) return [];
|
||||
|
||||
const files = fs.readdirSync(dir, { withFileTypes: true })
|
||||
.map(entry => {
|
||||
const item = path.resolve(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) return recursivelyFindFiles(item, extension);
|
||||
if (path.extname(entry.name) === `.${extension}`) return item;
|
||||
return false;
|
||||
});
|
||||
|
||||
return Array.prototype.concat(...files)
|
||||
.filter(file => file !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} dir
|
||||
* @param {String} build_type
|
||||
* @param {String} arch
|
||||
* @param {String} extension
|
||||
*/
|
||||
function findOutputFilesHelper (dir, build_type, arch, extension) {
|
||||
let files = recursivelyFindFiles(path.resolve(dir, build_type), extension);
|
||||
|
||||
if (files.length === 0) return files;
|
||||
|
||||
// Assume arch-specific build if newest apk has -x86 or -arm.
|
||||
const archSpecific = !!/-x86|-arm/.exec(path.basename(files[0]));
|
||||
|
||||
// And show only arch-specific ones (or non-arch-specific)
|
||||
files = files.filter(p => !!/-x86|-arm/.exec(path.basename(p)) === archSpecific);
|
||||
|
||||
if (archSpecific && files.length > 1 && arch) {
|
||||
files = files.filter(p => path.basename(p).indexOf('-' + arch) !== -1);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
class ProjectBuilder {
|
||||
constructor (rootDirectory) {
|
||||
this.root = rootDirectory || path.resolve(__dirname, '../../..');
|
||||
this.apkDir = path.join(this.root, 'app', 'build', 'outputs', 'apk');
|
||||
this.aabDir = path.join(this.root, 'app', 'build', 'outputs', 'bundle');
|
||||
}
|
||||
|
||||
getArgs (cmd, opts) {
|
||||
let args;
|
||||
let buildCmd = cmd;
|
||||
if (opts.packageType === PackageType.BUNDLE) {
|
||||
if (cmd === 'release') {
|
||||
buildCmd = ':app:bundleRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
buildCmd = ':app:bundleDebug';
|
||||
}
|
||||
|
||||
args = [buildCmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
} else {
|
||||
if (cmd === 'release') {
|
||||
buildCmd = 'cdvBuildRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
buildCmd = 'cdvBuildDebug';
|
||||
}
|
||||
|
||||
args = [buildCmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
|
||||
if (opts.arch) {
|
||||
args.push('-PcdvBuildArch=' + opts.arch);
|
||||
}
|
||||
}
|
||||
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns a promise
|
||||
*/
|
||||
runGradleWrapper (gradle_cmd) {
|
||||
var gradlePath = path.join(this.root, 'gradlew');
|
||||
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
|
||||
if (fs.existsSync(gradlePath)) {
|
||||
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
||||
} else {
|
||||
return execa(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], { stdio: 'inherit' });
|
||||
}
|
||||
}
|
||||
|
||||
readProjectProperties () {
|
||||
function findAllUniq (data, r) {
|
||||
var s = {};
|
||||
var m;
|
||||
while ((m = r.exec(data))) {
|
||||
s[m[1]] = 1;
|
||||
}
|
||||
return Object.keys(s);
|
||||
}
|
||||
|
||||
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
||||
return {
|
||||
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
||||
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
||||
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
||||
};
|
||||
}
|
||||
|
||||
extractRealProjectNameFromManifest () {
|
||||
var manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||
if (!m) {
|
||||
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||
}
|
||||
|
||||
var packageName = m[1];
|
||||
var lastDotIndex = packageName.lastIndexOf('.');
|
||||
return packageName.substring(lastDotIndex + 1);
|
||||
}
|
||||
|
||||
// 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 propertiesObj = this.readProjectProperties();
|
||||
var subProjects = propertiesObj.libs;
|
||||
|
||||
// Check and copy the gradle file into the subproject
|
||||
// Called by the loop before this function def
|
||||
|
||||
var checkAndCopy = function (subProject, root) {
|
||||
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||
// This is the future-proof way of checking if a file exists
|
||||
// This must be synchronous to satisfy a Travis test
|
||||
try {
|
||||
fs.accessSync(subProjectGradle, fs.F_OK);
|
||||
} catch (e) {
|
||||
fs.copySync(pluginBuildGradle, subProjectGradle);
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < subProjects.length; ++i) {
|
||||
if (subProjects[i] !== 'CordovaLib') {
|
||||
checkAndCopy(subProjects[i], this.root);
|
||||
}
|
||||
}
|
||||
var name = this.extractRealProjectNameFromManifest();
|
||||
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||
var settingsGradlePaths = subProjects.map(function (p) {
|
||||
var realDir = p.replace(/[/\\]/g, ':');
|
||||
var libName = realDir.replace(name + '-', '');
|
||||
var str = 'include ":' + libName + '"\n';
|
||||
if (realDir.indexOf(name + '-') !== -1) {
|
||||
str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n';
|
||||
}
|
||||
return str;
|
||||
});
|
||||
|
||||
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
|
||||
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||
'include ":"\n' + settingsGradlePaths.join(''));
|
||||
|
||||
// Update dependencies within build.gradle.
|
||||
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
|
||||
var depsList = '';
|
||||
var root = this.root;
|
||||
var insertExclude = function (p) {
|
||||
var gradlePath = path.join(root, p, 'build.gradle');
|
||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
|
||||
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||
} else {
|
||||
depsList += '\n';
|
||||
}
|
||||
};
|
||||
subProjects.forEach(function (p) {
|
||||
events.emit('log', 'Subproject Path: ' + p);
|
||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||
if (libName !== 'app') {
|
||||
depsList += ' implementation(project(path: ":' + libName + '"))';
|
||||
insertExclude(p);
|
||||
}
|
||||
});
|
||||
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||
var SYSTEM_LIBRARY_MAPPINGS = [
|
||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||
];
|
||||
|
||||
propertiesObj.systemLibs.forEach(function (p) {
|
||||
var mavenRef;
|
||||
// It's already in gradle form if it has two ':'s
|
||||
if (/:.*:/.exec(p)) {
|
||||
mavenRef = p;
|
||||
} else {
|
||||
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
|
||||
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
|
||||
if (pair[0].exec(p)) {
|
||||
mavenRef = p.replace(pair[0], pair[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mavenRef) {
|
||||
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
|
||||
}
|
||||
}
|
||||
depsList += ' implementation "' + mavenRef + '"\n';
|
||||
});
|
||||
|
||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||
var includeList = '';
|
||||
|
||||
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||
includeList += 'apply from: "../' + includePath + '"\n';
|
||||
});
|
||||
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
|
||||
// This needs to be stored in the app gradle, not the root grade
|
||||
fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
|
||||
}
|
||||
|
||||
prepEnv (opts) {
|
||||
var self = this;
|
||||
return check_reqs.check_gradle()
|
||||
.then(function (gradlePath) {
|
||||
return self.runGradleWrapper(gradlePath);
|
||||
}).then(function () {
|
||||
return self.prepBuildFiles();
|
||||
}).then(() => {
|
||||
// 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';
|
||||
gradleWrapperProperties.set('distributionUrl', distributionUrl);
|
||||
gradleWrapperProperties.save();
|
||||
|
||||
events.emit('verbose', `Gradle Distribution URL: ${distributionUrl}`);
|
||||
})
|
||||
.then(() => {
|
||||
const signingPropertiesPath = path.join(self.root, `${opts.buildType}${SIGNING_PROPERTIES}`);
|
||||
|
||||
if (fs.existsSync(signingPropertiesPath)) fs.removeSync(signingPropertiesPath);
|
||||
if (opts.packageInfo) {
|
||||
fs.ensureFileSync(signingPropertiesPath);
|
||||
const signingProperties = createEditor(signingPropertiesPath);
|
||||
signingProperties.addHeadComment(TEMPLATE);
|
||||
opts.packageInfo.appendToProperties(signingProperties);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds the project with gradle.
|
||||
* Returns a promise.
|
||||
*/
|
||||
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' })
|
||||
.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;
|
||||
});
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
clean (opts) {
|
||||
const wrapper = path.join(this.root, 'gradlew');
|
||||
const args = this.getArgs('clean', opts);
|
||||
return execa(wrapper, args, { stdio: 'inherit' })
|
||||
.then(() => {
|
||||
fs.removeSync(path.join(this.root, 'out'));
|
||||
|
||||
['debug', 'release'].map(config => path.join(this.root, `${config}${SIGNING_PROPERTIES}`))
|
||||
.forEach(file => {
|
||||
const hasFile = fs.existsSync(file);
|
||||
const hasMarker = hasFile && fs.readFileSync(file, 'utf8')
|
||||
.includes(MARKER);
|
||||
|
||||
if (hasFile && hasMarker) fs.removeSync(file);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
findOutputApks (build_type, arch) {
|
||||
return findOutputFilesHelper(this.apkDir, build_type, arch, 'apk').sort(fileSorter);
|
||||
}
|
||||
|
||||
findOutputBundles (build_type) {
|
||||
return findOutputFilesHelper(this.aabDir, build_type, false, 'aab').sort(fileSorter);
|
||||
}
|
||||
|
||||
fetchBuildResults (build_type, arch) {
|
||||
return {
|
||||
apkPaths: this.findOutputApks(build_type, arch),
|
||||
buildType: build_type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProjectBuilder;
|
||||
480
bin/templates/cordova/lib/check_reqs.js
vendored
@@ -1,480 +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 execa = require('execa');
|
||||
var path = require('path');
|
||||
var fs = require('fs-extra');
|
||||
var os = require('os');
|
||||
var which = require('which');
|
||||
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');
|
||||
|
||||
function forgivingWhichSync (cmd) {
|
||||
const whichResult = which.sync(cmd, { nothrow: true });
|
||||
|
||||
// On null, returns empty string to maintain backwards compatibility
|
||||
// realpathSync follows symlinks
|
||||
return whichResult === null ? '' : fs.realpathSync(whichResult);
|
||||
}
|
||||
|
||||
function getJDKDirectory (directory) {
|
||||
const p = path.resolve(directory, 'java');
|
||||
if (fs.existsSync(p)) {
|
||||
const directories = fs.readdirSync(p);
|
||||
for (let i = 0; i < directories.length; i++) {
|
||||
const dir = directories[i];
|
||||
if (/^(jdk)+./.test(dir)) {
|
||||
return path.resolve(directory, 'java', dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports.isWindows = function () {
|
||||
return (os.platform() === 'win32');
|
||||
};
|
||||
|
||||
module.exports.isDarwin = function () {
|
||||
return (os.platform() === 'darwin');
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @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')
|
||||
];
|
||||
|
||||
// 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 the repo config.xml file exists, find the desired targetSdkVersion.
|
||||
const configFile = path.join(REPO_ROOT, 'config.xml');
|
||||
if (!fs.existsSync(configFile)) return target;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// Returns a promise. Called only by build and clean commands.
|
||||
module.exports.check_ant = function () {
|
||||
return execa('ant', ['-version']).then(({ stdout: output }) => {
|
||||
// Parse Ant version from command output
|
||||
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
|
||||
}).catch(function (err) {
|
||||
if (err) {
|
||||
throw new CordovaError('Failed to run `ant -version`. Make sure you have `ant` on your $PATH.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.get_gradle_wrapper = function () {
|
||||
var androidStudioPath;
|
||||
var i = 0;
|
||||
var foundStudio = false;
|
||||
var program_dir;
|
||||
// OK, This hack only works on Windows, not on Mac OS or Linux. We will be deleting this eventually!
|
||||
if (module.exports.isWindows()) {
|
||||
var result = execa.sync(path.join(__dirname, 'getASPath.bat'));
|
||||
// console.log('result.stdout =' + result.stdout.toString());
|
||||
// console.log('result.stderr =' + result.stderr.toString());
|
||||
|
||||
if (result.stderr.toString().length > 0) {
|
||||
var androidPath = path.join(process.env.ProgramFiles, 'Android') + '/';
|
||||
if (fs.existsSync(androidPath)) {
|
||||
program_dir = fs.readdirSync(androidPath);
|
||||
while (i < program_dir.length && !foundStudio) {
|
||||
if (program_dir[i].startsWith('Android Studio')) {
|
||||
foundStudio = true;
|
||||
androidStudioPath = path.join(process.env.ProgramFiles, 'Android', program_dir[i], 'gradle');
|
||||
} else { ++i; }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// console.log('got android studio path from registry');
|
||||
// remove the (os independent) new line char at the end of stdout
|
||||
// add gradle to match the above.
|
||||
androidStudioPath = path.join(result.stdout.toString().split('\r\n')[0], 'gradle');
|
||||
}
|
||||
}
|
||||
|
||||
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
||||
var dirs = fs.readdirSync(androidStudioPath);
|
||||
if (dirs[0].split('-')[0] === 'gradle') {
|
||||
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
||||
}
|
||||
} else {
|
||||
// OK, let's try to check for Gradle!
|
||||
return forgivingWhichSync('gradle');
|
||||
}
|
||||
};
|
||||
|
||||
// Returns a promise. Called only by build and clean commands.
|
||||
module.exports.check_gradle = function () {
|
||||
var sdkDir = process.env.ANDROID_SDK_ROOT || process.env.ANDROID_HOME;
|
||||
if (!sdkDir) {
|
||||
return Promise.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
|
||||
'Might need to install Android SDK or set up \'ANDROID_SDK_ROOT\' env variable.'));
|
||||
}
|
||||
|
||||
var gradlePath = module.exports.get_gradle_wrapper();
|
||||
|
||||
if (gradlePath.length !== 0) return Promise.resolve(gradlePath);
|
||||
|
||||
return Promise.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
|
||||
'or on your system to install the gradle wrapper. Please include gradle \n' +
|
||||
'in your path, or install Android Studio'));
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.check_java = function () {
|
||||
var javacPath = forgivingWhichSync('javac');
|
||||
var hasJavaHome = !!process.env.JAVA_HOME;
|
||||
return Promise.resolve().then(function () {
|
||||
if (hasJavaHome) {
|
||||
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
|
||||
if (!javacPath) {
|
||||
process.env.PATH += path.delimiter + path.join(process.env.JAVA_HOME, 'bin');
|
||||
}
|
||||
} else {
|
||||
if (javacPath) {
|
||||
// OS X has a command for finding JAVA_HOME.
|
||||
var find_java = '/usr/libexec/java_home';
|
||||
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting it manually.';
|
||||
if (fs.existsSync(find_java)) {
|
||||
return execa(find_java).then(({ stdout }) => {
|
||||
process.env.JAVA_HOME = stdout;
|
||||
}).catch(function (err) {
|
||||
if (err) {
|
||||
throw new CordovaError(default_java_error_msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// See if we can derive it from javac's location.
|
||||
var maybeJavaHome = path.dirname(path.dirname(javacPath));
|
||||
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
||||
process.env.JAVA_HOME = maybeJavaHome;
|
||||
} else {
|
||||
throw new CordovaError(default_java_error_msg);
|
||||
}
|
||||
}
|
||||
} else if (module.exports.isWindows()) {
|
||||
const programFilesEnv = path.resolve(process.env.ProgramFiles);
|
||||
const programFiles = 'C:\\Program Files\\';
|
||||
const programFilesx86 = 'C:\\Program Files (x86)\\';
|
||||
|
||||
let firstJdkDir =
|
||||
getJDKDirectory(programFilesEnv) ||
|
||||
getJDKDirectory(programFiles) ||
|
||||
getJDKDirectory(programFilesx86);
|
||||
|
||||
if (firstJdkDir) {
|
||||
firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
|
||||
if (!javacPath) {
|
||||
process.env.PATH += path.delimiter + path.join(firstJdkDir, 'bin');
|
||||
}
|
||||
process.env.JAVA_HOME = firstJdkDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).then(function () {
|
||||
return execa('javac', ['-version'], { all: true })
|
||||
.then(({ all: output }) => {
|
||||
// Java <= 8 writes version info to stderr, Java >= 9 to stdout
|
||||
const match = /javac\s+([\d.]+)/i.exec(output);
|
||||
return match && match[1];
|
||||
}, () => {
|
||||
var msg =
|
||||
'Failed to run "javac -version", make sure that you have a JDK version 8 installed.\n' +
|
||||
'You can get it from the following location:\n' +
|
||||
'https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html';
|
||||
if (process.env.JAVA_HOME) {
|
||||
msg += '\n\n';
|
||||
msg += 'Your JAVA_HOME is invalid: ' + process.env.JAVA_HOME;
|
||||
}
|
||||
throw new CordovaError(msg);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.check_android = function () {
|
||||
return Promise.resolve().then(function () {
|
||||
function maybeSetAndroidHome (value) {
|
||||
if (!hasAndroidHome && fs.existsSync(value)) {
|
||||
hasAndroidHome = true;
|
||||
process.env.ANDROID_SDK_ROOT = value;
|
||||
}
|
||||
}
|
||||
|
||||
var androidCmdPath = forgivingWhichSync('android');
|
||||
var adbInPath = forgivingWhichSync('adb');
|
||||
var avdmanagerInPath = forgivingWhichSync('avdmanager');
|
||||
var hasAndroidHome = false;
|
||||
|
||||
if (process.env.ANDROID_SDK_ROOT) {
|
||||
maybeSetAndroidHome(path.resolve(process.env.ANDROID_SDK_ROOT));
|
||||
}
|
||||
|
||||
// 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 (process.env.ANDROID_HOME) {
|
||||
// Fallback to deprecated `ANDROID_HOME` variable
|
||||
maybeSetAndroidHome(path.join(process.env.ANDROID_HOME));
|
||||
}
|
||||
if (module.exports.isWindows()) {
|
||||
// Android Studio 1.0 installer
|
||||
if (process.env.LOCALAPPDATA) {
|
||||
maybeSetAndroidHome(path.join(process.env.LOCALAPPDATA, 'Android', 'sdk'));
|
||||
}
|
||||
if (process.env.ProgramFiles) {
|
||||
maybeSetAndroidHome(path.join(process.env.ProgramFiles, 'Android', 'sdk'));
|
||||
}
|
||||
|
||||
// Android Studio pre-1.0 installer
|
||||
if (process.env.LOCALAPPDATA) {
|
||||
maybeSetAndroidHome(path.join(process.env.LOCALAPPDATA, 'Android', 'android-studio', 'sdk'));
|
||||
}
|
||||
if (process.env.ProgramFiles) {
|
||||
maybeSetAndroidHome(path.join(process.env.ProgramFiles, 'Android', 'android-studio', 'sdk'));
|
||||
}
|
||||
|
||||
// Stand-alone installer
|
||||
if (process.env.LOCALAPPDATA) {
|
||||
maybeSetAndroidHome(path.join(process.env.LOCALAPPDATA, 'Android', 'android-sdk'));
|
||||
}
|
||||
if (process.env.ProgramFiles) {
|
||||
maybeSetAndroidHome(path.join(process.env.ProgramFiles, 'Android', 'android-sdk'));
|
||||
}
|
||||
} else if (module.exports.isDarwin()) {
|
||||
// Android Studio 1.0 installer
|
||||
if (process.env.HOME) {
|
||||
maybeSetAndroidHome(path.join(process.env.HOME, 'Library', 'Android', 'sdk'));
|
||||
}
|
||||
// Android Studio pre-1.0 installer
|
||||
maybeSetAndroidHome('/Applications/Android Studio.app/sdk');
|
||||
// Stand-alone zip file that user might think to put under /Applications
|
||||
maybeSetAndroidHome('/Applications/android-sdk-macosx');
|
||||
maybeSetAndroidHome('/Applications/android-sdk');
|
||||
}
|
||||
if (process.env.HOME) {
|
||||
// Stand-alone zip file that user might think to put under their home directory
|
||||
maybeSetAndroidHome(path.join(process.env.HOME, 'android-sdk-macosx'));
|
||||
maybeSetAndroidHome(path.join(process.env.HOME, 'android-sdk'));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (path.basename(parentDir) === 'platform-tools') {
|
||||
maybeSetAndroidHome(grandParentDir);
|
||||
} else {
|
||||
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
|
||||
'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
|
||||
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
|
||||
}
|
||||
}
|
||||
if (avdmanagerInPath) {
|
||||
parentDir = path.dirname(avdmanagerInPath);
|
||||
grandParentDir = path.dirname(parentDir);
|
||||
if (path.basename(parentDir) === 'bin' && path.basename(grandParentDir) === 'tools') {
|
||||
maybeSetAndroidHome(path.dirname(grandParentDir));
|
||||
} else {
|
||||
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
|
||||
'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
|
||||
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!process.env.ANDROID_SDK_ROOT) {
|
||||
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
|
||||
'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
|
||||
}
|
||||
if (!fs.existsSync(process.env.ANDROID_SDK_ROOT)) {
|
||||
throw new CordovaError('\'ANDROID_SDK_ROOT\' environment variable is set to non-existent path: ' + process.env.ANDROID_SDK_ROOT +
|
||||
'\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');
|
||||
}
|
||||
if (hasAndroidHome && !avdmanagerInPath) {
|
||||
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'tools', 'bin');
|
||||
}
|
||||
return hasAndroidHome;
|
||||
});
|
||||
};
|
||||
|
||||
// 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) {
|
||||
// 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();
|
||||
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);
|
||||
});
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.run = function () {
|
||||
console.log('Checking Java JDK and Android SDK versions');
|
||||
console.log('ANDROID_SDK_ROOT=' + process.env.ANDROID_SDK_ROOT + ' (recommended setting)');
|
||||
console.log('ANDROID_HOME=' + process.env.ANDROID_HOME + ' (DEPRECATED)');
|
||||
|
||||
return Promise.all([this.check_java(), this.check_android()]).then(function (values) {
|
||||
console.log('Using Android SDK: ' + process.env.ANDROID_SDK_ROOT);
|
||||
|
||||
if (!String(values[0]).startsWith('1.8.')) {
|
||||
throw new CordovaError(
|
||||
'Requirements check failed for JDK 8 (\'1.8.*\')! Detected version: ' + values[0] + '\n' +
|
||||
'Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!values[1]) {
|
||||
throw new CordovaError('Requirements check failed for Android SDK! Android SDK was not detected.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Object thar represents one of requirements for current platform.
|
||||
* @param {String} id The unique identifier for this requirements.
|
||||
* @param {String} name The name of requirements. Human-readable field.
|
||||
* @param {String} version The version of requirement installed. In some cases could be an array of strings
|
||||
* (for example, check_android_target returns an array of android targets installed)
|
||||
* @param {Boolean} installed Indicates whether the requirement is installed or not
|
||||
*/
|
||||
var Requirement = function (id, name, version, installed) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.installed = installed || false;
|
||||
this.metadata = {
|
||||
version: version
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
|
||||
*/
|
||||
module.exports.check_all = function () {
|
||||
var requirements = [
|
||||
new Requirement('java', 'Java JDK'),
|
||||
new Requirement('androidSdk', 'Android SDK'),
|
||||
new Requirement('androidTarget', 'Android target'),
|
||||
new Requirement('gradle', 'Gradle')
|
||||
];
|
||||
|
||||
var checkFns = [
|
||||
this.check_java,
|
||||
this.check_android,
|
||||
this.check_android_target,
|
||||
this.check_gradle
|
||||
];
|
||||
|
||||
// Then execute requirement checks one-by-one
|
||||
return checkFns.reduce(function (promise, checkFn, idx) {
|
||||
// Update each requirement with results
|
||||
var requirement = requirements[idx];
|
||||
return promise.then(checkFn).then(function (version) {
|
||||
requirement.installed = true;
|
||||
requirement.metadata.version = version;
|
||||
}, function (err) {
|
||||
requirement.metadata.reason = err instanceof Error ? err.message : err;
|
||||
});
|
||||
}, Promise.resolve()).then(function () {
|
||||
// When chain is completed, return requirements array to upstream API
|
||||
return requirements;
|
||||
});
|
||||
};
|
||||
109
bin/templates/cordova/lib/device.js
vendored
@@ -1,109 +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 execa = require('execa');
|
||||
var build = require('./build');
|
||||
var path = require('path');
|
||||
var Adb = require('./Adb');
|
||||
var AndroidManifest = require('./AndroidManifest');
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var events = require('cordova-common').events;
|
||||
|
||||
/**
|
||||
* Returns a promise for the list of the device ID's found
|
||||
* @param lookHarder When true, try restarting adb if no devices are found.
|
||||
*/
|
||||
module.exports.list = function (lookHarder) {
|
||||
return Adb.devices().then(function (list) {
|
||||
if (list.length === 0 && lookHarder) {
|
||||
// adb kill-server doesn't seem to do the trick.
|
||||
// Could probably find a x-platform version of killall, but I'm not actually
|
||||
// sure that this scenario even happens on non-OSX machines.
|
||||
return execa('killall', ['adb']).then(function () {
|
||||
events.emit('verbose', 'Restarting adb to see if more devices are detected.');
|
||||
return Adb.devices();
|
||||
}, function () {
|
||||
// For non-killall OS's.
|
||||
return list;
|
||||
});
|
||||
}
|
||||
return list;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.resolveTarget = function (target) {
|
||||
return this.list(true).then(function (device_list) {
|
||||
if (!device_list || !device_list.length) {
|
||||
return Promise.reject(new CordovaError('Failed to deploy to device, no devices found.'));
|
||||
}
|
||||
// default device
|
||||
target = target || device_list[0];
|
||||
|
||||
if (device_list.indexOf(target) < 0) {
|
||||
return Promise.reject(new CordovaError('ERROR: Unable to find target \'' + target + '\'.'));
|
||||
}
|
||||
|
||||
return build.detectArchitecture(target).then(function (arch) {
|
||||
return { target: target, arch: arch, isEmulator: false };
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Installs a previously built application on the device
|
||||
* and launches it.
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.install = function (target, buildResults) {
|
||||
return Promise.resolve().then(function () {
|
||||
if (target && typeof target === 'object') {
|
||||
return target;
|
||||
}
|
||||
return module.exports.resolveTarget(target);
|
||||
}).then(function (resolvedTarget) {
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch);
|
||||
var manifest = new AndroidManifest(path.join(__dirname, '../../app/src/main/AndroidManifest.xml'));
|
||||
var pkgName = manifest.getPackageId();
|
||||
var launchName = pkgName + '/.' + manifest.getActivity().getName();
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
events.emit('log', 'Package name: ' + pkgName);
|
||||
|
||||
return Adb.install(resolvedTarget.target, apk_path, { replace: true }).catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||
|
||||
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
|
||||
'installed app already signed with different key');
|
||||
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(resolvedTarget.target, pkgName).then(function () {
|
||||
return Adb.install(resolvedTarget.target, apk_path, { replace: true });
|
||||
});
|
||||
}).then(function () {
|
||||
// unlock screen
|
||||
return Adb.shell(resolvedTarget.target, 'input keyevent 82');
|
||||
}).then(function () {
|
||||
return Adb.start(resolvedTarget.target, launchName);
|
||||
}).then(function () {
|
||||
events.emit('log', 'LAUNCH SUCCESS');
|
||||
});
|
||||
});
|
||||
};
|
||||
517
bin/templates/cordova/lib/emulator.js
vendored
@@ -1,517 +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 execa = require('execa');
|
||||
const fs = require('fs-extra');
|
||||
var android_versions = require('android-versions');
|
||||
var retry = require('./retry');
|
||||
var build = require('./build');
|
||||
var path = require('path');
|
||||
var Adb = require('./Adb');
|
||||
var AndroidManifest = require('./AndroidManifest');
|
||||
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');
|
||||
var os = require('os');
|
||||
|
||||
// constants
|
||||
const ONE_SECOND = 1000; // in milliseconds
|
||||
const ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds
|
||||
const INSTALL_COMMAND_TIMEOUT = 5 * ONE_MINUTE; // in milliseconds
|
||||
const NUM_INSTALL_RETRIES = 3;
|
||||
const CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
||||
const EXEC_KILL_SIGNAL = 'SIGKILL';
|
||||
|
||||
function forgivingWhichSync (cmd) {
|
||||
const whichResult = which.sync(cmd, { nothrow: true });
|
||||
|
||||
// On null, returns empty string to maintain backwards compatibility
|
||||
// realpathSync follows symlinks
|
||||
return whichResult === null ? '' : fs.realpathSync(whichResult);
|
||||
}
|
||||
|
||||
module.exports.list_images_using_avdmanager = function () {
|
||||
return execa('avdmanager', ['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(/Target:\s/)) {
|
||||
i++;
|
||||
if (response[i + 1].match(/ABI:\s/)) {
|
||||
img_obj.abi = response[i + 1].split('ABI: ')[1].replace('\r', '');
|
||||
}
|
||||
// This next conditional just aims to match the old output of `android list avd`
|
||||
// We do so so that we don't have to change the logic when parsing for the
|
||||
// best emulator target to spawn (see below in `best_image`)
|
||||
// This allows us to transitionally support both `android` and `avdmanager` binaries,
|
||||
// depending on what SDK version the user has
|
||||
if (response[i + 1].match(/Based\son:\s/)) {
|
||||
img_obj.target = response[i + 1].split('Based on:')[1];
|
||||
if (img_obj.target.match(/Tag\/ABI:\s/)) {
|
||||
img_obj.target = img_obj.target.split('Tag/ABI:')[0].replace('\r', '').trim();
|
||||
if (img_obj.target.indexOf('(') > -1) {
|
||||
img_obj.target = img_obj.target.substr(0, img_obj.target.indexOf('(') - 1).trim();
|
||||
}
|
||||
}
|
||||
var version_string = img_obj.target.replace(/Android\s+/, '');
|
||||
|
||||
var api_level = android_sdk.version_string_to_api_level[version_string];
|
||||
if (api_level) {
|
||||
img_obj.target += ' (API level ' + api_level + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
});
|
||||
};
|
||||
|
||||
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
|
||||
* {
|
||||
name : <emulator_name>,
|
||||
device : <device>,
|
||||
path : <path_to_emulator_image>,
|
||||
target : <api_target>,
|
||||
abi : <cpu>,
|
||||
skin : <skin>
|
||||
}
|
||||
*/
|
||||
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?'));
|
||||
}
|
||||
}).then(function (avds) {
|
||||
// In case we're missing the Android OS version string from the target description, add it.
|
||||
return avds.map(function (avd) {
|
||||
if (avd.target && avd.target.indexOf('Android API') > -1 && avd.target.indexOf('API level') < 0) {
|
||||
var api_level = avd.target.match(/\d+/);
|
||||
if (api_level) {
|
||||
var level = android_versions.get(api_level);
|
||||
if (level) {
|
||||
avd.target = 'Android ' + level.semver + ' (API level ' + api_level + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
return avd;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Will return the closest avd to the projects target
|
||||
* or undefined if no avds exist.
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.best_image = function () {
|
||||
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) {
|
||||
var num = parseInt(target.split('(API level ')[1].replace(')', ''));
|
||||
if (num === project_target) {
|
||||
return images[i];
|
||||
} else if (project_target - num < closest && project_target > num) {
|
||||
closest = project_target - num;
|
||||
best = images[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
});
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.list_started = function () {
|
||||
return Adb.devices({ emulators: true });
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
// TODO: we should remove this, there's a more robust method under android_sdk.js
|
||||
module.exports.list_targets = function () {
|
||||
return execa('android', ['list', 'targets'], { cwd: os.tmpdir() }).then(({ stdout: output }) => {
|
||||
var target_out = output.split('\n');
|
||||
var targets = [];
|
||||
for (var i = target_out.length; i >= 0; i--) {
|
||||
if (target_out[i].match(/id:/)) {
|
||||
targets.push(targets[i].split(' ')[1]);
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Gets unused port for android emulator, between 5554 and 5584
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.get_available_port = function () {
|
||||
var self = this;
|
||||
|
||||
return self.list_started().then(function (emulators) {
|
||||
for (var p = 5584; p >= 5554; p -= 2) {
|
||||
if (emulators.indexOf('emulator-' + p) === -1) {
|
||||
events.emit('verbose', 'Found available port: ' + p);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
throw new CordovaError('Could not find an available avd port');
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
var self = this;
|
||||
|
||||
return Promise.resolve().then(function () {
|
||||
if (emulator_ID) return Promise.resolve(emulator_ID);
|
||||
|
||||
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
|
||||
var emulator_dir = path.dirname(which.sync('emulator'));
|
||||
var args = ['-avd', emulatorId, '-port', port];
|
||||
// Don't wait for it to finish, since the emulator will probably keep running for a long time.
|
||||
execa('emulator', args, { stdio: 'inherit', detached: true, cwd: emulator_dir })
|
||||
.unref();
|
||||
|
||||
// wait for emulator to start
|
||||
events.emit('log', 'Waiting for emulator to start...');
|
||||
return self.wait_for_emulator(port);
|
||||
});
|
||||
}).then(function (emulatorId) {
|
||||
if (!emulatorId) { return Promise.reject(new CordovaError('Failed to start emulator')); }
|
||||
|
||||
// wait for emulator to boot up
|
||||
process.stdout.write('Waiting for emulator to boot (this may take a while)...');
|
||||
return self.wait_for_boot(emulatorId, boot_timeout).then(function (success) {
|
||||
if (success) {
|
||||
events.emit('log', 'BOOT COMPLETE');
|
||||
// unlock screen
|
||||
return Adb.shell(emulatorId, 'input keyevent 82').then(function () {
|
||||
// return the new emulator id for the started emulators
|
||||
return emulatorId;
|
||||
});
|
||||
} else {
|
||||
// We timed out waiting for the boot to happen
|
||||
return null;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Waits for an emulator to boot on a given port.
|
||||
* Returns this emulator's ID in a promise.
|
||||
*/
|
||||
module.exports.wait_for_emulator = function (port) {
|
||||
var self = this;
|
||||
return Promise.resolve().then(function () {
|
||||
var emulator_id = 'emulator-' + port;
|
||||
return Adb.shell(emulator_id, 'getprop dev.bootcomplete').then(function (output) {
|
||||
if (output.indexOf('1') >= 0) {
|
||||
return emulator_id;
|
||||
}
|
||||
return self.wait_for_emulator(port);
|
||||
}, function (error) {
|
||||
if ((error && error.message &&
|
||||
(error.message.indexOf('not found') > -1)) ||
|
||||
(error.message.indexOf('device offline') > -1) ||
|
||||
(error.message.indexOf('device still connecting') > -1) ||
|
||||
(error.message.indexOf('device still authorizing') > -1)) {
|
||||
// emulator not yet started, continue waiting
|
||||
return self.wait_for_emulator(port);
|
||||
} else {
|
||||
// something unexpected has happened
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Waits for the core android process of the emulator to start. Returns a
|
||||
* promise that resolves to a boolean indicating success. Not specifying a
|
||||
* time_remaining or passing a negative value will cause it to wait forever
|
||||
*/
|
||||
module.exports.wait_for_boot = function (emulator_id, time_remaining) {
|
||||
var self = this;
|
||||
return Adb.shell(emulator_id, 'getprop sys.boot_completed').then(function (output) {
|
||||
if (output.match(/1/)) {
|
||||
return true;
|
||||
} else if (time_remaining === 0) {
|
||||
return false;
|
||||
} else {
|
||||
process.stdout.write('.');
|
||||
|
||||
return new Promise(resolve => {
|
||||
const delay = time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL;
|
||||
|
||||
setTimeout(() => {
|
||||
const updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
|
||||
resolve(self.wait_for_boot(emulator_id, updated_time));
|
||||
}, delay);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Create avd
|
||||
* TODO : Enter the stdin input required to complete the creation of an avd.
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.create_image = function (name, target) {
|
||||
console.log('Creating new avd named ' + name);
|
||||
if (target) {
|
||||
return execa('android', ['create', 'avd', '--name', name, '--target', target]).then(null, function (error) {
|
||||
console.error('ERROR : Failed to create emulator image : ');
|
||||
console.error(' Do you have the latest android targets including ' + target + '?');
|
||||
console.error(error.message);
|
||||
});
|
||||
} else {
|
||||
console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
|
||||
// TODO: there's a more robust method for finding targets in android_sdk.js
|
||||
return execa('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]]).then(function () {
|
||||
// TODO: This seems like another error case, even though it always happens.
|
||||
console.error('ERROR : Unable to create an avd emulator, no targets found.');
|
||||
console.error('Ensure you have targets available by running the "android" command');
|
||||
return Promise.reject(new CordovaError());
|
||||
}, function (error) {
|
||||
console.error('ERROR : Failed to create emulator image : ');
|
||||
console.error(error.message);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.resolveTarget = function (target) {
|
||||
return this.list_started().then(function (emulator_list) {
|
||||
if (emulator_list.length < 1) {
|
||||
return Promise.reject(new CordovaError('No running Android emulators found, please start an emulator before deploying your project.'));
|
||||
}
|
||||
|
||||
// default emulator
|
||||
target = target || emulator_list[0];
|
||||
if (emulator_list.indexOf(target) < 0) {
|
||||
return Promise.reject(new CordovaError('Unable to find target \'' + target + '\'. Failed to deploy to emulator.'));
|
||||
}
|
||||
|
||||
return build.detectArchitecture(target).then(function (arch) {
|
||||
return { target: target, arch: arch, isEmulator: true };
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Installs a previously built application on the emulator and launches it.
|
||||
* If no target is specified, then it picks one.
|
||||
* If no started emulators are found, error out.
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.install = function (givenTarget, buildResults) {
|
||||
var target;
|
||||
// We need to find the proper path to the Android Manifest
|
||||
const manifestPath = path.join(__dirname, '..', '..', 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||
const manifest = new AndroidManifest(manifestPath);
|
||||
const pkgName = manifest.getPackageId();
|
||||
|
||||
// resolve the target emulator
|
||||
return Promise.resolve().then(function () {
|
||||
if (givenTarget && typeof givenTarget === 'object') {
|
||||
return givenTarget;
|
||||
} else {
|
||||
return module.exports.resolveTarget(givenTarget);
|
||||
}
|
||||
|
||||
// set the resolved target
|
||||
}).then(function (resolvedTarget) {
|
||||
target = resolvedTarget;
|
||||
|
||||
// install the app
|
||||
}).then(function () {
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Promise.resolve().then(function () {
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
||||
var execOptions = {
|
||||
cwd: os.tmpdir(),
|
||||
timeout: INSTALL_COMMAND_TIMEOUT, // in milliseconds
|
||||
killSignal: EXEC_KILL_SIGNAL
|
||||
};
|
||||
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
events.emit('log', 'Package name: ' + pkgName);
|
||||
events.emit('verbose', 'Installing app on emulator...');
|
||||
|
||||
// A special function to call adb install in specific environment w/ specific options.
|
||||
// Introduced as a part of fix for http://issues.apache.org/jira/browse/CB-9119
|
||||
// to workaround sporadic emulator hangs
|
||||
function adbInstallWithOptions (target, apk, opts) {
|
||||
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
|
||||
|
||||
const args = ['-s', target, 'install', '-r', apk];
|
||||
return execa('adb', args, opts).then(({ stdout }) => {
|
||||
// adb does not return an error code even if installation fails. Instead it puts a specific
|
||||
// message to stdout, so we have to use RegExp matching to detect installation failure.
|
||||
if (/Failure/.test(stdout)) {
|
||||
if (stdout.match(/INSTALL_PARSE_FAILED_NO_CERTIFICATES/)) {
|
||||
stdout += 'Sign the build using \'-- --keystore\' or \'--buildConfig\'' +
|
||||
' or sign and deploy the unsigned apk manually using Android tools.';
|
||||
} else if (stdout.match(/INSTALL_FAILED_VERSION_DOWNGRADE/)) {
|
||||
stdout += 'You\'re trying to install apk with a lower versionCode that is already installed.' +
|
||||
'\nEither uninstall an app or increment the versionCode.';
|
||||
}
|
||||
|
||||
throw new CordovaError('Failed to install apk to emulator: ' + stdout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function installPromise () {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions).catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||
|
||||
events.emit('warn', 'Uninstalling app from device and reinstalling it because the ' +
|
||||
'currently installed app was signed with different key');
|
||||
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(target.target, pkgName).then(function () {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise).then(function (output) {
|
||||
events.emit('log', 'INSTALL SUCCESS');
|
||||
});
|
||||
});
|
||||
// unlock screen
|
||||
}).then(function () {
|
||||
events.emit('verbose', 'Unlocking screen...');
|
||||
return Adb.shell(target.target, 'input keyevent 82');
|
||||
}).then(function () {
|
||||
Adb.start(target.target, pkgName + '/.' + manifest.getActivity().getName());
|
||||
// report success or failure
|
||||
}).then(function (output) {
|
||||
events.emit('log', 'LAUNCH SUCCESS');
|
||||
});
|
||||
};
|
||||
@@ -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%
|
||||
@@ -1,42 +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 device = require('./device');
|
||||
var args = process.argv;
|
||||
|
||||
if (args.length > 2) {
|
||||
var install_target;
|
||||
if (args[2].substring(0, 9) === '--target=') {
|
||||
install_target = args[2].substring(9, args[2].length);
|
||||
device.install(install_target).catch(function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
} else {
|
||||
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
|
||||
process.exit(2);
|
||||
}
|
||||
} else {
|
||||
device.install().catch(function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
)
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
45
bin/templates/cordova/lib/log.js
vendored
@@ -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);
|
||||
};
|
||||
738
bin/templates/cordova/lib/prepare.js
vendored
@@ -1,738 +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 fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
const nopt = require('nopt');
|
||||
var events = require('cordova-common').events;
|
||||
var AndroidManifest = require('./AndroidManifest');
|
||||
var checkReqs = require('./check_reqs');
|
||||
var xmlHelpers = require('cordova-common').xmlHelpers;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var ConfigParser = require('cordova-common').ConfigParser;
|
||||
var FileUpdater = require('cordova-common').FileUpdater;
|
||||
var PlatformJson = require('cordova-common').PlatformJson;
|
||||
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
|
||||
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
|
||||
const utils = require('./utils');
|
||||
|
||||
const GradlePropertiesParser = require('./config/GradlePropertiesParser');
|
||||
|
||||
function parseArguments (argv) {
|
||||
return nopt({
|
||||
// `jvmargs` is a valid option however, we don't actually want to parse it because we want the entire string as is.
|
||||
// jvmargs: String
|
||||
}, {}, argv || [], 0);
|
||||
}
|
||||
|
||||
module.exports.prepare = function (cordovaProject, options) {
|
||||
var self = this;
|
||||
|
||||
let args = {};
|
||||
if (options && options.options) {
|
||||
args = parseArguments(options.options.argv);
|
||||
}
|
||||
|
||||
var platformJson = PlatformJson.load(this.locations.root, this.platform);
|
||||
var munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider());
|
||||
|
||||
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');
|
||||
|
||||
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 own www dir with project's www assets and plugins' assets and js-files
|
||||
return Promise.resolve(updateWww(cordovaProject, this.locations)).then(function () {
|
||||
// update project according to config.xml changes.
|
||||
return updateProjectAccordingTo(self._config, self.locations);
|
||||
}).then(function () {
|
||||
updateIcons(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
||||
updateSplashes(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
||||
updateFileResources(cordovaProject, path.relative(cordovaProject.root, self.locations.root));
|
||||
}).then(function () {
|
||||
events.emit('verbose', 'Prepared android project successfully');
|
||||
});
|
||||
};
|
||||
|
||||
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
|
||||
// noPrepare option passed in by the non-CLI clean script. If that's present, or if
|
||||
// there's no config.xml found at the project root, then don't clean prepared files.
|
||||
var projectRoot = path.resolve(this.root, '../..');
|
||||
if ((options && options.noPrepare) || !fs.existsSync(this.locations.configXml) ||
|
||||
!fs.existsSync(this.locations.configXml)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
var projectConfig = new ConfigParser(this.locations.configXml);
|
||||
|
||||
var self = this;
|
||||
return Promise.resolve().then(function () {
|
||||
cleanWww(projectRoot, self.locations);
|
||||
cleanIcons(projectRoot, projectConfig, path.relative(projectRoot, self.locations.res));
|
||||
cleanSplashes(projectRoot, projectConfig, path.relative(projectRoot, self.locations.res));
|
||||
cleanFileResources(projectRoot, projectConfig, path.relative(projectRoot, self.locations.root));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates config files in project based on app's config.xml and config munge,
|
||||
* generated by plugins.
|
||||
*
|
||||
* @param {ConfigParser} sourceConfig A project's configuration that will
|
||||
* be merged into platform's config.xml
|
||||
* @param {ConfigChanges} configMunger An initialized ConfigChanges instance
|
||||
* for this platform.
|
||||
* @param {Object} locations A map of locations for this platform
|
||||
*
|
||||
* @return {ConfigParser} An instance of ConfigParser, that
|
||||
* represents current project's configuration. When returned, the
|
||||
* configuration is already dumped to appropriate config.xml file.
|
||||
*/
|
||||
function updateConfigFilesFrom (sourceConfig, configMunger, locations) {
|
||||
events.emit('verbose', 'Generating platform-specific config.xml from defaults for android at ' + locations.configXml);
|
||||
|
||||
// First cleanup current config and merge project's one into own
|
||||
// Overwrite platform config.xml with defaults.xml.
|
||||
fs.copySync(locations.defaultConfigXml, locations.configXml);
|
||||
|
||||
// Then apply config changes from global munge to all config files
|
||||
// in project (including project's config)
|
||||
configMunger.reapply_global_munge().save_all();
|
||||
|
||||
events.emit('verbose', 'Merging project\'s config.xml into platform-specific android config.xml');
|
||||
// Merge changes from app's config.xml into platform's one
|
||||
var config = new ConfigParser(locations.configXml);
|
||||
xmlHelpers.mergeXml(sourceConfig.doc.getroot(),
|
||||
config.doc.getroot(), 'android', /* clobber= */true);
|
||||
|
||||
config.write();
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs all file operations via the verbose event stream, indented.
|
||||
*/
|
||||
function logFileOp (message) {
|
||||
events.emit('verbose', ' ' + message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates platform 'www' directory by replacing it with contents of
|
||||
* 'platform_www' and app www. Also copies project's overrides' folder into
|
||||
* the platform 'www' folder
|
||||
*
|
||||
* @param {Object} cordovaProject An object which describes cordova project.
|
||||
* @param {Object} destinations An object that contains destination
|
||||
* paths for www files.
|
||||
*/
|
||||
function updateWww (cordovaProject, destinations) {
|
||||
var sourceDirs = [
|
||||
path.relative(cordovaProject.root, cordovaProject.locations.www),
|
||||
path.relative(cordovaProject.root, destinations.platformWww)
|
||||
];
|
||||
|
||||
// If project contains 'merges' for our platform, use them as another overrides
|
||||
var merges_path = path.join(cordovaProject.root, 'merges', 'android');
|
||||
if (fs.existsSync(merges_path)) {
|
||||
events.emit('verbose', 'Found "merges/android" folder. Copying its contents into the android project.');
|
||||
sourceDirs.push(path.join('merges', 'android'));
|
||||
}
|
||||
|
||||
var targetDir = path.relative(cordovaProject.root, destinations.www);
|
||||
events.emit(
|
||||
'verbose', 'Merging and updating files from [' + sourceDirs.join(', ') + '] to ' + targetDir);
|
||||
FileUpdater.mergeAndUpdateDir(
|
||||
sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans all files from the platform 'www' directory.
|
||||
*/
|
||||
function cleanWww (projectRoot, locations) {
|
||||
var targetDir = path.relative(projectRoot, locations.www);
|
||||
events.emit('verbose', 'Cleaning ' + targetDir);
|
||||
|
||||
// No source paths are specified, so mergeAndUpdateDir() will clear the target directory.
|
||||
FileUpdater.mergeAndUpdateDir(
|
||||
[], targetDir, { rootDir: projectRoot, all: true }, logFileOp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates project structure and AndroidManifest according to project's configuration.
|
||||
*
|
||||
* @param {ConfigParser} platformConfig A project's configuration that will
|
||||
* be used to update project
|
||||
* @param {Object} locations A map of locations for this platform
|
||||
*/
|
||||
function updateProjectAccordingTo (platformConfig, locations) {
|
||||
// Update app name by editing res/values/strings.xml
|
||||
var strings = xmlHelpers.parseElementtreeSync(locations.strings);
|
||||
|
||||
var name = platformConfig.name();
|
||||
strings.find('string[@name="app_name"]').text = name.replace(/'/g, '\\\'');
|
||||
|
||||
var shortName = platformConfig.shortName && platformConfig.shortName();
|
||||
if (shortName && shortName !== name) {
|
||||
strings.find('string[@name="launcher_name"]').text = shortName.replace(/'/g, '\\\'');
|
||||
}
|
||||
|
||||
fs.writeFileSync(locations.strings, strings.write({ indent: 4 }), 'utf-8');
|
||||
events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings);
|
||||
|
||||
// Java packages cannot support dashes
|
||||
var androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
|
||||
|
||||
var manifest = new AndroidManifest(locations.manifest);
|
||||
var manifestId = manifest.getPackageId();
|
||||
|
||||
manifest.getActivity()
|
||||
.setOrientation(platformConfig.getPreference('orientation'))
|
||||
.setLaunchMode(findAndroidLaunchModePreference(platformConfig));
|
||||
|
||||
manifest.setVersionName(platformConfig.version())
|
||||
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
|
||||
.setPackageId(androidPkgName)
|
||||
.write();
|
||||
|
||||
// Java file paths shouldn't be hard coded
|
||||
const javaDirectory = path.join(locations.javaSrc, manifestId.replace(/\./g, '/'));
|
||||
const javaPattern = /\.java$/;
|
||||
const java_files = utils.scanDirectory(javaDirectory, javaPattern, true).filter(function (f) {
|
||||
return utils.grep(f, /extends\s+CordovaActivity/g) !== null;
|
||||
});
|
||||
|
||||
if (java_files.length === 0) {
|
||||
throw new CordovaError('No Java files found that extend CordovaActivity.');
|
||||
} else if (java_files.length > 1) {
|
||||
events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]);
|
||||
}
|
||||
|
||||
const destFile = java_files[0];
|
||||
|
||||
// var destFile = path.join(locations.root, 'app', 'src', 'main', 'java', androidPkgName.replace(/\./g, '/'), path.basename(java_files[0]));
|
||||
// fs.ensureDirSync(path.dirname(destFile));
|
||||
// events.emit('verbose', java_files[0]);
|
||||
// events.emit('verbose', destFile);
|
||||
// console.log(locations);
|
||||
// fs.copySync(java_files[0], destFile);
|
||||
utils.replaceFileContents(destFile, /package [\w.]*;/, 'package ' + androidPkgName + ';');
|
||||
events.emit('verbose', 'Wrote out Android package name "' + androidPkgName + '" to ' + destFile);
|
||||
|
||||
var removeOrigPkg = checkReqs.isWindows() || checkReqs.isDarwin()
|
||||
? manifestId.toUpperCase() !== androidPkgName.toUpperCase()
|
||||
: manifestId !== androidPkgName;
|
||||
|
||||
if (removeOrigPkg) {
|
||||
// If package was name changed we need to remove old java with main activity
|
||||
fs.removeSync(java_files[0]);
|
||||
// remove any empty directories
|
||||
var currentDir = path.dirname(java_files[0]);
|
||||
var sourcesRoot = path.resolve(locations.root, 'src');
|
||||
while (currentDir !== sourcesRoot) {
|
||||
if (fs.existsSync(currentDir) && fs.readdirSync(currentDir).length === 0) {
|
||||
fs.rmdirSync(currentDir);
|
||||
currentDir = path.resolve(currentDir, '..');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consturct the default value for versionCode as
|
||||
// PATCH + MINOR * 100 + MAJOR * 10000
|
||||
// see http://developer.android.com/tools/publishing/versioning.html
|
||||
function default_versionCode (version) {
|
||||
var nums = version.split('-')[0].split('.');
|
||||
var versionCode = 0;
|
||||
if (+nums[0]) {
|
||||
versionCode += +nums[0] * 10000;
|
||||
}
|
||||
if (+nums[1]) {
|
||||
versionCode += +nums[1] * 100;
|
||||
}
|
||||
if (+nums[2]) {
|
||||
versionCode += +nums[2];
|
||||
}
|
||||
|
||||
events.emit('verbose', 'android-versionCode not found in config.xml. Generating a code based on version in config.xml (' + version + '): ' + versionCode);
|
||||
return versionCode;
|
||||
}
|
||||
|
||||
function getImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||
if (/\.9\.png$/.test(sourceName)) {
|
||||
name = name.replace(/\.png$/, '.9.png');
|
||||
}
|
||||
var resourcePath = path.join(resourcesDir, (density ? type + '-' + density : type), name);
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
function getAdaptiveImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||
if (/\.9\.png$/.test(sourceName)) {
|
||||
name = name.replace(/\.png$/, '.9.png');
|
||||
}
|
||||
var resourcePath = path.join(resourcesDir, (density ? type + '-' + density + '-v26' : type), name);
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
function updateSplashes (cordovaProject, platformResourcesDir) {
|
||||
var resources = cordovaProject.projectConfig.getSplashScreens('android');
|
||||
|
||||
// if there are "splash" elements in config.xml
|
||||
if (resources.length === 0) {
|
||||
events.emit('verbose', 'This app does not have splash screens defined');
|
||||
return;
|
||||
}
|
||||
|
||||
var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'drawable', 'screen.png');
|
||||
|
||||
var hadMdpi = false;
|
||||
resources.forEach(function (resource) {
|
||||
if (!resource.density) {
|
||||
return;
|
||||
}
|
||||
if (resource.density === 'mdpi') {
|
||||
hadMdpi = true;
|
||||
}
|
||||
var targetPath = getImageResourcePath(
|
||||
platformResourcesDir, 'drawable', resource.density, 'screen.png', path.basename(resource.src));
|
||||
resourceMap[targetPath] = resource.src;
|
||||
});
|
||||
|
||||
// There's no "default" drawable, so assume default == mdpi.
|
||||
if (!hadMdpi && resources.defaultResource) {
|
||||
var targetPath = getImageResourcePath(
|
||||
platformResourcesDir, 'drawable', 'mdpi', 'screen.png', path.basename(resources.defaultResource.src));
|
||||
resourceMap[targetPath] = resources.defaultResource.src;
|
||||
}
|
||||
|
||||
events.emit('verbose', 'Updating splash screens at ' + platformResourcesDir);
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||
}
|
||||
|
||||
function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) {
|
||||
var resources = projectConfig.getSplashScreens('android');
|
||||
if (resources.length > 0) {
|
||||
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'drawable', 'screen.png');
|
||||
events.emit('verbose', 'Cleaning splash screens at ' + platformResourcesDir);
|
||||
|
||||
// No source paths are specified in the map, so updatePaths() will delete the target files.
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
|
||||
}
|
||||
}
|
||||
|
||||
function updateIcons (cordovaProject, platformResourcesDir) {
|
||||
const icons = cordovaProject.projectConfig.getIcons('android');
|
||||
|
||||
// Skip if there are no app defined icons in config.xml
|
||||
if (icons.length === 0) {
|
||||
events.emit('verbose', 'This app does not have launcher icons defined');
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. loop icons determin if there is an error in the setup.
|
||||
// 2. during initial loop, also setup for legacy support.
|
||||
const errorMissingAttributes = [];
|
||||
const errorLegacyIconNeeded = [];
|
||||
let hasAdaptive = false;
|
||||
icons.forEach((icon, key) => {
|
||||
if (
|
||||
(icon.background && !icon.foreground) ||
|
||||
(!icon.background && icon.foreground) ||
|
||||
(!icon.background && !icon.foreground && !icon.src)
|
||||
) {
|
||||
errorMissingAttributes.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
|
||||
}
|
||||
|
||||
if (icon.foreground) {
|
||||
hasAdaptive = true;
|
||||
|
||||
if (
|
||||
!icon.src &&
|
||||
(
|
||||
icon.foreground.startsWith('@color') ||
|
||||
path.extname(path.basename(icon.foreground)) === '.xml'
|
||||
)
|
||||
) {
|
||||
errorLegacyIconNeeded.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
|
||||
} else if (!icon.src) {
|
||||
icons[key].src = icon.foreground;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const errorMessage = [];
|
||||
if (errorMissingAttributes.length > 0) {
|
||||
errorMessage.push('One of the following attributes are set but missing the other for the density type: ' + errorMissingAttributes.join(', ') + '. Please ensure that all require attributes are defined.');
|
||||
}
|
||||
|
||||
if (errorLegacyIconNeeded.length > 0) {
|
||||
errorMessage.push('For the following icons with the density of: ' + errorLegacyIconNeeded.join(', ') + ', adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices. To support older Android environments, please provide a value for the src attribute.');
|
||||
}
|
||||
|
||||
if (errorMessage.length > 0) {
|
||||
throw new CordovaError(errorMessage.join(' '));
|
||||
}
|
||||
|
||||
let resourceMap = Object.assign(
|
||||
{},
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
|
||||
);
|
||||
|
||||
const preparedIcons = prepareIcons(icons);
|
||||
|
||||
if (hasAdaptive) {
|
||||
resourceMap = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);
|
||||
}
|
||||
|
||||
resourceMap = updateIconResourceForLegacy(preparedIcons, resourceMap, platformResourcesDir);
|
||||
|
||||
events.emit('verbose', 'Updating icons at ' + platformResourcesDir);
|
||||
FileUpdater.updatePaths(resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||
}
|
||||
|
||||
function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformResourcesDir) {
|
||||
const android_icons = preparedIcons.android_icons;
|
||||
const default_icon = preparedIcons.default_icon;
|
||||
|
||||
// The source paths for icons and splashes are relative to
|
||||
// project's config.xml location, so we use it as base path.
|
||||
let background;
|
||||
let foreground;
|
||||
let targetPathBackground;
|
||||
let targetPathForeground;
|
||||
|
||||
for (const density in android_icons) {
|
||||
let backgroundVal = '@mipmap/ic_launcher_background';
|
||||
let foregroundVal = '@mipmap/ic_launcher_foreground';
|
||||
|
||||
background = android_icons[density].background;
|
||||
foreground = android_icons[density].foreground;
|
||||
|
||||
if (!background || !foreground) {
|
||||
// This icon isn't an adaptive icon, so skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
if (background.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
backgroundVal = background; // Example: @color/background_foobar_1
|
||||
} else if (path.extname(path.basename(background)) === '.xml') {
|
||||
// Vector Use Case
|
||||
targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.xml', path.basename(android_icons[density].background));
|
||||
resourceMap[targetPathBackground] = android_icons[density].background;
|
||||
} else if (path.extname(path.basename(background)) === '.png') {
|
||||
// Images Use Case
|
||||
targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.png', path.basename(android_icons[density].background));
|
||||
resourceMap[targetPathBackground] = android_icons[density].background;
|
||||
}
|
||||
|
||||
if (foreground.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
foregroundVal = foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.xml') {
|
||||
// Vector Use Case
|
||||
targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.xml', path.basename(android_icons[density].foreground));
|
||||
resourceMap[targetPathForeground] = android_icons[density].foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.png') {
|
||||
// Images Use Case
|
||||
targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.png', path.basename(android_icons[density].foreground));
|
||||
resourceMap[targetPathForeground] = android_icons[density].foreground;
|
||||
}
|
||||
|
||||
// create an XML for DPI and set color
|
||||
const icLauncherTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="` + backgroundVal + `" />
|
||||
<foreground android:drawable="` + foregroundVal + `" />
|
||||
</adaptive-icon>`;
|
||||
|
||||
const launcherXmlPath = path.join(platformResourcesDir, 'mipmap-' + density + '-v26', 'ic_launcher.xml');
|
||||
|
||||
// Remove the XML from the resourceMap so the file does not get removed.
|
||||
delete resourceMap[launcherXmlPath];
|
||||
|
||||
fs.writeFileSync(path.resolve(launcherXmlPath), icLauncherTemplate);
|
||||
}
|
||||
|
||||
// There's no "default" drawable, so assume default == mdpi.
|
||||
if (default_icon && !android_icons.mdpi) {
|
||||
let defaultTargetPathBackground;
|
||||
let defaultTargetPathForeground;
|
||||
|
||||
if (background.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
targetPathBackground = default_icon.background;
|
||||
} else if (path.extname(path.basename(background)) === '.xml') {
|
||||
// Vector Use Case
|
||||
defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.xml', path.basename(default_icon.background));
|
||||
resourceMap[defaultTargetPathBackground] = default_icon.background;
|
||||
} else if (path.extname(path.basename(background)) === '.png') {
|
||||
// Images Use Case
|
||||
defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.png', path.basename(default_icon.background));
|
||||
resourceMap[defaultTargetPathBackground] = default_icon.background;
|
||||
}
|
||||
|
||||
if (foreground.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
targetPathForeground = default_icon.foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.xml') {
|
||||
// Vector Use Case
|
||||
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.xml', path.basename(default_icon.foreground));
|
||||
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.png') {
|
||||
// Images Use Case
|
||||
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.png', path.basename(default_icon.foreground));
|
||||
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
|
||||
}
|
||||
}
|
||||
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
function updateIconResourceForLegacy (preparedIcons, resourceMap, platformResourcesDir) {
|
||||
const android_icons = preparedIcons.android_icons;
|
||||
const default_icon = preparedIcons.default_icon;
|
||||
|
||||
// The source paths for icons and splashes are relative to
|
||||
// project's config.xml location, so we use it as base path.
|
||||
for (var density in android_icons) {
|
||||
var targetPath = getImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher.png', path.basename(android_icons[density].src));
|
||||
resourceMap[targetPath] = android_icons[density].src;
|
||||
}
|
||||
|
||||
// There's no "default" drawable, so assume default == mdpi.
|
||||
if (default_icon && !android_icons.mdpi) {
|
||||
var defaultTargetPath = getImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher.png', path.basename(default_icon.src));
|
||||
resourceMap[defaultTargetPath] = default_icon.src;
|
||||
}
|
||||
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
function prepareIcons (icons) {
|
||||
// http://developer.android.com/design/style/iconography.html
|
||||
const SIZE_TO_DENSITY_MAP = {
|
||||
36: 'ldpi',
|
||||
48: 'mdpi',
|
||||
72: 'hdpi',
|
||||
96: 'xhdpi',
|
||||
144: 'xxhdpi',
|
||||
192: 'xxxhdpi'
|
||||
};
|
||||
|
||||
const android_icons = {};
|
||||
let default_icon;
|
||||
|
||||
// find the best matching icon for a given density or size
|
||||
// @output android_icons
|
||||
var parseIcon = function (icon, icon_size) {
|
||||
// do I have a platform icon for that density already
|
||||
var density = icon.density || SIZE_TO_DENSITY_MAP[icon_size];
|
||||
if (!density) {
|
||||
// invalid icon defition ( or unsupported size)
|
||||
return;
|
||||
}
|
||||
var previous = android_icons[density];
|
||||
if (previous && previous.platform) {
|
||||
return;
|
||||
}
|
||||
android_icons[density] = icon;
|
||||
};
|
||||
|
||||
// iterate over all icon elements to find the default icon and call parseIcon
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
var icon = icons[i];
|
||||
var size = icon.width;
|
||||
|
||||
if (!size) {
|
||||
size = icon.height;
|
||||
}
|
||||
|
||||
if (!size && !icon.density) {
|
||||
if (default_icon) {
|
||||
const found = {};
|
||||
const favor = {};
|
||||
|
||||
// populating found icon.
|
||||
if (icon.background && icon.foreground) {
|
||||
found.background = icon.background;
|
||||
found.foreground = icon.foreground;
|
||||
}
|
||||
if (icon.src) {
|
||||
found.src = icon.src;
|
||||
}
|
||||
|
||||
if (default_icon.background && default_icon.foreground) {
|
||||
favor.background = default_icon.background;
|
||||
favor.foreground = default_icon.foreground;
|
||||
}
|
||||
if (default_icon.src) {
|
||||
favor.src = default_icon.src;
|
||||
}
|
||||
|
||||
events.emit('verbose', 'Found extra default icon: ' + JSON.stringify(found) + ' and ignoring in favor of ' + JSON.stringify(favor) + '.');
|
||||
} else {
|
||||
default_icon = icon;
|
||||
}
|
||||
} else {
|
||||
parseIcon(icon, size);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
android_icons: android_icons,
|
||||
default_icon: default_icon
|
||||
};
|
||||
}
|
||||
|
||||
function cleanIcons (projectRoot, projectConfig, platformResourcesDir) {
|
||||
var icons = projectConfig.getIcons('android');
|
||||
|
||||
// Skip if there are no app defined icons in config.xml
|
||||
if (icons.length === 0) {
|
||||
events.emit('verbose', 'This app does not have launcher icons defined');
|
||||
return;
|
||||
}
|
||||
|
||||
const resourceMap = Object.assign(
|
||||
{},
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
|
||||
);
|
||||
|
||||
events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir);
|
||||
|
||||
// No source paths are specified in the map, so updatePaths() will delete the target files.
|
||||
FileUpdater.updatePaths(resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map containing resources of a specified name from all drawable folders in a directory.
|
||||
*/
|
||||
function mapImageResources (rootDir, subDir, type, resourceName) {
|
||||
const pathMap = {};
|
||||
const pattern = new RegExp(type + '+-.+');
|
||||
utils.scanDirectory(path.join(rootDir, subDir), pattern).forEach(function (drawableFolder) {
|
||||
const imagePath = path.join(subDir, path.basename(drawableFolder), resourceName);
|
||||
pathMap[imagePath] = null;
|
||||
});
|
||||
return pathMap;
|
||||
}
|
||||
|
||||
function updateFileResources (cordovaProject, platformDir) {
|
||||
var files = cordovaProject.projectConfig.getFileResources('android');
|
||||
|
||||
// if there are resource-file elements in config.xml
|
||||
if (files.length === 0) {
|
||||
events.emit('verbose', 'This app does not have additional resource files defined');
|
||||
return;
|
||||
}
|
||||
|
||||
var resourceMap = {};
|
||||
files.forEach(function (res) {
|
||||
var targetPath = path.join(platformDir, res.target);
|
||||
resourceMap[targetPath] = res.src;
|
||||
});
|
||||
|
||||
events.emit('verbose', 'Updating resource files at ' + platformDir);
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||
}
|
||||
|
||||
function cleanFileResources (projectRoot, projectConfig, platformDir) {
|
||||
var files = projectConfig.getFileResources('android', true);
|
||||
if (files.length > 0) {
|
||||
events.emit('verbose', 'Cleaning resource files at ' + platformDir);
|
||||
|
||||
var resourceMap = {};
|
||||
files.forEach(function (res) {
|
||||
var filePath = path.join(platformDir, res.target);
|
||||
resourceMap[filePath] = null;
|
||||
});
|
||||
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and validates 'AndroidLaunchMode' prepference from config.xml. Returns
|
||||
* preference value and warns if it doesn't seems to be valid
|
||||
*
|
||||
* @param {ConfigParser} platformConfig A configParser instance for
|
||||
* platform.
|
||||
*
|
||||
* @return {String} Preference's value from config.xml or
|
||||
* default value, if there is no such preference. The default value is
|
||||
* 'singleTop'
|
||||
*/
|
||||
function findAndroidLaunchModePreference (platformConfig) {
|
||||
var launchMode = platformConfig.getPreference('AndroidLaunchMode');
|
||||
if (!launchMode) {
|
||||
// Return a default value
|
||||
return 'singleTop';
|
||||
}
|
||||
|
||||
var expectedValues = ['standard', 'singleTop', 'singleTask', 'singleInstance'];
|
||||
var valid = expectedValues.indexOf(launchMode) >= 0;
|
||||
if (!valid) {
|
||||
// Note: warn, but leave the launch mode as developer wanted, in case the list of options changes in the future
|
||||
events.emit('warn', 'Unrecognized value for AndroidLaunchMode preference: ' +
|
||||
launchMode + '. Expected values are: ' + expectedValues.join(', '));
|
||||
}
|
||||
|
||||
return launchMode;
|
||||
}
|
||||
137
bin/templates/cordova/lib/run.js
vendored
@@ -1,137 +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');
|
||||
var device = require('./device');
|
||||
var PackageType = require('./PackageType');
|
||||
const { CordovaError, events } = require('cordova-common');
|
||||
|
||||
function getInstallTarget (runOptions) {
|
||||
var install_target;
|
||||
if (runOptions.target) {
|
||||
install_target = runOptions.target;
|
||||
} else if (runOptions.device) {
|
||||
install_target = '--device';
|
||||
} else if (runOptions.emulator) {
|
||||
install_target = '--emulator';
|
||||
}
|
||||
|
||||
return install_target;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
var install_target = getInstallTarget(runOptions);
|
||||
|
||||
return Promise.resolve().then(function () {
|
||||
if (!install_target) {
|
||||
// no target given, deploy to device if available, otherwise use the emulator.
|
||||
return device.list().then(function (device_list) {
|
||||
if (device_list.length > 0) {
|
||||
events.emit('warn', 'No target specified, deploying to device \'' + device_list[0] + '\'.');
|
||||
install_target = device_list[0];
|
||||
} else {
|
||||
events.emit('warn', 'No target specified and no devices found, deploying to emulator');
|
||||
install_target = '--emulator';
|
||||
}
|
||||
});
|
||||
}
|
||||
}).then(function () {
|
||||
if (install_target === '--device') {
|
||||
return device.resolveTarget(null);
|
||||
} else if (install_target === '--emulator') {
|
||||
// Give preference to any already started emulators. Else, start one.
|
||||
return emulator.list_started().then(function (started) {
|
||||
return started && started.length > 0 ? started[0] : emulator.start();
|
||||
}).then(function (emulatorId) {
|
||||
return emulator.resolveTarget(emulatorId);
|
||||
});
|
||||
}
|
||||
// They specified a specific device/emulator ID.
|
||||
return device.list().then(function (devices) {
|
||||
if (devices.indexOf(install_target) > -1) {
|
||||
return device.resolveTarget(install_target);
|
||||
}
|
||||
return emulator.list_started().then(function (started_emulators) {
|
||||
if (started_emulators.indexOf(install_target) > -1) {
|
||||
return emulator.resolveTarget(install_target);
|
||||
}
|
||||
return emulator.list_images().then(function (avds) {
|
||||
// if target emulator isn't started, then start it.
|
||||
for (var avd in avds) {
|
||||
if (avds[avd].name === install_target) {
|
||||
return emulator.start(install_target).then(function (emulatorId) {
|
||||
return emulator.resolveTarget(emulatorId);
|
||||
});
|
||||
}
|
||||
}
|
||||
return Promise.reject(new CordovaError(`Target '${install_target}' not found, unable to run project`));
|
||||
});
|
||||
});
|
||||
});
|
||||
}).then(function (resolvedTarget) {
|
||||
return new Promise((resolve) => {
|
||||
const builder = require('./builders/builders').getBuilder();
|
||||
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(builder.fetchBuildResults(buildOptions.buildType, buildOptions.arch));
|
||||
}).then(function (buildResults) {
|
||||
if (resolvedTarget && resolvedTarget.isEmulator) {
|
||||
return emulator.wait_for_boot(resolvedTarget.target).then(function () {
|
||||
return emulator.install(resolvedTarget, buildResults);
|
||||
});
|
||||
}
|
||||
|
||||
return device.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);
|
||||
};
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
97
bin/templates/cordova/lib/utils.js
vendored
@@ -1,97 +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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Provides a set of utility methods, which can also be spied on during unit tests.
|
||||
*/
|
||||
|
||||
// TODO: Perhaps this should live in cordova-common?
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* Reads, searches, and replaces the found occurences with replacementString and then writes the file back out.
|
||||
* A backup is not made.
|
||||
*
|
||||
* @param {string} file A file path to a readable & writable file
|
||||
* @param {RegExp} searchRegex The search regex
|
||||
* @param {string} replacementString The string to replace the found occurences
|
||||
* @returns void
|
||||
*/
|
||||
exports.replaceFileContents = function (file, searchRegex, replacementString) {
|
||||
let contents = fs.readFileSync(file).toString();
|
||||
contents = contents.replace(searchRegex, replacementString);
|
||||
fs.writeFileSync(file, contents);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads a file and scans for regex. Returns the line of the first occurence or null if no occurences are found.
|
||||
*
|
||||
* @param {string} file A file path
|
||||
* @param {RegExp} regex A search regex
|
||||
* @returns string|null
|
||||
*/
|
||||
exports.grep = function (file, regex) {
|
||||
const contents = fs.readFileSync(file).toString().replace(/\\r/g, '').split('\n');
|
||||
for (let i = 0; i < contents.length; i++) {
|
||||
const line = contents[i];
|
||||
if (regex.test(line)) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scans directories and outputs a list of found paths that matches the regex
|
||||
*
|
||||
* @param {string} directory The starting directory
|
||||
* @param {RegExp} regex The search regex
|
||||
* @param {boolean} recursive Enables recursion
|
||||
* @returns Array<string>
|
||||
*/
|
||||
exports.scanDirectory = function (directory, regex, recursive) {
|
||||
let output = [];
|
||||
|
||||
if (fs.existsSync(directory)) {
|
||||
const items = fs.readdirSync(directory);
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
const itemPath = path.join(directory, item);
|
||||
const stats = fs.statSync(itemPath);
|
||||
|
||||
if (regex.test(itemPath)) {
|
||||
output.push(itemPath);
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
if (recursive) {
|
||||
output = output.concat(exports.scanDirectory(itemPath, regex, recursive));
|
||||
} else {
|
||||
// Move onto the next item
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
18
bin/templates/cordova/loggingHelper.js
vendored
@@ -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');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
)
|
||||
1904
bin/templates/project/assets/www/cordova.js
vendored
@@ -1,52 +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'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
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 {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
//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
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
# This file was originally created by the Android Tools, but is now
|
||||
# used by cordova-android to manage the state of the various third party
|
||||
# libraries used in your application
|
||||
|
||||
# This is the Library Module that contains the Cordova Library, this is not
|
||||
# required when using an AAR
|
||||
android.library.reference.1=CordovaLib
|
||||
|
||||
# This is the application project. This is only required for Android Studio Gradle projects
|
||||
android.library.reference.2=app
|
||||
|
||||
# Project target.
|
||||
target=This_gets_replaced
|
||||
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 192 KiB |
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App label shown within list of installed apps, battery & network usage screens. -->
|
||||
<string name="app_name">__NAME__</string>
|
||||
<!-- App label shown on the launcher. -->
|
||||
<string name="launcher_name">@string/app_name</string>
|
||||
<!-- App label shown on the task switcher. -->
|
||||
<string name="activity_name">@string/launcher_name</string>
|
||||
</resources>
|
||||
@@ -1,58 +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.
|
||||
-->
|
||||
<widget xmlns = "http://www.w3.org/ns/widgets"
|
||||
id = "io.cordova.helloCordova"
|
||||
version = "2.0.0">
|
||||
<name>Hello Cordova</name>
|
||||
|
||||
<description>
|
||||
A sample Apache Cordova application that responds to the deviceready event.
|
||||
</description>
|
||||
|
||||
<author href="http://cordova.io" email="dev@cordova.apache.org">
|
||||
Apache Cordova Team
|
||||
</author>
|
||||
|
||||
<!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
|
||||
<content src="index.html" />
|
||||
|
||||
<!-- Whitelist docs: https://github.com/apache/cordova-plugin-whitelist -->
|
||||
<access origin="*" />
|
||||
<!-- Grant certain URLs the ability to launch external applications. This
|
||||
behaviour is set to match that of Cordova versions before 3.6.0, and
|
||||
should be reviewed before launching an application in production. It
|
||||
may be changed in the future. -->
|
||||
<allow-intent href="http://*/*" />
|
||||
<allow-intent href="https://*/*" />
|
||||
<allow-intent href="tel:*" />
|
||||
<allow-intent href="sms:*" />
|
||||
<allow-intent href="mailto:*" />
|
||||
<allow-intent href="geo:*" />
|
||||
<allow-intent href="market:*" />
|
||||
|
||||
<preference name="loglevel" value="DEBUG" />
|
||||
<!--
|
||||
<preference name="splashscreen" value="splash" />
|
||||
<preference name="backgroundColor" value="0xFFF" />
|
||||
<preference name="loadUrlTimeoutValue" value="20000" />
|
||||
<preference name="InAppBrowserStorageEnabled" value="true" />
|
||||
<preference name="disallowOverscroll" value="true" />
|
||||
-->
|
||||
</widget>
|
||||
@@ -1 +0,0 @@
|
||||
//This file is intentionally just a comment
|
||||
40
bin/update
@@ -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;
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
4
cordova-js-src/exec.js
vendored
@@ -91,7 +91,7 @@ function androidExec (success, fail, service, action, args) {
|
||||
var callbackId = service + cordova.callbackId++;
|
||||
var argsJson = JSON.stringify(args);
|
||||
if (success || fail) {
|
||||
cordova.callbacks[callbackId] = { success: success, fail: fail };
|
||||
cordova.callbacks[callbackId] = { success, fail };
|
||||
}
|
||||
|
||||
var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
|
||||
@@ -131,6 +131,8 @@ function pollOnce (opt_fromOnlineEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
androidExec.pollOnce = pollOnce;
|
||||
|
||||
function pollingTimerFunc () {
|
||||
if (pollEnabled) {
|
||||
pollOnce();
|
||||
|
||||
7
cordova-js-src/platform.js
vendored
@@ -36,6 +36,13 @@ module.exports = {
|
||||
// TODO: Extract this as a proper plugin.
|
||||
modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
|
||||
|
||||
// Core Splash Screen
|
||||
modulemapper.clobbers('cordova/plugin/android/splashscreen', 'navigator.splashscreen');
|
||||
|
||||
// Attach the internal statusBar utility to window.statusbar
|
||||
// see the file under plugin/android/statusbar.js
|
||||
modulemapper.clobbers('cordova/plugin/android/statusbar', 'window.statusbar');
|
||||
|
||||
var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
|
||||
|
||||
// Inject a listener for the backbutton on the document.
|
||||
|
||||
4
cordova-js-src/plugin/android/app.js
vendored
@@ -31,14 +31,14 @@ module.exports = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the url into the webview or into new browser instance.
|
||||
* Load the url into the WebView or into new browser instance.
|
||||
*
|
||||
* @param url The URL to load
|
||||
* @param props Properties that can be passed in to the activity:
|
||||
* wait: int => wait msec before loading URL
|
||||
* loadingDialog: "Title,Message" => display a native loading dialog
|
||||
* loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
|
||||
* clearHistory: boolean => clear webview history (default=false)
|
||||
* clearHistory: boolean => clear WebView history (default=false)
|
||||
* openExternal: boolean => open in a new browser (default=false)
|
||||
*
|
||||
* Example:
|
||||
|
||||
33
cordova-js-src/plugin/android/splashscreen.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
*
|
||||
* 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 exec = require('cordova/exec');
|
||||
|
||||
var splashscreen = {
|
||||
show: function () {
|
||||
console.log('"navigator.splashscreen.show()" is unsupported on Android.');
|
||||
},
|
||||
hide: function () {
|
||||
exec(null, null, 'CordovaSplashScreenPlugin', 'hide', []);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = splashscreen;
|
||||
93
cordova-js-src/plugin/android/statusbar.js
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 exec = require('cordova/exec');
|
||||
|
||||
var statusBarVisible = true;
|
||||
var statusBar = {};
|
||||
|
||||
// This <script> element is explicitly used by Cordova's statusbar for computing color. (Do not use this element)
|
||||
const statusBarScript = document.createElement('script');
|
||||
document.head.appendChild(statusBarScript);
|
||||
|
||||
Object.defineProperty(statusBar, 'visible', {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
if (window.StatusBar) {
|
||||
// try to let the StatusBar plugin handle it
|
||||
return window.StatusBar.isVisible;
|
||||
}
|
||||
|
||||
return statusBarVisible;
|
||||
},
|
||||
set: function (value) {
|
||||
if (window.StatusBar) {
|
||||
// try to let the StatusBar plugin handle it
|
||||
if (value) {
|
||||
window.StatusBar.show();
|
||||
} else {
|
||||
window.StatusBar.hide();
|
||||
}
|
||||
} else {
|
||||
statusBarVisible = value;
|
||||
exec(null, null, 'SystemBarPlugin', 'setStatusBarVisible', [!!value]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(statusBar, 'setBackgroundColor', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: function (value) {
|
||||
statusBarScript.style.color = value;
|
||||
var rgbStr = window.getComputedStyle(statusBarScript).getPropertyValue('color');
|
||||
|
||||
if (!rgbStr.match(/^rgb/)) { return; }
|
||||
|
||||
var rgbVals = rgbStr.match(/\d+/g).map(function (v) { return parseInt(v, 10); });
|
||||
|
||||
if (rgbVals.length < 3) {
|
||||
return;
|
||||
} else if (rgbVals.length === 3) {
|
||||
rgbVals = [255].concat(rgbVals);
|
||||
}
|
||||
|
||||
// TODO: Use `padStart(2, '0')` once SDK 24 is dropped.
|
||||
const padRgb = (val) => {
|
||||
const hex = val.toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
};
|
||||
const a = padRgb(rgbVals[0]);
|
||||
const r = padRgb(rgbVals[1]);
|
||||
const g = padRgb(rgbVals[2]);
|
||||
const b = padRgb(rgbVals[3]);
|
||||
const hexStr = '#' + a + r + g + b;
|
||||
|
||||
if (window.StatusBar) {
|
||||
window.StatusBar.backgroundColorByHexString(hexStr);
|
||||
} else {
|
||||
exec(null, null, 'SystemBarPlugin', 'setStatusBarBackgroundColor', rgbVals);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = statusBar;
|
||||
66
eslint.config.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
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 { defineConfig, globalIgnores } = require('eslint/config');
|
||||
const nodeConfig = require('@cordova/eslint-config/node');
|
||||
const nodeTestConfig = require('@cordova/eslint-config/node-tests');
|
||||
const browserConfig = require('@cordova/eslint-config/browser');
|
||||
|
||||
module.exports = defineConfig([
|
||||
globalIgnores([
|
||||
'**/coverage/',
|
||||
'spec/fixtures/',
|
||||
'templates/project/assets/www/cordova.js',
|
||||
'test/android/app',
|
||||
'test/androidx/app'
|
||||
]),
|
||||
{
|
||||
// Include these JavaScript files that do not have file extensions.
|
||||
files: [
|
||||
'templates/cordova/version',
|
||||
'templates/cordova/android_sdk_version',
|
||||
'templates/cordova/lib/list-devices',
|
||||
'templates/cordova/lib/list-emulator-images'
|
||||
]
|
||||
},
|
||||
...nodeConfig,
|
||||
...nodeTestConfig.map(config => ({
|
||||
files: ['spec/**/*.js'],
|
||||
...config,
|
||||
rules: {
|
||||
...(config.rules || {}),
|
||||
'prefer-promise-reject-errors': 'off'
|
||||
}
|
||||
})),
|
||||
...browserConfig.map(config => ({
|
||||
files: [
|
||||
'cordova-js-src/**/*.js',
|
||||
'templates/project/assets/**/*.js'
|
||||
],
|
||||
...config,
|
||||
languageOptions: {
|
||||
...(config?.languageOptions || {}),
|
||||
globals: {
|
||||
...(config.languageOptions?.globals || {}),
|
||||
require: 'readonly',
|
||||
module: 'readonly'
|
||||
}
|
||||
}
|
||||
}))
|
||||
]);
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -18,5 +18,6 @@
|
||||
under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
|
||||
android:versionName="1.0"
|
||||
android:versionCode="1">
|
||||
</manifest>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -16,53 +16,47 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
ext {
|
||||
apply from: 'cordova.gradle'
|
||||
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
||||
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
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}"
|
||||
}
|
||||
|
||||
cdvHelpers.verifyCordovaConfigForBuild()
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
def hasRepositoriesGradle = file('repositories.gradle').exists()
|
||||
if (hasRepositoriesGradle) {
|
||||
apply from: 'repositories.gradle'
|
||||
} else {
|
||||
apply from: "${project.rootDir}/repositories.gradle"
|
||||
}
|
||||
|
||||
repositories repos
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
|
||||
group = 'org.apache.cordova'
|
||||
version = '9.0.0'
|
||||
|
||||
android {
|
||||
compileSdkVersion cdvCompileSdkVersion
|
||||
buildToolsVersion cdvBuildToolsVersion
|
||||
namespace = 'org.apache.cordova'
|
||||
|
||||
compileSdkVersion cordovaConfig.COMPILE_SDK_VERSION
|
||||
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaLanguageVersion.of(cordovaConfig.JAVA_SOURCE_COMPATIBILITY)
|
||||
targetCompatibility JavaLanguageVersion.of(cordovaConfig.JAVA_TARGET_COMPATIBILITY)
|
||||
}
|
||||
|
||||
// For the Android Cordova Lib, we will hardcode the minSdkVersion and not allow changes.
|
||||
// For the Android Cordova Lib, we allow changing the minSdkVersion, but it is at the users own risk
|
||||
defaultConfig {
|
||||
minSdkVersion 22
|
||||
minSdkVersion cordovaConfig.MIN_SDK_VERSION
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -83,66 +77,26 @@ android {
|
||||
exclude 'META-INF/DEPENDENCIES'
|
||||
exclude 'META-INF/NOTICE'
|
||||
}
|
||||
}
|
||||
|
||||
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'
|
||||
|
||||
}
|
||||
}
|
||||
publishing {
|
||||
singleVariant('release') {
|
||||
withSourcesJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
dependencies {
|
||||
api "androidx.appcompat:appcompat:${cordovaConfig.ANDROIDX_APP_COMPAT_VERSION}"
|
||||
implementation "androidx.webkit:webkit:${cordovaConfig.ANDROIDX_WEBKIT_VERSION}"
|
||||
implementation "androidx.core:core-splashscreen:${cordovaConfig.ANDROIDX_CORE_SPLASHSCREEN_VERSION}"
|
||||
}
|
||||
|
||||
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.0.0'
|
||||
released = new Date()
|
||||
vcsTag = '9.0.0'
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
19
framework/cdv-gradle-config-defaults.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"MIN_SDK_VERSION": 24,
|
||||
"SDK_VERSION": 36,
|
||||
"COMPILE_SDK_VERSION": null,
|
||||
"GRADLE_VERSION": "8.14.2",
|
||||
"MIN_BUILD_TOOLS_VERSION": "36.0.0",
|
||||
"AGP_VERSION": "8.10.1",
|
||||
"KOTLIN_VERSION": "2.1.21",
|
||||
"ANDROIDX_APP_COMPAT_VERSION": "1.7.1",
|
||||
"ANDROIDX_WEBKIT_VERSION": "1.14.0",
|
||||
"ANDROIDX_CORE_SPLASHSCREEN_VERSION": "1.0.1",
|
||||
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.4.2",
|
||||
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
|
||||
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false,
|
||||
"PACKAGE_NAMESPACE": "org.apache.cordova.hellocordova",
|
||||
"JAVA_SOURCE_COMPATIBILITY": 11,
|
||||
"JAVA_TARGET_COMPATIBILITY": 11,
|
||||
"KOTLIN_JVM_TARGET": null
|
||||
}
|
||||
121
framework/cordova-publish.gradle
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
groupId = 'org.apache.cordova'
|
||||
artifactId = 'framework'
|
||||
version = getCordovaAndroidVersion()
|
||||
|
||||
from components.release
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
@@ -44,6 +43,10 @@ Boolean isVersionValid(version) {
|
||||
return !(new Version(version)).isEqual('0.0.0')
|
||||
}
|
||||
|
||||
Boolean isVersionGreaterThanEqual(versionX, versionY) {
|
||||
return (new Version(versionX)) >= (new Version(versionY))
|
||||
}
|
||||
|
||||
String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
|
||||
def buildToolsDirContents
|
||||
try {
|
||||
@@ -54,24 +57,27 @@ 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) {
|
||||
throw new RuntimeException("""
|
||||
No installed build tools found. Install the Android build tools
|
||||
version ${minBuildToolsVersionString} or higher.
|
||||
No installed build tools found. Please install the Android build tools
|
||||
version ${minBuildToolsVersionString}.
|
||||
""".replaceAll(/\s+/, ' ').trim())
|
||||
}
|
||||
|
||||
if (highestBuildToolsVersion.isLowerThan(minBuildToolsVersionString)) {
|
||||
throw new RuntimeException("""
|
||||
No usable Android build tools found. Highest installed version is
|
||||
${highestBuildToolsVersion.getOriginalString()}; minimum version
|
||||
required is ${minBuildToolsVersionString}.
|
||||
No usable Android build tools found. Highest ${minBuildToolsVersion.getMajor()}.x installed version is
|
||||
${highestBuildToolsVersion.getOriginalString()}; Recommended version
|
||||
is ${minBuildToolsVersionString}.
|
||||
""".replaceAll(/\s+/, ' ').trim())
|
||||
}
|
||||
|
||||
@@ -81,9 +87,9 @@ String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
|
||||
String getAndroidSdkDir() {
|
||||
def rootDir = project.rootDir
|
||||
def androidSdkDir = null
|
||||
String envVar = System.getenv("ANDROID_SDK_ROOT")
|
||||
String envVar = System.getenv("ANDROID_HOME")
|
||||
if (envVar == null) {
|
||||
envVar = System.getenv("ANDROID_HOME")
|
||||
envVar = System.getenv("ANDROID_SDK_ROOT")
|
||||
}
|
||||
|
||||
def localProperties = new File(rootDir, 'local.properties')
|
||||
@@ -123,38 +129,6 @@ def doExtractIntFromManifest(name) {
|
||||
return new BigInteger(matcher.group(1))
|
||||
}
|
||||
|
||||
def doExtractStringFromManifest(name) {
|
||||
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
|
||||
def pattern = Pattern.compile(name + "=\"(\\S+)\"")
|
||||
def matcher = pattern.matcher(manifestFile.getText())
|
||||
matcher.find()
|
||||
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 +149,84 @@ def doGetConfigPreference(name, defaultValue) {
|
||||
return ret
|
||||
}
|
||||
|
||||
def doApplyCordovaConfigCustomization() {
|
||||
// Apply user override 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('cdvCompileSdkVersion')) {
|
||||
cordovaConfig.COMPILE_SDK_VERSION = Integer.parseInt('' + cdvCompileSdkVersion)
|
||||
}
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
def doVerifyCordovaConfigForBuild() {
|
||||
if (cordovaConfig.COMPILE_SDK_VERSION < cordovaConfig.SDK_VERSION) {
|
||||
println "The \"compileSdkVersion\" (${cordovaConfig.COMPILE_SDK_VERSION}) should be greater than or equal to the the \"targetSdkVersion\" (${cordovaConfig.SDK_VERSION})."
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
if (cordovaConfig.COMPILE_SDK_VERSION == null) {
|
||||
cordovaConfig.COMPILE_SDK_VERSION = cordovaConfig.SDK_VERSION
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -192,14 +235,15 @@ ext {
|
||||
cdvHelpers.getConfigXml = { doGetConfigXml() }
|
||||
// Returns the value for the desired <preference>. Added in 4.1.0.
|
||||
cdvHelpers.getConfigPreference = { name, defaultValue -> doGetConfigPreference(name, defaultValue) }
|
||||
// Display warnings if any cordova config is not proper for build.
|
||||
cdvHelpers.verifyCordovaConfigForBuild = { doVerifyCordovaConfigForBuild() }
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
apply from: 'repositories.gradle'
|
||||
repositories repos
|
||||
|
||||
dependencies {
|
||||
classpath 'com.g00fy2:versioncompare:1.3.4@jar'
|
||||
classpath 'io.github.g00fy2:versioncompare:1.4.1@jar'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=
|
||||
36
framework/gradle.properties
Normal file
@@ -0,0 +1,36 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# 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
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
@@ -1,6 +1,22 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#Thu Nov 09 10:50:25 PST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# GENERATED FILE! DO NOT EDIT!
|
||||
|
||||
# This file was originally created by the Android Tools, but is now
|
||||
# used by cordova-android to manage the project configuration.
|
||||
|
||||
@@ -5,7 +24,6 @@
|
||||
split.density=false
|
||||
|
||||
# Project target.
|
||||
target=android-29
|
||||
apk-configurations=
|
||||
renderscript.opt.level=O0
|
||||
android.library=true
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
wrapper {
|
||||
gradleVersion = '6.5'
|
||||
ext.repos = {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
@@ -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)) {
|
||||
160
framework/src/org/apache/cordova/AllowListPlugin.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
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 plugin developers 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);
|
||||
} 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 (Boolean.TRUE.equals(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;
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,7 @@ public class AuthenticationToken {
|
||||
/**
|
||||
* Sets the user name.
|
||||
*
|
||||
* @param userName
|
||||
* the new user name
|
||||
* @param userName the new user name
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
@@ -56,8 +55,7 @@ public class AuthenticationToken {
|
||||
/**
|
||||
* Sets the password.
|
||||
*
|
||||
* @param password
|
||||
* the new password
|
||||
* @param password the new password
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
|
||||
@@ -51,7 +51,8 @@ public class BuildHelper {
|
||||
{
|
||||
try
|
||||
{
|
||||
Class<?> clazz = Class.forName(ctx.getClass().getPackage().getName() + ".BuildConfig");
|
||||
String packageName = ctx.getApplicationInfo().packageName;
|
||||
Class<?> clazz = Class.forName(packageName + ".BuildConfig");
|
||||
Field field = clazz.getField(key);
|
||||
return field.get(null);
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
@@ -61,6 +61,15 @@ public class CallbackContext {
|
||||
webView.sendPluginResult(pluginResult, callbackId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for success callbacks that just returns the Status.OK by default
|
||||
*
|
||||
* @param message The message to add to the success result.
|
||||
*/
|
||||
public void success(boolean message) {
|
||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for success callbacks that just returns the Status.OK by default
|
||||
*
|
||||
|
||||
@@ -54,7 +54,7 @@ public class CallbackMap {
|
||||
* obtained from registerCallback()
|
||||
*
|
||||
* @param mappedId The request code obtained from registerCallback()
|
||||
* @return The CordovaPlugin and orignal request code that correspond to the
|
||||
* @return The CordovaPlugin and original request code that correspond to the
|
||||
* given mappedCode
|
||||
*/
|
||||
public synchronized Pair<CordovaPlugin, Integer> getAndRemoveCallback(int mappedId) {
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
@Deprecated // Use Whitelist, CordovaPrefences, etc. directly.
|
||||
@Deprecated // Use AllowList, CordovaPreferences, etc. directly.
|
||||
public class Config {
|
||||
private static final String TAG = "Config";
|
||||
|
||||
|
||||