Compare commits
488 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
5276f56cc4 | ||
|
|
9df6793f34 | ||
|
|
d90e191837 | ||
|
|
d5d448888d | ||
|
|
8d8600b442 | ||
|
|
0bf6455153 | ||
|
|
80b7a7f6ac | ||
|
|
6b789c57e8 | ||
|
|
b8a344fc17 | ||
|
|
1b6319e9cf | ||
|
|
2cc81253ff | ||
|
|
499c694146 | ||
|
|
bc32cca281 | ||
|
|
dead4b4ab6 | ||
|
|
305cb2cdd5 | ||
|
|
287bfcbaa3 | ||
|
|
2a61b751ab | ||
|
|
a830145f36 | ||
|
|
08dc1dd9b9 | ||
|
|
e86b211cd1 | ||
|
|
6c5febc189 | ||
|
|
4d0d60c294 | ||
|
|
16a88ec631 | ||
|
|
1ce2b6b315 | ||
|
|
43a6805902 | ||
|
|
566262c923 | ||
|
|
e4bff281b2 | ||
|
|
9a675912f8 | ||
|
|
f86044e6ce | ||
|
|
43fdaa91a3 | ||
|
|
80f46aefcd | ||
|
|
71f63d7b33 | ||
|
|
8d47cd73c0 | ||
|
|
6d451bc6f9 | ||
|
|
6402e7b755 | ||
|
|
c93f93f637 | ||
|
|
6e51943d15 | ||
|
|
c81cd871f8 | ||
|
|
8ab1dbc373 | ||
|
|
fb26050fab | ||
|
|
c56cd4d5a8 | ||
|
|
de105e8651 | ||
|
|
8e98de6e7c | ||
|
|
6372ca3fac | ||
|
|
3712619f5c | ||
|
|
dee1e77d0b | ||
|
|
d01ed80a61 | ||
|
|
92268b2e76 | ||
|
|
0924654a47 | ||
|
|
8ef742e79d | ||
|
|
64ef13c6e0 | ||
|
|
66ad2c948e | ||
|
|
60e022fedd | ||
|
|
09256b766f | ||
|
|
a951793431 | ||
|
|
f4b8f44d4a | ||
|
|
08ab7d4b59 | ||
|
|
5889001465 | ||
|
|
91d2716122 | ||
|
|
0e6ad28e56 | ||
|
|
fd57909730 | ||
|
|
e3cc75caff | ||
|
|
e26142f43b | ||
|
|
d0f972e128 | ||
|
|
e42fedc820 | ||
|
|
f0c9814c04 | ||
|
|
529278190c | ||
|
|
fcaab36484 | ||
|
|
5dfa995a4b | ||
|
|
c35a990c09 | ||
|
|
11f40bd2cc | ||
|
|
7e8b47d012 | ||
|
|
902aa32dda | ||
|
|
42c0cba7f7 | ||
|
|
f2b84d8d83 | ||
|
|
1b11206174 | ||
|
|
c93e3e9f6f | ||
|
|
9808a0d4d3 | ||
|
|
bd1697dbd2 | ||
|
|
b3b8690bbd | ||
|
|
ad742ec93c | ||
|
|
1de7c38134 | ||
|
|
997943a194 | ||
|
|
47c6048d53 | ||
|
|
a64d459c8e | ||
|
|
a5ad440f17 | ||
|
|
acad24d62a | ||
|
|
989b4cc913 | ||
|
|
38c6627999 | ||
|
|
4b9e18c6b8 | ||
|
|
906f8cc002 | ||
|
|
01ab11644c | ||
|
|
4cf3dcfaae | ||
|
|
b177f84825 | ||
|
|
485e6e0e4d | ||
|
|
516c3411aa | ||
|
|
908354e7fa | ||
|
|
9531dbbc7b | ||
|
|
d10dd1c0b4 | ||
|
|
6533474070 | ||
|
|
576edb53bb | ||
|
|
20e390af85 | ||
|
|
931251a5a8 | ||
|
|
9697550488 | ||
|
|
3dac984613 | ||
|
|
867da56e2e | ||
|
|
719acd3ab1 | ||
|
|
549cae0a06 | ||
|
|
bb45f4f3ba | ||
|
|
b4de6f55c4 | ||
|
|
e99c145d55 | ||
|
|
9cb9f32fbb | ||
|
|
a6f30b6977 | ||
|
|
73692e60d8 | ||
|
|
4abe3d3a49 | ||
|
|
54df4a116c | ||
|
|
715ce2f9ac | ||
|
|
7a98708eef | ||
|
|
d9c08f12a7 | ||
|
|
e41fbc5708 | ||
|
|
634f92efb6 | ||
|
|
98a7b759e8 | ||
|
|
3976685e4e | ||
|
|
f7688bc64e | ||
|
|
18e28294d6 | ||
|
|
39bd0d6463 | ||
|
|
c1819cc027 | ||
|
|
f228d90ca2 | ||
|
|
5f44af3757 | ||
|
|
8a4ae311ce | ||
|
|
ef2434188e | ||
|
|
a014228f7c | ||
|
|
2163c8ae05 | ||
|
|
47bb5184a0 | ||
|
|
f1f1ac3cbd | ||
|
|
f1396c7aad | ||
|
|
21ae48eada | ||
|
|
53e1c1b65c | ||
|
|
858611f95e | ||
|
|
5c334b6c10 | ||
|
|
cf5a02ea0f | ||
|
|
a67bc75b93 | ||
|
|
895ab0c970 | ||
|
|
21f84732c8 | ||
|
|
7eed65e9b4 | ||
|
|
cf5915ad01 | ||
|
|
a4caa87d29 | ||
|
|
bbb3913a36 | ||
|
|
92f07d0418 | ||
|
|
578a642209 | ||
|
|
9d03e4ec0a | ||
|
|
576ad183e7 | ||
|
|
e31596f60e | ||
|
|
ef493b4c0f | ||
|
|
c15312ee70 | ||
|
|
3caefcae49 | ||
|
|
c2f6631f91 | ||
|
|
fb1dfb27df | ||
|
|
898a6a8d8d | ||
|
|
7da53741cd | ||
|
|
47aabc631d | ||
|
|
fb75ac371d | ||
|
|
98c866704a | ||
|
|
e58453d3e6 | ||
|
|
03c62e1ce2 | ||
|
|
2c10545cd8 | ||
|
|
ff2ec7eed1 | ||
|
|
8dfddef6f9 | ||
|
|
73edf4de7b | ||
|
|
cfa58a5661 | ||
|
|
905bff3d59 | ||
|
|
eadcd33e84 | ||
|
|
76fe89dd1f | ||
|
|
3f487c5c28 | ||
|
|
c35a46ec45 | ||
|
|
e3eb933182 | ||
|
|
dacb0e5c72 | ||
|
|
23b24491c3 | ||
|
|
7ab0cf123d | ||
|
|
8f2a4c7231 | ||
|
|
ce53154555 | ||
|
|
c0188ab95a | ||
|
|
ebbd91f87d | ||
|
|
4b0725dfc2 | ||
|
|
350d35fb24 | ||
|
|
8ee3a73dd1 | ||
|
|
b6e4598e7c | ||
|
|
bd2ad99402 | ||
|
|
d26c1199ab | ||
|
|
1ea7c1366a | ||
|
|
b2263fe35e | ||
|
|
bd07907a4c | ||
|
|
ca8931c8af | ||
|
|
46a036ef26 | ||
|
|
e9750b5cab | ||
|
|
0bf0e48698 | ||
|
|
4f1aa97ea9 | ||
|
|
f90f004dea | ||
|
|
559b0833b4 | ||
|
|
31bad290d5 | ||
|
|
2e88f7ead2 | ||
|
|
1a8154c90e | ||
|
|
8fb49ec7ec | ||
|
|
393dad6349 | ||
|
|
2c3db19310 | ||
|
|
472ab626d6 | ||
|
|
2106e2e081 | ||
|
|
d3c80ea5d5 | ||
|
|
6dad25668c | ||
|
|
d862d42e76 | ||
|
|
828b5f053a | ||
|
|
032d1fa9cb | ||
|
|
83ad646734 | ||
|
|
88c25a6a6a | ||
|
|
a254cfc841 | ||
|
|
0d4b9f4ba6 | ||
|
|
bf29fe0e10 | ||
|
|
3df8f8b120 | ||
|
|
38d0e684f1 | ||
|
|
83e9aefff5 | ||
|
|
02ee925103 | ||
|
|
fc69da7a42 | ||
|
|
5dc179ebef | ||
|
|
59e3b907e9 | ||
|
|
fe7629e8fc | ||
|
|
76180d3ea1 | ||
|
|
5c4f8ca246 | ||
|
|
b8530a6b70 | ||
|
|
83686542b2 | ||
|
|
b1551cad98 | ||
|
|
5af6b016c1 | ||
|
|
6abd6d6b47 | ||
|
|
e456a325f9 | ||
|
|
eddad666ff | ||
|
|
ca9a25e860 | ||
|
|
8d9a1b82dd | ||
|
|
f1b57dd9b4 | ||
|
|
d2a0323ae4 | ||
|
|
3a339ba37f | ||
|
|
e9603b0738 | ||
|
|
3d83fd784b | ||
|
|
38a5f891a4 | ||
|
|
8563c8beef | ||
|
|
f91102ee07 | ||
|
|
cc08e9d84a | ||
|
|
075d38117a | ||
|
|
6cc4896690 | ||
|
|
673a6773b2 | ||
|
|
3a6923988d | ||
|
|
0d1692681f | ||
|
|
fcf705e007 | ||
|
|
5c93c214b9 | ||
|
|
7cbb8401a2 | ||
|
|
b3c262cd47 | ||
|
|
45a7b90c6c | ||
|
|
e1c3b4fd94 | ||
|
|
109112ae75 | ||
|
|
a24ba41eda | ||
|
|
be3f8ef80d | ||
|
|
d50dedb5d0 | ||
|
|
74e9e213d6 | ||
|
|
d8d92cae61 | ||
|
|
99d5b4d982 | ||
|
|
52fd32c837 | ||
|
|
061f08bc03 | ||
|
|
735bc98243 | ||
|
|
e53a65ef07 | ||
|
|
3642ffb57a | ||
|
|
3dcc319cd2 | ||
|
|
8484f7b906 | ||
|
|
59018ab632 | ||
|
|
c6cfeb15f4 | ||
|
|
adc7dab377 | ||
|
|
a9e01f4309 | ||
|
|
0269e532df | ||
|
|
4863320e45 | ||
|
|
2b20802dbb | ||
|
|
30c3713dca | ||
|
|
9d9bac397b | ||
|
|
d8f10c33dc | ||
|
|
5d57eff612 | ||
|
|
43956c1bc8 | ||
|
|
2930900963 | ||
|
|
3acba59494 | ||
|
|
b77febc7a7 | ||
|
|
f54336eb61 | ||
|
|
18d6884522 | ||
|
|
8ba0109e55 | ||
|
|
f50ca85a95 | ||
|
|
3ba00f91bb | ||
|
|
cbee8580d0 | ||
|
|
6ccd6b009b | ||
|
|
6cf6e20d2e | ||
|
|
8743e88550 | ||
|
|
f3c238db1c | ||
|
|
2534a3c767 | ||
|
|
b1f527e682 | ||
|
|
7d282426c4 | ||
|
|
0d98e09fb1 | ||
|
|
f18086f83a | ||
|
|
8fdb16c555 | ||
|
|
e91b19d006 | ||
|
|
46905ebe99 | ||
|
|
5fe95570d2 | ||
|
|
d0dab4bb09 | ||
|
|
00c879e27d | ||
|
|
b65af106ff | ||
|
|
fdd7eb3446 | ||
|
|
99f15c507d | ||
|
|
849b887e20 | ||
|
|
245d9a1e46 | ||
|
|
a7304b9a19 | ||
|
|
e456175a81 | ||
|
|
b20028c42b | ||
|
|
1cda7a9de0 | ||
|
|
49b76f5c71 | ||
|
|
c0474e811d | ||
|
|
40c9709445 | ||
|
|
b67e9905bc | ||
|
|
c74192d578 | ||
|
|
33feb00e8f | ||
|
|
8f16df4c90 | ||
|
|
fb6cb51e64 | ||
|
|
28ebbb8f02 | ||
|
|
bd4ddcdedd | ||
|
|
e621edfba7 | ||
|
|
304a899114 | ||
|
|
8391af2e8f | ||
|
|
69ab6a0e0d | ||
|
|
a216f0db75 | ||
|
|
69260fb96a | ||
|
|
db87e0ae6a | ||
|
|
8ead919fae | ||
|
|
b73c04f3c8 | ||
|
|
f790aeb8f6 | ||
|
|
7b17abc555 | ||
|
|
ffadf5dd51 | ||
|
|
23d8d99925 | ||
|
|
d88df59c32 |
46
.asf.yaml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
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
|
||||||
|
pullrequests_status: issues@cordova.apache.org
|
||||||
|
pullrequests_comment: issues@cordova.apache.org
|
||||||
@@ -1 +1,3 @@
|
|||||||
bin/templates/project/assets/www/cordova.js
|
templates/project/assets/www/cordova.js
|
||||||
|
test/android/app
|
||||||
|
test/androidx/app
|
||||||
|
|||||||
@@ -1,10 +1,27 @@
|
|||||||
root: true
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
extends: semistandard
|
# or more contributor license agreements. See the NOTICE file
|
||||||
rules:
|
# distributed with this work for additional information
|
||||||
indent:
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
- error
|
# to you under the Apache License, Version 2.0 (the
|
||||||
- 4
|
# "License"); you may not use this file except in compliance
|
||||||
camelcase: off
|
# with the License. You may obtain a copy of the License at
|
||||||
padded-blocks: off
|
#
|
||||||
operator-linebreak: off
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
no-throw-literal: off
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
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'
|
||||||
|
|||||||
42
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!--
|
||||||
|
Please have a look at the issue templates you get when you click "New issue" in the GitHub UI.
|
||||||
|
We very much prefer issues created by using one of these templates.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Issue Type
|
||||||
|
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
|
||||||
|
|
||||||
|
- [ ] Bug Report
|
||||||
|
- [ ] Feature Request
|
||||||
|
- [ ] Support Question
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
## Information
|
||||||
|
<!-- Include all relevant information that might help understand and reproduce the problem -->
|
||||||
|
|
||||||
|
### Command or Code
|
||||||
|
<!-- What command or code is needed to reproduce the problem? -->
|
||||||
|
|
||||||
|
### Environment, Platform, Device
|
||||||
|
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Version information
|
||||||
|
<!--
|
||||||
|
What are relevant versions you are using?
|
||||||
|
For example:
|
||||||
|
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
|
||||||
|
Other Frameworks: Ionic Framework and CLI version
|
||||||
|
Operating System, Android Studio, Xcode etc.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
<!-- Please check the boxes by putting an `x` in the `[ ]` like so: `[x]` -->
|
||||||
|
|
||||||
|
- [ ] I searched for already existing GitHub issues about this
|
||||||
|
- [ ] I updated all Cordova tooling to their most recent version
|
||||||
|
- [ ] I included all the necessary information above
|
||||||
50
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
name: 🐛 Bug Report
|
||||||
|
about: If something isn't working as expected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bug Report
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
### What is expected to happen?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### What does actually happen?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Information
|
||||||
|
<!-- Include all relevant information that might help understand and reproduce the problem -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Command or Code
|
||||||
|
<!-- What command or code is needed to reproduce the problem? -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Environment, Platform, Device
|
||||||
|
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Version information
|
||||||
|
<!--
|
||||||
|
What are relevant versions you are using?
|
||||||
|
For example:
|
||||||
|
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
|
||||||
|
Other Frameworks: Ionic Framework and CLI version
|
||||||
|
Operating System, Android Studio, Xcode etc.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
|
||||||
|
|
||||||
|
- [ ] I searched for existing GitHub issues
|
||||||
|
- [ ] I updated all Cordova tooling to most recent version
|
||||||
|
- [ ] I included all the necessary information above
|
||||||
29
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
name: 🚀 Feature Request
|
||||||
|
about: A suggestion for a new functionality
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Feature Request
|
||||||
|
|
||||||
|
## Motivation Behind Feature
|
||||||
|
<!-- Why should this feature be implemented? What problem does it solve? -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Feature Description
|
||||||
|
<!--
|
||||||
|
Describe your feature request in detail
|
||||||
|
Please provide any code examples or screenshots of what this feature would look like
|
||||||
|
Are there any drawbacks? Will this break anything for existing users?
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Alternatives or Workarounds
|
||||||
|
<!--
|
||||||
|
Describe alternatives or workarounds you are currently using
|
||||||
|
Are there ways to do this with existing functionality?
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
27
.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
name: 💬 Support Question
|
||||||
|
about: If you have a question, please check out our Slack or StackOverflow!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!------------^ Click "Preview" for a nicer view! -->
|
||||||
|
|
||||||
|
Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
|
||||||
|
For usage and support questions, please check out the resources below. Thanks!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
You can get answers to your usage and support questions about **Apache Cordova** on:
|
||||||
|
|
||||||
|
* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
|
||||||
|
* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
|
||||||
|
|
||||||
|
* **Ionic Framework**
|
||||||
|
* [Ionic Community Forum](https://forum.ionicframework.com/)
|
||||||
|
* [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
|
||||||
|
* **PhoneGap**
|
||||||
|
* [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)
|
||||||
27
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
Please make sure the checklist boxes are all checked before submitting the PR. The checklist
|
Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines:
|
||||||
is intended as a quick reference, for complete details please see our Contributor Guidelines:
|
|
||||||
|
|
||||||
http://cordova.apache.org/contribute/contribute_guidelines.html
|
http://cordova.apache.org/contribute/contribute_guidelines.html
|
||||||
|
|
||||||
@@ -10,13 +9,27 @@ Thanks!
|
|||||||
### Platforms affected
|
### Platforms affected
|
||||||
|
|
||||||
|
|
||||||
### What does this PR do?
|
|
||||||
|
### Motivation and Context
|
||||||
|
<!-- Why is this change required? What problem does it solve? -->
|
||||||
|
<!-- If it fixes an open issue, please link to the issue here. -->
|
||||||
|
|
||||||
|
|
||||||
### What testing has been done on this change?
|
|
||||||
|
### Description
|
||||||
|
<!-- Describe your changes in detail -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
<!-- Please describe in detail how you tested your changes. -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Checklist
|
### Checklist
|
||||||
- [ ] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
|
|
||||||
- [ ] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
|
- [ ] I've run the tests to see all new and existing tests pass
|
||||||
- [ ] Added automated test coverage as appropriate for this change.
|
- [ ] I added automated test coverage as appropriate for this change
|
||||||
|
- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
|
||||||
|
- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
|
||||||
|
- [ ] I've updated the documentation if necessary
|
||||||
|
|||||||
61
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# 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: Node CI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: NodeJS ${{ matrix.node-version }} on ${{ matrix.os }}
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [12.x, 14.x, 16.x]
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
|
- name: set up JDK 1.8
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 1.8
|
||||||
|
|
||||||
|
- name: Environment Information
|
||||||
|
run: |
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
gradle --version
|
||||||
|
|
||||||
|
- name: npm install and test
|
||||||
|
run: |
|
||||||
|
npm i
|
||||||
|
npm t
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
|
||||||
|
- uses: codecov/codecov-action@v1
|
||||||
|
with:
|
||||||
|
fail_ci_if_error: true
|
||||||
110
.gitignore
vendored
@@ -25,11 +25,16 @@ example
|
|||||||
/framework/libs
|
/framework/libs
|
||||||
/framework/javadoc-public
|
/framework/javadoc-public
|
||||||
/framework/javadoc-private
|
/framework/javadoc-private
|
||||||
|
|
||||||
|
**/assets/www/cordova.js
|
||||||
|
|
||||||
/test/.externalNativeBuild
|
/test/.externalNativeBuild
|
||||||
/test/build.gradle
|
|
||||||
/test/gradle
|
/test/androidx/gradle
|
||||||
/test/gradlew
|
/test/androidx/gradlew
|
||||||
/test/gradlew.bat
|
/test/androidx/gradlew.bat
|
||||||
|
/test/androidx/cdv-gradle-config.json
|
||||||
|
|
||||||
/test/assets/www/.tmp*
|
/test/assets/www/.tmp*
|
||||||
/test/assets/www/cordova.js
|
/test/assets/www/cordova.js
|
||||||
/test/bin
|
/test/bin
|
||||||
@@ -43,93 +48,10 @@ tmp/**/*
|
|||||||
**/.idea/**/*
|
**/.idea/**/*
|
||||||
*.iml
|
*.iml
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
node_modules/jshint
|
node_modules/
|
||||||
node_modules/promise-matchers
|
coverage/
|
||||||
node_modules/jasmine
|
.nyc_output/
|
||||||
node_modules/rewire
|
# Eclipse Buildship files
|
||||||
node_modules/istanbul
|
.project
|
||||||
node_modules/.bin/cake
|
.settings
|
||||||
node_modules/.bin/coffee
|
.classpath
|
||||||
node_modules/.bin/escodegen
|
|
||||||
node_modules/.bin/esgenerate
|
|
||||||
node_modules/.bin/esparse
|
|
||||||
node_modules/.bin/esvalidate
|
|
||||||
node_modules/.bin/handlebars
|
|
||||||
node_modules/.bin/istanbul
|
|
||||||
node_modules/.bin/jasmine
|
|
||||||
node_modules/.bin/js-yaml
|
|
||||||
node_modules/.bin/jshint
|
|
||||||
node_modules/.bin/mkdirp
|
|
||||||
node_modules/.bin/r.js
|
|
||||||
node_modules/.bin/r_js
|
|
||||||
node_modules/.bin/strip-json-comments
|
|
||||||
node_modules/.bin/uglifyjs
|
|
||||||
node_modules/.bin/which
|
|
||||||
node_modules/align-text/
|
|
||||||
node_modules/amdefine/
|
|
||||||
node_modules/argparse/
|
|
||||||
node_modules/async/
|
|
||||||
node_modules/camelcase/
|
|
||||||
node_modules/center-align/
|
|
||||||
node_modules/cli/
|
|
||||||
node_modules/cliui/
|
|
||||||
node_modules/coffee-script/
|
|
||||||
node_modules/console-browserify/
|
|
||||||
node_modules/core-util-is/
|
|
||||||
node_modules/date-now/
|
|
||||||
node_modules/decamelize/
|
|
||||||
node_modules/deep-is/
|
|
||||||
node_modules/dom-serializer/
|
|
||||||
node_modules/domelementtype/
|
|
||||||
node_modules/domhandler/
|
|
||||||
node_modules/domutils/
|
|
||||||
node_modules/entities/
|
|
||||||
node_modules/escodegen/
|
|
||||||
node_modules/esprima/
|
|
||||||
node_modules/estraverse/
|
|
||||||
node_modules/esutils/
|
|
||||||
node_modules/exit/
|
|
||||||
node_modules/fast-levenshtein/
|
|
||||||
node_modules/fileset/
|
|
||||||
node_modules/gaze/
|
|
||||||
node_modules/growl/
|
|
||||||
node_modules/handlebars/
|
|
||||||
node_modules/has-flag/
|
|
||||||
node_modules/htmlparser2/
|
|
||||||
node_modules/is-buffer/
|
|
||||||
node_modules/isarray/
|
|
||||||
node_modules/isexe/
|
|
||||||
node_modules/jasmine-growl-reporter/
|
|
||||||
node_modules/jasmine-reporters/
|
|
||||||
node_modules/js-yaml/
|
|
||||||
node_modules/kind-of/
|
|
||||||
node_modules/lazy-cache/
|
|
||||||
node_modules/levn/
|
|
||||||
node_modules/longest/
|
|
||||||
node_modules/lru-cache/
|
|
||||||
node_modules/minimist/
|
|
||||||
node_modules/mkdirp/
|
|
||||||
node_modules/optimist/
|
|
||||||
node_modules/optionator/
|
|
||||||
node_modules/prelude-ls/
|
|
||||||
node_modules/readable-stream/
|
|
||||||
node_modules/repeat-string/
|
|
||||||
node_modules/requirejs/
|
|
||||||
node_modules/resolve/
|
|
||||||
node_modules/right-align/
|
|
||||||
node_modules/sigmund/
|
|
||||||
node_modules/source-map/
|
|
||||||
node_modules/sprintf-js/
|
|
||||||
node_modules/string_decoder/
|
|
||||||
node_modules/strip-json-comments/
|
|
||||||
node_modules/supports-color/
|
|
||||||
node_modules/type-check/
|
|
||||||
node_modules/uglify-js/
|
|
||||||
node_modules/uglify-to-browserify/
|
|
||||||
node_modules/walkdir/
|
|
||||||
node_modules/which/
|
|
||||||
node_modules/window-size/
|
|
||||||
node_modules/wordwrap/
|
|
||||||
node_modules/yargs/
|
|
||||||
node_modules/jasmine-core/
|
|
||||||
node_modules/fs.realpath/
|
|
||||||
|
|||||||
6
.npmignore
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.*
|
||||||
|
coverage
|
||||||
|
test
|
||||||
|
spec
|
||||||
|
framework/build
|
||||||
|
cordova-js-src
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
*.properties
|
*.properties
|
||||||
bin
|
templates
|
||||||
gen
|
gen
|
||||||
proguard-project.txt
|
proguard-project.txt
|
||||||
spec
|
spec
|
||||||
appveyor.yml
|
|
||||||
framework/build
|
framework/build
|
||||||
ic_launcher.png
|
ic_launcher.png
|
||||||
|
build
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
GUESS_FIELDS = True
|
GUESS_FIELDS = True
|
||||||
OPEN_BROWSER = True
|
OPEN_BROWSER = True
|
||||||
TARGET_GROUPS = 'cordova'
|
TARGET_GROUPS = 'cordova'
|
||||||
REVIEWBOARD_URL = 'http://reviews.apache.org'
|
REVIEWBOARD_URL = 'https://reviews.apache.org'
|
||||||
|
|
||||||
|
|||||||
28
.travis.yml
@@ -1,28 +0,0 @@
|
|||||||
language: android
|
|
||||||
sudo: false
|
|
||||||
jdk:
|
|
||||||
- oraclejdk8
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- ANDROID_TOOLS=${ANDROID_HOME}/tools
|
|
||||||
before_install:
|
|
||||||
- nvm install 6
|
|
||||||
# ensure at least gradle 3.3 is in place.
|
|
||||||
- wget http://services.gradle.org/distributions/gradle-3.3-bin.zip
|
|
||||||
- unzip gradle-3.3-bin.zip
|
|
||||||
- export GRADLE_HOME=$PWD/gradle-3.3
|
|
||||||
- export PATH=${GRADLE_HOME}/bin:${ANDROID_HOME}:${ANDROID_HOME}/emulator:${ANDROID_TOOLS}:${ANDROID_TOOLS}/bin:${ANDROID_HOME}/platform-tools:$PATH
|
|
||||||
- node --version
|
|
||||||
- gradle --version
|
|
||||||
- echo y | android --silent update sdk --no-ui --all --filter platform-tools,tools,build-tools-26.0.2,android-26,android-25,extra-google-m2repository,extra-android-m2repository
|
|
||||||
android:
|
|
||||||
components:
|
|
||||||
- tools
|
|
||||||
install:
|
|
||||||
- npm install
|
|
||||||
- npm install -g codecov
|
|
||||||
script:
|
|
||||||
- npm test
|
|
||||||
- npm run cover
|
|
||||||
after_script:
|
|
||||||
- codecov
|
|
||||||
@@ -25,13 +25,12 @@ Anyone can contribute to Cordova. And we need your contributions.
|
|||||||
|
|
||||||
There are multiple ways to contribute: report bugs, improve the docs, and
|
There are multiple ways to contribute: report bugs, improve the docs, and
|
||||||
contribute code.
|
contribute code.
|
||||||
|
|
||||||
For instructions on this, start with the
|
For instructions on this, start with the
|
||||||
[contribution overview](http://cordova.apache.org/contribute/).
|
[contribution overview](http://cordova.apache.org/contribute/).
|
||||||
|
|
||||||
The details are explained there, but the important items are:
|
The details are explained there, but the important items are:
|
||||||
- Sign and submit an Apache ICLA (Contributor License Agreement).
|
- Check for Github issues that corresponds to your contribution and link or create them if necessary.
|
||||||
- Have a Jira issue open that corresponds to your contribution.
|
|
||||||
- Run the tests so your patch doesn't break existing functionality.
|
- Run the tests so your patch doesn't break existing functionality.
|
||||||
|
|
||||||
We look forward to your contributions!
|
We look forward to your contributions!
|
||||||
|
|||||||
114
LICENSE
@@ -187,7 +187,7 @@
|
|||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2015 Apache Cordova
|
Copyright 2015-2020 Apache Cordova
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -200,115 +200,3 @@
|
|||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
ADDITIONAL LICENSES:
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
bin/node_modules/q
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
Copyright 2009–2012 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/shelljs
|
|
||||||
================================================================================
|
|
||||||
Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
You may use this project under the terms of the New BSD license as follows:
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Artur Adib nor the
|
|
||||||
names of the contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
bin/node_modules/nopt
|
|
||||||
================================================================================
|
|
||||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
|
||||||
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/which
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
14
NOTICE
@@ -1,15 +1,5 @@
|
|||||||
Apache Cordova
|
Apache Cordova
|
||||||
Copyright 2015 The Apache Software Foundation
|
Copyright 2015-2020 The Apache Software Foundation
|
||||||
|
|
||||||
This product includes software developed at
|
This product includes software developed at
|
||||||
The Apache Software Foundation (http://www.apache.org)
|
The Apache Software Foundation (http://www.apache.org/).
|
||||||
|
|
||||||
=========================================================================
|
|
||||||
== NOTICE file corresponding to the section 4 d of ==
|
|
||||||
== the Apache License, Version 2.0, ==
|
|
||||||
== in this case for the Android-specific code. ==
|
|
||||||
=========================================================================
|
|
||||||
|
|
||||||
This product includes software developed as part of
|
|
||||||
The Android Open Source Project (http://source.android.com).
|
|
||||||
|
|
||||||
|
|||||||
63
README.md
@@ -19,52 +19,53 @@
|
|||||||
#
|
#
|
||||||
-->
|
-->
|
||||||
|
|
||||||
[](https://ci.appveyor.com/project/Humbedooh/cordova-android)
|
|
||||||
[](https://travis-ci.org/apache/cordova-android)
|
|
||||||
[](https://codecov.io/github/apache/cordova-android?branch=master)
|
|
||||||
|
|
||||||
# Cordova Android
|
# Cordova Android
|
||||||
|
|
||||||
Cordova Android is an Android application library that allows for Cordova-based
|
[](https://nodei.co/npm/cordova-android/)
|
||||||
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).
|
[](https://github.com/apache/cordova-android/actions?query=branch%3Amaster)
|
||||||
|
[](https://codecov.io/github/apache/cordova-android?branch=master)
|
||||||
|
|
||||||
:warning: Report issues on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Android%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)
|
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)](https://apache.org/).
|
||||||
|
|
||||||
## Requires
|
## Requirements
|
||||||
|
|
||||||
- Java JDK 1.8 or greater
|
* Java Development Kit (JDK) 11
|
||||||
- Android SDK [http://developer.android.com](http://developer.android.com)
|
* [Android SDK](https://developer.android.com/)
|
||||||
|
* [Node.js](https://nodejs.org)
|
||||||
|
|
||||||
|
## Create a Cordova project
|
||||||
|
|
||||||
## Cordova Android Developer Tools
|
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/)
|
||||||
|
|
||||||
We recommend using the [Cordova command-line tool](https://www.npmjs.com/package/cordova) to create projects and be able to easily install plugins.
|
To use a **shared framework**, for example in development, link the appropriate cordova-android platform folder path:
|
||||||
|
|
||||||
However, the following scripts can be used instead:
|
```bash
|
||||||
|
cordova platform add --link /path/to/cordova-android
|
||||||
|
```
|
||||||
|
|
||||||
./bin/create [path package activity] ... creates the ./example app or a cordova android project
|
## Updating a Cordova project
|
||||||
./bin/check_reqs ....................... checks that your environment is set up for cordova-android development
|
|
||||||
./bin/update [path] .................... updates an existing cordova-android project to the version of the framework
|
|
||||||
|
|
||||||
These commands live in a generated Cordova Android project. Any interactions with the emulator require you to have an AVD defined.
|
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:
|
||||||
|
|
||||||
./cordova/clean ........................ cleans the project
|
```bash
|
||||||
./cordova/build ........................ calls `clean` then compiles the project
|
cordova platform rm android
|
||||||
./cordova/log ........................ streams device or emulator logs to STDOUT
|
cordova platform add android
|
||||||
./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
|
|
||||||
|
|
||||||
## Using Android Studio
|
## Debugging in Android Studio
|
||||||
|
|
||||||
1. Create a project
|
Import project in Android Studio through _File > Open_ and targeting `/path/to/your-cdv-project/platforms/android/`.
|
||||||
2. Import it via "Non-Android Studio Project"
|
|
||||||
|
|
||||||
## Running the Native Tests
|
## How to Test Repo Development
|
||||||
|
|
||||||
The `test/` directory in this project contains an Android test project that can
|
```bash
|
||||||
be used to run different kinds of native tests. Check out the
|
npm install
|
||||||
[README contained therein](test/README.md) for more details!
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Further reading
|
||||||
|
|
||||||
|
* [Apache Cordova](https://cordova.apache.org/)
|
||||||
|
|||||||
401
RELEASENOTES.md
@@ -18,7 +18,406 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
-->
|
-->
|
||||||
## Release Notes for Cordova (Android) ##
|
## Release Notes for Cordova (Android)
|
||||||
|
|
||||||
|
### 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
|
||||||
|
* [GH-971](https://github.com/apache/cordova-android/pull/971) fix: Accept multiple mime types on file input
|
||||||
|
* [GH-1001](https://github.com/apache/cordova-android/pull/1001) fix: support both adaptive and standard icons at the same time
|
||||||
|
* [GH-985](https://github.com/apache/cordova-android/pull/985) fix: Plugin install fails when preview sdk is installed
|
||||||
|
* [GH-994](https://github.com/apache/cordova-android/pull/994) chore: cleanup yaml files
|
||||||
|
* [GH-999](https://github.com/apache/cordova-android/pull/999) chore: remove trailing spaces from Java sources
|
||||||
|
* [GH-992](https://github.com/apache/cordova-android/pull/992) chore: update some dependencies
|
||||||
|
* [GH-998](https://github.com/apache/cordova-android/pull/998) chore: remove trailing spaces from framework build files
|
||||||
|
* [GH-997](https://github.com/apache/cordova-android/pull/997) chore: remove trailing spaces from project template
|
||||||
|
* [GH-996](https://github.com/apache/cordova-android/pull/996) chore: remove trailing spaces from bat files
|
||||||
|
* [GH-995](https://github.com/apache/cordova-android/pull/995) remove trailing spaces from markdown files
|
||||||
|
* [GH-993](https://github.com/apache/cordova-android/pull/993) chore: update `devDependencies`
|
||||||
|
* [GH-987](https://github.com/apache/cordova-android/pull/987) breaking: reduce combined response cutoff to 16 MB
|
||||||
|
* [GH-988](https://github.com/apache/cordova-android/pull/988) major: Gradle 6.5 & **Android** Gradle plugin 4.0.0 updates
|
||||||
|
* [GH-990](https://github.com/apache/cordova-android/pull/990) chore: remove trailing spaces from `app/build.gradle`
|
||||||
|
* [GH-989](https://github.com/apache/cordova-android/pull/989) breaking: remove `legacy/build.gradle` from template
|
||||||
|
* [GH-978](https://github.com/apache/cordova-android/pull/978) fix: `wait_for_boot` waiting forever
|
||||||
|
* [GH-965](https://github.com/apache/cordova-android/pull/965) fix: Increased `detectArchitecture()` timeout
|
||||||
|
* [GH-962](https://github.com/apache/cordova-android/pull/962) breaking: Bump **Android** gradle plugin to 3.6.0
|
||||||
|
* [GH-948](https://github.com/apache/cordova-android/pull/948) feature: JVM Args flag
|
||||||
|
* [GH-951](https://github.com/apache/cordova-android/pull/951) fix: `ANDROID_SDK_ROOT` variable
|
||||||
|
* [GH-959](https://github.com/apache/cordova-android/pull/959) test: synced AndroidX gradle versions to the same version as the **Android** test
|
||||||
|
* [GH-960](https://github.com/apache/cordova-android/pull/960) feat: `com.android.tools.build:gradle:3.5.3`
|
||||||
|
* [GH-956](https://github.com/apache/cordova-android/pull/956) chore(npm): add `package-lock.json`
|
||||||
|
* [GH-958](https://github.com/apache/cordova-android/pull/958) chore(npm): add ignore list
|
||||||
|
* [GH-957](https://github.com/apache/cordova-android/pull/957) chore: various cleanup
|
||||||
|
* [GH-955](https://github.com/apache/cordova-android/pull/955) chore(eslint): bump package & apply eslint fix
|
||||||
|
* [GH-954](https://github.com/apache/cordova-android/pull/954) breaking(npm): bump packages
|
||||||
|
* [GH-953](https://github.com/apache/cordova-android/pull/953) chore(npm): use short notation in `package.json`
|
||||||
|
* [GH-823](https://github.com/apache/cordova-android/pull/823) fix: prevent exit fullscreen mode from closing application
|
||||||
|
* [GH-950](https://github.com/apache/cordova-android/pull/950) fix: removed redundent logcat print
|
||||||
|
* [GH-915](https://github.com/apache/cordova-android/pull/915) breaking: bump minSdkVersion to 22 and drop pre-Lollipop specific code
|
||||||
|
* [GH-941](https://github.com/apache/cordova-android/pull/941) fix: GH-873 App bundle builds to obey command-line arguments
|
||||||
|
* [GH-940](https://github.com/apache/cordova-android/pull/940) ci: drop travis & move codecov to gh-actions
|
||||||
|
* [GH-929](https://github.com/apache/cordova-android/pull/929) chore: updated `README` to reflect what **Android** requires more accurately, which is Java 8, not anything less, not anything greater. Java 1.8.x is required.
|
||||||
|
* [GH-937](https://github.com/apache/cordova-android/pull/937) fix: GH-935 replaced `compare-func` with native sort method
|
||||||
|
* [GH-939](https://github.com/apache/cordova-android/pull/939) fix: test failure with shebang interpreter in `rewired` files
|
||||||
|
* [GH-911](https://github.com/apache/cordova-android/pull/911) refactor: use es6 class
|
||||||
|
* [GH-910](https://github.com/apache/cordova-android/pull/910) refactor (eslint): use `cordova-eslint`
|
||||||
|
* [GH-909](https://github.com/apache/cordova-android/pull/909) chore: remove appveyor residual
|
||||||
|
* [GH-895](https://github.com/apache/cordova-android/pull/895) feat: add github actions
|
||||||
|
* [GH-842](https://github.com/apache/cordova-android/pull/842) refactor: remove `shelljs` dependency
|
||||||
|
* [GH-896](https://github.com/apache/cordova-android/pull/896) feat: add Kotlin support
|
||||||
|
* [GH-901](https://github.com/apache/cordova-android/pull/901) feat: add AndroidX support
|
||||||
|
* [GH-849](https://github.com/apache/cordova-android/pull/849) fix: cordova requirements consider the `android-targetSdkVersion`
|
||||||
|
* [GH-904](https://github.com/apache/cordova-android/pull/904) fix (adb): shell to return expected stdout
|
||||||
|
* [GH-792](https://github.com/apache/cordova-android/pull/792) feat: upgrade `gradle` to 6.1 & gradle build tools to 3.5.3
|
||||||
|
* [GH-902](https://github.com/apache/cordova-android/pull/902) chore: remove `.project` file & add `.settings` to `gitignore`
|
||||||
|
* [GH-900](https://github.com/apache/cordova-android/pull/900) refactor: simplify `doFindLatestInstalledBuildTools`
|
||||||
|
* [GH-751](https://github.com/apache/cordova-android/pull/751) feat: use Java package name for loading `BuildConfig`
|
||||||
|
* [GH-898](https://github.com/apache/cordova-android/pull/898) chore: rename gradle plugin google services `preference` options
|
||||||
|
* [GH-893](https://github.com/apache/cordova-android/pull/893) feat: add Google Services support
|
||||||
|
* [GH-709](https://github.com/apache/cordova-android/pull/709) feat: add `version-compare` library to compare `build-tools` versions properly.
|
||||||
|
* [GH-831](https://github.com/apache/cordova-android/pull/831) chore: ignore auto-generated eclipse buildship files
|
||||||
|
* [GH-848](https://github.com/apache/cordova-android/pull/848) breaking: increased default target sdk to 29
|
||||||
|
* [GH-859](https://github.com/apache/cordova-android/pull/859) breaking: removed unnecessary project name restriction
|
||||||
|
* [GH-833](https://github.com/apache/cordova-android/pull/833) chore: drop `q` module
|
||||||
|
* [GH-862](https://github.com/apache/cordova-android/pull/862) chore: replace `superspawn` & `child_process` with `execa`
|
||||||
|
* [GH-860](https://github.com/apache/cordova-android/pull/860) feat: don't filter gradle's stderr anymore
|
||||||
|
* [GH-832](https://github.com/apache/cordova-android/pull/832) chore: drop node 6 and 8 support
|
||||||
|
* [GH-890](https://github.com/apache/cordova-android/pull/890) chore: bump version to 9.0.0-dev
|
||||||
|
* [GH-697](https://github.com/apache/cordova-android/pull/697) chore: optimization code
|
||||||
|
* [GH-863](https://github.com/apache/cordova-android/pull/863) chore: removed comment that serves no purpose
|
||||||
|
* [GH-861](https://github.com/apache/cordova-android/pull/861) chore: update `jasmine` to 3.5.0
|
||||||
|
* [GH-858](https://github.com/apache/cordova-android/pull/858) chore: modernize our one E2E test
|
||||||
|
* [GH-854](https://github.com/apache/cordova-android/pull/854) chore: ensure to lint as many files as possible
|
||||||
|
|
||||||
|
### 8.1.0 (Sep 11, 2019)
|
||||||
|
|
||||||
|
* [GH-827](https://github.com/apache/cordova-android/pull/827) chore: bump dependencies for release 8.1.0
|
||||||
|
* [GH-651](https://github.com/apache/cordova-android/pull/651) feat: added multiple selection for filepicker
|
||||||
|
* [GH-672](https://github.com/apache/cordova-android/pull/672) chore: compress files in /res with tinypng.com
|
||||||
|
* [GH-815](https://github.com/apache/cordova-android/pull/815) fix: `clean` command
|
||||||
|
* [GH-750](https://github.com/apache/cordova-android/pull/750) Don't request focus explicitly if not needed
|
||||||
|
* [GH-800](https://github.com/apache/cordova-android/pull/800) [GH-799](https://github.com/apache/cordova-android/pull/799) (android) Stop webview from restarting when activity resizes
|
||||||
|
* [GH-764](https://github.com/apache/cordova-android/pull/764) feat: Build app bundles (.aab files)
|
||||||
|
* [GH-788](https://github.com/apache/cordova-android/pull/788) Simplify `apkSorter` using `compare-func` package
|
||||||
|
* [GH-787](https://github.com/apache/cordova-android/pull/787) Simplify and fix promise handling in specs
|
||||||
|
* [GH-784](https://github.com/apache/cordova-android/pull/784) Properly handle promise in create script
|
||||||
|
* [GH-783](https://github.com/apache/cordova-android/pull/783) Do not clobber process properties with test mocks
|
||||||
|
* [GH-782](https://github.com/apache/cordova-android/pull/782) Do not clobber `console.log` to spy on it
|
||||||
|
* [GH-724](https://github.com/apache/cordova-android/pull/724) Add Node.js 12 to CI Services
|
||||||
|
* [GH-777](https://github.com/apache/cordova-android/pull/777) ci(travis): set `dist: trusty` in `.travis.yml`
|
||||||
|
* [GH-779](https://github.com/apache/cordova-android/pull/779) Consistent order from `ProjectBuilder.apkSorter`
|
||||||
|
* [GH-778](https://github.com/apache/cordova-android/pull/778) test: use verbose spec reporter
|
||||||
|
* [GH-774](https://github.com/apache/cordova-android/pull/774) `rewire` workaround for NodeJS 12
|
||||||
|
* [GH-772](https://github.com/apache/cordova-android/pull/772) `nyc@14` update in devDependencies
|
||||||
|
* [GH-765](https://github.com/apache/cordova-android/pull/765) ci(travis): Fix **Android** SDK
|
||||||
|
* [GH-713](https://github.com/apache/cordova-android/pull/713) Do not explicitly require modules from project directory
|
||||||
|
* [GH-676](https://github.com/apache/cordova-android/pull/676) Added allprojects repositories for Framework Release Builds
|
||||||
|
* [GH-699](https://github.com/apache/cordova-android/pull/699) Improve Gradle Build Arguments
|
||||||
|
* [GH-710](https://github.com/apache/cordova-android/pull/710) Fix deprecation warning in `SystemCookieManager`
|
||||||
|
* [GH-691](https://github.com/apache/cordova-android/pull/691) [GH-690](https://github.com/apache/cordova-android/pull/690): Run `prepare` with the correct `ConfigParser`
|
||||||
|
* [GH-673](https://github.com/apache/cordova-android/pull/673) Updated `Android_HOME` Test to Follow [GH-656](https://github.com/apache/cordova-android/pull/656) Change
|
||||||
|
|
||||||
|
### 8.0.0 (Feb 13, 2019)
|
||||||
|
* [GH-669](https://github.com/apache/cordova-android/pull/669) Added Missing License Headers
|
||||||
|
* [GH-655](https://github.com/apache/cordova-android/pull/655) Use custom Gradle properties to read minSdkVersion value from `config.xml`
|
||||||
|
* [GH-656](https://github.com/apache/cordova-android/pull/656) Quick fix to support **Android**_SDK_ROOT
|
||||||
|
* [GH-632](https://github.com/apache/cordova-android/pull/632) Ignore more Gradle build artifacts in **Android** project
|
||||||
|
* [GH-642](https://github.com/apache/cordova-android/pull/642) **Android** tools 3.3 & **Gradle** 4.10.3 update
|
||||||
|
* [GH-654](https://github.com/apache/cordova-android/pull/654) Quick updates to top-level `project.properties`
|
||||||
|
* [GH-635](https://github.com/apache/cordova-android/pull/635) Ignore **Android** Studio `.idea` files in project
|
||||||
|
* [GH-624](https://github.com/apache/cordova-android/pull/624) Add missing log to Java version check
|
||||||
|
* [GH-630](https://github.com/apache/cordova-android/pull/630) Update `emulator.js` to fix issue [GH-608](https://github.com/apache/cordova-android/pull/608)
|
||||||
|
* [GH-626](https://github.com/apache/cordova-android/pull/626) Added `package-lock.json` to `.gitignore`
|
||||||
|
* [GH-620](https://github.com/apache/cordova-android/pull/620) Fix requirements error messages for JDK 8
|
||||||
|
* [GH-619](https://github.com/apache/cordova-android/pull/619) javac error message fixes in requirements check
|
||||||
|
* [GH-612](https://github.com/apache/cordova-android/pull/612) Android Platform Release Preparation (Cordova 9)
|
||||||
|
* [GH-607](https://github.com/apache/cordova-android/pull/607) Copy `node_modules` if the directory exists
|
||||||
|
* [GH-582](https://github.com/apache/cordova-android/pull/582) Improve Test `README`
|
||||||
|
* [GH-589](https://github.com/apache/cordova-android/pull/589) Rewrite install dir resolution for legacy plugins
|
||||||
|
* [GH-572](https://github.com/apache/cordova-android/pull/572) Resolve issue with plugin `target-dir="app*"` subdirs
|
||||||
|
* [GH-567](https://github.com/apache/cordova-android/pull/567) Output current package name if package name can't be validated
|
||||||
|
* [GH-507](https://github.com/apache/cordova-android/pull/507) Gradle Updates
|
||||||
|
* [GH-559](https://github.com/apache/cordova-android/pull/559) Eslint ignore version file
|
||||||
|
* [GH-550](https://github.com/apache/cordova-android/pull/550) Fix for old plugins with non-Java sources
|
||||||
|
* [GH-558](https://github.com/apache/cordova-android/pull/558) Update `cordova.js` from `cordova-js@4.2.3`
|
||||||
|
* [GH-553](https://github.com/apache/cordova-android/pull/553) Check for `build-extras.gradle` in the app-parent directory
|
||||||
|
* [GH-551](https://github.com/apache/cordova-android/pull/551) Add missing cast for `cdvMinSdkVersion`
|
||||||
|
* [GH-539](https://github.com/apache/cordova-android/pull/539) Fix destination path fallback
|
||||||
|
* [GH-544](https://github.com/apache/cordova-android/pull/544) Remove obsolete check for JellyBean
|
||||||
|
* [GH-465](https://github.com/apache/cordova-android/pull/465) Removes Gradle property in-line command arguments for `gradle.properties`
|
||||||
|
* [GH-523](https://github.com/apache/cordova-android/pull/523) Always put the Google repo above jcenter
|
||||||
|
* [GH-486](https://github.com/apache/cordova-android/pull/486) Change deprecated "compile" to "implementation"
|
||||||
|
* [GH-495](https://github.com/apache/cordova-android/pull/495) Incorrect default sdk version issue fix
|
||||||
|
* [GH-493](https://github.com/apache/cordova-android/pull/493) Remove bundled dependencies
|
||||||
|
* [GH-490](https://github.com/apache/cordova-android/pull/490) Fixes build & run related bugs from builder refactor
|
||||||
|
* [GH-464](https://github.com/apache/cordova-android/pull/464) Unit tests for **Android**_sdk and **Android**Project
|
||||||
|
* [GH-448](https://github.com/apache/cordova-android/pull/448) [CB-13685](https://issues.apache.org/jira/browse/CB-13685) Adaptive Icon Support
|
||||||
|
* [GH-487](https://github.com/apache/cordova-android/pull/487) Do not attempt an activity intent AND a url load into the webview, return from the internal webview load.
|
||||||
|
* [GH-461](https://github.com/apache/cordova-android/pull/461) Remove old builders code
|
||||||
|
* [GH-463](https://github.com/apache/cordova-android/pull/463) Emulator: Add unit tests and remove Q
|
||||||
|
* [GH-462](https://github.com/apache/cordova-android/pull/462) Device: Add unit tests and remove Q
|
||||||
|
* [GH-457](https://github.com/apache/cordova-android/pull/457) Emulator: handle "device still connecting" error
|
||||||
|
* [GH-445](https://github.com/apache/cordova-android/pull/445) Run and retryPromise improvements and tests
|
||||||
|
* [GH-453](https://github.com/apache/cordova-android/pull/453) Lint JS files w/out extension too
|
||||||
|
* [GH-452](https://github.com/apache/cordova-android/pull/452) Emit log event instead of logging directly
|
||||||
|
* [GH-449](https://github.com/apache/cordova-android/pull/449) Increase old plugin compatibility
|
||||||
|
* [GH-442](https://github.com/apache/cordova-android/pull/442) Fixes and cleanup for Java tests and CI
|
||||||
|
* [GH-446](https://github.com/apache/cordova-android/pull/446) [CB-14101](https://issues.apache.org/jira/browse/CB-14101) Fix Java version check for Java >= 9
|
||||||
|
* [CB-14127](https://issues.apache.org/jira/browse/CB-14127) Move google maven repo ahead of jcenter
|
||||||
|
* [CB-14038](https://issues.apache.org/jira/browse/CB-14038) Fix false positive detecting project type
|
||||||
|
* [CB-14008](https://issues.apache.org/jira/browse/CB-14008) Updating Gradle Libraries to work with **Android** Studio 3.1.0
|
||||||
|
* [CB-13975](https://issues.apache.org/jira/browse/CB-13975) Fix to fire pause event when cdvStartInBackground=true
|
||||||
|
* [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.
|
||||||
|
* [CB-13800](https://issues.apache.org/jira/browse/CB-13800) Drop pre-KitKat specific code
|
||||||
|
* [CB-13724](https://issues.apache.org/jira/browse/CB-13724) Updated the **Android** Tooling required for the latest version on both the test project, and the template
|
||||||
|
* [CB-13724](https://issues.apache.org/jira/browse/CB-13724) Bump Target SDK to API 27
|
||||||
|
* [CB-13646](https://issues.apache.org/jira/browse/CB-13646) Using the deprecated `NDK` by default breaks the build. Crosswalk users need to specify the Gradle parameters to keep it working.
|
||||||
|
* [CB-12218](https://issues.apache.org/jira/browse/CB-12218) Fix consistency of null result message
|
||||||
|
* [CB-13571](https://issues.apache.org/jira/browse/CB-13571) Prevent crash with unrecognized **Android** version
|
||||||
|
* [CB-13721](https://issues.apache.org/jira/browse/CB-13721) Fix build apps that use `cdvHelpers.getConfigPreference`
|
||||||
|
* [CB-13621](https://issues.apache.org/jira/browse/CB-13621) Wrote similar warning to [CB-12948](https://issues.apache.org/jira/browse/CB-12948) on **iOS**. We no longer support `cordova update` command.
|
||||||
|
|
||||||
|
### 7.0.0 (Nov 30, 2017)
|
||||||
|
* [CB-13612](https://issues.apache.org/jira/browse/CB-13612) Fix the remapper so that XML files copy over and the Camera works again.
|
||||||
|
* [CB-13741](https://issues.apache.org/jira/browse/CB-13741) Bump `package.json` so we can install plugins
|
||||||
|
* [CB-13610](https://issues.apache.org/jira/browse/CB-13610) Compress the default app assets
|
||||||
|
* [CB-12835](https://issues.apache.org/jira/browse/CB-12835) add a Context getter in CordovaInterface
|
||||||
|
* [CB-8976](https://issues.apache.org/jira/browse/CB-8976) Added the `cdvVersionCodeForceAbiDigit` flag to the template build.gradle that appends 0 to the versionCode when `cdvBuildMultipleApks` is not set
|
||||||
|
* [CB-12291](https://issues.apache.org/jira/browse/CB-12291) (android) Add x86_64, arm64 and armeabi architecture flavors
|
||||||
|
* [CB-13602](https://issues.apache.org/jira/browse/CB-13602) We were setting the path wrong, this is hacky but it works
|
||||||
|
* [CB-13601](https://issues.apache.org/jira/browse/CB-13601) Fixing the standalone run scripts to make sure this works without using the CLI
|
||||||
|
* [CB-13580](https://issues.apache.org/jira/browse/CB-13580) fix build for multiple apks (different product flavors)
|
||||||
|
* [CB-13558](https://issues.apache.org/jira/browse/CB-13558) Upgrading the gradle so we can upload the AAR
|
||||||
|
* [CB-13297](https://issues.apache.org/jira/browse/CB-13297) This just works once you bump the project structure. Java 1.8 compatibility baked-in
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) **Android** Studio 3 work, things have changed with how the platform is built
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Found bug where the gradle subproject changes weren't actually getting written to the correct gradle file
|
||||||
|
* [CB-13470](https://issues.apache.org/jira/browse/CB-13470) Fix Clean so that it cleans the **Android** Studio structure
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Adding specs for resource files inside an **Android** Studio Project
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Added remapping for drawables
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Found bug in Api.js where xml/strings.xml is used instead of values/strings.xml
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Setup Api.js to support multiple builders based on project structure
|
||||||
|
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Changing directory creation, will most likely hide this behind a flag for the next release of `cordova-android`, and then make it default in the next major pending feedback
|
||||||
|
* Adding the Studio Builder to build a project based on **Android** Studio, and deleting Ant, since Google does not support Ant Builds anymore. Sorry guys!
|
||||||
|
|
||||||
### 6.4.0 (Nov 06, 2017)
|
### 6.4.0 (Nov 06, 2017)
|
||||||
* [CB-13289](https://issues.apache.org/jira/browse/CB-13289) Fixing build problems with Studio Three, but keeping **Windows** Gradle fix for now, will be deprecated
|
* [CB-13289](https://issues.apache.org/jira/browse/CB-13289) Fixing build problems with Studio Three, but keeping **Windows** Gradle fix for now, will be deprecated
|
||||||
|
|||||||
38
appveyor.yml
@@ -1,38 +0,0 @@
|
|||||||
image:
|
|
||||||
- Previous Visual Studio 2015
|
|
||||||
|
|
||||||
environment:
|
|
||||||
ANDROID_HOME: "C:\\android"
|
|
||||||
matrix:
|
|
||||||
- nodejs_version: "4"
|
|
||||||
- nodejs_version: "6"
|
|
||||||
- nodejs_version: "8"
|
|
||||||
|
|
||||||
init:
|
|
||||||
- mkdir "%ANDROID_HOME%
|
|
||||||
- cd "%ANDROID_HOME%"
|
|
||||||
- appveyor DownloadFile "https://dl.google.com/android/repository/tools_r25.2.3-windows.zip"
|
|
||||||
- 7z x "tools_r25.2.3-windows.zip" > nul
|
|
||||||
- cd "C:\projects\cordova-android"
|
|
||||||
|
|
||||||
install:
|
|
||||||
- choco install gradle -version 3.4.1
|
|
||||||
- gradle -version
|
|
||||||
- echo y | "%ANDROID_HOME%\tools\android.bat" --silent update sdk --no-ui --all --filter platform-tools,tools,build-tools-26.0.2,android-26,android-25,extra-google-m2repository,extra-android-m2repository
|
|
||||||
# on windows we need to accept sublicenses for the new tooling, wee. 30 is an arbitrary number,
|
|
||||||
# but should be the maximum number of licenses we explicitly need to type "Y ENTER" for.
|
|
||||||
# also, the sdkmanager in all its glory leaks a bit of output to stderr, and powershell
|
|
||||||
# and appveyor interpret that as errors, and blows up. so, when piping in our "Y ENTER"
|
|
||||||
# responses, we invoke cmd so we can redirect stderr to stdout, and tell it to --update itself.
|
|
||||||
- ps: for($i=0;$i -lt 30;$i++) { $response += "y`n"}; $response | cmd /c 'C:\android\tools\bin\sdkmanager.bat 2>&1' --update
|
|
||||||
- ps: Install-Product node $env:nodejs_version
|
|
||||||
- npm install
|
|
||||||
# below is a workaround on using gradle installed via choco on appveyor
|
|
||||||
- set path=C:\ProgramData\chocolatey\lib\gradle\tools\gradle-3.4.1\bin;%path%
|
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- node --version
|
|
||||||
- npm --version
|
|
||||||
- npm test
|
|
||||||
@@ -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
|
|
||||||
)
|
|
||||||
58
bin/create
@@ -1,58 +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).done();
|
|
||||||
@@ -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,348 +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 shell = require('shelljs');
|
|
||||||
var Q = require('q');
|
|
||||||
var path = require('path');
|
|
||||||
var fs = require('fs');
|
|
||||||
var check_reqs = require('./../templates/cordova/lib/check_reqs');
|
|
||||||
var ROOT = path.join(__dirname, '..', '..');
|
|
||||||
|
|
||||||
var MIN_SDK_VERSION = 16;
|
|
||||||
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
|
||||||
|
|
||||||
// Export all helper functions, and make sure internally within this module, we
|
|
||||||
// reference these methods via the `exports` object - this helps with testing
|
|
||||||
// (since we can then mock and control behaviour of all of these functions)
|
|
||||||
exports.validatePackageName = validatePackageName;
|
|
||||||
exports.validateProjectName = validateProjectName;
|
|
||||||
exports.setShellFatal = setShellFatal;
|
|
||||||
exports.copyJsAndLibrary = copyJsAndLibrary;
|
|
||||||
exports.copyScripts = copyScripts;
|
|
||||||
exports.copyBuildRules = copyBuildRules;
|
|
||||||
exports.writeProjectProperties = writeProjectProperties;
|
|
||||||
exports.prepBuildFiles = prepBuildFiles;
|
|
||||||
|
|
||||||
function setShellFatal (value, func) {
|
|
||||||
var oldVal = shell.config.fatal;
|
|
||||||
shell.config.fatal = value;
|
|
||||||
func();
|
|
||||||
shell.config.fatal = oldVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFrameworkDir (projectPath, shared) {
|
|
||||||
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyJsAndLibrary (projectPath, shared, projectName) {
|
|
||||||
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
|
|
||||||
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
|
|
||||||
shell.cp('-f', srcCordovaJsPath, path.join(projectPath, 'assets', 'www', 'cordova.js'));
|
|
||||||
|
|
||||||
// Copy the cordova.js file to platforms/<platform>/platform_www/
|
|
||||||
// The www dir is nuked on each prepare so we keep cordova.js in platform_www
|
|
||||||
shell.mkdir('-p', path.join(projectPath, 'platform_www'));
|
|
||||||
shell.cp('-f', srcCordovaJsPath, path.join(projectPath, 'platform_www'));
|
|
||||||
|
|
||||||
// Copy cordova-js-src directory into platform_www directory.
|
|
||||||
// We need these files to build cordova.js if using browserify method.
|
|
||||||
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
|
|
||||||
|
|
||||||
// Don't fail if there are no old jars.
|
|
||||||
exports.setShellFatal(false, function () {
|
|
||||||
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
|
||||||
console.log('Deleting ' + oldJar);
|
|
||||||
shell.rm('-f', oldJar);
|
|
||||||
});
|
|
||||||
var wasSymlink = true;
|
|
||||||
try {
|
|
||||||
// Delete the symlink if it was one.
|
|
||||||
fs.unlinkSync(nestedCordovaLibPath);
|
|
||||||
} catch (e) {
|
|
||||||
wasSymlink = false;
|
|
||||||
}
|
|
||||||
// Delete old library project if it existed.
|
|
||||||
if (shared) {
|
|
||||||
shell.rm('-rf', nestedCordovaLibPath);
|
|
||||||
} else if (!wasSymlink) {
|
|
||||||
// Delete only the src, since Eclipse / Android Studio can't handle their project files being deleted.
|
|
||||||
shell.rm('-rf', path.join(nestedCordovaLibPath, 'src'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (shared) {
|
|
||||||
var relativeFrameworkPath = path.relative(projectPath, getFrameworkDir(projectPath, true));
|
|
||||||
fs.symlinkSync(relativeFrameworkPath, nestedCordovaLibPath, 'dir');
|
|
||||||
} else {
|
|
||||||
shell.mkdir('-p', nestedCordovaLibPath);
|
|
||||||
shell.cp('-f', path.join(ROOT, 'framework', 'AndroidManifest.xml'), nestedCordovaLibPath);
|
|
||||||
shell.cp('-f', path.join(ROOT, 'framework', 'project.properties'), nestedCordovaLibPath);
|
|
||||||
shell.cp('-f', path.join(ROOT, 'framework', 'build.gradle'), nestedCordovaLibPath);
|
|
||||||
shell.cp('-f', path.join(ROOT, 'framework', 'cordova.gradle'), nestedCordovaLibPath);
|
|
||||||
shell.cp('-r', path.join(ROOT, 'framework', 'src'), nestedCordovaLibPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractSubProjectPaths (data) {
|
|
||||||
var ret = {};
|
|
||||||
var r = /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg;
|
|
||||||
var m;
|
|
||||||
while ((m = r.exec(data))) {
|
|
||||||
ret[m[1]] = 1;
|
|
||||||
}
|
|
||||||
return Object.keys(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeProjectProperties (projectPath, target_api) {
|
|
||||||
var dstPath = path.join(projectPath, 'project.properties');
|
|
||||||
var templatePath = path.join(ROOT, 'bin', 'templates', 'project', 'project.properties');
|
|
||||||
var srcPath = fs.existsSync(dstPath) ? dstPath : templatePath;
|
|
||||||
|
|
||||||
var data = fs.readFileSync(srcPath, 'utf8');
|
|
||||||
data = data.replace(/^target=.*/m, 'target=' + target_api);
|
|
||||||
var subProjects = extractSubProjectPaths(data);
|
|
||||||
subProjects = subProjects.filter(function (p) {
|
|
||||||
return !(/^CordovaLib$/m.exec(p) ||
|
|
||||||
/[\\/]cordova-android[\\/]framework$/m.exec(p) ||
|
|
||||||
/^(\.\.[\\/])+framework$/m.exec(p));
|
|
||||||
});
|
|
||||||
subProjects.unshift('CordovaLib');
|
|
||||||
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
|
|
||||||
if (!/\n$/.exec(data)) {
|
|
||||||
data += '\n';
|
|
||||||
}
|
|
||||||
for (var i = 0; i < subProjects.length; ++i) {
|
|
||||||
data += 'android.library.reference.' + (i + 1) + '=' + subProjects[i] + '\n';
|
|
||||||
}
|
|
||||||
fs.writeFileSync(dstPath, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepBuildFiles (projectPath) {
|
|
||||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
|
||||||
buildModule.getBuilder('gradle').prepBuildFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyBuildRules (projectPath) {
|
|
||||||
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
|
|
||||||
|
|
||||||
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
|
|
||||||
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyScripts (projectPath) {
|
|
||||||
var bin = path.join(ROOT, 'bin');
|
|
||||||
var srcScriptsDir = path.join(bin, 'templates', 'cordova');
|
|
||||||
var destScriptsDir = path.join(projectPath, 'cordova');
|
|
||||||
// Delete old scripts directory if this is an update.
|
|
||||||
shell.rm('-rf', destScriptsDir);
|
|
||||||
// Copy in the new ones.
|
|
||||||
shell.cp('-r', srcScriptsDir, projectPath);
|
|
||||||
shell.cp('-r', path.join(ROOT, 'node_modules'), destScriptsDir);
|
|
||||||
shell.cp(path.join(bin, 'check_reqs*'), destScriptsDir);
|
|
||||||
shell.cp(path.join(bin, 'android_sdk_version*'), destScriptsDir);
|
|
||||||
var check_reqs = path.join(destScriptsDir, 'check_reqs');
|
|
||||||
var android_sdk_version = path.join(destScriptsDir, 'android_sdk_version');
|
|
||||||
// TODO: the two files being edited on-the-fly here are shared between
|
|
||||||
// platform and project-level commands. the below `sed` is updating the
|
|
||||||
// `require` path for the two libraries. if there's a better way to share
|
|
||||||
// modules across both the repo and generated projects, we should make sure
|
|
||||||
// to remove/update this.
|
|
||||||
shell.sed('-i', /templates\/cordova\//, '', android_sdk_version);
|
|
||||||
shell.sed('-i', /templates\/cordova\//, '', check_reqs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether a package name is acceptable for use as an android project.
|
|
||||||
* Returns a promise, fulfilled if the package name is acceptable; rejected
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
function validatePackageName (package_name) {
|
|
||||||
// Make the package conform to Java package types
|
|
||||||
// http://developer.android.com/guide/topics/manifest/manifest-element.html#package
|
|
||||||
// Enforce underscore limitation
|
|
||||||
var msg = 'Error validating package name. ';
|
|
||||||
|
|
||||||
if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) {
|
|
||||||
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class is a reserved word
|
|
||||||
if (/\b[Cc]lass\b/.test(package_name)) {
|
|
||||||
return Q.reject(new CordovaError(msg + '"class" is a reserved word'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether a project name is acceptable for use as an android class.
|
|
||||||
* Returns a promise, fulfilled if the project name is acceptable; rejected
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
function validateProjectName (project_name) {
|
|
||||||
var msg = 'Error validating project name. ';
|
|
||||||
// Make sure there's something there
|
|
||||||
if (project_name === '') {
|
|
||||||
return Q.reject(new CordovaError(msg + 'Project name cannot be empty'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce stupid name error
|
|
||||||
if (project_name === 'CordovaActivity') {
|
|
||||||
return Q.reject(new CordovaError(msg + 'Project name cannot be CordovaActivity'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Classes in Java don't begin with numbers
|
|
||||||
if (/^[0-9]/.test(project_name)) {
|
|
||||||
return Q.reject(new CordovaError(msg + 'Project name must not begin with a number'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an android application with the given options.
|
|
||||||
*
|
|
||||||
* @param {String} project_path Path to the new Cordova android project.
|
|
||||||
* @param {ConfigParser} config Instance of ConfigParser to retrieve basic
|
|
||||||
* project properties.
|
|
||||||
* @param {Object} [options={}] Various options
|
|
||||||
* @param {String} [options.activityName='MainActivity'] Name for the
|
|
||||||
* activity
|
|
||||||
* @param {Boolean} [options.link=false] Specifies whether javascript files
|
|
||||||
* and CordovaLib framework will be symlinked to created application.
|
|
||||||
* @param {String} [options.customTemplate] Path to project template
|
|
||||||
* (override)
|
|
||||||
* @param {EventEmitter} [events] An EventEmitter instance for logging
|
|
||||||
* events
|
|
||||||
*
|
|
||||||
* @return {Promise<String>} Directory where application has been created
|
|
||||||
*/
|
|
||||||
exports.create = function (project_path, config, options, events) {
|
|
||||||
|
|
||||||
options = options || {};
|
|
||||||
|
|
||||||
// Set default values for path, package and name
|
|
||||||
project_path = path.relative(process.cwd(), (project_path || 'CordovaExample'));
|
|
||||||
// Check if project already exists
|
|
||||||
if (fs.existsSync(project_path)) {
|
|
||||||
return Q.reject(new CordovaError('Project already exists! Delete and recreate'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var package_name = config.android_packageName() || config.packageName() || 'my.cordova.project';
|
|
||||||
var project_name = config.name() ?
|
|
||||||
config.name().replace(/[^\w.]/g, '_') : 'CordovaExample';
|
|
||||||
|
|
||||||
var safe_activity_name = config.android_activityName() || options.activityName || 'MainActivity';
|
|
||||||
var target_api = check_reqs.get_target();
|
|
||||||
|
|
||||||
// Make the package conform to Java package types
|
|
||||||
return exports.validatePackageName(package_name)
|
|
||||||
.then(function () {
|
|
||||||
exports.validateProjectName(project_name);
|
|
||||||
}).then(function () {
|
|
||||||
// Log the given values for the project
|
|
||||||
events.emit('log', 'Creating Cordova project for the Android platform:');
|
|
||||||
events.emit('log', '\tPath: ' + project_path);
|
|
||||||
events.emit('log', '\tPackage: ' + package_name);
|
|
||||||
events.emit('log', '\tName: ' + project_name);
|
|
||||||
events.emit('log', '\tActivity: ' + safe_activity_name);
|
|
||||||
events.emit('log', '\tAndroid target: ' + target_api);
|
|
||||||
|
|
||||||
events.emit('verbose', 'Copying android template project to ' + project_path);
|
|
||||||
|
|
||||||
exports.setShellFatal(true, function () {
|
|
||||||
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
|
||||||
// copy project template
|
|
||||||
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
|
|
||||||
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
|
|
||||||
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
|
|
||||||
|
|
||||||
// Manually create directories that would be empty within the template (since git doesn't track directories).
|
|
||||||
shell.mkdir(path.join(project_path, 'libs'));
|
|
||||||
|
|
||||||
// copy cordova.js, cordova.jar
|
|
||||||
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
|
||||||
|
|
||||||
// interpolate the activity name and package
|
|
||||||
var packagePath = package_name.replace(/\./g, path.sep);
|
|
||||||
var activity_dir = path.join(project_path, 'src', packagePath);
|
|
||||||
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
|
|
||||||
shell.mkdir('-p', activity_dir);
|
|
||||||
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
|
|
||||||
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
|
|
||||||
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
|
|
||||||
shell.sed('-i', /__ID__/, package_name, activity_path);
|
|
||||||
|
|
||||||
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
|
||||||
manifest.setPackageId(package_name)
|
|
||||||
.setTargetSdkVersion(target_api.split('-')[1])
|
|
||||||
.getActivity().setName(safe_activity_name);
|
|
||||||
|
|
||||||
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
|
|
||||||
manifest.write(manifest_path);
|
|
||||||
|
|
||||||
exports.copyScripts(project_path);
|
|
||||||
exports.copyBuildRules(project_path);
|
|
||||||
});
|
|
||||||
// Link it to local android install.
|
|
||||||
exports.writeProjectProperties(project_path, target_api);
|
|
||||||
exports.prepBuildFiles(project_path);
|
|
||||||
events.emit('log', generateDoneMessage('create', options.link));
|
|
||||||
}).thenResolve(project_path);
|
|
||||||
};
|
|
||||||
|
|
||||||
function generateDoneMessage (type, link) {
|
|
||||||
var pkg = require('../../package');
|
|
||||||
var msg = 'Android project ' + (type === 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
|
|
||||||
if (link) {
|
|
||||||
msg += ' and has a linked CordovaLib';
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a promise.
|
|
||||||
exports.update = function (projectPath, options, events) {
|
|
||||||
options = options || {};
|
|
||||||
|
|
||||||
return Q()
|
|
||||||
.then(function () {
|
|
||||||
|
|
||||||
var manifest = new AndroidManifest(path.join(projectPath, 'AndroidManifest.xml'));
|
|
||||||
|
|
||||||
if (Number(manifest.getMinSdkVersion()) < MIN_SDK_VERSION) {
|
|
||||||
events.emit('verbose', 'Updating minSdkVersion to ' + MIN_SDK_VERSION + ' in AndroidManifest.xml');
|
|
||||||
manifest.setMinSdkVersion(MIN_SDK_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
manifest.setDebuggable(false).write();
|
|
||||||
|
|
||||||
var projectName = manifest.getActivity().getName();
|
|
||||||
var target_api = check_reqs.get_target();
|
|
||||||
|
|
||||||
exports.copyJsAndLibrary(projectPath, options.link, projectName);
|
|
||||||
exports.copyScripts(projectPath);
|
|
||||||
exports.copyBuildRules(projectPath);
|
|
||||||
exports.writeProjectProperties(projectPath, target_api);
|
|
||||||
exports.prepBuildFiles(projectPath);
|
|
||||||
events.emit('log', generateDoneMessage('update', options.link));
|
|
||||||
}).thenResolve(projectPath);
|
|
||||||
};
|
|
||||||
396
bin/templates/cordova/Api.js
vendored
@@ -1,396 +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 Q = require('q');
|
|
||||||
|
|
||||||
var AndroidProject = require('./lib/AndroidProject');
|
|
||||||
var AndroidStudio = require('./lib/AndroidStudio');
|
|
||||||
var PluginManager = require('cordova-common').PluginManager;
|
|
||||||
|
|
||||||
var CordovaLogger = require('cordova-common').CordovaLogger;
|
|
||||||
var selfEvents = require('cordova-common').events;
|
|
||||||
|
|
||||||
var PLATFORM = 'android';
|
|
||||||
|
|
||||||
function setupEvents (externalEventEmitter) {
|
|
||||||
if (externalEventEmitter) {
|
|
||||||
// This will make the platform internal events visible outside
|
|
||||||
selfEvents.forwardEventsTo(externalEventEmitter);
|
|
||||||
return externalEventEmitter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is no logger if external emitter is not present,
|
|
||||||
// so attach a console logger
|
|
||||||
CordovaLogger.get().subscribe(selfEvents);
|
|
||||||
return selfEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class, that acts as abstraction over particular platform. Encapsulates the
|
|
||||||
* platform's properties and methods.
|
|
||||||
*
|
|
||||||
* Platform that implements own PlatformApi instance _should implement all
|
|
||||||
* prototype methods_ of this class to be fully compatible with cordova-lib.
|
|
||||||
*
|
|
||||||
* The PlatformApi instance also should define the following field:
|
|
||||||
*
|
|
||||||
* * platform: String that defines a platform name.
|
|
||||||
*/
|
|
||||||
function Api (platform, platformRootDir, events) {
|
|
||||||
this.platform = PLATFORM;
|
|
||||||
this.root = path.resolve(__dirname, '..');
|
|
||||||
|
|
||||||
setupEvents(events);
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.locations = {
|
|
||||||
root: self.root,
|
|
||||||
www: path.join(self.root, 'assets/www'),
|
|
||||||
res: path.join(self.root, 'res'),
|
|
||||||
platformWww: path.join(self.root, 'platform_www'),
|
|
||||||
configXml: path.join(self.root, 'res/xml/config.xml'),
|
|
||||||
defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'),
|
|
||||||
strings: path.join(self.root, 'res/values/strings.xml'),
|
|
||||||
manifest: path.join(self.root, 'AndroidManifest.xml'),
|
|
||||||
build: path.join(self.root, 'build'),
|
|
||||||
// NOTE: Due to platformApi spec we need to return relative paths here
|
|
||||||
cordovaJs: 'bin/templates/project/assets/www/cordova.js',
|
|
||||||
cordovaJsSrc: 'cordova-js-src'
|
|
||||||
};
|
|
||||||
|
|
||||||
// XXX Override some locations for Android Studio projects
|
|
||||||
if (AndroidStudio.isAndroidStudioProject(self.root) === true) {
|
|
||||||
selfEvents.emit('log', 'Android Studio project detected');
|
|
||||||
this.android_studio = true;
|
|
||||||
this.locations.configXml = path.join(self.root, 'app/src/main/res/xml/config.xml');
|
|
||||||
this.locations.strings = path.join(self.root, 'app/src/main/res/xml/strings.xml');
|
|
||||||
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
|
|
||||||
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
|
|
||||||
this.locations.res = path.join(self.root, 'app/src/main/res');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs platform to specified directory and creates a platform project.
|
|
||||||
*
|
|
||||||
* @param {String} destination Destination directory, where insatll platform to
|
|
||||||
* @param {ConfigParser} [config] ConfgiParser instance, used to retrieve
|
|
||||||
* project creation options, such as package id and project name.
|
|
||||||
* @param {Object} [options] An options object. The most common options are:
|
|
||||||
* @param {String} [options.customTemplate] A path to custom template, that
|
|
||||||
* should override the default one from platform.
|
|
||||||
* @param {Boolean} [options.link] Flag that indicates that platform's
|
|
||||||
* sources will be linked to installed platform instead of copying.
|
|
||||||
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
|
|
||||||
* logging purposes. If no EventEmitter provided, all events will be logged to
|
|
||||||
* console
|
|
||||||
*
|
|
||||||
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
|
|
||||||
* instance or rejected with CordovaError.
|
|
||||||
*/
|
|
||||||
Api.createPlatform = function (destination, config, options, events) {
|
|
||||||
events = setupEvents(events);
|
|
||||||
var result;
|
|
||||||
try {
|
|
||||||
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
|
|
||||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
|
||||||
return new PlatformApi(PLATFORM, destination, events);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
events.emit('error', 'createPlatform is not callable from the android project API.');
|
|
||||||
throw (e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates already installed platform.
|
|
||||||
*
|
|
||||||
* @param {String} destination Destination directory, where platform installed
|
|
||||||
* @param {Object} [options] An options object. The most common options are:
|
|
||||||
* @param {String} [options.customTemplate] A path to custom template, that
|
|
||||||
* should override the default one from platform.
|
|
||||||
* @param {Boolean} [options.link] Flag that indicates that platform's
|
|
||||||
* sources will be linked to installed platform instead of copying.
|
|
||||||
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
|
|
||||||
* logging purposes. If no EventEmitter provided, all events will be logged to
|
|
||||||
* console
|
|
||||||
*
|
|
||||||
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
|
|
||||||
* instance or rejected with CordovaError.
|
|
||||||
*/
|
|
||||||
Api.updatePlatform = function (destination, options, events) {
|
|
||||||
events = setupEvents(events);
|
|
||||||
var result;
|
|
||||||
try {
|
|
||||||
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
|
||||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
|
||||||
return new PlatformApi('android', destination, events);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
|
||||||
throw (e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a CordovaPlatform object, that represents the platform structure.
|
|
||||||
*
|
|
||||||
* @return {CordovaPlatform} A structure that contains the description of
|
|
||||||
* platform's file structure and other properties of platform.
|
|
||||||
*/
|
|
||||||
Api.prototype.getPlatformInfo = function () {
|
|
||||||
var result = {};
|
|
||||||
result.locations = this.locations;
|
|
||||||
result.root = this.root;
|
|
||||||
result.name = this.platform;
|
|
||||||
result.version = require('./version');
|
|
||||||
result.projectConfig = this._config;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates installed platform with provided www assets and new app
|
|
||||||
* configuration. This method is required for CLI workflow and will be called
|
|
||||||
* each time before build, so the changes, made to app configuration and www
|
|
||||||
* code, will be applied to platform.
|
|
||||||
*
|
|
||||||
* @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a
|
|
||||||
* project structure and configuration, that should be applied to platform
|
|
||||||
* (contains project's www location and ConfigParser instance for project's
|
|
||||||
* config).
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError instance.
|
|
||||||
*/
|
|
||||||
Api.prototype.prepare = function (cordovaProject, prepareOptions) {
|
|
||||||
return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs a new plugin into platform. This method only copies non-www files
|
|
||||||
* (sources, libs, etc.) to platform. It also doesn't resolves the
|
|
||||||
* dependencies of plugin. Both of handling of www files, such as assets and
|
|
||||||
* js-files and resolving dependencies are the responsibility of caller.
|
|
||||||
*
|
|
||||||
* @param {PluginInfo} plugin A PluginInfo instance that represents plugin
|
|
||||||
* that will be installed.
|
|
||||||
* @param {Object} installOptions An options object. Possible options below:
|
|
||||||
* @param {Boolean} installOptions.link: Flag that specifies that plugin
|
|
||||||
* sources will be symlinked to app's directory instead of copying (if
|
|
||||||
* possible).
|
|
||||||
* @param {Object} installOptions.variables An object that represents
|
|
||||||
* variables that will be used to install plugin. See more details on plugin
|
|
||||||
* variables in documentation:
|
|
||||||
* https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError instance.
|
|
||||||
*/
|
|
||||||
Api.prototype.addPlugin = function (plugin, installOptions) {
|
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
installOptions = installOptions || {};
|
|
||||||
installOptions.variables = installOptions.variables || {};
|
|
||||||
// Add PACKAGE_NAME variable into vars
|
|
||||||
if (!installOptions.variables.PACKAGE_NAME) {
|
|
||||||
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.android_studio === true) {
|
|
||||||
installOptions.android_studio = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Q().then(function () {
|
|
||||||
// CB-11964: Do a clean when installing the plugin code to get around
|
|
||||||
// the Gradle bug introduced by the Android Gradle Plugin Version 2.2
|
|
||||||
// TODO: Delete when the next version of Android Gradle plugin comes out
|
|
||||||
|
|
||||||
// Since clean doesn't just clean the build, it also wipes out www, we need
|
|
||||||
// to pass additional options.
|
|
||||||
|
|
||||||
// Do some basic argument parsing
|
|
||||||
var opts = {};
|
|
||||||
|
|
||||||
// Skip cleaning prepared files when not invoking via cordova CLI.
|
|
||||||
opts.noPrepare = true;
|
|
||||||
|
|
||||||
if (!AndroidStudio.isAndroidStudioProject(self.root) && !project.isClean()) {
|
|
||||||
return self.clean(opts);
|
|
||||||
}
|
|
||||||
}).then(function () {
|
|
||||||
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
|
||||||
}).then(function () {
|
|
||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
|
||||||
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
|
||||||
}.bind(this))
|
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
|
||||||
.thenResolve(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an installed plugin from platform.
|
|
||||||
*
|
|
||||||
* Since method accepts PluginInfo instance as input parameter instead of plugin
|
|
||||||
* id, caller shoud take care of managing/storing PluginInfo instances for
|
|
||||||
* future uninstalls.
|
|
||||||
*
|
|
||||||
* @param {PluginInfo} plugin A PluginInfo instance that represents plugin
|
|
||||||
* that will be installed.
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError instance.
|
|
||||||
*/
|
|
||||||
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
|
||||||
|
|
||||||
if (uninstallOptions && uninstallOptions.usePlatformWww === true && this.android_studio === true) {
|
|
||||||
uninstallOptions.usePlatformWww = false;
|
|
||||||
uninstallOptions.android_studio = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PluginManager.get(this.platform, this.locations, project)
|
|
||||||
.removePlugin(plugin, uninstallOptions)
|
|
||||||
.then(function () {
|
|
||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
|
||||||
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
|
||||||
}.bind(this))
|
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
|
||||||
.thenResolve(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds an application package for current platform.
|
|
||||||
*
|
|
||||||
* @param {Object} buildOptions A build options. This object's structure is
|
|
||||||
* highly depends on platform's specific. The most common options are:
|
|
||||||
* @param {Boolean} buildOptions.debug Indicates that packages should be
|
|
||||||
* built with debug configuration. This is set to true by default unless the
|
|
||||||
* 'release' option is not specified.
|
|
||||||
* @param {Boolean} buildOptions.release Indicates that packages should be
|
|
||||||
* built with release configuration. If not set to true, debug configuration
|
|
||||||
* will be used.
|
|
||||||
* @param {Boolean} buildOptions.device Specifies that built app is intended
|
|
||||||
* to run on device
|
|
||||||
* @param {Boolean} buildOptions.emulator: Specifies that built app is
|
|
||||||
* intended to run on emulator
|
|
||||||
* @param {String} buildOptions.target Specifies the device id that will be
|
|
||||||
* used to run built application.
|
|
||||||
* @param {Boolean} buildOptions.nobuild Indicates that this should be a
|
|
||||||
* dry-run call, so no build artifacts will be produced.
|
|
||||||
* @param {String[]} buildOptions.archs Specifies chip architectures which
|
|
||||||
* app packages should be built for. List of valid architectures is depends on
|
|
||||||
* platform.
|
|
||||||
* @param {String} buildOptions.buildConfig The path to build configuration
|
|
||||||
* file. The format of this file is depends on platform.
|
|
||||||
* @param {String[]} buildOptions.argv Raw array of command-line arguments,
|
|
||||||
* passed to `build` command. The purpose of this property is to pass a
|
|
||||||
* platform-specific arguments, and eventually let platform define own
|
|
||||||
* arguments processing logic.
|
|
||||||
*
|
|
||||||
* @return {Promise<Object[]>} A promise either fulfilled with an array of build
|
|
||||||
* artifacts (application packages) if package was built successfully,
|
|
||||||
* or rejected with CordovaError. The resultant build artifact objects is not
|
|
||||||
* strictly typed and may conatin arbitrary set of fields as in sample below.
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* architecture: 'x86',
|
|
||||||
* buildType: 'debug',
|
|
||||||
* path: '/path/to/build',
|
|
||||||
* type: 'app'
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* The return value in most cases will contain only one item but in some cases
|
|
||||||
* there could be multiple items in output array, e.g. when multiple
|
|
||||||
* arhcitectures is specified.
|
|
||||||
*/
|
|
||||||
Api.prototype.build = function (buildOptions) {
|
|
||||||
var self = this;
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
|
||||||
return require('./lib/build').run.call(self, buildOptions);
|
|
||||||
}).then(function (buildResults) {
|
|
||||||
// Cast build result to array of build artifacts
|
|
||||||
return buildResults.apkPaths.map(function (apkPath) {
|
|
||||||
return {
|
|
||||||
buildType: buildResults.buildType,
|
|
||||||
buildMethod: buildResults.buildMethod,
|
|
||||||
path: apkPath,
|
|
||||||
type: 'apk'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds an application package for current platform and runs it on
|
|
||||||
* specified/default device. If no 'device'/'emulator'/'target' options are
|
|
||||||
* specified, then tries to run app on default device if connected, otherwise
|
|
||||||
* runs the app on emulator.
|
|
||||||
*
|
|
||||||
* @param {Object} runOptions An options object. The structure is the same
|
|
||||||
* as for build options.
|
|
||||||
*
|
|
||||||
* @return {Promise} A promise either fulfilled if package was built and ran
|
|
||||||
* successfully, or rejected with CordovaError.
|
|
||||||
*/
|
|
||||||
Api.prototype.run = function (runOptions) {
|
|
||||||
var self = this;
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
|
||||||
return require('./lib/run').run.call(self, runOptions);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans out the build artifacts from platform's directory, and also
|
|
||||||
* cleans out the platform www directory if called without options specified.
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError.
|
|
||||||
*/
|
|
||||||
Api.prototype.clean = function (cleanOptions) {
|
|
||||||
var self = this;
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
|
||||||
return require('./lib/build').runClean.call(self, cleanOptions);
|
|
||||||
}).then(function () {
|
|
||||||
return require('./lib/prepare').clean.call(self, cleanOptions);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a requirements check for current platform. Each platform defines its
|
|
||||||
* own set of requirements, which should be resolved before platform can be
|
|
||||||
* built successfully.
|
|
||||||
*
|
|
||||||
* @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
|
|
||||||
* objects for current platform.
|
|
||||||
*/
|
|
||||||
Api.prototype.requirements = function () {
|
|
||||||
return require('./lib/check_reqs').check_all();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Api;
|
|
||||||
@@ -1,50 +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(process.argv[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
|
|
||||||
)
|
|
||||||
160
bin/templates/cordova/lib/AndroidManifest.js
vendored
@@ -1,160 +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');
|
|
||||||
var et = require('elementtree');
|
|
||||||
var xml = require('cordova-common').xmlHelpers;
|
|
||||||
|
|
||||||
var DEFAULT_ORIENTATION = 'default';
|
|
||||||
|
|
||||||
/** Wraps an AndroidManifest file */
|
|
||||||
function AndroidManifest (path) {
|
|
||||||
this.path = path;
|
|
||||||
this.doc = xml.parseElementtreeSync(path);
|
|
||||||
if (this.doc.getroot().tag !== 'manifest') {
|
|
||||||
throw new Error('AndroidManifest at ' + path + ' has incorrect root node name (expected "manifest")');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getVersionName = function () {
|
|
||||||
return this.doc.getroot().attrib['android:versionName'];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setVersionName = function (versionName) {
|
|
||||||
this.doc.getroot().attrib['android:versionName'] = versionName;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getVersionCode = function () {
|
|
||||||
return this.doc.getroot().attrib['android:versionCode'];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setVersionCode = function (versionCode) {
|
|
||||||
this.doc.getroot().attrib['android:versionCode'] = versionCode;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getPackageId = function () {
|
|
||||||
/* jshint -W069 */
|
|
||||||
return this.doc.getroot().attrib['package'];
|
|
||||||
/* jshint +W069 */
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setPackageId = function (pkgId) {
|
|
||||||
/* jshint -W069 */
|
|
||||||
this.doc.getroot().attrib['package'] = pkgId;
|
|
||||||
/* jshint +W069 */
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getActivity = function () {
|
|
||||||
var activity = this.doc.getroot().find('./application/activity');
|
|
||||||
return {
|
|
||||||
getName: function () {
|
|
||||||
return activity.attrib['android:name'];
|
|
||||||
},
|
|
||||||
setName: function (name) {
|
|
||||||
if (!name) {
|
|
||||||
delete activity.attrib['android:name'];
|
|
||||||
} else {
|
|
||||||
activity.attrib['android:name'] = name;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
getOrientation: function () {
|
|
||||||
return activity.attrib['android:screenOrientation'];
|
|
||||||
},
|
|
||||||
setOrientation: function (orientation) {
|
|
||||||
if (!orientation || orientation.toLowerCase() === DEFAULT_ORIENTATION) {
|
|
||||||
delete activity.attrib['android:screenOrientation'];
|
|
||||||
} else {
|
|
||||||
activity.attrib['android:screenOrientation'] = orientation;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
getLaunchMode: function () {
|
|
||||||
return activity.attrib['android:launchMode'];
|
|
||||||
},
|
|
||||||
setLaunchMode: function (launchMode) {
|
|
||||||
if (!launchMode) {
|
|
||||||
delete activity.attrib['android:launchMode'];
|
|
||||||
} else {
|
|
||||||
activity.attrib['android:launchMode'] = launchMode;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function (sdkPrefName) {
|
|
||||||
// Copy variable reference to avoid closure issues
|
|
||||||
var prefName = sdkPrefName;
|
|
||||||
|
|
||||||
AndroidManifest.prototype['get' + capitalize(prefName)] = function () {
|
|
||||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
|
||||||
return usesSdk && usesSdk.attrib['android:' + prefName];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype['set' + capitalize(prefName)] = function (prefValue) {
|
|
||||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
|
||||||
|
|
||||||
if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first
|
|
||||||
usesSdk = new et.Element('uses-sdk');
|
|
||||||
this.doc.getroot().append(usesSdk);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prefValue) {
|
|
||||||
usesSdk.attrib['android:' + prefName] = prefValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getDebuggable = function () {
|
|
||||||
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setDebuggable = function (value) {
|
|
||||||
var application = this.doc.getroot().find('./application');
|
|
||||||
if (value) {
|
|
||||||
application.attrib['android:debuggable'] = 'true';
|
|
||||||
} else {
|
|
||||||
// The default value is "false", so we can remove attribute at all.
|
|
||||||
delete application.attrib['android:debuggable'];
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes manifest to disk syncronously. If filename is specified, then manifest
|
|
||||||
* will be written to that file
|
|
||||||
*
|
|
||||||
* @param {String} [destPath] File to write manifest to. If omitted,
|
|
||||||
* manifest will be written to file it has been read from.
|
|
||||||
*/
|
|
||||||
AndroidManifest.prototype.write = function (destPath) {
|
|
||||||
fs.writeFileSync(destPath || this.path, this.doc.write({indent: 4}), 'utf-8');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AndroidManifest;
|
|
||||||
|
|
||||||
function capitalize (str) {
|
|
||||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
||||||
}
|
|
||||||
209
bin/templates/cordova/lib/AndroidProject.js
vendored
@@ -1,209 +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');
|
|
||||||
var path = require('path');
|
|
||||||
var properties_parser = require('properties-parser');
|
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
|
||||||
var AndroidStudio = require('./AndroidStudio');
|
|
||||||
var pluginHandlers = require('./pluginHandlers');
|
|
||||||
|
|
||||||
var projectFileCache = {};
|
|
||||||
|
|
||||||
function addToPropertyList (projectProperties, key, value) {
|
|
||||||
var i = 1;
|
|
||||||
while (projectProperties.get(key + '.' + i)) { i++; }
|
|
||||||
|
|
||||||
projectProperties.set(key + '.' + i, value);
|
|
||||||
projectProperties.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeFromPropertyList (projectProperties, key, value) {
|
|
||||||
var i = 1;
|
|
||||||
var currentValue;
|
|
||||||
while ((currentValue = projectProperties.get(key + '.' + i))) {
|
|
||||||
if (currentValue === value) {
|
|
||||||
while ((currentValue = projectProperties.get(key + '.' + (i + 1)))) {
|
|
||||||
projectProperties.set(key + '.' + i, currentValue);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
projectProperties.set(key + '.' + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
projectProperties.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRelativeLibraryPath (parentDir, subDir) {
|
|
||||||
var libraryPath = path.relative(parentDir, subDir);
|
|
||||||
return (path.sep === '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
function AndroidProject (projectDir) {
|
|
||||||
this._propertiesEditors = {};
|
|
||||||
this._subProjectDirs = {};
|
|
||||||
this._dirty = false;
|
|
||||||
this.projectDir = projectDir;
|
|
||||||
this.platformWww = path.join(this.projectDir, 'platform_www');
|
|
||||||
this.www = path.join(this.projectDir, 'assets/www');
|
|
||||||
if (AndroidStudio.isAndroidStudioProject(projectDir) === true) {
|
|
||||||
this.www = path.join(this.projectDir, 'app/src/main/assets/www');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AndroidProject.getProjectFile = function (projectDir) {
|
|
||||||
if (!projectFileCache[projectDir]) {
|
|
||||||
projectFileCache[projectDir] = new AndroidProject(projectDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectFileCache[projectDir];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.purgeCache = function (projectDir) {
|
|
||||||
if (projectDir) {
|
|
||||||
delete projectFileCache[projectDir];
|
|
||||||
} else {
|
|
||||||
projectFileCache = {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the package name out of the Android Manifest file
|
|
||||||
*
|
|
||||||
* @param {String} projectDir The absolute path to the directory containing the project
|
|
||||||
*
|
|
||||||
* @return {String} The name of the package
|
|
||||||
*/
|
|
||||||
AndroidProject.prototype.getPackageName = function () {
|
|
||||||
var manifestPath = path.join(this.projectDir, 'AndroidManifest.xml');
|
|
||||||
if (AndroidStudio.isAndroidStudioProject(this.projectDir) === true) {
|
|
||||||
manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
|
||||||
}
|
|
||||||
return new AndroidManifest(manifestPath).getPackageId();
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.getCustomSubprojectRelativeDir = function (plugin_id, src) {
|
|
||||||
// All custom subprojects are prefixed with the last portion of the package id.
|
|
||||||
// This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name.
|
|
||||||
var packageName = this.getPackageName();
|
|
||||||
var lastDotIndex = packageName.lastIndexOf('.');
|
|
||||||
var prefix = packageName.substring(lastDotIndex + 1);
|
|
||||||
var subRelativeDir = path.join(plugin_id, prefix + '-' + path.basename(src));
|
|
||||||
return subRelativeDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.addSubProject = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var subProjectFile = path.resolve(subDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
// TODO: Setting the target needs to happen only for pre-3.7.0 projects
|
|
||||||
if (fs.existsSync(subProjectFile)) {
|
|
||||||
var subProperties = this._getPropertiesFile(subProjectFile);
|
|
||||||
subProperties.set('target', parentProperties.get('target'));
|
|
||||||
subProperties.dirty = true;
|
|
||||||
this._subProjectDirs[subDir] = true;
|
|
||||||
}
|
|
||||||
addToPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.removeSubProject = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
delete this._subProjectDirs[subDir];
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.addGradleReference = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.removeGradleReference = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.addSystemLibrary = function (parentDir, value) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
addToPropertyList(parentProperties, 'cordova.system.library', value);
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.removeSystemLibrary = function (parentDir, value) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
removeFromPropertyList(parentProperties, 'cordova.system.library', value);
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.write = function () {
|
|
||||||
if (!this._dirty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._dirty = false;
|
|
||||||
|
|
||||||
for (var filename in this._propertiesEditors) {
|
|
||||||
var editor = this._propertiesEditors[filename];
|
|
||||||
if (editor.dirty) {
|
|
||||||
fs.writeFileSync(filename, editor.toString());
|
|
||||||
editor.dirty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype._getPropertiesFile = function (filename) {
|
|
||||||
if (!this._propertiesEditors[filename]) {
|
|
||||||
if (fs.existsSync(filename)) {
|
|
||||||
this._propertiesEditors[filename] = properties_parser.createEditor(filename);
|
|
||||||
} else {
|
|
||||||
this._propertiesEditors[filename] = properties_parser.createEditor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._propertiesEditors[filename];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.getInstaller = function (type) {
|
|
||||||
return pluginHandlers.getInstaller(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.getUninstaller = function (type) {
|
|
||||||
return pluginHandlers.getUninstaller(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This checks if an Android project is clean or has old build artifacts
|
|
||||||
*/
|
|
||||||
|
|
||||||
AndroidProject.prototype.isClean = function () {
|
|
||||||
var build_path = path.join(this.projectDir, 'build');
|
|
||||||
// If the build directory doesn't exist, it's clean
|
|
||||||
return !(fs.existsSync(build_path));
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AndroidProject;
|
|
||||||
42
bin/templates/cordova/lib/AndroidStudio.js
vendored
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This is a simple routine that checks if project is an Android Studio Project
|
|
||||||
*
|
|
||||||
* @param {String} root Root folder of the project
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* jshint esnext: false */
|
|
||||||
|
|
||||||
var path = require('path');
|
|
||||||
var fs = require('fs');
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
|
|
||||||
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
|
|
||||||
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res', 'project.properties', 'platform_www'];
|
|
||||||
var androidStudioFiles = ['app', 'gradle', 'app/src/main/res'];
|
|
||||||
|
|
||||||
// assume it is an AS project and not an Eclipse project
|
|
||||||
var isEclipse = false;
|
|
||||||
var isAS = true;
|
|
||||||
|
|
||||||
if (!fs.existsSync(root)) {
|
|
||||||
throw new CordovaError('AndroidStudio.js:inAndroidStudioProject root does not exist: ' + root);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if any of the following exists, then we are not an ASProj
|
|
||||||
eclipseFiles.forEach(function (file) {
|
|
||||||
if (fs.existsSync(path.join(root, file))) {
|
|
||||||
isEclipse = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// if it is NOT an eclipse project, check that all required files exist
|
|
||||||
if (!isEclipse) {
|
|
||||||
androidStudioFiles.forEach(function (file) {
|
|
||||||
if (!fs.existsSync(path.join(root, file))) {
|
|
||||||
console.log('missing file :: ' + file);
|
|
||||||
isAS = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return (!isEclipse && isAS);
|
|
||||||
};
|
|
||||||
153
bin/templates/cordova/lib/builders/AntBuilder.js
vendored
@@ -1,153 +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.
|
|
||||||
*/
|
|
||||||
/* eslint no-unused-vars: 0 */
|
|
||||||
|
|
||||||
var Q = require('q');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
var util = require('util');
|
|
||||||
var shell = require('shelljs');
|
|
||||||
var spawn = require('cordova-common').superspawn.spawn;
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var check_reqs = require('../check_reqs');
|
|
||||||
|
|
||||||
var SIGNING_PROPERTIES = '-signing.properties';
|
|
||||||
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
|
||||||
var TEMPLATE =
|
|
||||||
'# This file is automatically generated.\n' +
|
|
||||||
'# Do not modify this file -- ' + MARKER + '\n';
|
|
||||||
|
|
||||||
var GenericBuilder = require('./GenericBuilder');
|
|
||||||
|
|
||||||
function AntBuilder (projectRoot) {
|
|
||||||
GenericBuilder.call(this, projectRoot);
|
|
||||||
|
|
||||||
this.binDirs = {ant: this.binDirs.ant};
|
|
||||||
}
|
|
||||||
|
|
||||||
util.inherits(AntBuilder, GenericBuilder);
|
|
||||||
|
|
||||||
AntBuilder.prototype.getArgs = function (cmd, opts) {
|
|
||||||
var args = [cmd, '-f', path.join(this.root, 'build.xml')];
|
|
||||||
// custom_rules.xml is required for incremental builds.
|
|
||||||
if (hasCustomRules(this.root)) {
|
|
||||||
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
|
|
||||||
}
|
|
||||||
if (opts.packageInfo) {
|
|
||||||
args.push('-propertyfile=' + path.join(this.root, opts.buildType + SIGNING_PROPERTIES));
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
};
|
|
||||||
|
|
||||||
AntBuilder.prototype.prepEnv = function (opts) {
|
|
||||||
var self = this;
|
|
||||||
return check_reqs.check_ant().then(function () {
|
|
||||||
// Copy in build.xml on each build so that:
|
|
||||||
// A) we don't require the Android SDK at project creation time, and
|
|
||||||
// B) we always use the SDK's latest version of it.
|
|
||||||
/* jshint -W069 */
|
|
||||||
var sdkDir = process.env['ANDROID_HOME'];
|
|
||||||
/* jshint +W069 */
|
|
||||||
var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8');
|
|
||||||
function writeBuildXml (projectPath) {
|
|
||||||
var newData = buildTemplate.replace('PROJECT_NAME', self.extractRealProjectNameFromManifest());
|
|
||||||
fs.writeFileSync(path.join(projectPath, 'build.xml'), newData);
|
|
||||||
if (!fs.existsSync(path.join(projectPath, 'local.properties'))) {
|
|
||||||
fs.writeFileSync(path.join(projectPath, 'local.properties'), TEMPLATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeBuildXml(self.root);
|
|
||||||
var propertiesObj = self.readProjectProperties();
|
|
||||||
var subProjects = propertiesObj.libs;
|
|
||||||
for (var i = 0; i < subProjects.length; ++i) {
|
|
||||||
writeBuildXml(path.join(self.root, subProjects[i]));
|
|
||||||
}
|
|
||||||
if (propertiesObj.systemLibs.length > 0) {
|
|
||||||
throw new CordovaError('Project contains at least one plugin that requires a system library. This is not supported with ANT. Use gradle instead.');
|
|
||||||
}
|
|
||||||
|
|
||||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
|
||||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
|
||||||
if (opts.packageInfo) {
|
|
||||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
|
||||||
} else if (isAutoGenerated(propertiesFilePath)) {
|
|
||||||
shell.rm('-f', propertiesFilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Builds the project with ant.
|
|
||||||
* Returns a promise.
|
|
||||||
*/
|
|
||||||
AntBuilder.prototype.build = function (opts) {
|
|
||||||
// Without our custom_rules.xml, we need to clean before building.
|
|
||||||
var ret = Q();
|
|
||||||
if (!hasCustomRules(this.root)) {
|
|
||||||
// clean will call check_ant() for us.
|
|
||||||
ret = this.clean(opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
|
||||||
return check_reqs.check_ant().then(function () {
|
|
||||||
return spawn('ant', args, {stdio: 'pipe'});
|
|
||||||
}).progress(function (stdio) {
|
|
||||||
if (stdio.stderr) {
|
|
||||||
process.stderr.write(stdio.stderr);
|
|
||||||
} else {
|
|
||||||
process.stdout.write(stdio.stdout);
|
|
||||||
}
|
|
||||||
}).catch(function (error) {
|
|
||||||
if (error.toString().indexOf('Unable to resolve project target') >= 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.
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
AntBuilder.prototype.clean = function (opts) {
|
|
||||||
var args = this.getArgs('clean', opts);
|
|
||||||
var self = this;
|
|
||||||
return check_reqs.check_ant().then(function () {
|
|
||||||
return spawn('ant', args, {stdio: 'inherit'});
|
|
||||||
}).then(function () {
|
|
||||||
shell.rm('-rf', path.join(self.root, 'out'));
|
|
||||||
|
|
||||||
['debug', 'release'].forEach(function (config) {
|
|
||||||
var propertiesFilePath = path.join(self.root, config + SIGNING_PROPERTIES);
|
|
||||||
if (isAutoGenerated(propertiesFilePath)) {
|
|
||||||
shell.rm('-f', propertiesFilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AntBuilder;
|
|
||||||
|
|
||||||
function hasCustomRules (projectRoot) {
|
|
||||||
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAutoGenerated (file) {
|
|
||||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
|
||||||
}
|
|
||||||
160
bin/templates/cordova/lib/builders/GenericBuilder.js
vendored
@@ -1,160 +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.
|
|
||||||
*/
|
|
||||||
/* eslint no-self-assign: 0 */
|
|
||||||
/* eslint no-unused-vars: 0 */
|
|
||||||
|
|
||||||
var Q = require('q');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
var shell = require('shelljs');
|
|
||||||
var events = require('cordova-common').events;
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
|
|
||||||
function GenericBuilder (projectDir) {
|
|
||||||
this.root = projectDir || path.resolve(__dirname, '../../..');
|
|
||||||
this.binDirs = {
|
|
||||||
ant: path.join(this.root, hasCustomRules(this.root) ? 'ant-build' : 'bin'),
|
|
||||||
gradle: path.join(this.root, 'build', 'outputs', 'apk')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasCustomRules (projectRoot) {
|
|
||||||
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericBuilder.prototype.prepEnv = function () {
|
|
||||||
return Q();
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericBuilder.prototype.build = function () {
|
|
||||||
events.emit('log', 'Skipping build...');
|
|
||||||
return Q(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericBuilder.prototype.clean = function () {
|
|
||||||
return Q();
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericBuilder.prototype.findOutputApks = function (build_type, arch) {
|
|
||||||
var self = this;
|
|
||||||
return Object.keys(this.binDirs).reduce(function (result, builderName) {
|
|
||||||
var binDir = self.binDirs[builderName];
|
|
||||||
return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
|
|
||||||
}, []).sort(apkSorter);
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericBuilder.prototype.readProjectProperties = function () {
|
|
||||||
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)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
|
||||||
var manifestPath = path.join(this.root, '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);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = GenericBuilder;
|
|
||||||
|
|
||||||
function apkSorter (fileA, fileB) {
|
|
||||||
// De-prioritize arch specific builds
|
|
||||||
var archSpecificRE = /-x86|-arm/;
|
|
||||||
if (archSpecificRE.exec(fileA)) {
|
|
||||||
return 1;
|
|
||||||
} else if (archSpecificRE.exec(fileB)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// De-prioritize unsigned builds
|
|
||||||
var unsignedRE = /-unsigned/;
|
|
||||||
if (unsignedRE.exec(fileA)) {
|
|
||||||
return 1;
|
|
||||||
} else if (unsignedRE.exec(fileB)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeDiff = fs.statSync(fileB).mtime - fs.statSync(fileA).mtime;
|
|
||||||
return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findOutputApksHelper (dir, build_type, arch) {
|
|
||||||
var shellSilent = shell.config.silent;
|
|
||||||
shell.config.silent = true;
|
|
||||||
|
|
||||||
// list directory recursively
|
|
||||||
var ret = shell.ls('-R', dir).map(function (file) {
|
|
||||||
// ls does not include base directory
|
|
||||||
return path.join(dir, file);
|
|
||||||
}).filter(function (file) {
|
|
||||||
// find all APKs
|
|
||||||
return file.match(/\.apk?$/i);
|
|
||||||
}).filter(function (candidate) {
|
|
||||||
var apkName = path.basename(candidate);
|
|
||||||
// Need to choose between release and debug .apk.
|
|
||||||
if (build_type === 'debug') {
|
|
||||||
return /-debug/.exec(apkName) && !/-unaligned|-unsigned/.exec(apkName);
|
|
||||||
}
|
|
||||||
if (build_type === 'release') {
|
|
||||||
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}).sort(apkSorter);
|
|
||||||
|
|
||||||
shellSilent = shellSilent;
|
|
||||||
|
|
||||||
if (ret.length === 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
// Assume arch-specific build if newest apk has -x86 or -arm.
|
|
||||||
var archSpecific = !!/-x86|-arm/.exec(path.basename(ret[0]));
|
|
||||||
// And show only arch-specific ones (or non-arch-specific)
|
|
||||||
ret = ret.filter(function (p) {
|
|
||||||
/* jshint -W018 */
|
|
||||||
return !!/-x86|-arm/.exec(path.basename(p)) === archSpecific;
|
|
||||||
/* jshint +W018 */
|
|
||||||
});
|
|
||||||
|
|
||||||
if (archSpecific && ret.length > 1 && arch) {
|
|
||||||
ret = ret.filter(function (p) {
|
|
||||||
return path.basename(p).indexOf('-' + arch) !== -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
279
bin/templates/cordova/lib/builders/GradleBuilder.js
vendored
@@ -1,279 +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 Q = require('q');
|
|
||||||
var fs = require('fs');
|
|
||||||
var util = require('util');
|
|
||||||
var path = require('path');
|
|
||||||
var shell = require('shelljs');
|
|
||||||
var superspawn = require('cordova-common').superspawn;
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var check_reqs = require('../check_reqs');
|
|
||||||
|
|
||||||
var GenericBuilder = require('./GenericBuilder');
|
|
||||||
|
|
||||||
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
|
||||||
var SIGNING_PROPERTIES = '-signing.properties';
|
|
||||||
var TEMPLATE =
|
|
||||||
'# This file is automatically generated.\n' +
|
|
||||||
'# Do not modify this file -- ' + MARKER + '\n';
|
|
||||||
|
|
||||||
function GradleBuilder (projectRoot) {
|
|
||||||
GenericBuilder.call(this, projectRoot);
|
|
||||||
|
|
||||||
this.binDirs = { gradle: this.binDirs.gradle };
|
|
||||||
}
|
|
||||||
|
|
||||||
util.inherits(GradleBuilder, GenericBuilder);
|
|
||||||
|
|
||||||
GradleBuilder.prototype.getArgs = function (cmd, opts) {
|
|
||||||
if (cmd === 'release') {
|
|
||||||
cmd = 'cdvBuildRelease';
|
|
||||||
} else if (cmd === 'debug') {
|
|
||||||
cmd = 'cdvBuildDebug';
|
|
||||||
}
|
|
||||||
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
|
||||||
if (opts.arch) {
|
|
||||||
args.push('-PcdvBuildArch=' + opts.arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10 seconds -> 6 seconds
|
|
||||||
args.push('-Dorg.gradle.daemon=true');
|
|
||||||
// to allow dex in process
|
|
||||||
args.push('-Dorg.gradle.jvmargs=-Xmx2048m');
|
|
||||||
// allow NDK to be used - required by Gradle 1.5 plugin
|
|
||||||
args.push('-Pandroid.useDeprecatedNdk=true');
|
|
||||||
args.push.apply(args, opts.extraArgs);
|
|
||||||
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
|
|
||||||
// args.push('-Dorg.gradle.parallel=true');
|
|
||||||
return args;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This returns a promise
|
|
||||||
*/
|
|
||||||
|
|
||||||
GradleBuilder.prototype.runGradleWrapper = function (gradle_cmd, gradle_file) {
|
|
||||||
var gradlePath = path.join(this.root, 'gradlew');
|
|
||||||
gradle_file = path.join(this.root, (gradle_file || 'wrapper.gradle'));
|
|
||||||
if (fs.existsSync(gradlePath)) {
|
|
||||||
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
|
||||||
} else {
|
|
||||||
return superspawn.spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', gradle_file], { stdio: 'pipe' })
|
|
||||||
.progress(function (stdio) {
|
|
||||||
suppressJavaOptionsInfo(stdio);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Makes the project buildable, minus the gradle wrapper.
|
|
||||||
GradleBuilder.prototype.prepBuildFiles = function () {
|
|
||||||
// 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;
|
|
||||||
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) {
|
|
||||||
shell.cp('-f', 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;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Write the settings.gradle file.
|
|
||||||
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, '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) {
|
|
||||||
console.log('Subproject Path: ' + p);
|
|
||||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
|
||||||
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 += ' compile "' + 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');
|
|
||||||
fs.writeFileSync(path.join(this.root, 'build.gradle'), buildGradle);
|
|
||||||
};
|
|
||||||
|
|
||||||
GradleBuilder.prototype.prepEnv = function (opts) {
|
|
||||||
var self = this;
|
|
||||||
return check_reqs.check_gradle().then(function (gradlePath) {
|
|
||||||
return self.runGradleWrapper(gradlePath);
|
|
||||||
}).then(function () {
|
|
||||||
return self.prepBuildFiles();
|
|
||||||
}).then(function () {
|
|
||||||
// We now copy the gradle out of the framework
|
|
||||||
// This is a dirty patch to get the build working
|
|
||||||
/*
|
|
||||||
var wrapperDir = path.join(self.root, 'CordovaLib');
|
|
||||||
if (process.platform == 'win32') {
|
|
||||||
shell.rm('-f', path.join(self.root, 'gradlew.bat'));
|
|
||||||
shell.cp(path.join(wrapperDir, 'gradlew.bat'), self.root);
|
|
||||||
} else {
|
|
||||||
shell.rm('-f', path.join(self.root, 'gradlew'));
|
|
||||||
shell.cp(path.join(wrapperDir, 'gradlew'), self.root);
|
|
||||||
}
|
|
||||||
shell.rm('-rf', path.join(self.root, 'gradle', 'wrapper'));
|
|
||||||
shell.mkdir('-p', path.join(self.root, 'gradle'));
|
|
||||||
shell.cp('-r', path.join(wrapperDir, 'gradle', 'wrapper'), path.join(self.root, 'gradle'));
|
|
||||||
*/
|
|
||||||
// If the gradle distribution URL is set, make sure it points to version we want.
|
|
||||||
// If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with.
|
|
||||||
// For some reason, using ^ and $ don't work. This does the job, though.
|
|
||||||
var distributionUrlRegex = /distributionUrl.*zip/;
|
|
||||||
/* jshint -W069 */
|
|
||||||
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.1-all.zip';
|
|
||||||
/* jshint +W069 */
|
|
||||||
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
|
||||||
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
|
||||||
shell.sed('-i', distributionUrlRegex, 'distributionUrl=' + distributionUrl, gradleWrapperPropertiesPath);
|
|
||||||
|
|
||||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
|
||||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
|
||||||
if (opts.packageInfo) {
|
|
||||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
|
||||||
} else if (isAutoGenerated(propertiesFilePath)) {
|
|
||||||
shell.rm('-f', propertiesFilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Builds the project with gradle.
|
|
||||||
* Returns a promise.
|
|
||||||
*/
|
|
||||||
GradleBuilder.prototype.build = function (opts) {
|
|
||||||
var wrapper = path.join(this.root, 'gradlew');
|
|
||||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
|
||||||
|
|
||||||
return superspawn.spawn(wrapper, args, { stdio: 'pipe' })
|
|
||||||
.progress(function (stdio) {
|
|
||||||
suppressJavaOptionsInfo(stdio);
|
|
||||||
}).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.
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
GradleBuilder.prototype.clean = function (opts) {
|
|
||||||
var builder = this;
|
|
||||||
var wrapper = path.join(this.root, 'gradlew');
|
|
||||||
var args = builder.getArgs('clean', opts);
|
|
||||||
return Q().then(function () {
|
|
||||||
return superspawn.spawn(wrapper, args, { stdio: 'inherit' });
|
|
||||||
}).then(function () {
|
|
||||||
shell.rm('-rf', path.join(builder.root, 'out'));
|
|
||||||
|
|
||||||
['debug', 'release'].forEach(function (config) {
|
|
||||||
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
|
||||||
if (isAutoGenerated(propertiesFilePath)) {
|
|
||||||
shell.rm('-f', propertiesFilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = GradleBuilder;
|
|
||||||
|
|
||||||
function suppressJavaOptionsInfo (stdio) {
|
|
||||||
if (stdio.stderr) {
|
|
||||||
/*
|
|
||||||
* Workaround for the issue with Java printing some unwanted information to
|
|
||||||
* stderr instead of stdout.
|
|
||||||
* This function suppresses 'Picked up _JAVA_OPTIONS' message from being
|
|
||||||
* printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for
|
|
||||||
* explanation.
|
|
||||||
*/
|
|
||||||
var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(stdio.stderr.toString());
|
|
||||||
if (suppressThisLine) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
process.stderr.write(stdio.stderr);
|
|
||||||
} else {
|
|
||||||
process.stdout.write(stdio.stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAutoGenerated (file) {
|
|
||||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
|
||||||
}
|
|
||||||
46
bin/templates/cordova/lib/builders/builders.js
vendored
@@ -1,46 +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 CordovaError = require('cordova-common').CordovaError;
|
|
||||||
|
|
||||||
var knownBuilders = {
|
|
||||||
ant: 'AntBuilder',
|
|
||||||
gradle: 'GradleBuilder',
|
|
||||||
none: 'GenericBuilder'
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method that instantiates and returns a builder for specified build
|
|
||||||
* type.
|
|
||||||
*
|
|
||||||
* @param {String} builderType Builder name to construct and return. Must
|
|
||||||
* be one of 'ant', 'gradle' or 'none'
|
|
||||||
*
|
|
||||||
* @return {Builder} A builder instance for specified build type.
|
|
||||||
*/
|
|
||||||
module.exports.getBuilder = function (builderType, projectRoot) {
|
|
||||||
if (!knownBuilders[builderType]) { throw new CordovaError('Builder ' + builderType + ' is not supported.'); }
|
|
||||||
|
|
||||||
try {
|
|
||||||
var Builder = require('./' + knownBuilders[builderType]);
|
|
||||||
return new Builder(projectRoot);
|
|
||||||
} catch (err) {
|
|
||||||
throw new CordovaError('Failed to instantiate ' + knownBuilders[builderType] + ' builder: ' + err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
432
bin/templates/cordova/lib/check_reqs.js
vendored
@@ -1,432 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* jshint sub:true */
|
|
||||||
|
|
||||||
var shelljs = require('shelljs');
|
|
||||||
var child_process = require('child_process');
|
|
||||||
var Q = require('q');
|
|
||||||
var path = require('path');
|
|
||||||
var fs = require('fs');
|
|
||||||
var os = require('os');
|
|
||||||
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
|
|
||||||
var PROJECT_ROOT = path.join(__dirname, '..', '..');
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var superspawn = require('cordova-common').superspawn;
|
|
||||||
var android_sdk = require('./android_sdk');
|
|
||||||
|
|
||||||
function forgivingWhichSync (cmd) {
|
|
||||||
try {
|
|
||||||
return fs.realpathSync(shelljs.which(cmd));
|
|
||||||
} catch (e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function tryCommand (cmd, errMsg, catchStderr) {
|
|
||||||
var d = Q.defer();
|
|
||||||
child_process.exec(cmd, function (err, stdout, stderr) {
|
|
||||||
if (err) d.reject(new CordovaError(errMsg));
|
|
||||||
// Sometimes it is necessary to return an stderr instead of stdout in case of success, since
|
|
||||||
// some commands prints theirs output to stderr instead of stdout. 'javac' is the example
|
|
||||||
else d.resolve((catchStderr ? stderr : stdout).trim());
|
|
||||||
});
|
|
||||||
return d.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.isWindows = function () {
|
|
||||||
return (os.platform() === 'win32');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.isDarwin = function () {
|
|
||||||
return (os.platform() === 'darwin');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
|
||||||
module.exports.get_target = function () {
|
|
||||||
function extractFromFile (filePath) {
|
|
||||||
var target = shelljs.grep(/\btarget=/, filePath);
|
|
||||||
if (!target) {
|
|
||||||
throw new Error('Could not find android target within: ' + filePath);
|
|
||||||
}
|
|
||||||
return target.split('=')[1].trim();
|
|
||||||
}
|
|
||||||
var repo_file = path.join(REPO_ROOT, 'framework', 'project.properties');
|
|
||||||
if (fs.existsSync(repo_file)) {
|
|
||||||
return extractFromFile(repo_file);
|
|
||||||
}
|
|
||||||
var project_file = path.join(PROJECT_ROOT, 'project.properties');
|
|
||||||
if (fs.existsSync(project_file)) {
|
|
||||||
// if no target found, we're probably in a project and project.properties is in PROJECT_ROOT.
|
|
||||||
return extractFromFile(project_file);
|
|
||||||
}
|
|
||||||
throw new Error('Could not find android target in either ' + repo_file + ' nor ' + project_file);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a promise. Called only by build and clean commands.
|
|
||||||
module.exports.check_ant = function () {
|
|
||||||
return superspawn.spawn('ant', ['-version']).then(function (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 = child_process.spawnSync(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_HOME'];
|
|
||||||
var d = Q.defer();
|
|
||||||
if (!sdkDir) {
|
|
||||||
return Q.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_HOME\' env variable.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var gradlePath = module.exports.get_gradle_wrapper();
|
|
||||||
if (gradlePath.length !== 0) { d.resolve(gradlePath); } else {
|
|
||||||
d.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'));
|
|
||||||
}
|
|
||||||
return d.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a promise.
|
|
||||||
module.exports.check_java = function () {
|
|
||||||
var javacPath = forgivingWhichSync('javac');
|
|
||||||
var hasJavaHome = !!process.env['JAVA_HOME'];
|
|
||||||
return Q().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 superspawn.spawn(find_java).then(function (stdout) {
|
|
||||||
process.env['JAVA_HOME'] = stdout.trim();
|
|
||||||
}).catch(function (err) {
|
|
||||||
if (err) {
|
|
||||||
throw new CordovaError(default_java_error_msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// See if we can derive it from javac's location.
|
|
||||||
// fs.realpathSync is require on Ubuntu, which symplinks from /usr/bin -> JDK
|
|
||||||
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()) {
|
|
||||||
// Try to auto-detect java in the default install paths.
|
|
||||||
var oldSilent = shelljs.config.silent;
|
|
||||||
shelljs.config.silent = true;
|
|
||||||
var firstJdkDir =
|
|
||||||
shelljs.ls(process.env['ProgramFiles'] + '\\java\\jdk*')[0] ||
|
|
||||||
shelljs.ls('C:\\Program Files\\java\\jdk*')[0] ||
|
|
||||||
shelljs.ls('C:\\Program Files (x86)\\java\\jdk*')[0];
|
|
||||||
shelljs.config.silent = oldSilent;
|
|
||||||
if (firstJdkDir) {
|
|
||||||
// shelljs always uses / in paths.
|
|
||||||
firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
|
|
||||||
if (!javacPath) {
|
|
||||||
process.env['PATH'] += path.delimiter + path.join(firstJdkDir, 'bin');
|
|
||||||
}
|
|
||||||
process.env['JAVA_HOME'] = firstJdkDir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).then(function () {
|
|
||||||
var msg =
|
|
||||||
'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
|
|
||||||
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
|
||||||
if (process.env['JAVA_HOME']) {
|
|
||||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
|
||||||
}
|
|
||||||
// We use tryCommand with catchStderr = true, because
|
|
||||||
// javac writes version info to stderr instead of stdout
|
|
||||||
return tryCommand('javac -version', msg, true).then(function (output) {
|
|
||||||
// Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
|
||||||
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
|
||||||
return match && match[1];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a promise.
|
|
||||||
module.exports.check_android = function () {
|
|
||||||
return Q().then(function () {
|
|
||||||
var androidCmdPath = forgivingWhichSync('android');
|
|
||||||
var adbInPath = forgivingWhichSync('adb');
|
|
||||||
var avdmanagerInPath = forgivingWhichSync('avdmanager');
|
|
||||||
var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
|
|
||||||
function maybeSetAndroidHome (value) {
|
|
||||||
if (!hasAndroidHome && fs.existsSync(value)) {
|
|
||||||
hasAndroidHome = true;
|
|
||||||
process.env['ANDROID_HOME'] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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 (module.exports.isWindows()) {
|
|
||||||
// Android Studio 1.0 installer
|
|
||||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'sdk'));
|
|
||||||
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'sdk'));
|
|
||||||
// Android Studio pre-1.0 installer
|
|
||||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-studio', 'sdk'));
|
|
||||||
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-studio', 'sdk'));
|
|
||||||
// Stand-alone installer
|
|
||||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-sdk'));
|
|
||||||
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-sdk'));
|
|
||||||
} else if (module.exports.isDarwin()) {
|
|
||||||
// Android Studio 1.0 installer
|
|
||||||
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_HOME, 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_HOME\' 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_HOME\' 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_HOME\' 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_HOME']) {
|
|
||||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' 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_HOME'])) {
|
|
||||||
throw new CordovaError('\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process.env['ANDROID_HOME'] +
|
|
||||||
'\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_HOME'], 'tools');
|
|
||||||
}
|
|
||||||
if (hasAndroidHome && !adbInPath) {
|
|
||||||
process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'platform-tools');
|
|
||||||
}
|
|
||||||
if (hasAndroidHome && !avdmanagerInPath) {
|
|
||||||
process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], '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 () {
|
|
||||||
return Q.all([this.check_java(), this.check_android()]).then(function (values) {
|
|
||||||
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
|
|
||||||
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
|
|
||||||
|
|
||||||
if (!values[0]) {
|
|
||||||
throw new CordovaError('Requirements check failed for JDK 1.8 or greater');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!values[1]) {
|
|
||||||
throw new CordovaError('Requirements check failed for Android SDK');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
});
|
|
||||||
}, Q()).then(function () {
|
|
||||||
// When chain is completed, return requirements array to upstream API
|
|
||||||
return requirements;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
112
bin/templates/cordova/lib/device.js
vendored
@@ -1,112 +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 Q = require('q');
|
|
||||||
var build = require('./build');
|
|
||||||
var path = require('path');
|
|
||||||
var Adb = require('./Adb');
|
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
|
||||||
var spawn = require('cordova-common').superspawn.spawn;
|
|
||||||
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 spawn('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 Q.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 Q.reject('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 Q().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, '../../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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
526
bin/templates/cordova/lib/emulator.js
vendored
@@ -1,526 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* jshint sub:true */
|
|
||||||
|
|
||||||
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 superspawn = require('cordova-common').superspawn;
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var shelljs = require('shelljs');
|
|
||||||
var android_sdk = require('./android_sdk');
|
|
||||||
var check_reqs = require('./check_reqs');
|
|
||||||
|
|
||||||
var Q = require('q');
|
|
||||||
var os = require('os');
|
|
||||||
var fs = require('fs');
|
|
||||||
var child_process = require('child_process');
|
|
||||||
|
|
||||||
// constants
|
|
||||||
var ONE_SECOND = 1000; // in milliseconds
|
|
||||||
var ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds
|
|
||||||
var INSTALL_COMMAND_TIMEOUT = 5 * ONE_MINUTE; // in milliseconds
|
|
||||||
var NUM_INSTALL_RETRIES = 3;
|
|
||||||
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
|
||||||
var EXEC_KILL_SIGNAL = 'SIGKILL';
|
|
||||||
|
|
||||||
function forgivingWhichSync (cmd) {
|
|
||||||
try {
|
|
||||||
return fs.realpathSync(shelljs.which(cmd));
|
|
||||||
} catch (e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.list_images_using_avdmanager = function () {
|
|
||||||
return superspawn.spawn('avdmanager', ['list', 'avd']).then(function (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 superspawn.spawn('android', ['list', 'avd']).then(function (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 Q.fcall(function () {
|
|
||||||
if (forgivingWhichSync('avdmanager')) {
|
|
||||||
return module.exports.list_images_using_avdmanager();
|
|
||||||
} else if (forgivingWhichSync('android')) {
|
|
||||||
return module.exports.list_images_using_android();
|
|
||||||
} else {
|
|
||||||
return Q().then(function () {
|
|
||||||
throw 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);
|
|
||||||
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 superspawn.spawn('android', ['list', 'targets'], {cwd: os.tmpdir()}).then(function (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 Q().then(function () {
|
|
||||||
if (emulator_ID) return Q(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 Q.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(shelljs.which('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.
|
|
||||||
child_process
|
|
||||||
.spawn('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 Q.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 Q().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)) {
|
|
||||||
// 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, 'ps').then(function (output) {
|
|
||||||
if (output.match(/android\.process\.acore/)) {
|
|
||||||
return true;
|
|
||||||
} else if (time_remaining === 0) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
process.stdout.write('.');
|
|
||||||
|
|
||||||
// Check at regular intervals
|
|
||||||
return Q.delay(time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL).then(function () {
|
|
||||||
var updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
|
|
||||||
return self.wait_for_boot(emulator_id, updated_time);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 superspawn.spawn('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);
|
|
||||||
});
|
|
||||||
} 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 superspawn.spawn('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 Q.reject();
|
|
||||||
}, function (error) {
|
|
||||||
console.error('ERROR : Failed to create emulator image : ');
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.resolveTarget = function (target) {
|
|
||||||
return this.list_started().then(function (emulator_list) {
|
|
||||||
if (emulator_list.length < 1) {
|
|
||||||
return Q.reject('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 Q.reject('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;
|
|
||||||
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
|
||||||
var pkgName = manifest.getPackageId();
|
|
||||||
|
|
||||||
// resolve the target emulator
|
|
||||||
return Q().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 Q.when().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 + '...');
|
|
||||||
|
|
||||||
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
|
|
||||||
return Q.promise(function (resolve, reject) {
|
|
||||||
child_process.exec(command, opts, function (err, stdout, stderr) {
|
|
||||||
if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr));
|
|
||||||
// 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.
|
|
||||||
else 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.';
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(new CordovaError('Failed to install apk to emulator: ' + stdout));
|
|
||||||
} else resolve(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'),
|
|
||||||
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).done(null, function(err) {
|
|
||||||
console.error('ERROR: ' + err);
|
|
||||||
process.exit(2);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
|
|
||||||
process.exit(2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
device.install().done(null, 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,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'),
|
|
||||||
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.install(install_target).done(null, 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-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().done(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
|
|
||||||
)
|
|
||||||
56
bin/templates/cordova/lib/log.js
vendored
@@ -1,56 +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 os = require('os');
|
|
||||||
var Q = require('q');
|
|
||||||
var child_process = require('child_process');
|
|
||||||
var ROOT = path.join(__dirname, '..', '..');
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Starts running logcat in the shell.
|
|
||||||
* Returns a promise.
|
|
||||||
*/
|
|
||||||
module.exports.run = function () {
|
|
||||||
var d = Q.defer();
|
|
||||||
var adb = child_process.spawn('adb', ['logcat'], {cwd: os.tmpdir()});
|
|
||||||
|
|
||||||
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'));
|
|
||||||
});
|
|
||||||
|
|
||||||
adb.stderr.on('data', console.error);
|
|
||||||
adb.on('close', function (code) {
|
|
||||||
if (code > 0) {
|
|
||||||
d.reject('Failed to run logcat command.');
|
|
||||||
} else d.resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
return d.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
479
bin/templates/cordova/lib/prepare.js
vendored
@@ -1,479 +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.
|
|
||||||
*/
|
|
||||||
/* eslint no-useless-escape: 0 */
|
|
||||||
|
|
||||||
var Q = require('q');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
var shell = require('shelljs');
|
|
||||||
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;
|
|
||||||
|
|
||||||
module.exports.prepare = function (cordovaProject, options) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Update own www dir with project's www assets and plugins' assets and js-files
|
|
||||||
return Q.when(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 Q();
|
|
||||||
}
|
|
||||||
|
|
||||||
var projectConfig = new ConfigParser(this.locations.configXml);
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
return Q().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.
|
|
||||||
shell.cp('-f', 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)
|
|
||||||
.setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android'))
|
|
||||||
.setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android'))
|
|
||||||
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
|
||||||
.write();
|
|
||||||
|
|
||||||
var javaPattern = path.join(locations.root, 'src', manifestId.replace(/\./g, '/'), '*.java');
|
|
||||||
var java_files = shell.ls(javaPattern).filter(function (f) {
|
|
||||||
return shell.grep(/extends\s+CordovaActivity/g, f);
|
|
||||||
});
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var destFile = path.join(locations.root, 'src', androidPkgName.replace(/\./g, '/'), path.basename(java_files[0]));
|
|
||||||
shell.mkdir('-p', path.dirname(destFile));
|
|
||||||
shell.sed(/package [\w\.]*;/, 'package ' + androidPkgName + ';', java_files[0]).to(destFile);
|
|
||||||
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
|
|
||||||
shell.rm('-Rf', 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 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) {
|
|
||||||
var icons = cordovaProject.projectConfig.getIcons('android');
|
|
||||||
|
|
||||||
// if there are icon elements in config.xml
|
|
||||||
if (icons.length === 0) {
|
|
||||||
events.emit('verbose', 'This app does not have launcher icons defined');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'icon.png');
|
|
||||||
|
|
||||||
var android_icons = {};
|
|
||||||
var default_icon;
|
|
||||||
// http://developer.android.com/design/style/iconography.html
|
|
||||||
var sizeToDensityMap = {
|
|
||||||
36: 'ldpi',
|
|
||||||
48: 'mdpi',
|
|
||||||
72: 'hdpi',
|
|
||||||
96: 'xhdpi',
|
|
||||||
144: 'xxhdpi',
|
|
||||||
192: 'xxxhdpi'
|
|
||||||
};
|
|
||||||
// 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 || sizeToDensityMap[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) {
|
|
||||||
events.emit('verbose', 'Found extra default icon: ' + icon.src + ' (ignoring in favor of ' + default_icon.src + ')');
|
|
||||||
} else {
|
|
||||||
default_icon = icon;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parseIcon(icon, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, 'icon.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', 'icon.png', path.basename(default_icon.src));
|
|
||||||
resourceMap[defaultTargetPath] = default_icon.src;
|
|
||||||
}
|
|
||||||
|
|
||||||
events.emit('verbose', 'Updating icons at ' + platformResourcesDir);
|
|
||||||
FileUpdater.updatePaths(
|
|
||||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanIcons (projectRoot, projectConfig, platformResourcesDir) {
|
|
||||||
var icons = projectConfig.getIcons('android');
|
|
||||||
if (icons.length > 0) {
|
|
||||||
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'icon.png');
|
|
||||||
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) {
|
|
||||||
var pathMap = {};
|
|
||||||
shell.ls(path.join(rootDir, subDir, type + '-*')).forEach(function (drawableFolder) {
|
|
||||||
var 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;
|
|
||||||
}
|
|
||||||
132
bin/templates/cordova/lib/run.js
vendored
@@ -1,132 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* jshint loopfunc:true */
|
|
||||||
|
|
||||||
var path = require('path');
|
|
||||||
var build = require('./build');
|
|
||||||
var emulator = require('./emulator');
|
|
||||||
var device = require('./device');
|
|
||||||
var Q = require('q');
|
|
||||||
var events = require('cordova-common').events;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
var install_target = getInstallTarget(runOptions);
|
|
||||||
|
|
||||||
return Q().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 Q.reject('Target \'' + install_target + '\' not found, unable to run project');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}).then(function (resolvedTarget) {
|
|
||||||
// Better just call self.build, but we're doing some processing of
|
|
||||||
// build results (according to platformApi spec) so they are in different
|
|
||||||
// format than emulator.install expects.
|
|
||||||
// TODO: Update emulator/device.install to handle this change
|
|
||||||
return build.run.call(self, runOptions, resolvedTarget).then(function (buildResults) {
|
|
||||||
if (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,39 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var emulator = require('./emulator'),
|
|
||||||
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).done(null, 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
|
|
||||||
)
|
|
||||||
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,53 +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
|
|
||||||
)
|
|
||||||
2188
bin/templates/project/assets/www/cordova.js
vendored
@@ -1,15 +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 edit
|
|
||||||
# "ant.properties", and override values to adapt the script to your
|
|
||||||
# project structure.
|
|
||||||
#
|
|
||||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
|
||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
|
||||||
|
|
||||||
android.library.reference.1=CordovaLib
|
|
||||||
# Project target.
|
|
||||||
target=This_gets_replaced
|
|
||||||
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 292 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
37
bin/update
@@ -1,37 +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)}).done();
|
|
||||||
@@ -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
|
|
||||||
)
|
|
||||||
6
cordova-js-src/android/nativeapiprovider.js
vendored
@@ -25,12 +25,12 @@ var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativ
|
|||||||
var currentApi = nativeApi;
|
var currentApi = nativeApi;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get: function() { return currentApi; },
|
get: function () { return currentApi; },
|
||||||
setPreferPrompt: function(value) {
|
setPreferPrompt: function (value) {
|
||||||
currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
|
currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
|
||||||
},
|
},
|
||||||
// Used only by tests.
|
// Used only by tests.
|
||||||
set: function(value) {
|
set: function (value) {
|
||||||
currentApi = value;
|
currentApi = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,13 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
exec: function(bridgeSecret, service, action, callbackId, argsJson) {
|
exec: function (bridgeSecret, service, action, callbackId, argsJson) {
|
||||||
return prompt(argsJson, 'gap:'+JSON.stringify([bridgeSecret, service, action, callbackId]));
|
return prompt(argsJson, 'gap:' + JSON.stringify([bridgeSecret, service, action, callbackId]));
|
||||||
},
|
},
|
||||||
setNativeToJsBridgeMode: function(bridgeSecret, value) {
|
setNativeToJsBridgeMode: function (bridgeSecret, value) {
|
||||||
prompt(value, 'gap_bridge_mode:' + bridgeSecret);
|
prompt(value, 'gap_bridge_mode:' + bridgeSecret);
|
||||||
},
|
},
|
||||||
retrieveJsMessages: function(bridgeSecret, fromOnlineEvent) {
|
retrieveJsMessages: function (bridgeSecret, fromOnlineEvent) {
|
||||||
return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret);
|
return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
144
cordova-js-src/exec.js
vendored
@@ -33,38 +33,38 @@
|
|||||||
* @param {String} action Action to be run in cordova
|
* @param {String} action Action to be run in cordova
|
||||||
* @param {String[]} [args] Zero or more arguments to pass to the method
|
* @param {String[]} [args] Zero or more arguments to pass to the method
|
||||||
*/
|
*/
|
||||||
var cordova = require('cordova'),
|
var cordova = require('cordova');
|
||||||
nativeApiProvider = require('cordova/android/nativeapiprovider'),
|
var nativeApiProvider = require('cordova/android/nativeapiprovider');
|
||||||
utils = require('cordova/utils'),
|
var utils = require('cordova/utils');
|
||||||
base64 = require('cordova/base64'),
|
var base64 = require('cordova/base64');
|
||||||
channel = require('cordova/channel'),
|
var channel = require('cordova/channel');
|
||||||
jsToNativeModes = {
|
var jsToNativeModes = {
|
||||||
PROMPT: 0,
|
PROMPT: 0,
|
||||||
JS_OBJECT: 1
|
JS_OBJECT: 1
|
||||||
},
|
};
|
||||||
nativeToJsModes = {
|
var nativeToJsModes = {
|
||||||
// Polls for messages using the JS->Native bridge.
|
// Polls for messages using the JS->Native bridge.
|
||||||
POLLING: 0,
|
POLLING: 0,
|
||||||
// For LOAD_URL to be viable, it would need to have a work-around for
|
// For LOAD_URL to be viable, it would need to have a work-around for
|
||||||
// the bug where the soft-keyboard gets dismissed when a message is sent.
|
// the bug where the soft-keyboard gets dismissed when a message is sent.
|
||||||
LOAD_URL: 1,
|
LOAD_URL: 1,
|
||||||
// For the ONLINE_EVENT to be viable, it would need to intercept all event
|
// For the ONLINE_EVENT to be viable, it would need to intercept all event
|
||||||
// listeners (both through addEventListener and window.ononline) as well
|
// listeners (both through addEventListener and window.ononline) as well
|
||||||
// as set the navigator property itself.
|
// as set the navigator property itself.
|
||||||
ONLINE_EVENT: 2,
|
ONLINE_EVENT: 2,
|
||||||
EVAL_BRIDGE: 3
|
EVAL_BRIDGE: 3
|
||||||
},
|
};
|
||||||
jsToNativeBridgeMode, // Set lazily.
|
var jsToNativeBridgeMode; // Set lazily.
|
||||||
nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE,
|
var nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE;
|
||||||
pollEnabled = false,
|
var pollEnabled = false;
|
||||||
bridgeSecret = -1;
|
var bridgeSecret = -1;
|
||||||
|
|
||||||
var messagesFromNative = [];
|
var messagesFromNative = [];
|
||||||
var isProcessing = false;
|
var isProcessing = false;
|
||||||
var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
|
var resolvedPromise = typeof Promise === 'undefined' ? null : Promise.resolve();
|
||||||
var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };
|
var nextTick = resolvedPromise ? function (fn) { resolvedPromise.then(fn); } : function (fn) { setTimeout(fn); };
|
||||||
|
|
||||||
function androidExec(success, fail, service, action, args) {
|
function androidExec (success, fail, service, action, args) {
|
||||||
if (bridgeSecret < 0) {
|
if (bridgeSecret < 0) {
|
||||||
// If we ever catch this firing, we'll need to queue up exec()s
|
// If we ever catch this firing, we'll need to queue up exec()s
|
||||||
// and fire them once we get a secret. For now, I don't think
|
// and fire them once we get a secret. For now, I don't think
|
||||||
@@ -83,21 +83,21 @@ function androidExec(success, fail, service, action, args) {
|
|||||||
|
|
||||||
// Process any ArrayBuffers in the args into a string.
|
// Process any ArrayBuffers in the args into a string.
|
||||||
for (var i = 0; i < args.length; i++) {
|
for (var i = 0; i < args.length; i++) {
|
||||||
if (utils.typeName(args[i]) == 'ArrayBuffer') {
|
if (utils.typeName(args[i]) === 'ArrayBuffer') {
|
||||||
args[i] = base64.fromArrayBuffer(args[i]);
|
args[i] = base64.fromArrayBuffer(args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var callbackId = service + cordova.callbackId++,
|
var callbackId = service + cordova.callbackId++;
|
||||||
argsJson = JSON.stringify(args);
|
var argsJson = JSON.stringify(args);
|
||||||
if (success || fail) {
|
if (success || fail) {
|
||||||
cordova.callbacks[callbackId] = {success:success, fail:fail};
|
cordova.callbacks[callbackId] = { success: success, fail: fail };
|
||||||
}
|
}
|
||||||
|
|
||||||
var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
|
var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
|
||||||
// If argsJson was received by Java as null, try again with the PROMPT bridge mode.
|
// If argsJson was received by Java as null, try again with the PROMPT bridge mode.
|
||||||
// This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
|
// This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
|
||||||
if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && msgs === "@Null arguments.") {
|
if (jsToNativeBridgeMode === jsToNativeModes.JS_OBJECT && msgs === '@Null arguments.') {
|
||||||
androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
|
androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
|
||||||
androidExec(success, fail, service, action, args);
|
androidExec(success, fail, service, action, args);
|
||||||
androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
|
androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
|
||||||
@@ -108,27 +108,16 @@ function androidExec(success, fail, service, action, args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
androidExec.init = function() {
|
androidExec.init = function () {
|
||||||
//CB-11828
|
|
||||||
//This failsafe checks the version of Android and if it's Jellybean, it switches it to
|
|
||||||
//using the Online Event bridge for communicating from Native to JS
|
|
||||||
//
|
|
||||||
//It's ugly, but it's necessary.
|
|
||||||
var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/);
|
|
||||||
var version_code = check && check[0].match(/4.[0-3].*/);
|
|
||||||
if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) {
|
|
||||||
nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
|
bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
|
||||||
channel.onNativeReady.fire();
|
channel.onNativeReady.fire();
|
||||||
};
|
};
|
||||||
|
|
||||||
function pollOnceFromOnlineEvent() {
|
function pollOnceFromOnlineEvent () {
|
||||||
pollOnce(true);
|
pollOnce(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pollOnce(opt_fromOnlineEvent) {
|
function pollOnce (opt_fromOnlineEvent) {
|
||||||
if (bridgeSecret < 0) {
|
if (bridgeSecret < 0) {
|
||||||
// This can happen when the NativeToJsMessageQueue resets the online state on page transitions.
|
// This can happen when the NativeToJsMessageQueue resets the online state on page transitions.
|
||||||
// We know there's nothing to retrieve, so no need to poll.
|
// We know there's nothing to retrieve, so no need to poll.
|
||||||
@@ -142,15 +131,15 @@ function pollOnce(opt_fromOnlineEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pollingTimerFunc() {
|
function pollingTimerFunc () {
|
||||||
if (pollEnabled) {
|
if (pollEnabled) {
|
||||||
pollOnce();
|
pollOnce();
|
||||||
setTimeout(pollingTimerFunc, 50);
|
setTimeout(pollingTimerFunc, 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hookOnlineApis() {
|
function hookOnlineApis () {
|
||||||
function proxyEvent(e) {
|
function proxyEvent (e) {
|
||||||
cordova.fireWindowEvent(e.type);
|
cordova.fireWindowEvent(e.type);
|
||||||
}
|
}
|
||||||
// The network module takes care of firing online and offline events.
|
// The network module takes care of firing online and offline events.
|
||||||
@@ -170,19 +159,19 @@ hookOnlineApis();
|
|||||||
androidExec.jsToNativeModes = jsToNativeModes;
|
androidExec.jsToNativeModes = jsToNativeModes;
|
||||||
androidExec.nativeToJsModes = nativeToJsModes;
|
androidExec.nativeToJsModes = nativeToJsModes;
|
||||||
|
|
||||||
androidExec.setJsToNativeBridgeMode = function(mode) {
|
androidExec.setJsToNativeBridgeMode = function (mode) {
|
||||||
if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
|
if (mode === jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
|
||||||
mode = jsToNativeModes.PROMPT;
|
mode = jsToNativeModes.PROMPT;
|
||||||
}
|
}
|
||||||
nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
|
nativeApiProvider.setPreferPrompt(mode === jsToNativeModes.PROMPT);
|
||||||
jsToNativeBridgeMode = mode;
|
jsToNativeBridgeMode = mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
androidExec.setNativeToJsBridgeMode = function(mode) {
|
androidExec.setNativeToJsBridgeMode = function (mode) {
|
||||||
if (mode == nativeToJsBridgeMode) {
|
if (mode === nativeToJsBridgeMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
|
if (nativeToJsBridgeMode === nativeToJsModes.POLLING) {
|
||||||
pollEnabled = false;
|
pollEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,32 +182,32 @@ androidExec.setNativeToJsBridgeMode = function(mode) {
|
|||||||
nativeApiProvider.get().setNativeToJsBridgeMode(bridgeSecret, mode);
|
nativeApiProvider.get().setNativeToJsBridgeMode(bridgeSecret, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == nativeToJsModes.POLLING) {
|
if (mode === nativeToJsModes.POLLING) {
|
||||||
pollEnabled = true;
|
pollEnabled = true;
|
||||||
setTimeout(pollingTimerFunc, 1);
|
setTimeout(pollingTimerFunc, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildPayload(payload, message) {
|
function buildPayload (payload, message) {
|
||||||
var payloadKind = message.charAt(0);
|
var payloadKind = message.charAt(0);
|
||||||
if (payloadKind == 's') {
|
if (payloadKind === 's') {
|
||||||
payload.push(message.slice(1));
|
payload.push(message.slice(1));
|
||||||
} else if (payloadKind == 't') {
|
} else if (payloadKind === 't') {
|
||||||
payload.push(true);
|
payload.push(true);
|
||||||
} else if (payloadKind == 'f') {
|
} else if (payloadKind === 'f') {
|
||||||
payload.push(false);
|
payload.push(false);
|
||||||
} else if (payloadKind == 'N') {
|
} else if (payloadKind === 'N') {
|
||||||
payload.push(null);
|
payload.push(null);
|
||||||
} else if (payloadKind == 'n') {
|
} else if (payloadKind === 'n') {
|
||||||
payload.push(+message.slice(1));
|
payload.push(+message.slice(1));
|
||||||
} else if (payloadKind == 'A') {
|
} else if (payloadKind === 'A') {
|
||||||
var data = message.slice(1);
|
var data = message.slice(1);
|
||||||
payload.push(base64.toArrayBuffer(data));
|
payload.push(base64.toArrayBuffer(data));
|
||||||
} else if (payloadKind == 'S') {
|
} else if (payloadKind === 'S') {
|
||||||
payload.push(window.atob(message.slice(1)));
|
payload.push(window.atob(message.slice(1)));
|
||||||
} else if (payloadKind == 'M') {
|
} else if (payloadKind === 'M') {
|
||||||
var multipartMessages = message.slice(1);
|
var multipartMessages = message.slice(1);
|
||||||
while (multipartMessages !== "") {
|
while (multipartMessages !== '') {
|
||||||
var spaceIdx = multipartMessages.indexOf(' ');
|
var spaceIdx = multipartMessages.indexOf(' ');
|
||||||
var msgLen = +multipartMessages.slice(0, spaceIdx);
|
var msgLen = +multipartMessages.slice(0, spaceIdx);
|
||||||
var multipartMessage = multipartMessages.substr(spaceIdx + 1, msgLen);
|
var multipartMessage = multipartMessages.substr(spaceIdx + 1, msgLen);
|
||||||
@@ -231,14 +220,15 @@ function buildPayload(payload, message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Processes a single message, as encoded by NativeToJsMessageQueue.java.
|
// Processes a single message, as encoded by NativeToJsMessageQueue.java.
|
||||||
function processMessage(message) {
|
function processMessage (message) {
|
||||||
var firstChar = message.charAt(0);
|
var firstChar = message.charAt(0);
|
||||||
if (firstChar == 'J') {
|
if (firstChar === 'J') {
|
||||||
// This is deprecated on the .java side. It doesn't work with CSP enabled.
|
// This is deprecated on the .java side. It doesn't work with CSP enabled.
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
eval(message.slice(1));
|
eval(message.slice(1));
|
||||||
} else if (firstChar == 'S' || firstChar == 'F') {
|
} else if (firstChar === 'S' || firstChar === 'F') {
|
||||||
var success = firstChar == 'S';
|
var success = firstChar === 'S';
|
||||||
var keepCallback = message.charAt(1) == '1';
|
var keepCallback = message.charAt(1) === '1';
|
||||||
var spaceIdx = message.indexOf(' ', 2);
|
var spaceIdx = message.indexOf(' ', 2);
|
||||||
var status = +message.slice(2, spaceIdx);
|
var status = +message.slice(2, spaceIdx);
|
||||||
var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
|
var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
|
||||||
@@ -248,11 +238,11 @@ function processMessage(message) {
|
|||||||
buildPayload(payload, payloadMessage);
|
buildPayload(payload, payloadMessage);
|
||||||
cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
|
cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
|
||||||
} else {
|
} else {
|
||||||
console.log("processMessage failed: invalid message: " + JSON.stringify(message));
|
console.log('processMessage failed: invalid message: ' + JSON.stringify(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processMessages() {
|
function processMessages () {
|
||||||
// Check for the reentrant case.
|
// Check for the reentrant case.
|
||||||
if (isProcessing) {
|
if (isProcessing) {
|
||||||
return;
|
return;
|
||||||
@@ -265,7 +255,7 @@ function processMessages() {
|
|||||||
var msg = popMessageFromQueue();
|
var msg = popMessageFromQueue();
|
||||||
// The Java side can send a * message to indicate that it
|
// The Java side can send a * message to indicate that it
|
||||||
// still has messages waiting to be retrieved.
|
// still has messages waiting to be retrieved.
|
||||||
if (msg == '*' && messagesFromNative.length === 0) {
|
if (msg === '*' && messagesFromNative.length === 0) {
|
||||||
nextTick(pollOnce);
|
nextTick(pollOnce);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -278,9 +268,9 @@ function processMessages() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function popMessageFromQueue() {
|
function popMessageFromQueue () {
|
||||||
var messageBatch = messagesFromNative.shift();
|
var messageBatch = messagesFromNative.shift();
|
||||||
if (messageBatch == '*') {
|
if (messageBatch === '*') {
|
||||||
return '*';
|
return '*';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
89
cordova-js-src/platform.js
vendored
@@ -24,11 +24,11 @@ var lastResumeEvent = null;
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
id: 'android',
|
id: 'android',
|
||||||
bootstrap: function() {
|
bootstrap: function () {
|
||||||
var channel = require('cordova/channel'),
|
var channel = require('cordova/channel');
|
||||||
cordova = require('cordova'),
|
var cordova = require('cordova');
|
||||||
exec = require('cordova/exec'),
|
var exec = require('cordova/exec');
|
||||||
modulemapper = require('cordova/modulemapper');
|
var modulemapper = require('cordova/modulemapper');
|
||||||
|
|
||||||
// Get the shared secret needed to use the bridge.
|
// Get the shared secret needed to use the bridge.
|
||||||
exec.init();
|
exec.init();
|
||||||
@@ -40,21 +40,21 @@ module.exports = {
|
|||||||
|
|
||||||
// Inject a listener for the backbutton on the document.
|
// Inject a listener for the backbutton on the document.
|
||||||
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
|
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
|
||||||
backButtonChannel.onHasSubscribersChange = function() {
|
backButtonChannel.onHasSubscribersChange = function () {
|
||||||
// If we just attached the first handler or detached the last handler,
|
// If we just attached the first handler or detached the last handler,
|
||||||
// let native know we need to override the back button.
|
// let native know we need to override the back button.
|
||||||
exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [this.numHandlers == 1]);
|
exec(null, null, APP_PLUGIN_NAME, 'overrideBackbutton', [this.numHandlers === 1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add hardware MENU and SEARCH button handlers
|
// Add hardware MENU and SEARCH button handlers
|
||||||
cordova.addDocumentEventHandler('menubutton');
|
cordova.addDocumentEventHandler('menubutton');
|
||||||
cordova.addDocumentEventHandler('searchbutton');
|
cordova.addDocumentEventHandler('searchbutton');
|
||||||
|
|
||||||
function bindButtonChannel(buttonName) {
|
function bindButtonChannel (buttonName) {
|
||||||
// generic button bind used for volumeup/volumedown buttons
|
// generic button bind used for volumeup/volumedown buttons
|
||||||
var volumeButtonChannel = cordova.addDocumentEventHandler(buttonName + 'button');
|
var volumeButtonChannel = cordova.addDocumentEventHandler(buttonName + 'button');
|
||||||
volumeButtonChannel.onHasSubscribersChange = function() {
|
volumeButtonChannel.onHasSubscribersChange = function () {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "overrideButton", [buttonName, this.numHandlers == 1]);
|
exec(null, null, APP_PLUGIN_NAME, 'overrideButton', [buttonName, this.numHandlers === 1]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Inject a listener for the volume buttons on the document.
|
// Inject a listener for the volume buttons on the document.
|
||||||
@@ -66,7 +66,7 @@ module.exports = {
|
|||||||
// plugin result is delivered even after the event is fired (CB-10498)
|
// plugin result is delivered even after the event is fired (CB-10498)
|
||||||
var cordovaAddEventListener = document.addEventListener;
|
var cordovaAddEventListener = document.addEventListener;
|
||||||
|
|
||||||
document.addEventListener = function(evt, handler, capture) {
|
document.addEventListener = function (evt, handler, capture) {
|
||||||
cordovaAddEventListener(evt, handler, capture);
|
cordovaAddEventListener(evt, handler, capture);
|
||||||
|
|
||||||
if (evt === 'resume' && lastResumeEvent) {
|
if (evt === 'resume' && lastResumeEvent) {
|
||||||
@@ -76,50 +76,47 @@ module.exports = {
|
|||||||
|
|
||||||
// Let native code know we are all done on the JS side.
|
// Let native code know we are all done on the JS side.
|
||||||
// Native code will then un-hide the WebView.
|
// Native code will then un-hide the WebView.
|
||||||
channel.onCordovaReady.subscribe(function() {
|
channel.onCordovaReady.subscribe(function () {
|
||||||
exec(onMessageFromNative, null, APP_PLUGIN_NAME, 'messageChannel', []);
|
exec(onMessageFromNative, null, APP_PLUGIN_NAME, 'messageChannel', []);
|
||||||
exec(null, null, APP_PLUGIN_NAME, "show", []);
|
exec(null, null, APP_PLUGIN_NAME, 'show', []);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function onMessageFromNative(msg) {
|
function onMessageFromNative (msg) {
|
||||||
var cordova = require('cordova');
|
var cordova = require('cordova');
|
||||||
var action = msg.action;
|
var action = msg.action;
|
||||||
|
|
||||||
switch (action)
|
switch (action) {
|
||||||
{
|
// pause and resume are Android app life cycle events
|
||||||
// Button events
|
case 'backbutton':
|
||||||
case 'backbutton':
|
case 'menubutton':
|
||||||
case 'menubutton':
|
case 'searchbutton':
|
||||||
case 'searchbutton':
|
case 'pause':
|
||||||
// App life cycle events
|
case 'volumedownbutton':
|
||||||
case 'pause':
|
case 'volumeupbutton':
|
||||||
// Volume events
|
cordova.fireDocumentEvent(action);
|
||||||
case 'volumedownbutton':
|
break;
|
||||||
case 'volumeupbutton':
|
case 'resume':
|
||||||
cordova.fireDocumentEvent(action);
|
if (arguments.length > 1 && msg.pendingResult) {
|
||||||
break;
|
if (arguments.length === 2) {
|
||||||
case 'resume':
|
msg.pendingResult.result = arguments[1];
|
||||||
if(arguments.length > 1 && msg.pendingResult) {
|
} else {
|
||||||
if(arguments.length === 2) {
|
// The plugin returned a multipart message
|
||||||
msg.pendingResult.result = arguments[1];
|
var res = [];
|
||||||
} else {
|
for (var i = 1; i < arguments.length; i++) {
|
||||||
// The plugin returned a multipart message
|
res.push(arguments[i]);
|
||||||
var res = [];
|
|
||||||
for(var i = 1; i < arguments.length; i++) {
|
|
||||||
res.push(arguments[i]);
|
|
||||||
}
|
|
||||||
msg.pendingResult.result = res;
|
|
||||||
}
|
}
|
||||||
|
msg.pendingResult.result = res;
|
||||||
// Save the plugin result so that it can be delivered to the js
|
|
||||||
// even if they miss the initial firing of the event
|
|
||||||
lastResumeEvent = msg;
|
|
||||||
}
|
}
|
||||||
cordova.fireDocumentEvent(action, msg);
|
|
||||||
break;
|
// Save the plugin result so that it can be delivered to the js
|
||||||
default:
|
// even if they miss the initial firing of the event
|
||||||
throw new Error('Unknown event action ' + action);
|
lastResumeEvent = msg;
|
||||||
|
}
|
||||||
|
cordova.fireDocumentEvent(action, msg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown event action ' + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
cordova-js-src/plugin/android/app.js
vendored
@@ -26,8 +26,8 @@ module.exports = {
|
|||||||
/**
|
/**
|
||||||
* Clear the resource cache.
|
* Clear the resource cache.
|
||||||
*/
|
*/
|
||||||
clearCache:function() {
|
clearCache: function () {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "clearCache", []);
|
exec(null, null, APP_PLUGIN_NAME, 'clearCache', []);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,31 +44,31 @@ module.exports = {
|
|||||||
* Example:
|
* Example:
|
||||||
* navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
|
* navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
|
||||||
*/
|
*/
|
||||||
loadUrl:function(url, props) {
|
loadUrl: function (url, props) {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "loadUrl", [url, props]);
|
exec(null, null, APP_PLUGIN_NAME, 'loadUrl', [url, props]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel loadUrl that is waiting to be loaded.
|
* Cancel loadUrl that is waiting to be loaded.
|
||||||
*/
|
*/
|
||||||
cancelLoadUrl:function() {
|
cancelLoadUrl: function () {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "cancelLoadUrl", []);
|
exec(null, null, APP_PLUGIN_NAME, 'cancelLoadUrl', []);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear web history in this web view.
|
* Clear web history in this web view.
|
||||||
* Instead of BACK button loading the previous web page, it will exit the app.
|
* Instead of BACK button loading the previous web page, it will exit the app.
|
||||||
*/
|
*/
|
||||||
clearHistory:function() {
|
clearHistory: function () {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "clearHistory", []);
|
exec(null, null, APP_PLUGIN_NAME, 'clearHistory', []);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Go to previous page displayed.
|
* Go to previous page displayed.
|
||||||
* This is the same as pressing the backbutton on Android device.
|
* This is the same as pressing the backbutton on Android device.
|
||||||
*/
|
*/
|
||||||
backHistory:function() {
|
backHistory: function () {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "backHistory", []);
|
exec(null, null, APP_PLUGIN_NAME, 'backHistory', []);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,8 +80,8 @@ module.exports = {
|
|||||||
*
|
*
|
||||||
* @param override T=override, F=cancel override
|
* @param override T=override, F=cancel override
|
||||||
*/
|
*/
|
||||||
overrideBackbutton:function(override) {
|
overrideBackbutton: function (override) {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [override]);
|
exec(null, null, APP_PLUGIN_NAME, 'overrideBackbutton', [override]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,14 +95,14 @@ module.exports = {
|
|||||||
* @param button volumeup, volumedown
|
* @param button volumeup, volumedown
|
||||||
* @param override T=override, F=cancel override
|
* @param override T=override, F=cancel override
|
||||||
*/
|
*/
|
||||||
overrideButton:function(button, override) {
|
overrideButton: function (button, override) {
|
||||||
exec(null, null, APP_PLUGIN_NAME, "overrideButton", [button, override]);
|
exec(null, null, APP_PLUGIN_NAME, 'overrideButton', [button, override]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exit and terminate the application.
|
* Exit and terminate the application.
|
||||||
*/
|
*/
|
||||||
exitApp:function() {
|
exitApp: function () {
|
||||||
return exec(null, null, APP_PLUGIN_NAME, "exitApp", []);
|
return exec(null, null, APP_PLUGIN_NAME, 'exitApp', []);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
|
||||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
|
||||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
|
||||||
<classpathentry kind="src" path="src"/>
|
|
||||||
<classpathentry kind="src" path="gen"/>
|
|
||||||
<classpathentry kind="output" path="bin/classes"/>
|
|
||||||
</classpath>
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>Cordova</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
||||||
@@ -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
|
|
||||||
@@ -19,5 +19,4 @@
|
|||||||
-->
|
-->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
|
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
|
||||||
<uses-sdk android:minSdkVersion="14" />
|
|
||||||
</manifest>
|
</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,42 +16,43 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ext {
|
|
||||||
apply from: 'cordova.gradle'
|
|
||||||
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
|
||||||
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
|
||||||
}
|
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
apply from: 'cordova.gradle'
|
||||||
jcenter()
|
apply from: 'repositories.gradle'
|
||||||
maven {
|
|
||||||
url "https://maven.google.com"
|
repositories repos
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0'
|
// Android Gradle Plugin (AGP) Build Tools
|
||||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
|
classpath "com.android.tools.build:gradle:${cordovaConfig.AGP_VERSION}"
|
||||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
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.android.library'
|
||||||
apply plugin: 'com.github.dcendents.android-maven'
|
|
||||||
apply plugin: 'com.jfrog.bintray'
|
|
||||||
|
|
||||||
group = 'org.apache.cordova'
|
|
||||||
version = '6.4.1-dev'
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion cdvCompileSdkVersion
|
compileSdkVersion cordovaConfig.SDK_VERSION
|
||||||
buildToolsVersion cdvBuildToolsVersion
|
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
|
||||||
publishNonDefault true
|
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_6
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_6
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the Android Cordova Lib, we allow changing the minSdkVersion, but it is at the users own risk
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion cordovaConfig.MIN_SDK_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -74,64 +75,17 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
install {
|
dependencies {
|
||||||
repositories.mavenInstaller {
|
implementation "androidx.appcompat:appcompat:${cordovaConfig.ANDROIDX_APP_COMPAT_VERSION}"
|
||||||
pom {
|
implementation "androidx.webkit:webkit:${cordovaConfig.ANDROIDX_WEBKIT_VERSION}"
|
||||||
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 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
|
|
||||||
developerConnection 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
|
|
||||||
url 'https://git-wip-us.apache.org/repos/asf?p=cordova-android'
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task sourcesJar(type: Jar) {
|
/**
|
||||||
from android.sourceSets.main.java.srcDirs
|
* In a project created though CLI, the `cordova-publish.gradle` file is not copied to the `framework` dir.
|
||||||
classifier = 'sources'
|
* 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.
|
||||||
|
*/
|
||||||
artifacts {
|
def cordovaPublishGradle = './cordova-publish.gradle'
|
||||||
archives sourcesJar
|
if(file(cordovaPublishGradle).exists()) {
|
||||||
}
|
apply from: cordovaPublishGradle
|
||||||
|
|
||||||
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://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
|
|
||||||
websiteUrl = 'https://cordova.apache.org'
|
|
||||||
issueTrackerUrl = 'https://issues.apache.org/jira/browse/CB'
|
|
||||||
publicDownloadNumbers = true
|
|
||||||
licenses = ['Apache-2.0']
|
|
||||||
labels = ['android', 'cordova', 'phonegap']
|
|
||||||
version {
|
|
||||||
name = '6.4.1-dev'
|
|
||||||
released = new Date()
|
|
||||||
vcsTag = '6.4.1-dev'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
|
||||||
13
framework/cdv-gradle-config-defaults.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"MIN_SDK_VERSION": 22,
|
||||||
|
"SDK_VERSION": 30,
|
||||||
|
"GRADLE_VERSION": "7.1.1",
|
||||||
|
"MIN_BUILD_TOOLS_VERSION": "30.0.3",
|
||||||
|
"AGP_VERSION": "4.2.2",
|
||||||
|
"KOTLIN_VERSION": "1.5.21",
|
||||||
|
"ANDROIDX_APP_COMPAT_VERSION": "1.3.1",
|
||||||
|
"ANDROIDX_WEBKIT_VERSION": "1.4.0",
|
||||||
|
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.8",
|
||||||
|
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
|
||||||
|
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false
|
||||||
|
}
|
||||||
125
framework/cordova-publish.gradle
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'maven-publish'
|
||||||
|
apply plugin: 'signing'
|
||||||
|
|
||||||
|
String getCordovaAndroidVersion() {
|
||||||
|
// Fetch Data from Cordova-Android package.json (Used only by framework build/publishing)
|
||||||
|
def cordovaAndroidRepoPackageJson = "$projectDir/../package.json"
|
||||||
|
if(file(cordovaAndroidRepoPackageJson).exists()) {
|
||||||
|
def packageJsonFile = new File(cordovaAndroidRepoPackageJson)
|
||||||
|
def packageJson = new groovy.json.JsonSlurper().parseText(packageJsonFile.text)
|
||||||
|
return packageJson.version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable signing by default when keyId and secretKeyRingFile is defined.
|
||||||
|
ext.cdvEnableSigning = project.hasProperty('signing.keyId') && project.hasProperty('signing.secretKeyRingFile')
|
||||||
|
if (cdvEnableSigning) {
|
||||||
|
logger.debug('[Cordova] Signing has been enabled by default because the signing keyId & secretKeyRingFile has been defined.')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty('signEnabled')) {
|
||||||
|
if(!cdvEnableSigning && Boolean.valueOf(signEnabled)) {
|
||||||
|
logger.debug("[Cordova] The \"signEnabled\" override can not be set to \"true\" when the signing properties are missing.")
|
||||||
|
} else {
|
||||||
|
// Override the default setting with the "signEnabled" property. (In this case it should only accept false)
|
||||||
|
logger.debug("[Cordova] The \"signEnabled\" property has been detected and forcing enabled signing to \"$signEnabled\".")
|
||||||
|
cdvEnableSigning = signEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task sourcesJar(type: Jar) {
|
||||||
|
from android.sourceSets.main.java.srcDirs
|
||||||
|
classifier = 'sources'
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
mavenJava(MavenPublication) {
|
||||||
|
groupId = 'org.apache.cordova'
|
||||||
|
artifactId = 'framework'
|
||||||
|
version = getCordovaAndroidVersion()
|
||||||
|
|
||||||
|
artifact(sourcesJar)
|
||||||
|
artifact("$buildDir/outputs/aar/framework-release.aar")
|
||||||
|
|
||||||
|
pom {
|
||||||
|
name = 'Cordova'
|
||||||
|
description = 'A library to build Cordova-based projects for the Android platform.'
|
||||||
|
url = 'https://cordova.apache.org'
|
||||||
|
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name = 'Apache License, Version 2.0'
|
||||||
|
url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id = 'stevengill'
|
||||||
|
name = 'Steve Gill'
|
||||||
|
}
|
||||||
|
developer {
|
||||||
|
id = 'erisu'
|
||||||
|
name = 'Bryan Ellis'
|
||||||
|
email = 'erisu@apache.org'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scm {
|
||||||
|
connection = 'scm:git:https://github.com/apache/cordova-android.git'
|
||||||
|
developerConnection = 'scm:git:git@github.com:apache/cordova-android.git'
|
||||||
|
url = 'https://github.com/apache/cordova-android'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
def releasesRepoUrl = 'https://repository.apache.org/content/repositories/releases'
|
||||||
|
def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots'
|
||||||
|
|
||||||
|
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
|
||||||
|
|
||||||
|
credentials {
|
||||||
|
if (project.hasProperty('apacheUsername') && project.hasProperty('apachePassword')) {
|
||||||
|
username apacheUsername
|
||||||
|
password apachePassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signing {
|
||||||
|
if (Boolean.valueOf(cdvEnableSigning)) {
|
||||||
|
sign publishing.publications.mavenJava
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.whenTaskAdded {task ->
|
||||||
|
if(task.name.contains('sign')) {
|
||||||
|
logger.debug("[Cordova] The task \"${task.name}\" is enabled? ${cdvEnableSigning}")
|
||||||
|
task.enabled = cdvEnableSigning
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import groovy.swing.SwingBuilder
|
import io.github.g00fy2.versioncompare.Version
|
||||||
|
|
||||||
String doEnsureValueExists(filePath, props, key) {
|
String doEnsureValueExists(filePath, props, key) {
|
||||||
if (props.get(key) == null) {
|
if (props.get(key) == null) {
|
||||||
@@ -29,68 +29,65 @@ String doEnsureValueExists(filePath, props, key) {
|
|||||||
|
|
||||||
String doGetProjectTarget() {
|
String doGetProjectTarget() {
|
||||||
def props = new Properties()
|
def props = new Properties()
|
||||||
file('project.properties').withReader { reader ->
|
def propertiesFile = 'project.properties';
|
||||||
|
if(!(file(propertiesFile).exists())) {
|
||||||
|
propertiesFile = '../project.properties';
|
||||||
|
}
|
||||||
|
file(propertiesFile).withReader { reader ->
|
||||||
props.load(reader)
|
props.load(reader)
|
||||||
}
|
}
|
||||||
return doEnsureValueExists('project.properties', props, 'target')
|
return doEnsureValueExists('project.properties', props, 'target')
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] getAvailableBuildTools() {
|
Boolean isVersionValid(version) {
|
||||||
def buildToolsDir = new File(getAndroidSdkDir(), "build-tools")
|
return !(new Version(version)).isEqual('0.0.0')
|
||||||
buildToolsDir.list()
|
|
||||||
.findAll { it ==~ /[0-9.]+/ }
|
|
||||||
.sort { a, b -> compareVersions(b, a) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String doFindLatestInstalledBuildTools(String minBuildToolsVersion) {
|
String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
|
||||||
def availableBuildToolsVersions
|
def buildToolsDirContents
|
||||||
try {
|
try {
|
||||||
availableBuildToolsVersions = getAvailableBuildTools()
|
def buildToolsDir = new File(getAndroidSdkDir(), "build-tools")
|
||||||
|
buildToolsDirContents = buildToolsDir.list()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
println "An exception occurred while trying to find the Android build tools."
|
println "An exception occurred while trying to find the Android build tools."
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
if (availableBuildToolsVersions.length > 0) {
|
|
||||||
def highestBuildToolsVersion = availableBuildToolsVersions[0]
|
def minBuildToolsVersion = new Version(minBuildToolsVersionString)
|
||||||
if (compareVersions(highestBuildToolsVersion, minBuildToolsVersion) < 0) {
|
def maxVersion = new Version((minBuildToolsVersion.getMajor() + 1) + ".0.0")
|
||||||
throw new RuntimeException(
|
|
||||||
"No usable Android build tools found. Highest installed version is " +
|
def highestBuildToolsVersion = buildToolsDirContents
|
||||||
highestBuildToolsVersion + "; minimum version required is " +
|
.collect { new Version(it) }
|
||||||
minBuildToolsVersion + ".")
|
// Invalid inputs will be handled as 0.0.0
|
||||||
}
|
.findAll { it.isHigherThan('0.0.0') && it.isLowerThan(maxVersion) }
|
||||||
highestBuildToolsVersion
|
.max()
|
||||||
} else {
|
|
||||||
throw new RuntimeException(
|
if (highestBuildToolsVersion == null) {
|
||||||
"No installed build tools found. Install the Android build tools version " +
|
throw new RuntimeException("""
|
||||||
minBuildToolsVersion + " or higher.")
|
No installed build tools found. Install the Android build tools
|
||||||
|
version ${minBuildToolsVersionString} or higher.
|
||||||
|
""".replaceAll(/\s+/, ' ').trim())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Return the first non-zero result of subtracting version list elements
|
if (highestBuildToolsVersion.isLowerThan(minBuildToolsVersionString)) {
|
||||||
// pairwise. If they are all identical, return the difference in length of
|
throw new RuntimeException("""
|
||||||
// the two lists.
|
No usable Android build tools found. Highest ${minBuildToolsVersion.getMajor()}.x installed version is
|
||||||
int compareVersionList(Collection aParts, Collection bParts) {
|
${highestBuildToolsVersion.getOriginalString()}; minimum version
|
||||||
def pairs = ([aParts, bParts]).transpose()
|
required is ${minBuildToolsVersionString}.
|
||||||
pairs.findResult(aParts.size()-bParts.size()) {it[0] - it[1] != 0 ? it[0] - it[1] : null}
|
""".replaceAll(/\s+/, ' ').trim())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare two version strings, such as "19.0.0" and "18.1.1.0". If all matched
|
highestBuildToolsVersion.getOriginalString()
|
||||||
// elements are identical, the longer version is the largest by this method.
|
|
||||||
// Examples:
|
|
||||||
// "19.0.0" > "19"
|
|
||||||
// "19.0.1" > "19.0.0"
|
|
||||||
// "19.1.0" > "19.0.1"
|
|
||||||
// "19" > "18.999.999"
|
|
||||||
int compareVersions(String a, String b) {
|
|
||||||
def aParts = a.tokenize('.').collect {it.toInteger()}
|
|
||||||
def bParts = b.tokenize('.').collect {it.toInteger()}
|
|
||||||
compareVersionList(aParts, bParts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAndroidSdkDir() {
|
String getAndroidSdkDir() {
|
||||||
def rootDir = project.rootDir
|
def rootDir = project.rootDir
|
||||||
def androidSdkDir = null
|
def androidSdkDir = null
|
||||||
String envVar = System.getenv("ANDROID_HOME")
|
String envVar = System.getenv("ANDROID_SDK_ROOT")
|
||||||
|
if (envVar == null) {
|
||||||
|
envVar = System.getenv("ANDROID_HOME")
|
||||||
|
}
|
||||||
|
|
||||||
def localProperties = new File(rootDir, 'local.properties')
|
def localProperties = new File(rootDir, 'local.properties')
|
||||||
String systemProperty = System.getProperty("android.home")
|
String systemProperty = System.getProperty("android.home")
|
||||||
if (envVar != null) {
|
if (envVar != null) {
|
||||||
@@ -136,32 +133,8 @@ def doExtractStringFromManifest(name) {
|
|||||||
return matcher.group(1)
|
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 doGetConfigXml() {
|
||||||
def xml = file("res/xml/config.xml").getText()
|
def xml = file("src/main/res/xml/config.xml").getText()
|
||||||
// Disable namespace awareness since Cordova doesn't use them properly
|
// Disable namespace awareness since Cordova doesn't use them properly
|
||||||
return new XmlParser(false, false).parseText(xml)
|
return new XmlParser(false, false).parseText(xml)
|
||||||
}
|
}
|
||||||
@@ -180,15 +153,72 @@ def doGetConfigPreference(name, defaultValue) {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def doApplyCordovaConfigCustomization() {
|
||||||
|
// Apply user overide properties that comes from the "--gradleArg=-P" parameters
|
||||||
|
if (project.hasProperty('cdvMinSdkVersion')) {
|
||||||
|
cordovaConfig.MIN_SDK_VERSION = Integer.parseInt('' + cdvMinSdkVersion)
|
||||||
|
}
|
||||||
|
if (project.hasProperty('cdvSdkVersion')) {
|
||||||
|
cordovaConfig.SDK_VERSION = Integer.parseInt('' + cdvSdkVersion)
|
||||||
|
}
|
||||||
|
if (project.hasProperty('cdvMaxSdkVersion')) {
|
||||||
|
cordovaConfig.MAX_SDK_VERSION = Integer.parseInt('' + cdvMaxSdkVersion)
|
||||||
|
}
|
||||||
|
if (project.hasProperty('cdvBuildToolsVersion')) {
|
||||||
|
cordovaConfig.BUILD_TOOLS_VERSION = cdvBuildToolsVersion
|
||||||
|
}
|
||||||
|
if (project.hasProperty('cdvAndroidXAppCompatVersion')) {
|
||||||
|
cordovaConfig.ANDROIDX_APP_COMPAT_VERSION = cdvAndroidXAppCompatVersion
|
||||||
|
}
|
||||||
|
if (project.hasProperty('cdvAndroidXWebKitVersion')) {
|
||||||
|
cordovaConfig.ANDROIDX_WEBKIT_VERSION = cdvAndroidXWebKitVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cordovaConfig.BUILD_TOOLS_VERSION) {
|
||||||
|
cordovaConfig.BUILD_TOOLS_VERSION = doFindLatestInstalledBuildTools(
|
||||||
|
cordovaConfig.MIN_BUILD_TOOLS_VERSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the configured build tools version is at least our declared minimum
|
||||||
|
def buildToolsVersion = new Version(cordovaConfig.BUILD_TOOLS_VERSION)
|
||||||
|
if (buildToolsVersion.isLowerThan(cordovaConfig.MIN_BUILD_TOOLS_VERSION)) {
|
||||||
|
throw new RuntimeException("""
|
||||||
|
Expected Android Build Tools version >= ${cordovaConfig.MIN_BUILD_TOOLS_VERSION},
|
||||||
|
but got Android Build Tools version ${cordovaConfig.BUILD_TOOLS_VERSION}. Please use version ${cordovaConfig.MIN_BUILD_TOOLS_VERSION} or later.
|
||||||
|
""".replaceAll(/\s+/, ' ').trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Properties exported here are visible to all plugins.
|
// Properties exported here are visible to all plugins.
|
||||||
ext {
|
ext {
|
||||||
|
def defaultsFilePath = './cdv-gradle-config-defaults.json'
|
||||||
|
def projectConfigFilePath = "$rootDir/cdv-gradle-config.json"
|
||||||
|
def targetConfigFilePath = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the project config file path exists. This file will exist if coming from CLI project.
|
||||||
|
* If this file does not exist, falls back onto the default file.
|
||||||
|
* This scenario can occur if building the framework's AAR package for publishing.
|
||||||
|
*/
|
||||||
|
if(file(projectConfigFilePath).exists()) {
|
||||||
|
targetConfigFilePath = projectConfigFilePath
|
||||||
|
} else {
|
||||||
|
targetConfigFilePath = defaultsFilePath
|
||||||
|
}
|
||||||
|
|
||||||
|
def jsonFile = new File(targetConfigFilePath)
|
||||||
|
cordovaConfig = new groovy.json.JsonSlurper().parseText(jsonFile.text)
|
||||||
|
|
||||||
|
// Apply Gradle Properties
|
||||||
|
doApplyCordovaConfigCustomization()
|
||||||
|
|
||||||
// These helpers are shared, but are not guaranteed to be stable / unchanged.
|
// These helpers are shared, but are not guaranteed to be stable / unchanged.
|
||||||
privateHelpers = {}
|
privateHelpers = {}
|
||||||
privateHelpers.getProjectTarget = { doGetProjectTarget() }
|
privateHelpers.getProjectTarget = { doGetProjectTarget() }
|
||||||
privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') }
|
privateHelpers.applyCordovaConfigCustomization = { doApplyCordovaConfigCustomization() }
|
||||||
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
|
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
|
||||||
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
|
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
|
||||||
privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) }
|
|
||||||
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
|
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
|
||||||
|
|
||||||
// These helpers can be used by plugins / projects and will not change.
|
// These helpers can be used by plugins / projects and will not change.
|
||||||
@@ -199,3 +229,13 @@ ext {
|
|||||||
cdvHelpers.getConfigPreference = { name, defaultValue -> doGetConfigPreference(name, defaultValue) }
|
cdvHelpers.getConfigPreference = { name, defaultValue -> doGetConfigPreference(name, defaultValue) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
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=
|
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
android.useAndroidX=true
|
||||||
|
android.enableJetifier=true
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
@@ -3,4 +3,3 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
# This file is automatically generated by Android Tools.
|
# GENERATED FILE! DO NOT EDIT!
|
||||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
|
||||||
#
|
# This file was originally created by the Android Tools, but is now
|
||||||
# This file must be checked in Version Control Systems.
|
# used by cordova-android to manage the project configuration.
|
||||||
#
|
|
||||||
# To customize properties used by the Ant build system use,
|
|
||||||
# "ant.properties", and override values to adapt the script to your
|
|
||||||
# project structure.
|
|
||||||
|
|
||||||
# Indicates whether an apk should be generated for each density.
|
# Indicates whether an apk should be generated for each density.
|
||||||
split.density=false
|
split.density=false
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-26
|
|
||||||
apk-configurations=
|
apk-configurations=
|
||||||
renderscript.opt.level=O0
|
renderscript.opt.level=O0
|
||||||
android.library=true
|
android.library=true
|
||||||
|
|||||||