Compare commits

..

61 Commits
8.0.0 ... 7.1.x

Author SHA1 Message Date
Christopher J. Brody
a0cb7da1e3 Set VERSION to 7.1.5-dev 2018-11-23 13:01:25 -05:00
Christopher J. Brody
a68f9fd752 Update VERSION & RELEASENOTES for 7.1.4
NOTE: VERSION was updated based on e1befac.
2018-11-22 22:38:38 -05:00
Christopher J. Brody
84cb08b23e Revert "Other minor dependencies updates in 7.1.x patch"
This reverts commit 5a5f544a48.

Rationale: base64-js update in 5a5f544 causes extra
base64-js version to be installed under plist
(node_modules/plist/node_modules/base64-js),
which would need to be committed to satisfy the needs
of the deprecated Node.js 4 version.

The extra base64-js version in
node_modules/plist/node_modules/base64-js
was missed at the time 5a5f544 was committed.

The base64-js update in 5a5f544 is now deemed as
not wanted due to the extra base64-js version that
would need to be committed.

The other dependencies updates in 5a5f544
may be nice to have but not considered necessary
for the patch release.

Reverting now to unblock the upcoming 7.1.4 patch release.

Note that neither 5a5f544 nor this revert will
show up in the master branch.
2018-11-22 22:18:32 -05:00
Chris Brody
b7643a3712 Merge pull request #573 from brodybits/7.1.4-patch-updates
7.1.4 patch updates
2018-11-22 14:45:04 -05:00
Chris Brody
8586d4a7ba Resolve issue with plugin target-dir="app*" subdirs (#572)
(subdirectories) such as "appco", with unit tests to verify

Needed for @katzer plugins that use de/appplant subdirectory,
for example:
* cordova-plugin-local-notifications
* cordova-plugin-badge
* cordova-plugin-background-mode

Also needed for cordova-plugin-inappbrowser

Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
Co-authored-by: Julio César <jcesarmobile@gmail.com>
Co-authored-by: Jan Piotrowski <piotrowski+github@gmail.com>
2018-11-22 10:01:27 -05:00
Jan Piotrowski
f2d700515d Output current package name if package name can't be validated (#567)
We have this of the package name. It only outputs that the current one
is bad, not what the current one actually is. Added an output of the
current one to the error.
2018-11-22 10:00:36 -05:00
Christopher J. Brody
5a5f544a48 Other minor dependencies updates in 7.1.x patch 2018-11-22 09:57:22 -05:00
Christopher J. Brody
d918c7a83c android-versions@1.4.0 update in 7.1.x (add Pie) 2018-11-22 09:49:22 -05:00
Christopher J. Brody
afdffe4028 Set Version to 7.1.4-dev
(based on e1befaca5a)
2018-11-22 09:25:57 -05:00
Christopher J. Brody
e1befaca5a Update VERSION & RELEASENOTES for 7.1.3
NOTE: The version was manually updated in the following files:
* RELEASENOTES.md
* VERSION
* bin/templates/cordova/version
* bin/templates/project/assets/www/cordova.js
* framework/build.gradle
* framework/src/org/apache/cordova/CordovaWebView.java
* package.json

with help from git & bash tricks based on changes in the following
commits for 7.1.2 & 7.1.3-dev versions:
- 725e75fa0d
- f86519b158

FUTURE TBD: it is desired that we can set the version in
one place as discussed in: apache/cordova#50
2018-11-19 16:37:39 -05:00
Chris Brody
7b33517339 Mark some 7.1.3 bundled dependency versions (#566)
to resolve red entries from npm outdated
2018-11-19 11:30:29 -05:00
Chris Brody
442734dc47 Merge pull request #555 from brodybits/7.1.3-patch-updates
7.1.3 patch updates
2018-11-17 19:32:57 -05:00
David Boho
32e3eae83e GH-552 (android) check for build-extras.gradle in the app-parent directory (#553)
as documented in https://cordova.apache.org/docs/en/latest/guide/platforms/android/?#extending-buildgradle

and deal with multiple build-extras.gradle locations

Co-authored-by: David Boho <david.boho@tu-ilmenau.de>
Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
2018-11-16 13:22:43 -05:00
David Boho
0ebc9a6f8d add missing cast for cdvMinSdkVersion (GH-551) 2018-11-16 13:22:43 -05:00
Christopher J. Brody
9848aa885f GH-547 Fix for old plugins with non-Java sources (PR #550)
(source-file entries)

including aidl, aar, jar, and so files
2018-11-16 13:22:43 -05:00
Christopher J. Brody
298f1e3cc8 Fix comments in getInstallDestination (PR #550)
(in pluginHandlers.js)
2018-11-16 13:22:43 -05:00
Christopher J. Brody
07e1fe18ff Cleanup getInstallDestination in pluginHandlers.js (PR #550) 2018-11-16 13:22:43 -05:00
Christopher J. Brody
9537e3468b Test old plugin aidl & lib mapping - repros GH-547 (PR #550)
(reproduces GH-547)
2018-11-16 13:22:43 -05:00
Christopher J. Brody
dea6846918 Check old compat of other extension (CB-14125) (PR #550)
of plugin source file installed into app/src/main with
old target-dir scheme

NOTE: These tests do *not* check compatibility of
plugins with old lib target-dir scheme.
2018-11-16 13:22:43 -05:00
Christopher J. Brody
e3468c66a3 Check target-dir mapping of plugin xml source file (PR #550)
Possibly related to: CB-13830: Add handlers for plugins
that use non-Java source files, such as Camera
2018-11-16 13:22:42 -05:00
Christopher J. Brody
5222a0f605 Fix tests of plugin files with new app dir scheme (PR #542)
(new app target-dir scheme)
2018-11-16 13:22:42 -05:00
Christopher J. Brody
717d768cec GH-540 fix for source-file with app target-dir (PR #542) 2018-11-16 13:22:42 -05:00
Christopher J. Brody
951ff5552e unit test uninstall of <source-file> with app dest (PR #542)
for Java source, JAR, and AAR

Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
Co-authored-by: Kyle Kirbatski <kkirbatski@gmrmarketing.com>
Co-authored-by: Antonio Facciolo <afdev82@users.noreply.github.com>
2018-11-16 13:22:42 -05:00
Christopher J. Brody
f8584c63e6 unit test source-file with custom lib target-dir (PR #542)
for JAR and AAR

(GH-540)

Co-Authored-By: Kyle Kirbatski <kkirbatski@gmrmarketing.com>
Co-Authored-By: Christopher J. Brody <chris.brody@gmail.com>
Co-Authored-By: @afdev82 (Antonio Facciolo)
2018-11-16 13:22:42 -05:00
Christopher J. Brody
4d151d3057 GH-539 fix destination path fallback (PR #542)
Fallback to old path mapping if no Android Studio path mapping exists

(with slight difference on 7.1.x branch)

Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
Co-authored-by: Kyle Kirbatski <kkirbatski@gmrmarketing.com>
2018-11-16 13:22:42 -05:00
Christopher J. Brody
55f2986b85 unit test uninstall of <source-file> with app dest (PR #542)
for Java source only (GH-539)

Co-Authored-By: Christopher J. Brody <chris.brody@gmail.com>
Co-Authored-By: Kyle Kirbatski <kkirbatski@gmrmarketing.com>
2018-11-16 13:22:42 -05:00
Kyle Kirbatski
c0e9f25150 Add a unit test to test source-file target-dir /app/src/main/… (PR #542) 2018-11-16 13:22:42 -05:00
Chris Brody
9f6c332b8c Remove obsolete check for JellyBean (GH-534) (#544)
to work properly on Android Pie

was introduced in dc0bfeb0c (CB-11828)

Resolves #534

Co-authored-by: <pradiv-kumar@users.noreply.github.com>
Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
2018-11-16 13:22:41 -05:00
Chris Brody
dbc99e8f4c Update comments (#496)
as followup to GH-495
2018-11-16 13:22:41 -05:00
Darshan-Chauhan
00134cf9f3 Incorrect default sdk version issue fix (PR #495) 2018-11-16 13:22:37 -05:00
Darryl Pogue
f86519b158 Bump version to 7.1.3-dev 2018-11-05 12:23:23 -08:00
Darryl Pogue
725e75fa0d Update RELEASENOTES & version for v7.1.2 2018-11-05 12:17:08 -08:00
Darryl Pogue
36c6f44697 Always put the Google repo above jcenter 2018-10-23 20:17:21 -07:00
Rizal M. S
750531c4bc CB-14165 Emulator: handle "device still connecting" error (#457)
Keep waiting for emulator when connection fails with "device still connecting" error
2018-08-02 13:18:25 -04:00
Julio César
8a69e32800 CB-14125:(android) Increase old plugin compatibility 2018-08-02 13:18:25 -04:00
Joe Bowser
ea6477f4d3 CB-13830: Add handlers for plugins that use non-Java source files, such as Camera 2018-08-02 13:18:25 -04:00
Julio César
e32bcd88aa CB-14038 (android): fix false positive detecting project type 2018-08-02 13:18:25 -04:00
Christopher J. Brody
1efcbfa1d5 CB-14240 Set version & VERSION to 7.1.2-dev (coho) 2018-08-02 13:04:46 -04:00
Christopher J. Brody
f19ffd7abd CB-14240 Update JS to version 7.1.2-dev (via coho) 2018-08-02 13:04:45 -04:00
Christopher J. Brody
7a97fd7e34 Set VERSION to 7.1.1 (via coho) 2018-07-11 21:36:34 -04:00
Christopher J. Brody
cc87a9da1e Update JS snapshot to version 7.1.1 (via coho) 2018-07-11 21:36:33 -04:00
Christopher J. Brody
b84034da6c CB-14203 Update RELEASENOTES & version for 7.1.1 2018-07-11 19:29:29 -04:00
Christopher J. Brody
97ea735e53 pin some added bundled dependencies in 7.1.x only
Needed to clear the red highlights in npm outdated --depth=0
2018-07-11 18:55:03 -04:00
Gearoid M
c26082d362 Fix unsafe property access in run.js (#445) 2018-07-11 08:57:13 -04:00
Raphael von der Grün
9f33b0bb71 Emit log event instead of logging directly (#452)
in builder scripts
2018-07-11 08:57:13 -04:00
Raphael von der Grün
3570ca8113 CB-14101 Fix Java version check for Java >= 9 (#446)
This also checks that we have exactly 1.8 since nothing else works with
the Android SDK. The user facing error was updated accordingly.
2018-07-11 08:57:13 -04:00
Julio César
a1bd9e7d73 CB-14127: (android) Move google maven repo ahead of jcenter 2018-07-11 08:57:13 -04:00
Anthony Ward
1702b6470f CB-13923 (android) fix -1 length for compressed files 2018-07-11 08:57:13 -04:00
Christopher J. Brody
7a155259e9 package.json more bundledDependencies - 7.1.x only
(indirect production dependencies needed by deprecated Node.js 4.x)
2018-07-11 08:57:13 -04:00
Christopher J. Brody
6758793f09 CB-14145 commit updated node_modules in 7.1.x only
(installed by npm@6.1.0)
2018-07-11 08:57:13 -04:00
Christopher J. Brody
3071bb313f .gitignore updates (7.1.x patch)
- ignore all contents of node_modules/.bin
- explicitly ignore some node_modules contents not needed
- ignore package-lock.json in 7.1.x only
2018-07-11 08:57:13 -04:00
Christopher J. Brody
975e3a12f3 package.json pin other dependencies in 7.1.x only
- android-versions@1.3.0
- nopt@3.0.1
- properties-parser@0.2.3
- q@1.4.1
- shelljs@0.5.3

(elementtree@0.1.6 was already pinned)
2018-07-11 08:57:13 -04:00
Christopher J. Brody
566bca805e CB-14145 cordova-common@2 update&pin in 7.1.x only
resolves npm audit issue
2018-07-11 08:57:13 -04:00
Christopher J. Brody
94ea252259 CB-14145 remove old node_modules before patch fix 2018-07-11 08:57:13 -04:00
Christopher J. Brody
efb387b6ee CB-9366 log error.stack in cordova.js
(update JS snapshot from cordova-js@4.2.4 via coho)
2018-07-11 08:57:13 -04:00
Christopher J. Brody
0bd3309323 Set VERSION to 7.1.1-dev (via coho) 2018-06-19 15:01:50 -04:00
Christopher J. Brody
e73d8384f5 Update JS snapshot to version 7.1.1-dev (via coho) 2018-06-19 15:01:49 -04:00
Christopher J. Brody
4aeb892457 Revert "package.json mark 7.1.1-dev"
This reverts commit 3a83b5e8ee.

(leave it to coho)
2018-06-19 14:31:48 -04:00
Christopher J. Brody
3a83b5e8ee package.json mark 7.1.1-dev 2018-06-19 13:46:52 -04:00
Steve Gill
f7d122bd8e Set VERSION to 7.1.0 (via coho) 2018-02-21 10:52:01 -08:00
Steve Gill
152984855b Update JS snapshot to version 7.1.0 (via coho) 2018-02-21 10:52:00 -08:00
444 changed files with 69033 additions and 4666 deletions

View File

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

View File

@@ -1,42 +0,0 @@
<!--
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

View File

@@ -1,50 +0,0 @@
---
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

View File

@@ -1,29 +0,0 @@
---
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?
-->

View File

@@ -1,27 +0,0 @@
---
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)

View File

@@ -1,5 +1,6 @@
<!--
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:
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:
http://cordova.apache.org/contribute/contribute_guidelines.html
@@ -9,27 +10,13 @@ Thanks!
### Platforms affected
### 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 does this PR do?
### Description
<!-- Describe your changes in detail -->
### Testing
<!-- Please describe in detail how you tested your changes. -->
### What testing has been done on this change?
### Checklist
- [ ] I've run the tests to see all new and existing tests pass
- [ ] 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
- [ ] [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.
- [ ] Added automated test coverage as appropriate for this change.

80
.gitignore vendored
View File

@@ -26,6 +26,7 @@ example
/framework/javadoc-public
/framework/javadoc-private
/test/.externalNativeBuild
/test/build.gradle
/test/gradle
/test/gradlew
/test/gradlew.bat
@@ -42,7 +43,80 @@ tmp/**/*
**/.idea/**/*
*.iml
npm-debug.log
node_modules/
coverage/
.nyc_output/
node_modules/.bin
node_modules/concat-map/example
node_modules/properties-parser/test
node_modules/jshint
node_modules/promise-matchers
node_modules/jasmine
node_modules/rewire
node_modules/istanbul
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/
package-lock.json

View File

@@ -2,36 +2,27 @@ language: android
sudo: false
jdk:
- oraclejdk8
android:
components:
- build-tools-28.0.3
env:
global:
# Keep gradle from crapping all over the log
- TERM=dumb
matrix:
- nodejs_version=6
- nodejs_version=8
- nodejs_version=10
- 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:
# Install a sdkmanager version that supports the --licenses switch and
# accept any Android SDK licenses. The output redirection prevents us from
# hitting the travis log size limit of 4MB which would fail the build.
- yes | sdkmanager tools > /dev/null
- yes | sdkmanager --licenses > /dev/null
- nvm install $nodejs_version
- npm install
- npm install -g codecov
script:
- gradle --version
- node --version
- npm --version
- npm test
- npm run cover
after_script:
- codecov

View File

@@ -30,6 +30,7 @@ For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).
The details are explained there, but the important items are:
- Sign and submit an Apache ICLA (Contributor License Agreement).
- Have a Jira issue open that corresponds to your contribution.
- Run the tests so your patch doesn't break existing functionality.

View File

@@ -31,6 +31,9 @@ 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).
: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)
## Requires
- Java JDK 1.8 or greater

View File

@@ -20,58 +20,37 @@
-->
## Release Notes for Cordova (Android) ##
### 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"
### 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-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
* [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

View File

@@ -1 +1 @@
8.0.0
7.1.5-dev

View File

@@ -1,36 +1,38 @@
image:
- Previous Visual Studio 2015
environment:
ANDROID_HOME: "C:\\android"
ANDROID_HOME: "C:\\android"
matrix:
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
# If the gradle daemon is used, the build hangs after generating the wrapper
GRADLE_OPTS: -Dorg.gradle.daemon=false
# URL for SDK Tools, Revision 26.1.1 (September 2017)
SDK_TOOLS_URL: https://dl.google.com/android/repository/sdk-tools-windows-4333796.zip
matrix:
- nodejs_version: 6
- nodejs_version: 8
- nodejs_version: 10
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:
# Install Android SDK Tools
- mkdir "%ANDROID_HOME%"
- appveyor DownloadFile "%SDK_TOOLS_URL%" -FileName "%TMP%/sdk-tools.zip"
- 7z x "%TMP%/sdk-tools.zip" -o"%ANDROID_HOME%" > nul
- set PATH=%PATH%;"%ANDROID_HOME%\tools\bin"
- yes 2> nul | sdkmanager --licenses > nul
- sdkmanager "build-tools;28.0.3"
- choco install gradle --version 3.4.1
- ps: Install-Product node $env:nodejs_version
- npm 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:
- gradle --version
- node --version
- npm --version
- npm test
- node --version
- npm --version
- npm test

View File

@@ -21,7 +21,9 @@
var android_sdk = require('./templates/cordova/lib/android_sdk');
android_sdk.print_newest_available_sdk_target().done(null, function (err) {
android_sdk.print_newest_available_sdk_target().done(null, function(err) {
console.error(err);
process.exit(2);
});

View File

@@ -22,10 +22,9 @@
var check_reqs = require('./templates/cordova/lib/check_reqs');
check_reqs.run().done(
function success () {
function success() {
console.log('Looks like your environment fully supports cordova-android development!');
},
function fail (err) {
}, function fail(err) {
console.log(err);
process.exit(2);
}

View File

@@ -23,12 +23,12 @@ 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' });
'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]');

View File

@@ -141,9 +141,9 @@ function writeProjectProperties (projectPath, target_api) {
}
// This makes no sense, what if you're building with a different build system?
function prepBuildFiles (projectPath) {
function prepBuildFiles (projectPath, builder) {
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
buildModule.getBuilder().prepBuildFiles();
buildModule.getBuilder(builder).prepBuildFiles();
}
function copyBuildRules (projectPath, isLegacy) {
@@ -168,10 +168,7 @@ function copyScripts (projectPath) {
shell.rm('-rf', destScriptsDir);
// Copy in the new ones.
shell.cp('-r', srcScriptsDir, projectPath);
let nodeModulesDir = path.join(ROOT, 'node_modules');
if (fs.existsSync(nodeModulesDir)) shell.cp('-r', nodeModulesDir, destScriptsDir);
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');
@@ -332,7 +329,7 @@ exports.create = function (project_path, config, options, events) {
});
// Link it to local android install.
exports.writeProjectProperties(project_path, target_api);
exports.prepBuildFiles(project_path);
exports.prepBuildFiles(project_path, 'studio');
events.emit('log', generateDoneMessage('create', options.link));
}).thenResolve(project_path);
};

View File

@@ -21,6 +21,7 @@ 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;
@@ -55,27 +56,41 @@ function setupEvents (externalEventEmitter) {
function Api (platform, platformRootDir, events) {
this.platform = PLATFORM;
this.root = path.resolve(__dirname, '..');
this.builder = 'gradle';
setupEvents(events);
const appMain = path.join(this.root, 'app', 'src', 'main');
const appRes = path.join(appMain, 'res');
var self = this;
this.locations = {
root: this.root,
www: path.join(appMain, 'assets', 'www'),
res: appRes,
platformWww: path.join(this.root, 'platform_www'),
configXml: path.join(appRes, 'xml', 'config.xml'),
defaultConfigXml: path.join(this.root, 'cordova', 'defaults.xml'),
strings: path.join(appRes, 'values', 'strings.xml'),
manifest: path.join(appMain, 'AndroidManifest.xml'),
build: path.join(this.root, 'build'),
javaSrc: path.join(appMain, 'java'),
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'),
javaSrc: path.join(self.root, 'src'),
// 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.builder = 'studio';
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/values/strings.xml');
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
// We could have Java Source, we could have other languages
this.locations.javaSrc = path.join(self.root, 'app/src/main/java/');
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
this.locations.res = path.join(self.root, 'app/src/main/res');
}
}
/**
@@ -208,13 +223,33 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
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>');
// This should pick the correct builder, not just get gradle
require('./lib/builders/builders').getBuilder().prepBuildFiles();
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
}.bind(this))
// CB-11022 Return truthy value to prevent running prepare after
.thenResolve(true);
@@ -236,8 +271,9 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
var project = AndroidProject.getProjectFile(this.root);
if (uninstallOptions && uninstallOptions.usePlatformWww === true) {
if (uninstallOptions && uninstallOptions.usePlatformWww === true && this.android_studio === true) {
uninstallOptions.usePlatformWww = false;
uninstallOptions.android_studio = true;
}
return PluginManager.get(this.platform, this.locations, project)
@@ -246,7 +282,7 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
if (plugin.getFrameworks(this.platform).length === 0) return;
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
require('./lib/builders/builders').getBuilder().prepBuildFiles();
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
}.bind(this))
// CB-11022 Return truthy value to prevent running prepare after
.thenResolve(true);
@@ -299,7 +335,9 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
*/
Api.prototype.build = function (buildOptions) {
var self = this;
if (this.android_studio) {
buildOptions.studio = true;
}
return require('./lib/check_reqs').run().then(function () {
return require('./lib/build').run.call(self, buildOptions);
}).then(function (buildResults) {
@@ -343,9 +381,12 @@ Api.prototype.run = function (runOptions) {
*/
Api.prototype.clean = function (cleanOptions) {
var self = this;
// This will lint, checking for null won't
if (typeof cleanOptions === 'undefined') {
cleanOptions = {};
if (this.android_studio) {
// This will lint, checking for null won't
if (typeof cleanOptions === 'undefined') {
cleanOptions = {};
}
cleanOptions.studio = true;
}
return require('./lib/check_reqs').run().then(function () {

View File

@@ -19,25 +19,24 @@
under the License.
*/
var args = process.argv;
var args = process.argv;
var Api = require('./Api');
var nopt = require('nopt');
var path = require('path');
// Support basic help commands
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[2]) >= 0) {
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,
'verbose' : Boolean,
'silent' : Boolean,
'debug' : Boolean,
'release' : Boolean,
'nobuild': Boolean,
'buildConfig': path
}, { 'd': '--verbose' });
'buildConfig' : path
}, { 'd' : '--verbose' });
// Make buildOptions compatible with PlatformApi build method spec
buildOpts.argv = buildOpts.argv.original;
@@ -45,7 +44,7 @@ buildOpts.argv = buildOpts.argv.original;
require('./loggingHelper').adjustLoggerLevel(buildOpts);
new Api().build(buildOpts)
.catch(function (err) {
console.error(err.stack);
process.exit(2);
});
.catch(function(err) {
console.error(err.stack);
process.exit(2);
});

View File

@@ -20,11 +20,11 @@
*/
var Api = require('./Api');
var path = require('path');
var path = require('path');
var nopt = require('nopt');
// Support basic help commands
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
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);
@@ -32,9 +32,9 @@ if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >=
// Do some basic argument parsing
var opts = nopt({
'verbose': Boolean,
'silent': Boolean
}, { 'd': '--verbose' });
'verbose' : Boolean,
'silent' : Boolean
}, { 'd' : '--verbose' });
// Make buildOptions compatible with PlatformApi clean method spec
opts.argv = opts.argv.original;
@@ -45,7 +45,7 @@ opts.noPrepare = true;
require('./loggingHelper').adjustLoggerLevel(opts);
new Api().clean(opts)
.catch(function (err) {
console.error(err.stack);
process.exit(2);
});
.catch(function(err) {
console.error(err.stack);
process.exit(2);
});

View File

@@ -44,7 +44,7 @@ function isEmulator (line) {
* devices/emulators
*/
Adb.devices = function (opts) {
return spawn('adb', ['devices'], { cwd: os.tmpdir() }).then(function (output) {
return spawn('adb', ['devices'], {cwd: os.tmpdir()}).then(function (output) {
return output.split('\n').filter(function (line) {
// Filter out either real devices or emulators, depending on options
return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line);
@@ -58,7 +58,7 @@ Adb.install = function (target, packagePath, opts) {
events.emit('verbose', 'Installing apk ' + packagePath + ' on target ' + target + '...');
var args = ['-s', target, 'install'];
if (opts && opts.replace) args.push('-r');
return spawn('adb', args.concat(packagePath), { cwd: os.tmpdir() }).then(function (output) {
return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()}).then(function (output) {
// 'adb install' seems to always returns no error, even if installation fails
// so we catching output to detect installation failure
if (output.match(/Failure/)) {
@@ -77,14 +77,14 @@ Adb.install = function (target, packagePath, opts) {
Adb.uninstall = function (target, packageId) {
events.emit('verbose', 'Uninstalling package ' + packageId + ' from target ' + target + '...');
return spawn('adb', ['-s', target, 'uninstall', packageId], { cwd: os.tmpdir() });
return spawn('adb', ['-s', target, 'uninstall', packageId], {cwd: os.tmpdir()});
};
Adb.shell = function (target, shellCommand) {
events.emit('verbose', 'Running adb shell command "' + shellCommand + '" on target ' + target + '...');
var args = ['-s', target, 'shell'];
shellCommand = shellCommand.split(/\s+/);
return spawn('adb', args.concat(shellCommand), { cwd: os.tmpdir() }).catch(function (output) {
return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()}).catch(function (output) {
return Q.reject(new CordovaError('Failed to execute shell command "' +
shellCommand + '"" on device: ' + output));
});

View File

@@ -51,11 +51,15 @@ AndroidManifest.prototype.setVersionCode = function (versionCode) {
};
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;
};
@@ -146,7 +150,7 @@ AndroidManifest.prototype.setDebuggable = function (value) {
* 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');
fs.writeFileSync(destPath || this.path, this.doc.write({indent: 4}), 'utf-8');
};
module.exports = AndroidManifest;

View File

@@ -21,6 +21,7 @@ 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 = {};
@@ -61,7 +62,10 @@ function AndroidProject (projectDir) {
this._dirty = false;
this.projectDir = projectDir;
this.platformWww = path.join(this.projectDir, 'platform_www');
this.www = path.join(this.projectDir, 'app/src/main/assets/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) {
@@ -88,7 +92,10 @@ AndroidProject.purgeCache = function (projectDir) {
* @return {String} The name of the package
*/
AndroidProject.prototype.getPackageName = function () {
var manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
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();
};

View File

@@ -0,0 +1,11 @@
/*
* 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 */
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
return true;
};

View File

@@ -17,6 +17,7 @@
under the License.
*/
var Q = require('q');
var superspawn = require('cordova-common').superspawn;
var suffix_number_regex = /(\d+)$/;
@@ -94,7 +95,7 @@ module.exports.list_targets = function () {
} else throw err;
}).then(function (targets) {
if (targets.length === 0) {
return Promise.reject(new Error('No android targets (SDKs) installed!'));
return Q.reject(new Error('No android targets (SDKs) installed!'));
}
return targets;
});

View File

@@ -31,10 +31,11 @@ var events = require('cordova-common').events;
var spawn = require('cordova-common').superspawn.spawn;
var CordovaError = require('cordova-common').CordovaError;
module.exports.parseBuildOptions = parseOpts;
function parseOpts (options, resolvedTarget, projectRoot) {
options = options || {};
options.argv = nopt({
gradle: Boolean,
studio: Boolean,
prepenv: Boolean,
versionCode: String,
minSdkVersion: String,
@@ -49,13 +50,26 @@ function parseOpts (options, resolvedTarget, projectRoot) {
// Android Studio Build method is the default
var ret = {
buildType: options.release ? 'release' : 'debug',
buildMethod: process.env.ANDROID_BUILD || 'studio',
prepEnv: options.argv.prepenv,
arch: resolvedTarget && resolvedTarget.arch,
extraArgs: []
};
if (options.argv.gradle || options.argv.studio) {
ret.buildMethod = options.argv.studio ? 'studio' : 'gradle';
}
// This comes from cordova/run
if (options.studio) ret.buildMethod = 'studio';
if (options.gradle) ret.buildMethod = 'gradle';
if (options.nobuild) ret.buildMethod = 'none';
if (options.argv.versionCode) { ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); }
if (options.argv.minSdkVersion) { ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); }
if (options.argv.gradleArg) {
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
}
@@ -115,8 +129,7 @@ function parseOpts (options, resolvedTarget, projectRoot) {
*/
module.exports.runClean = function (options) {
var opts = parseOpts(options, null, this.root);
var builder = builders.getBuilder();
var builder = builders.getBuilder(opts.buildMethod);
return builder.prepEnv(opts).then(function () {
return builder.clean(opts);
});
@@ -136,8 +149,8 @@ module.exports.runClean = function (options) {
*/
module.exports.run = function (options, optResolvedTarget) {
var opts = parseOpts(options, optResolvedTarget, this.root);
var builder = builders.getBuilder();
console.log(opts.buildMethod);
var builder = builders.getBuilder(opts.buildMethod);
return builder.prepEnv(opts).then(function () {
if (opts.prepEnv) {
events.emit('verbose', 'Build file successfully prepared.');
@@ -148,7 +161,8 @@ module.exports.run = function (options, optResolvedTarget) {
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
return {
apkPaths: apkPaths,
buildType: opts.buildType
buildType: opts.buildType,
buildMethod: opts.buildMethod
};
});
});
@@ -262,10 +276,12 @@ module.exports.help = function () {
console.log('Flags:');
console.log(' \'--debug\': will build project in debug mode (default)');
console.log(' \'--release\': will build project for release');
console.log(' \'--ant\': will build project with ant');
console.log(' \'--gradle\': will build project with gradle (default)');
console.log(' \'--nobuild\': will skip build process (useful when using run command)');
console.log(' \'--prepenv\': don\'t build, but copy in build scripts where necessary');
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs.');
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build. Useful for uploading multiple APKs.');
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs. Requires --gradle.');
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build. Useful for uploading multiple APKs. Requires --gradle.');
console.log(' \'--gradleArg=<gradle command line arg>\': Extra args to pass to the gradle command. Use one flag per arg. Ex. --gradleArg=-PcdvBuildMultipleApks=true');
console.log('');
console.log('Signed APK flags (overwrites debug/release-signing.proprties) :');

View File

@@ -0,0 +1,124 @@
/*
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;
function GenericBuilder (projectDir) {
this.root = projectDir || path.resolve(__dirname, '../../..');
this.binDirs = {
studio: path.join(this.root, 'app', 'build', 'outputs', 'apk'),
gradle: path.join(this.root, 'build', 'outputs', 'apk')
};
}
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);
};
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;
}

View File

@@ -0,0 +1,331 @@
/*
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 events = require('cordova-common').events;
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);
});
}
};
/*
* We need to kill this in a fire.
*/
GradleBuilder.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)
};
};
GradleBuilder.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);
};
// 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;
// Check and copy the gradle file into the subproject.
// Called by the loop below this function def.
var checkAndCopy = function (subProject, root) {
var subProjectGradle = path.join(root, subProject, 'build.gradle');
// This is the future-proof way of checking if a file exists
// This must be synchronous to satisfy a Travis test
try {
fs.accessSync(subProjectGradle, fs.F_OK);
} catch (e) {
shell.cp('-f', pluginBuildGradle, subProjectGradle);
}
};
// Some dependencies on Android don't use gradle, or don't have default
// gradle files. This copies a dummy gradle file into them
for (var i = 0; i < subProjects.length; ++i) {
if (subProjects[i] !== 'CordovaLib' && subProjects[i] !== 'app') {
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;
// Cordova Plugins can be written as library modules that would use Cordova as a
// dependency. Because we need to make sure that Cordova is compiled only once for
// dexing, we make sure to exclude CordovaLib from these modules
var insertExclude = function (p) {
var gradlePath = path.join(root, p, 'build.gradle');
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
depsList += '{\n exclude module:("CordovaLib")\n }\n';
} else {
depsList += '\n';
}
};
subProjects.forEach(function (p) {
events.emit('log', 'Subproject Path: ' + p);
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
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';
});
// This code is dangerous and actually writes gradle declarations directly into the build.gradle
// Try not to mess with this if possible
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;
}

View File

@@ -1,370 +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 spawn = require('cordova-common').superspawn.spawn;
var events = require('cordova-common').events;
var CordovaError = require('cordova-common').CordovaError;
var check_reqs = require('../check_reqs');
const MARKER = 'YOUR CHANGES WILL BE ERASED!';
const SIGNING_PROPERTIES = '-signing.properties';
const TEMPLATE =
'# This file is automatically generated.\n' +
'# Do not modify this file -- ' + MARKER + '\n';
class ProjectBuilder {
constructor (rootDirectory) {
this.root = rootDirectory || path.resolve(__dirname, '../../..');
this.binDir = path.join(this.root, 'app', 'build', 'outputs', 'apk');
}
getArgs (cmd, opts) {
if (cmd === 'release') {
cmd = 'cdvBuildRelease';
} else if (cmd === 'debug') {
cmd = 'cdvBuildDebug';
}
let args = [cmd, '-b', path.join(this.root, 'build.gradle')];
if (opts.arch) {
args.push('-PcdvBuildArch=' + opts.arch);
}
args.push.apply(args, opts.extraArgs);
return args;
}
/*
* This returns a promise
*/
runGradleWrapper (gradle_cmd) {
var gradlePath = path.join(this.root, 'gradlew');
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
if (fs.existsSync(gradlePath)) {
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
} else {
return spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], { stdio: 'inherit' });
}
}
readProjectProperties () {
function findAllUniq (data, r) {
var s = {};
var m;
while ((m = r.exec(data))) {
s[m[1]] = 1;
}
return Object.keys(s);
}
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
return {
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
};
}
extractRealProjectNameFromManifest () {
var manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
var manifestData = fs.readFileSync(manifestPath, 'utf8');
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
if (!m) {
throw new CordovaError('Could not find package name in ' + manifestPath);
}
var packageName = m[1];
var lastDotIndex = packageName.lastIndexOf('.');
return packageName.substring(lastDotIndex + 1);
}
// Makes the project buildable, minus the gradle wrapper.
prepBuildFiles () {
// Update the version of build.gradle in each dependent library.
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
var propertiesObj = this.readProjectProperties();
var subProjects = propertiesObj.libs;
// Check and copy the gradle file into the subproject
// Called by the loop before this function def
var checkAndCopy = function (subProject, root) {
var subProjectGradle = path.join(root, subProject, 'build.gradle');
// This is the future-proof way of checking if a file exists
// This must be synchronous to satisfy a Travis test
try {
fs.accessSync(subProjectGradle, fs.F_OK);
} catch (e) {
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;
});
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
'// GENERATED FILE - DO NOT EDIT\n' +
'include ":"\n' + settingsGradlePaths.join(''));
// Update dependencies within build.gradle.
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
var depsList = '';
var root = this.root;
var insertExclude = function (p) {
var gradlePath = path.join(root, p, 'build.gradle');
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
depsList += '{\n exclude module:("CordovaLib")\n }\n';
} else {
depsList += '\n';
}
};
subProjects.forEach(function (p) {
events.emit('log', 'Subproject Path: ' + p);
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
if (libName !== 'app') {
depsList += ' implementation(project(path: ":' + libName + '"))';
insertExclude(p);
}
});
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
var SYSTEM_LIBRARY_MAPPINGS = [
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
];
propertiesObj.systemLibs.forEach(function (p) {
var mavenRef;
// It's already in gradle form if it has two ':'s
if (/:.*:/.exec(p)) {
mavenRef = p;
} else {
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
if (pair[0].exec(p)) {
mavenRef = p.replace(pair[0], pair[1]);
break;
}
}
if (!mavenRef) {
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
}
}
depsList += ' implementation "' + mavenRef + '"\n';
});
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
var includeList = '';
propertiesObj.gradleIncludes.forEach(function (includePath) {
includeList += 'apply from: "../' + includePath + '"\n';
});
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
// This needs to be stored in the app gradle, not the root grade
fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
}
prepEnv (opts) {
var self = this;
return check_reqs.check_gradle()
.then(function (gradlePath) {
return self.runGradleWrapper(gradlePath);
}).then(function () {
return self.prepBuildFiles();
}).then(function () {
// 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/;
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.10.3-all.zip';
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.
*/
build (opts) {
var wrapper = path.join(this.root, 'gradlew');
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
return spawn(wrapper, args, { stdio: 'pipe' })
.progress(function (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);
}
}).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);
});
}
clean (opts) {
var builder = this;
var wrapper = path.join(this.root, 'gradlew');
var args = builder.getArgs('clean', opts);
return Q().then(function () {
return 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);
}
});
});
}
findOutputApks (build_type, arch) {
return findOutputApksHelper(this.binDir, build_type, arch).sort(apkSorter);
}
fetchBuildResults (build_type, arch) {
return {
apkPaths: this.findOutputApks(build_type, arch),
buildType: build_type
};
}
}
module.exports = ProjectBuilder;
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) {
return !!/-x86|-arm/.exec(path.basename(p)) === archSpecific;
});
if (archSpecific && ret.length > 1 && arch) {
ret = ret.filter(function (p) {
return path.basename(p).indexOf('-' + arch) !== -1;
});
}
return ret;
}
function isAutoGenerated (file) {
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
}

View File

@@ -0,0 +1,303 @@
/*
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 spawn = require('cordova-common').superspawn.spawn;
var events = require('cordova-common').events;
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 StudioBuilder (projectRoot) {
GenericBuilder.call(this, projectRoot);
this.binDirs = {gradle: this.binDirs.studio};
}
util.inherits(StudioBuilder, GenericBuilder);
StudioBuilder.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
*/
StudioBuilder.prototype.runGradleWrapper = function (gradle_cmd) {
var gradlePath = path.join(this.root, 'gradlew');
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
if (fs.existsSync(gradlePath)) {
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
} else {
return spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], {stdio: 'inherit'});
}
};
StudioBuilder.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)
};
};
StudioBuilder.prototype.extractRealProjectNameFromManifest = function () {
var manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
var manifestData = fs.readFileSync(manifestPath, 'utf8');
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
if (!m) {
throw new CordovaError('Could not find package name in ' + manifestPath);
}
var packageName = m[1];
var lastDotIndex = packageName.lastIndexOf('.');
return packageName.substring(lastDotIndex + 1);
};
// Makes the project buildable, minus the gradle wrapper.
StudioBuilder.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;
// Check and copy the gradle file into the subproject
// Called by the loop before this function def
var checkAndCopy = function (subProject, root) {
var subProjectGradle = path.join(root, subProject, 'build.gradle');
// This is the future-proof way of checking if a file exists
// This must be synchronous to satisfy a Travis test
try {
fs.accessSync(subProjectGradle, fs.F_OK);
} catch (e) {
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;
});
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
'// GENERATED FILE - DO NOT EDIT\n' +
'include ":"\n' + settingsGradlePaths.join(''));
// Update dependencies within build.gradle.
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
var depsList = '';
var root = this.root;
var insertExclude = function (p) {
var gradlePath = path.join(root, p, 'build.gradle');
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
depsList += '{\n exclude module:("CordovaLib")\n }\n';
} else {
depsList += '\n';
}
};
subProjects.forEach(function (p) {
events.emit('log', 'Subproject Path: ' + p);
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
if (libName !== 'app') {
depsList += ' implementation(project(path: ":' + libName + '"))';
insertExclude(p);
}
});
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
var SYSTEM_LIBRARY_MAPPINGS = [
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
];
propertiesObj.systemLibs.forEach(function (p) {
var mavenRef;
// It's already in gradle form if it has two ':'s
if (/:.*:/.exec(p)) {
mavenRef = p;
} else {
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
if (pair[0].exec(p)) {
mavenRef = p.replace(pair[0], pair[1]);
break;
}
}
if (!mavenRef) {
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
}
}
depsList += ' 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');
// This needs to be stored in the app gradle, not the root grade
fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
};
StudioBuilder.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 () {
// 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/;
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.1-all.zip';
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.
*/
StudioBuilder.prototype.build = function (opts) {
var wrapper = path.join(this.root, 'gradlew');
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
return spawn(wrapper, args, {stdio: 'pipe'})
.progress(function (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);
}
}).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);
});
};
StudioBuilder.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 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 = StudioBuilder;
function isAutoGenerated (file) {
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
}

View File

@@ -1,34 +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
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
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.
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
const CordovaError = require('cordova-common').CordovaError;
var CordovaError = require('cordova-common').CordovaError;
var knownBuilders = {
gradle: 'GradleBuilder',
studio: 'StudioBuilder',
none: 'GenericBuilder'
};
/**
* Helper method that instantiates and returns a builder for specified build type.
* Helper method that instantiates and returns a builder for specified build
* type.
*
* @return {Builder} A builder instance 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 () {
module.exports.getBuilder = function (builderType, projectRoot) {
if (!knownBuilders[builderType]) { throw new CordovaError('Builder ' + builderType + ' is not supported.'); }
try {
const Builder = require('./ProjectBuilder');
return new Builder();
var Builder = require('./' + knownBuilders[builderType]);
return new Builder(projectRoot);
} catch (err) {
throw new CordovaError('Failed to instantiate ProjectBuilder builder: ' + err);
throw new CordovaError('Failed to instantiate ' + knownBuilders[builderType] + ' builder: ' + err);
}
};

View File

@@ -19,6 +19,8 @@
under the License.
*/
/* jshint sub:true */
var shelljs = require('shelljs');
var child_process = require('child_process');
var Q = require('q');
@@ -203,12 +205,10 @@ module.exports.check_java = function () {
return match && match[1];
}, () => {
var msg =
'Failed to run "javac -version", make sure that you have a JDK version 8 installed.\n' +
'You can get it from the following location:\n' +
'https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html';
'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 += '\n\n';
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'];
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
}
throw new CordovaError(msg);
});
@@ -231,14 +231,6 @@ module.exports.check_android = function () {
// First ensure ANDROID_HOME is set
// If we have no hints (nothing in PATH), try a few default locations
if (!hasAndroidHome && !androidCmdPath && !adbInPath && !avdmanagerInPath) {
if (process.env['ANDROID_SDK_ROOT']) {
// Quick fix to set ANDROID_HOME according to ANDROID_SDK_ROOT
// if ANDROID_HOME is **not** defined and
// ANDROID_SDK_ROOT **is** defined
// according to environment variables as documented in:
// https://developer.android.com/studio/command-line/variables
maybeSetAndroidHome(path.join(process.env['ANDROID_SDK_ROOT']));
}
if (module.exports.isWindows()) {
// Android Studio 1.0 installer
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'sdk'));
@@ -363,19 +355,15 @@ module.exports.check_android_target = function (originalError) {
// Returns a promise.
module.exports.run = function () {
return Q.all([this.check_java(), this.check_android()]).then(function (values) {
console.log('Checking Java JDK and Android SDK versions');
console.log('ANDROID_SDK_ROOT=' + process.env['ANDROID_SDK_ROOT'] + ' (recommended setting)');
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME'] + ' (DEPRECATED)');
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
if (!String(values[0]).startsWith('1.8.')) {
throw new CordovaError(
'Requirements check failed for JDK 8 (\'1.8.*\')! Detected version: ' + values[0] + '\n' +
'Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.'
);
throw new CordovaError('Requirements check failed for JDK 1.8');
}
if (!values[1]) {
throw new CordovaError('Requirements check failed for Android SDK! Android SDK was not detected.');
throw new CordovaError('Requirements check failed for Android SDK');
}
});
};

View File

@@ -1,104 +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.
*/
let fs = require('fs');
let path = require('path');
let propertiesParser = require('properties-parser');
let events = require('cordova-common').events;
class GradlePropertiesParser {
/**
* Loads and Edits Gradle Properties File.
*
* @param {String} platformDir is the path of the Android platform directory
*/
constructor (platformDir) {
this._defaults = {
// 10 seconds -> 6 seconds
'org.gradle.daemon': 'true',
// to allow dex in process
'org.gradle.jvmargs': '-Xmx2048m',
// allow NDK to be used - required by Gradle 1.5 plugin
'android.useDeprecatedNdk': 'true'
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
// 'org.gradle.parallel': 'true'
};
this.gradleFilePath = path.join(platformDir, 'gradle.properties');
}
configure (userConfigs) {
events.emit('verbose', '[Gradle Properties] Preparing Configuration');
this._initializeEditor();
events.emit('verbose', '[Gradle Properties] Appending default configuration properties');
this._configureProperties(this._defaults);
events.emit('verbose', '[Gradle Properties] Appending custom configuration properties');
this._configureProperties(userConfigs);
this._save();
}
/**
* Initialize the properties editor for parsing, setting, etc.
*/
_initializeEditor () {
// Touch empty gradle.properties file if missing.
if (!fs.existsSync(this.gradleFilePath)) {
events.emit('verbose', '[Gradle Properties] File missing, creating file with Cordova defaults.');
fs.writeFileSync(this.gradleFilePath, '', 'utf-8');
}
// Create an editor for parsing, getting, and setting configurations.
this.gradleFile = propertiesParser.createEditor(this.gradleFilePath);
}
/**
* Validate that defaults or user configuration properties are set and
* set the missing items.
*/
_configureProperties (properties) {
// Iterate though the properties and set only if missing.
Object.keys(properties).forEach(key => {
let value = this.gradleFile.get(key);
if (!value) {
events.emit('verbose', `[Gradle Properties] Appending configuration item: ${key}=${properties[key]}`);
this.gradleFile.set(key, properties[key]);
} else if (value !== properties[key]) {
events.emit('info', `[Gradle Properties] Detected Gradle property "${key}" with the value of "${value}", Cordova's recommended value is "${properties[key]}"`);
}
});
}
/**
* Saves any changes that has been made to the properties file.
*/
_save () {
events.emit('verbose', '[Gradle Properties] Updating and Saving File');
this.gradleFile.save();
}
}
module.exports = GradlePropertiesParser;

View File

@@ -19,6 +19,7 @@
under the License.
*/
var Q = require('q');
var build = require('./build');
var path = require('path');
var Adb = require('./Adb');
@@ -52,13 +53,13 @@ module.exports.list = function (lookHarder) {
module.exports.resolveTarget = function (target) {
return this.list(true).then(function (device_list) {
if (!device_list || !device_list.length) {
return Promise.reject(new CordovaError('Failed to deploy to device, no devices found.'));
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 Promise.reject(new CordovaError('ERROR: Unable to find target \'' + target + '\'.'));
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
}
return build.detectArchitecture(target).then(function (arch) {
@@ -73,7 +74,7 @@ module.exports.resolveTarget = function (target) {
* Returns a promise.
*/
module.exports.install = function (target, buildResults) {
return Promise.resolve().then(function () {
return Q().then(function () {
if (target && typeof target === 'object') {
return target;
}
@@ -86,7 +87,7 @@ module.exports.install = function (target, buildResults) {
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) {
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; }
@@ -97,7 +98,7 @@ module.exports.install = function (target, buildResults) {
// 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 });
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
});
}).then(function () {
// unlock screen

View File

@@ -19,6 +19,8 @@
under the License.
*/
/* jshint sub:true */
var android_versions = require('android-versions');
var retry = require('./retry');
var build = require('./build');
@@ -32,6 +34,7 @@ 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');
@@ -167,13 +170,15 @@ module.exports.list_images_using_android = function () {
}
*/
module.exports.list_images = function () {
return Promise.resolve().then(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 Promise.reject(new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?'));
return 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.
@@ -223,13 +228,13 @@ module.exports.best_image = function () {
// Returns a promise.
module.exports.list_started = function () {
return Adb.devices({ emulators: true });
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) {
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--) {
@@ -272,8 +277,8 @@ module.exports.get_available_port = function () {
module.exports.start = function (emulator_ID, boot_timeout) {
var self = this;
return Promise.resolve().then(function () {
if (emulator_ID) return Promise.resolve(emulator_ID);
return Q().then(function () {
if (emulator_ID) return Q(emulator_ID);
return self.best_image().then(function (best) {
if (best && best.name) {
@@ -282,7 +287,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
}
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
return Promise.reject(new CordovaError('No emulator images (avds) found.\n' +
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'));
@@ -303,7 +308,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
return self.wait_for_emulator(port);
});
}).then(function (emulatorId) {
if (!emulatorId) { return Promise.reject(new CordovaError('Failed to start emulator')); }
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)...');
@@ -329,7 +334,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
*/
module.exports.wait_for_emulator = function (port) {
var self = this;
return Promise.resolve().then(function () {
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) {
@@ -340,8 +345,7 @@ module.exports.wait_for_emulator = function (port) {
if ((error && error.message &&
(error.message.indexOf('not found') > -1)) ||
(error.message.indexOf('device offline') > -1) ||
(error.message.indexOf('device still connecting') > -1) ||
(error.message.indexOf('device still authorizing') > -1)) {
(error.message.indexOf('device still connecting') > -1)) {
// emulator not yet started, continue waiting
return self.wait_for_emulator(port);
} else {
@@ -367,13 +371,10 @@ module.exports.wait_for_boot = function (emulator_id, time_remaining) {
} else {
process.stdout.write('.');
return new Promise(resolve => {
const delay = time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL;
setTimeout(() => {
const updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
resolve(self.wait_for_boot(emulator_id, updated_time));
}, delay);
// 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);
});
}
});
@@ -399,7 +400,7 @@ module.exports.create_image = function (name, target) {
// TODO: This seems like another error case, even though it always happens.
console.error('ERROR : Unable to create an avd emulator, no targets found.');
console.error('Ensure you have targets available by running the "android" command');
return Promise.reject(new CordovaError());
return Q.reject();
}, function (error) {
console.error('ERROR : Failed to create emulator image : ');
console.error(error);
@@ -410,17 +411,17 @@ module.exports.create_image = function (name, target) {
module.exports.resolveTarget = function (target) {
return this.list_started().then(function (emulator_list) {
if (emulator_list.length < 1) {
return Promise.reject(new CordovaError('No running Android emulators found, please start an emulator before deploying your project.'));
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 Promise.reject(new CordovaError('Unable to find target \'' + target + '\'. Failed to deploy to emulator.'));
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 };
return {target: target, arch: arch, isEmulator: true};
});
});
};
@@ -435,12 +436,15 @@ module.exports.install = function (givenTarget, buildResults) {
var target;
// We need to find the proper path to the Android Manifest
const manifestPath = path.join(__dirname, '..', '..', 'app', 'src', 'main', 'AndroidManifest.xml');
const manifest = new AndroidManifest(manifestPath);
const pkgName = manifest.getPackageId();
var manifestPath = path.join(__dirname, '..', '..', 'app', 'src', 'main', 'AndroidManifest.xml');
if (buildResults.buildMethod === 'gradle') {
manifestPath = path.join(__dirname, '../../AndroidManifest.xml');
}
var manifest = new AndroidManifest(manifestPath);
var pkgName = manifest.getPackageId();
// resolve the target emulator
return Promise.resolve().then(function () {
return Q().then(function () {
if (givenTarget && typeof givenTarget === 'object') {
return givenTarget;
} else {
@@ -455,7 +459,7 @@ module.exports.install = function (givenTarget, buildResults) {
}).then(function () {
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
// or the app doesn't installed at all, so no error catching needed.
return Promise.resolve().then(function () {
return Q.when().then(function () {
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
var execOptions = {
@@ -475,7 +479,7 @@ module.exports.install = function (givenTarget, buildResults) {
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
return new Promise(function (resolve, reject) {
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

View File

@@ -19,23 +19,23 @@
under the License.
*/
var device = require('./device');
var args = process.argv;
var device = require('./device'),
args = process.argv;
if (args.length > 2) {
if(args.length > 2) {
var install_target;
if (args[2].substring(0, 9) === '--target=') {
if (args[2].substring(0, 9) == '--target=') {
install_target = args[2].substring(9, args[2].length);
device.install(install_target).catch(function (err) {
device.install(install_target).done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});
} else {
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
} else {
device.install().catch(function (err) {
device.install().done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -19,20 +19,20 @@
under the License.
*/
var emulator = require('./emulator');
var args = process.argv;
var emulator = require('./emulator'),
args = process.argv;
var install_target;
if (args.length > 2) {
if (args[2].substring(0, 9) === '--target=') {
if(args.length > 2) {
if (args[2].substring(0, 9) == '--target=') {
install_target = args[2].substring(9, args[2].length);
} else {
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
}
emulator.install(install_target).catch(function (err) {
emulator.install(install_target).done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -22,12 +22,12 @@
var devices = require('./device');
// Usage support for when args are given
require('./check_reqs').check_android().then(function () {
devices.list().then(function (device_list) {
device_list && device_list.forEach(function (dev) {
require('./check_reqs').check_android().then(function() {
devices.list().done(function(device_list) {
device_list && device_list.forEach(function(dev) {
console.log(dev);
});
}, function (err) {
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -22,12 +22,12 @@
var emulators = require('./emulator');
// Usage support for when args are given
require('./check_reqs').check_android().then(function () {
emulators.list_images().then(function (emulator_list) {
emulator_list && emulator_list.forEach(function (emu) {
require('./check_reqs').check_android().then(function() {
emulators.list_images().done(function(emulator_list) {
emulator_list && emulator_list.forEach(function(emu) {
console.log(emu.name);
});
}, function (err) {
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -22,12 +22,12 @@
var emulators = require('./emulator');
// Usage support for when args are given
require('./check_reqs').check_android().then(function () {
emulators.list_started().then(function (emulator_list) {
emulator_list && emulator_list.forEach(function (emu) {
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) {
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -31,7 +31,7 @@ var ROOT = path.join(__dirname, '..', '..');
*/
module.exports.run = function () {
var d = Q.defer();
var adb = child_process.spawn('adb', ['logcat'], { cwd: os.tmpdir() });
var adb = child_process.spawn('adb', ['logcat'], {cwd: os.tmpdir()});
adb.stdout.on('data', function (data) {
var lines = data ? data.toString().split('\n') : [];

View File

@@ -20,7 +20,9 @@
buildscript {
repositories {
google()
maven {
url "https://maven.google.com"
}
jcenter()
}
@@ -36,7 +38,7 @@ buildscript {
apply plugin: 'com.android.library'
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
compile fileTree(dir: 'libs', include: '*.jar')
debugCompile project(path: ":CordovaLib", configuration: "debug")
releaseCompile project(path: ":CordovaLib", configuration: "release")
}
@@ -44,6 +46,7 @@ dependencies {
android {
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
publishNonDefault true
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6

View File

@@ -14,6 +14,8 @@
*
*/
/* jshint unused: vars */
var fs = require('fs');
var path = require('path');
var shell = require('shelljs');
@@ -26,7 +28,14 @@ var handlers = {
if (!obj.src) throw new CordovaError(generateAttributeError('src', 'source-file', plugin.id));
if (!obj.targetDir) throw new CordovaError(generateAttributeError('target-dir', 'source-file', plugin.id));
var dest = getInstallDestination(obj);
var dest = path.join(obj.targetDir, path.basename(obj.src));
// TODO: This code needs to be replaced, since the core plugins need to be re-mapped to a different location in
// a later plugins release. This is for legacy plugins to work with Cordova.
if (options && options.android_studio === true) {
dest = getInstallDestination(obj);
}
if (options && options.force) {
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
@@ -35,7 +44,11 @@ var handlers = {
}
},
uninstall: function (obj, plugin, project, options) {
var dest = getInstallDestination(obj);
var dest = path.join(obj.targetDir, path.basename(obj.src));
if (options && options.android_studio === true) {
dest = getInstallDestination(obj);
}
// TODO: Add Koltin extension to uninstall, since they are handled like Java files
if (obj.src.endsWith('java')) {
@@ -48,21 +61,33 @@ var handlers = {
},
'lib-file': {
install: function (obj, plugin, project, options) {
var dest = path.join('app/libs', path.basename(obj.src));
var dest = path.join('libs', path.basename(obj.src));
if (options && options.android_studio === true) {
dest = path.join('app/libs', path.basename(obj.src));
}
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
},
uninstall: function (obj, plugin, project, options) {
var dest = path.join('app/libs', path.basename(obj.src));
var dest = path.join('libs', path.basename(obj.src));
if (options && options.android_studio === true) {
dest = path.join('app/libs', path.basename(obj.src));
}
removeFile(project.projectDir, dest);
}
},
'resource-file': {
install: function (obj, plugin, project, options) {
var dest = path.join('app', 'src', 'main', obj.target);
var dest = path.normalize(obj.target);
if (options && options.android_studio === true) {
dest = path.join('app/src/main', dest);
}
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
},
uninstall: function (obj, plugin, project, options) {
var dest = path.join('app', 'src', 'main', obj.target);
var dest = path.normalize(obj.target);
if (options && options.android_studio === true) {
dest = path.join('app/src/main', dest);
}
removeFile(project.projectDir, dest);
}
},
@@ -294,41 +319,27 @@ function generateAttributeError (attribute, element, id) {
function getInstallDestination (obj) {
var APP_MAIN_PREFIX = 'app/src/main';
var PATH_SEPARATOR = '/';
var PATH_SEP_MATCH = '\\' + PATH_SEPARATOR;
var PATH_SEP_OR_EOL_MATCH = '(\\' + PATH_SEPARATOR + '|$)';
var appReg = new RegExp('^app' + PATH_SEP_OR_EOL_MATCH);
var libsReg = new RegExp('^libs' + PATH_SEP_OR_EOL_MATCH);
var srcReg = new RegExp('^src' + PATH_SEP_OR_EOL_MATCH);
var srcMainReg = new RegExp('^src' + PATH_SEP_MATCH + 'main' + PATH_SEP_OR_EOL_MATCH);
if (appReg.test(obj.targetDir)) {
if (obj.targetDir.startsWith('app')) {
// If any source file is using the new app directory structure,
// don't penalize it
return path.join(obj.targetDir, path.basename(obj.src));
} else {
// Plugin using deprecated target directory structure (GH-580)
if (obj.src.endsWith('.java')) {
return path.join(APP_MAIN_PREFIX, 'java', obj.targetDir.replace(srcReg, ''),
path.basename(obj.src));
} else if (obj.src.endsWith('.aidl')) {
return path.join(APP_MAIN_PREFIX, 'aidl', obj.targetDir.replace(srcReg, ''),
path.basename(obj.src));
} else if (libsReg.test(obj.targetDir)) {
if (obj.src.endsWith('.so')) {
return path.join(APP_MAIN_PREFIX, 'jniLibs', obj.targetDir.replace(libsReg, ''),
path.basename(obj.src));
} else {
return path.join('app', obj.targetDir, path.basename(obj.src));
}
} else if (srcMainReg.test(obj.targetDir)) {
} else if (obj.src.endsWith('.java')) {
return path.join(APP_MAIN_PREFIX, 'java', obj.targetDir.substring(4), path.basename(obj.src));
} else if (obj.src.endsWith('.aidl')) {
return path.join(APP_MAIN_PREFIX, 'aidl', obj.targetDir.substring(4), path.basename(obj.src));
} else if (obj.targetDir.includes('libs')) {
if (obj.src.endsWith('.so')) {
return path.join(APP_MAIN_PREFIX, 'jniLibs', obj.targetDir.substring(5), path.basename(obj.src));
} else {
return path.join('app', obj.targetDir, path.basename(obj.src));
}
} else if (obj.targetDir.includes('src/main')) {
return path.join('app', obj.targetDir, path.basename(obj.src));
} else {
// For all other source files not using the new app directory structure,
// add 'app/src/main' to the targetDir
return path.join(APP_MAIN_PREFIX, obj.targetDir, path.basename(obj.src));
}
}

View File

@@ -33,8 +33,6 @@ var PlatformJson = require('cordova-common').PlatformJson;
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
const GradlePropertiesParser = require('./config/GradlePropertiesParser');
module.exports.prepare = function (cordovaProject, options) {
var self = this;
@@ -43,15 +41,6 @@ module.exports.prepare = function (cordovaProject, options) {
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
// Get the min SDK version from config.xml
const minSdkVersion = this._config.getPreference('android-minSdkVersion', 'android');
let gradlePropertiesUserConfig = {};
if (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion;
let gradlePropertiesParser = new GradlePropertiesParser(this.locations.root);
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
// Update own www dir with project's www assets and plugins' assets and js-files
return Q.when(updateWww(cordovaProject, this.locations)).then(function () {
// update project according to config.xml changes.
@@ -189,7 +178,7 @@ function updateProjectAccordingTo (platformConfig, locations) {
strings.find('string[@name="launcher_name"]').text = shortName.replace(/\'/g, '\\\'');
}
fs.writeFileSync(locations.strings, strings.write({ indent: 4 }), 'utf-8');
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
@@ -276,14 +265,6 @@ function getImageResourcePath (resourcesDir, type, density, name, sourceName) {
return resourcePath;
}
function getAdaptiveImageResourcePath (resourcesDir, type, density, name, sourceName) {
if (/\.9\.png$/.test(sourceName)) {
name = name.replace(/\.png$/, '.9.png');
}
var resourcePath = path.join(resourcesDir, (density ? type + '-' + density + '-v26' : type), name);
return resourcePath;
}
function updateSplashes (cordovaProject, platformResourcesDir) {
var resources = cordovaProject.projectConfig.getSplashScreens('android');
@@ -333,197 +314,20 @@ function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) {
}
function updateIcons (cordovaProject, platformResourcesDir) {
let icons = cordovaProject.projectConfig.getIcons('android');
var icons = cordovaProject.projectConfig.getIcons('android');
// Skip if there are no app defined icons in config.xml
// if there are icon elements in config.xml
if (icons.length === 0) {
events.emit('verbose', 'This app does not have launcher icons defined');
return;
}
// 1. loop icons determin if there is an error in the setup.
// 2. during initial loop, also setup for legacy support.
let errorMissingAttributes = [];
let errorLegacyIconNeeded = [];
let hasAdaptive = false;
icons.forEach((icon, key) => {
if (
(icon.background && !icon.foreground)
|| (!icon.background && icon.foreground)
|| (!icon.background && !icon.foreground && !icon.src)
) {
errorMissingAttributes.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
}
var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'icon.png');
if (icon.foreground) {
hasAdaptive = true;
if (
!icon.src
&& (
icon.foreground.startsWith('@color')
|| path.extname(path.basename(icon.foreground)) === '.xml'
)
) {
errorLegacyIconNeeded.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
} else if (!icon.src) {
icons[key].src = icon.foreground;
}
}
});
let errorMessage = [];
if (errorMissingAttributes.length > 0) {
errorMessage.push('One of the following attributes are set but missing the other for the density type: ' + errorMissingAttributes.join(', ') + '. Please ensure that all require attributes are defined.');
}
if (errorLegacyIconNeeded.length > 0) {
errorMessage.push('For the following icons with the density of: ' + errorLegacyIconNeeded.join(', ') + ', adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices. To support older Android environments, please provide a value for the src attribute.');
}
if (errorMessage.length > 0) {
throw new CordovaError(errorMessage.join(' '));
}
let resourceMap = Object.assign(
{},
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
);
let preparedIcons = prepareIcons(icons);
if (hasAdaptive) {
resourceMap = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);
}
resourceMap = updateIconResourceForLegacy(preparedIcons, resourceMap, platformResourcesDir);
events.emit('verbose', 'Updating icons at ' + platformResourcesDir);
FileUpdater.updatePaths(resourceMap, { rootDir: cordovaProject.root }, logFileOp);
}
function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformResourcesDir) {
let android_icons = preparedIcons.android_icons;
let default_icon = preparedIcons.default_icon;
// The source paths for icons and splashes are relative to
// project's config.xml location, so we use it as base path.
let background;
let foreground;
let targetPathBackground;
let targetPathForeground;
for (let density in android_icons) {
let backgroundVal = '@mipmap/ic_launcher_background';
let foregroundVal = '@mipmap/ic_launcher_foreground';
background = android_icons[density].background;
foreground = android_icons[density].foreground;
if (background.startsWith('@color')) {
// Colors Use Case
backgroundVal = background; // Example: @color/background_foobar_1
} else if (path.extname(path.basename(background)) === '.xml') {
// Vector Use Case
targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.xml', path.basename(android_icons[density].background));
resourceMap[targetPathBackground] = android_icons[density].background;
} else if (path.extname(path.basename(background)) === '.png') {
// Images Use Case
targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.png', path.basename(android_icons[density].background));
resourceMap[targetPathBackground] = android_icons[density].background;
}
if (foreground.startsWith('@color')) {
// Colors Use Case
foregroundVal = foreground;
} else if (path.extname(path.basename(foreground)) === '.xml') {
// Vector Use Case
targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.xml', path.basename(android_icons[density].foreground));
resourceMap[targetPathForeground] = android_icons[density].foreground;
} else if (path.extname(path.basename(foreground)) === '.png') {
// Images Use Case
targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.png', path.basename(android_icons[density].foreground));
resourceMap[targetPathForeground] = android_icons[density].foreground;
}
// create an XML for DPI and set color
const icLauncherTemplate = `<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="` + backgroundVal + `" />
<foreground android:drawable="` + foregroundVal + `" />
</adaptive-icon>`;
let launcherXmlPath = path.join(platformResourcesDir, 'mipmap-' + density + '-v26', 'ic_launcher.xml');
// Remove the XML from the resourceMap so the file does not get removed.
delete resourceMap[launcherXmlPath];
fs.writeFileSync(path.resolve(launcherXmlPath), icLauncherTemplate);
}
// There's no "default" drawable, so assume default == mdpi.
if (default_icon && !android_icons.mdpi) {
let defaultTargetPathBackground;
let defaultTargetPathForeground;
if (background.startsWith('@color')) {
// Colors Use Case
targetPathBackground = default_icon.background;
} else if (path.extname(path.basename(background)) === '.xml') {
// Vector Use Case
defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.xml', path.basename(default_icon.background));
resourceMap[defaultTargetPathBackground] = default_icon.background;
} else if (path.extname(path.basename(background)) === '.png') {
// Images Use Case
defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.png', path.basename(default_icon.background));
resourceMap[defaultTargetPathBackground] = default_icon.background;
}
if (foreground.startsWith('@color')) {
// Colors Use Case
targetPathForeground = default_icon.foreground;
} else if (path.extname(path.basename(foreground)) === '.xml') {
// Vector Use Case
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.xml', path.basename(default_icon.foreground));
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
} else if (path.extname(path.basename(foreground)) === '.png') {
// Images Use Case
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.png', path.basename(default_icon.foreground));
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
}
}
return resourceMap;
}
function updateIconResourceForLegacy (preparedIcons, resourceMap, platformResourcesDir) {
let android_icons = preparedIcons.android_icons;
let default_icon = preparedIcons.default_icon;
// The source paths for icons and splashes are relative to
// project's config.xml location, so we use it as base path.
for (var density in android_icons) {
var targetPath = getImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher.png', path.basename(android_icons[density].src));
resourceMap[targetPath] = android_icons[density].src;
}
// There's no "default" drawable, so assume default == mdpi.
if (default_icon && !android_icons.mdpi) {
var defaultTargetPath = getImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher.png', path.basename(default_icon.src));
resourceMap[defaultTargetPath] = default_icon.src;
}
return resourceMap;
}
function prepareIcons (icons) {
var android_icons = {};
var default_icon;
// http://developer.android.com/design/style/iconography.html
const SIZE_TO_DENSITY_MAP = {
var sizeToDensityMap = {
36: 'ldpi',
48: 'mdpi',
72: 'hdpi',
@@ -531,15 +335,11 @@ function prepareIcons (icons) {
144: 'xxhdpi',
192: 'xxxhdpi'
};
let android_icons = {};
let default_icon;
// find the best matching icon for a given density or size
// @output android_icons
var parseIcon = function (icon, icon_size) {
// do I have a platform icon for that density already
var density = icon.density || SIZE_TO_DENSITY_MAP[icon_size];
var density = icon.density || sizeToDensityMap[icon_size];
if (!density) {
// invalid icon defition ( or unsupported size)
return;
@@ -555,34 +355,12 @@ function prepareIcons (icons) {
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) {
let found = {};
let favor = {};
// populating found icon.
if (icon.background && icon.foreground) {
found.background = icon.background;
found.foreground = icon.foreground;
}
if (icon.src) {
found.src = icon.src;
}
if (default_icon.background && default_icon.foreground) {
favor.background = default_icon.background;
favor.foreground = default_icon.foreground;
}
if (default_icon.src) {
favor.src = default_icon.src;
}
events.emit('verbose', 'Found extra default icon: ' + JSON.stringify(found) + ' and ignoring in favor of ' + JSON.stringify(favor) + '.');
events.emit('verbose', 'Found extra default icon: ' + icon.src + ' (ignoring in favor of ' + default_icon.src + ')');
} else {
default_icon = icon;
}
@@ -591,35 +369,36 @@ function prepareIcons (icons) {
}
}
return {
android_icons: android_icons,
default_icon: default_icon
};
// The source paths for icons and splashes are relative to
// project's config.xml location, so we use it as base path.
for (var density in android_icons) {
var targetPath = getImageResourcePath(
platformResourcesDir, 'mipmap', density, '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);
// Skip if there are no app defined icons in config.xml
if (icons.length === 0) {
events.emit('verbose', 'This app does not have launcher icons defined');
return;
// No source paths are specified in the map, so updatePaths() will delete the target files.
FileUpdater.updatePaths(
resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
}
let resourceMap = Object.assign(
{},
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
);
events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir);
// No source paths are specified in the map, so updatePaths() will delete the target files.
FileUpdater.updatePaths(resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
}
/**
@@ -667,7 +446,7 @@ function cleanFileResources (projectRoot, projectConfig, platformDir) {
FileUpdater.updatePaths(
resourceMap, {
rootDir: projectRoot, all: true }, logFileOp);
rootDir: projectRoot, all: true}, logFileOp);
}
}

View File

@@ -19,6 +19,8 @@
under the License.
*/
/* jshint node: true */
'use strict';
var events = require('cordova-common').events;
@@ -27,20 +29,21 @@ var events = require('cordova-common').events;
* Retry a promise-returning function a number of times, propagating its
* results on success or throwing its error on a failed final attempt.
*
* @arg {Number} attemptsLeft - The number of times to retry the passed call.
* @arg {Number} attemts_left - The number of times to retry the passed call.
* @arg {Function} promiseFunction - A function that returns a promise.
* @arg {...} - Arguments to pass to promiseFunction.
*
* @returns {Promise}
*/
module.exports.retryPromise = function (attemptsLeft, promiseFunction) {
module.exports.retryPromise = function (attemts_left, promiseFunction) {
// NOTE:
// get all trailing arguments, by skipping the first two (attemptsLeft and
// get all trailing arguments, by skipping the first two (attemts_left and
// promiseFunction) because they shouldn't get passed to promiseFunction
var promiseFunctionArguments = Array.prototype.slice.call(arguments, 2);
return promiseFunction.apply(undefined, promiseFunctionArguments).then(
// on success pass results through
function onFulfilled (value) {
return value;
@@ -48,16 +51,17 @@ module.exports.retryPromise = function (attemptsLeft, promiseFunction) {
// on rejection either retry, or throw the error
function onRejected (error) {
attemptsLeft -= 1;
if (attemptsLeft < 1) {
attemts_left -= 1;
if (attemts_left < 1) {
throw error;
}
events.emit('verbose', 'A retried call failed. Retrying ' + attemptsLeft + ' more time(s).');
events.emit('verbose', 'A retried call failed. Retrying ' + attemts_left + ' more time(s).');
// retry call self again with the same arguments, except attemptsLeft is now lower
var fullArguments = [attemptsLeft, promiseFunction].concat(promiseFunctionArguments);
// retry call self again with the same arguments, except attemts_left is now lower
var fullArguments = [attemts_left, promiseFunction].concat(promiseFunctionArguments);
return module.exports.retryPromise.apply(undefined, fullArguments);
}
);

View File

@@ -19,7 +19,10 @@
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');
@@ -49,7 +52,6 @@ function getInstallTarget (runOptions) {
* @return {Promise}
*/
module.exports.run = function (runOptions) {
runOptions = runOptions || {};
var self = this;
var install_target = getInstallTarget(runOptions);
@@ -101,17 +103,16 @@ module.exports.run = function (runOptions) {
});
});
}).then(function (resolvedTarget) {
return new Promise((resolve) => {
const builder = require('./builders/builders').getBuilder();
const buildOptions = require('./build').parseBuildOptions(runOptions, null, self.root);
resolve(builder.fetchBuildResults(buildOptions.buildType, buildOptions.arch));
}).then(function (buildResults) {
// 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 && resolvedTarget.isEmulator) {
return emulator.wait_for_boot(resolvedTarget.target).then(function () {
return emulator.install(resolvedTarget, buildResults);
});
}
return device.install(resolvedTarget, buildResults);
});
});

View File

@@ -19,20 +19,21 @@
under the License.
*/
var emulator = require('./emulator');
var args = process.argv;
var emulator = require('./emulator'),
args = process.argv;
var install_target;
if (args.length > 2) {
if (args[2].substring(0, 9) === '--target=') {
if(args.length > 2) {
if (args[2].substring(0, 9) == '--target=') {
install_target = args[2].substring(9, args[2].length);
} else {
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
}
emulator.start(install_target).catch(function (err) {
emulator.start(install_target).done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -19,17 +19,17 @@
under the License.
*/
var log = require('./lib/log');
var reqs = require('./lib/check_reqs');
var args = process.argv;
var log = require('./lib/log'),
reqs = require('./lib/check_reqs'),
args = process.argv;
// Usage support for when args are given
if (args.length > 2) {
if(args.length > 2) {
log.help();
} else {
reqs.run().done(function () {
reqs.run().done(function() {
return log.run();
}, function (err) {
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@@ -24,23 +24,22 @@ var nopt = require('nopt');
var path = require('path');
// Support basic help commands
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
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,
'verbose' : Boolean,
'silent' : Boolean,
'debug' : Boolean,
'release' : Boolean,
'nobuild': Boolean,
'buildConfig': path,
'archs': String,
'device': Boolean,
'buildConfig' : path,
'archs' : String,
'device' : Boolean,
'emulator': Boolean,
'target': String
}, { 'd': '--verbose' });
'target' : String
}, { 'd' : '--verbose' });
// Make runOptions compatible with PlatformApi run method spec
runOpts.argv = runOpts.argv.remain;
@@ -48,7 +47,7 @@ runOpts.argv = runOpts.argv.remain;
require('./loggingHelper').adjustLoggerLevel(runOpts);
new Api().run(runOpts)
.catch(function (err) {
console.error(err, err.stack);
process.exit(2);
});
.catch(function(err) {
console.error(err, err.stack);
process.exit(2);
});

View File

@@ -20,7 +20,7 @@
*/
// Coho updates this line:
var VERSION = "8.0.0";
var VERSION = "7.1.5-dev";
module.exports.version = VERSION;

View File

@@ -30,7 +30,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
<application android:icon="@mipmap/icon" android:label="@string/app_name"
android:hardwareAccelerated="true" android:supportsRtl="true">
<activity android:name="__ACTIVITY__"
android:label="@string/activity_name"

View File

@@ -22,32 +22,33 @@ apply plugin: 'com.android.application'
buildscript {
repositories {
mavenCentral()
google()
maven {
url "https://maven.google.com"
}
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
// Allow plugins to declare Maven dependencies via build-extras.gradle.
allprojects {
repositories {
mavenCentral()
mavenCentral();
jcenter()
}
}
task wrapper(type: Wrapper) {
gradleVersion = '4.10.3'
gradleVersion = '4.1.0'
}
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
// Refer to: http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html
ext {
apply from: '../CordovaLib/cordova.gradle'
// The value for android.compileSdkVersion.
if (!project.hasProperty('cdvCompileSdkVersion')) {
cdvCompileSdkVersion = null;
@@ -144,25 +145,24 @@ cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}
task cdvPrintProps {
doLast {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
println('cdvBuildArch=' + cdvBuildArch)
println('computedVersionCode=' + android.defaultConfig.versionCode)
android.productFlavors.each { flavor ->
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
}
task cdvPrintProps << {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
println('cdvBuildArch=' + cdvBuildArch)
println('computedVersionCode=' + android.defaultConfig.versionCode)
android.productFlavors.each { flavor ->
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
}
}
android {
defaultConfig {
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
applicationId privateHelpers.extractStringFromManifest("package")
@@ -249,7 +249,6 @@ android {
}
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (cdvDebugSigningPropertiesFile) {
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}

View File

@@ -1,5 +1,5 @@
// Platform: android
// 882658ab17740dbdece764e68c1f1f1f44fe3f9d
// 9e8e1b716252c4a08abcd31a13013b868d6f4141
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,9 +19,12 @@
under the License.
*/
;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '8.0.0';
var PLATFORM_VERSION_BUILD_LABEL = '7.1.5-dev';
// file: src/scripts/require.js
/* jshint -W079 */
/* jshint -W020 */
var require;
var define;
@@ -324,7 +327,7 @@ module.exports = cordova;
});
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
// file: /Users/brodybits/Documents/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
define("cordova/android/nativeapiprovider", function(require, exports, module) {
/**
@@ -347,7 +350,7 @@ module.exports = {
});
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
// file: /Users/brodybits/Documents/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
define("cordova/android/promptbasednativeapi", function(require, exports, module) {
/**
@@ -879,7 +882,7 @@ module.exports = channel;
});
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/exec.js
// file: /Users/brodybits/Documents/cordova/cordova-android/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) {
/**
@@ -972,6 +975,17 @@ function androidExec(success, fail, service, action, args) {
}
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);
channel.onNativeReady.fire();
};
@@ -1306,6 +1320,130 @@ channel.join(function () {
});
// file: src/common/init_b.js
define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel');
var cordova = require('cordova');
var modulemapper = require('cordova/modulemapper');
var platform = require('cordova/platform');
var pluginloader = require('cordova/pluginloader');
var utils = require('cordova/utils');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
// setting exec
cordova.exec = require('cordova/exec');
function logUnfiredChannels (arr) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i].state !== 2) {
console.log('Channel not fired: ' + arr[i].type);
}
}
}
window.setTimeout(function () {
if (channel.onDeviceReady.state !== 2) {
console.log('deviceready has not fired after 5 seconds.');
logUnfiredChannels(platformInitChannelsArray);
logUnfiredChannels(channel.deviceReadyChannelsArray);
}
}, 5000);
// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
// We replace it so that properties that can't be clobbered can instead be overridden.
function replaceNavigator (origNavigator) {
var CordovaNavigator = function () {};
CordovaNavigator.prototype = origNavigator;
var newNavigator = new CordovaNavigator();
// This work-around really only applies to new APIs that are newer than Function.bind.
// Without it, APIs such as getGamepads() break.
if (CordovaNavigator.bind) {
for (var key in origNavigator) {
if (typeof origNavigator[key] === 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
} else {
(function (k) {
utils.defineGetterSetter(newNavigator, key, function () {
return origNavigator[k];
});
})(key);
}
}
}
return newNavigator;
}
if (window.navigator) {
window.navigator = replaceNavigator(window.navigator);
}
if (!window.console) {
window.console = {
log: function () {}
};
}
if (!window.console.warn) {
window.console.warn = function (msg) {
this.log('warn: ' + msg);
};
}
// Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onActivated = cordova.addDocumentEventHandler('activated');
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
// Listen for DOMContentLoaded and notify our channel subscribers.
if (document.readyState === 'complete' || document.readyState === 'interactive') {
channel.onDOMContentLoaded.fire();
} else {
document.addEventListener('DOMContentLoaded', function () {
channel.onDOMContentLoaded.fire();
}, false);
}
// _nativeReady is global variable that the native side can set
// to signify that the native code is ready. It is a global since
// it may be called before any cordova JS is ready.
if (window._nativeReady) {
channel.onNativeReady.fire();
}
// Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap();
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
// The delay allows the attached modules to be defined before the plugin loader looks for them.
setTimeout(function () {
pluginloader.load(function () {
channel.onPluginsReady.fire();
});
}, 0);
/**
* Create all cordova objects once native side is ready.
*/
channel.join(function () {
modulemapper.mapModules(window);
platform.initialize && platform.initialize();
// Fire event to notify that all objects are created
channel.onCordovaReady.fire();
// Fire onDeviceReady event once page has fully loaded, all
// constructors have run and cordova info has been received from native
// side.
channel.join(function () {
require('cordova').fireDocumentEvent('deviceready');
}, channel.deviceReadyChannelsArray);
}, platformInitChannelsArray);
});
// file: src/common/modulemapper.js
define("cordova/modulemapper", function(require, exports, module) {
@@ -1406,7 +1544,103 @@ exports.reset();
});
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/platform.js
// file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder');
var symbolList = [];
var deprecationMap;
exports.reset = function () {
symbolList = [];
deprecationMap = {};
};
function addEntry (strategy, moduleName, symbolPath, opt_deprecationMessage) {
symbolList.push(strategy, moduleName, symbolPath);
if (opt_deprecationMessage) {
deprecationMap[symbolPath] = opt_deprecationMessage;
}
}
// Note: Android 2.3 does have Function.bind().
exports.clobbers = function (moduleName, symbolPath, opt_deprecationMessage) {
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
};
exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
};
exports.defaults = function (moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
};
exports.runs = function (moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace (symbolPath, context) {
if (!symbolPath) {
return context;
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
cur = cur[part] = cur[part] || {};
}
return cur;
}
exports.mapModules = function (context) {
var origSymbols = {};
context.CDV_origSymbols = origSymbols;
for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i];
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy === 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy === 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
}
}
};
exports.getOriginalSymbol = function (context, symbolPath) {
var origSymbols = context.CDV_origSymbols;
if (origSymbols && (symbolPath in origSymbols)) {
return origSymbols[symbolPath];
}
var parts = symbolPath.split('.');
var obj = context;
for (var i = 0; i < parts.length; ++i) {
obj = obj && obj[parts[i]];
}
return obj;
};
exports.reset();
});
// file: /Users/brodybits/Documents/cordova/cordova-android/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) {
// The last resume event that was received that had the result of a plugin call.
@@ -1516,7 +1750,7 @@ function onMessageFromNative(msg) {
});
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/plugin/android/app.js
// file: /Users/brodybits/Documents/cordova/cordova-android/cordova-js-src/plugin/android/app.js
define("cordova/plugin/android/app", function(require, exports, module) {
var exec = require('cordova/exec');
@@ -1719,6 +1953,53 @@ exports.load = function (callback) {
});
// file: src/common/pluginloader_b.js
define("cordova/pluginloader_b", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
// Handler for the cordova_plugins.js content.
// See plugman's plugin_loader.js for the details of this object.
function handlePluginsObject (moduleList) {
// if moduleList is not defined or empty, we've nothing to do
if (!moduleList || !moduleList.length) {
return;
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) { // eslint-disable-line no-cond-assign
if (module.clobbers && module.clobbers.length) {
for (var j = 0; j < module.clobbers.length; j++) {
modulemapper.clobbers(module.id, module.clobbers[j]);
}
}
if (module.merges && module.merges.length) {
for (var k = 0; k < module.merges.length; k++) {
modulemapper.merges(module.id, module.merges[k]);
}
}
// Finally, if runs is truthy we want to simply require() the module.
if (module.runs) {
modulemapper.runs(module.id);
}
}
}
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
// but the method accepts callback to be compatible with non-browserify flow.
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
// no plugins to load, or they are all done.
exports.load = function (callback) {
var moduleList = require('cordova/plugin_list');
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) {
@@ -1905,4 +2186,4 @@ window.cordova = require('cordova');
require('cordova/init');
})();
})();

View File

@@ -20,30 +20,32 @@
buildscript {
repositories {
google()
maven {
url "https://maven.google.com"
}
jcenter()
}
dependencies {
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
allprojects {
repositories {
google()
maven {
url "https://maven.google.com"
}
jcenter()
}
//This replaces project.properties w.r.t. build settings
project.ext {
defaultBuildToolsVersion="28.0.3" //String
defaultBuildToolsVersion="27.0.1" //String
defaultMinSdkVersion=19 //Integer - Minimum requirement is Android 4.4
defaultTargetSdkVersion=28 //Integer - We ALWAYS target the latest by default
defaultCompileSdkVersion=28 //Integer - We ALWAYS compile with the latest by default
defaultTargetSdkVersion=27 //Integer - We ALWAYS target the latest by default
defaultCompileSdkVersion=27 //Integer - We ALWAYS compile with the latest by default
}
}

View File

@@ -10,12 +10,5 @@ ant-gen
# Eclipse builds
gen
out
# Gradle build artifacts
.gradle
.gradletasknamecache
# Gradle builds
/build
/CordovaLib/build
/app/build
gradle-app.setting
# Android Studio
.idea

View File

@@ -245,7 +245,7 @@ android {
}
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
compile fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
// SUB-PROJECT DEPENDENCIES END
}

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -18,13 +18,13 @@
specific language governing permissions and limitations
under the License.
*/
var path = require('path');
var path = require('path');
var Api = require('./templates/cordova/Api');
var args = require('nopt')({
var args = require('nopt')({
'link': Boolean,
'shared': Boolean,
'help': Boolean
}, { 'd': '--verbose' });
}, { '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]');
@@ -34,4 +34,4 @@ if (args.help || args.argv.remain.length === 0) {
require('./templates/cordova/loggingHelper').adjustLoggerLevel(args);
Api.updatePlatform(args.argv.remain[0], { link: (args.link || args.shared) }).done();
Api.updatePlatform(args.argv.remain[0], {link: (args.link || args.shared)}).done();

View File

@@ -24,15 +24,15 @@ ext {
buildscript {
repositories {
google()
maven {
url "https://maven.google.com"
}
jcenter()
}
dependencies {
// The gradle plugin and the maven plugin have to be updated after each version of Android
// studio comes out
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
}
}
@@ -42,11 +42,12 @@ apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
group = 'org.apache.cordova'
version = '8.0.0'
version = '7.1.5-dev'
android {
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
publishNonDefault true
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -93,9 +94,9 @@ install {
}
}
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'
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'
}
}
@@ -121,16 +122,16 @@ bintray {
name = 'cordova-android'
userOrg = 'cordova'
licenses = ['Apache-2.0']
vcsUrl = 'https://github.com/apache/cordova-android'
vcsUrl = 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
websiteUrl = 'https://cordova.apache.org'
issueTrackerUrl = 'https://github.com/apache/cordova-android/issues'
issueTrackerUrl = 'https://issues.apache.org/jira/browse/CB'
publicDownloadNumbers = true
licenses = ['Apache-2.0']
labels = ['android', 'cordova', 'phonegap']
version {
name = '8.0.0'
name = '7.1.5-dev'
released = new Date()
vcsTag = '8.0.0'
vcsTag = '7.1.5-dev'
}
}
}

View File

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

View File

@@ -1,11 +1,16 @@
# This file was originally created by the Android Tools, but is now
# used by cordova-android to manage the project configuration.
# 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,
# "ant.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-28
target=android-27
apk-configurations=
renderscript.opt.level=O0
android.library=true

View File

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

View File

@@ -216,10 +216,8 @@ public class CordovaWebViewImpl implements CordovaWebView {
// TODO: What about params?
// Load new URL
loadUrlIntoView(url, true);
return;
} else {
LOG.w(TAG, "showWebPage: Refusing to load URL into webview since it is not in the <allow-navigation> whitelist. URL=" + url);
return;
}
}
if (!pluginManager.shouldOpenExternalUrl(url)) {

View File

@@ -43,7 +43,6 @@ public class CoreAndroid extends CordovaPlugin {
private BroadcastReceiver telephonyReceiver;
private CallbackContext messageChannel;
private PluginResult pendingResume;
private PluginResult pendingPause;
private final Object messageChannelLock = new Object();
/**
@@ -114,10 +113,6 @@ public class CoreAndroid extends CordovaPlugin {
else if (action.equals("messageChannel")) {
synchronized(messageChannelLock) {
messageChannel = callbackContext;
if (pendingPause != null) {
sendEventMessage(pendingPause);
pendingPause = null;
}
if (pendingResume != null) {
sendEventMessage(pendingResume);
pendingResume = null;
@@ -144,7 +139,7 @@ public class CoreAndroid extends CordovaPlugin {
public void clearCache() {
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
webView.clearCache();
webView.clearCache(true);
}
});
}
@@ -326,19 +321,7 @@ public class CoreAndroid extends CordovaPlugin {
} catch (JSONException e) {
LOG.e(TAG, "Failed to create event message", e);
}
PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
if (messageChannel == null) {
LOG.i(TAG, "Request to send event before messageChannel initialised: " + action);
if ("pause".equals(action)) {
pendingPause = result;
} else if ("resume".equals(action)) {
// When starting normally onPause then onResume is called
pendingPause = null;
}
} else {
sendEventMessage(result);
}
sendEventMessage(new PluginResult(PluginResult.Status.OK, obj));
}
private void sendEventMessage(PluginResult payload) {

View File

@@ -58,11 +58,7 @@ class SystemCookieManager implements ICordovaCookieManager {
}
public void clearCookies() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.removeAllCookies(null);
} else {
cookieManager.removeAllCookie();
}
cookieManager.removeAllCookie();
}
public void flush() {

View File

@@ -142,7 +142,6 @@ public class SystemWebChromeClient extends WebChromeClient {
* Handle database quota exceeded notification.
*/
@Override
@SuppressWarnings("deprecation")
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
{
@@ -181,13 +180,11 @@ public class SystemWebChromeClient extends WebChromeClient {
// API level 7 is required for this, see if we could lower this using something else
@Override
@SuppressWarnings("deprecation")
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
parentEngine.getCordovaWebView().showCustomView(view, callback);
}
@Override
@SuppressWarnings("deprecation")
public void onHideCustomView() {
parentEngine.getCordovaWebView().hideCustomView();
}

View File

@@ -74,8 +74,7 @@ public class SystemWebViewClient extends WebViewClient {
* @param url The url to be loaded.
* @return true to override, false for default behavior
*/
@Override
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return parentEngine.client.onNavigationAttempt(url);
}
@@ -187,7 +186,6 @@ public class SystemWebViewClient extends WebViewClient {
* @param failingUrl The url that failed to load.
*/
@Override
@SuppressWarnings("deprecation")
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Ignore error due to stopLoading().
if (!isCurrentlyLoading) {
@@ -318,7 +316,6 @@ public class SystemWebViewClient extends WebViewClient {
}
@Override
@SuppressWarnings("deprecation")
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
try {
// Check the against the whitelist and lock out access to the WebView directory

46
node_modules/abbrev/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,46 @@
This software is dual-licensed under the ISC and MIT licenses.
You may use this software under EITHER of the following licenses.
----------
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------
Copyright Isaac Z. Schlueter and Contributors
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.

23
node_modules/abbrev/README.md generated vendored Normal file
View File

@@ -0,0 +1,23 @@
# abbrev-js
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
Usage:
var abbrev = require("abbrev");
abbrev("foo", "fool", "folding", "flop");
// returns:
{ fl: 'flop'
, flo: 'flop'
, flop: 'flop'
, fol: 'folding'
, fold: 'folding'
, foldi: 'folding'
, foldin: 'folding'
, folding: 'folding'
, foo: 'foo'
, fool: 'fool'
}
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.

61
node_modules/abbrev/abbrev.js generated vendored Normal file
View File

@@ -0,0 +1,61 @@
module.exports = exports = abbrev.abbrev = abbrev
abbrev.monkeyPatch = monkeyPatch
function monkeyPatch () {
Object.defineProperty(Array.prototype, 'abbrev', {
value: function () { return abbrev(this) },
enumerable: false, configurable: true, writable: true
})
Object.defineProperty(Object.prototype, 'abbrev', {
value: function () { return abbrev(Object.keys(this)) },
enumerable: false, configurable: true, writable: true
})
}
function abbrev (list) {
if (arguments.length !== 1 || !Array.isArray(list)) {
list = Array.prototype.slice.call(arguments, 0)
}
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
}
// sort them lexicographically, so that they're next to their nearest kin
args = args.sort(lexSort)
// walk through each, seeing how much it has in common with the next and previous
var abbrevs = {}
, prev = ""
for (var i = 0, l = args.length ; i < l ; i ++) {
var current = args[i]
, next = args[i + 1] || ""
, nextMatches = true
, prevMatches = true
if (current === next) continue
for (var j = 0, cl = current.length ; j < cl ; j ++) {
var curChar = current.charAt(j)
nextMatches = nextMatches && curChar === next.charAt(j)
prevMatches = prevMatches && curChar === prev.charAt(j)
if (!nextMatches && !prevMatches) {
j ++
break
}
}
prev = current
if (j === cl) {
abbrevs[current] = current
continue
}
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
abbrevs[a] = current
a += current.charAt(j)
}
}
return abbrevs
}
function lexSort (a, b) {
return a === b ? 0 : a > b ? 1 : -1
}

56
node_modules/abbrev/package.json generated vendored Normal file
View File

@@ -0,0 +1,56 @@
{
"_from": "abbrev@1",
"_id": "abbrev@1.1.1",
"_inBundle": false,
"_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"_location": "/abbrev",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "abbrev@1",
"name": "abbrev",
"escapedName": "abbrev",
"rawSpec": "1",
"saveSpec": null,
"fetchSpec": "1"
},
"_requiredBy": [
"/nopt"
],
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"_shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8",
"_spec": "abbrev@1",
"_where": "/Users/brodybits/Documents/cordova/cordova-android/node_modules/nopt",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me"
},
"bugs": {
"url": "https://github.com/isaacs/abbrev-js/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Like ruby's abbrev module, but in js",
"devDependencies": {
"tap": "^10.1"
},
"files": [
"abbrev.js"
],
"homepage": "https://github.com/isaacs/abbrev-js#readme",
"license": "ISC",
"main": "abbrev.js",
"name": "abbrev",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
},
"scripts": {
"postpublish": "git push origin --all; git push origin --tags",
"postversion": "npm publish",
"preversion": "npm test",
"test": "tap test.js --100"
},
"version": "1.1.1"
}

8
node_modules/android-versions/.jshintignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
.git/
node_modules/
coverage/
build/
assets/
dist/
docs/
tests/

29
node_modules/android-versions/.jshintrc generated vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"esversion": 6,
"indent": 2,
"forin": true,
"noarg": true,
"bitwise": true,
"nonew": true,
"strict": true,
"browser": true,
"devel": true,
"node": false,
"jquery": false,
"esnext": false,
"moz": false,
"es3": false,
"asi": true,
"eqnull": true,
"debug": true,
"boss": true,
"evil": true,
"loopfunc": true,
"laxbreak": true,
"unused": true,
"undef": true
}

3
node_modules/android-versions/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,3 @@
language: node_js
node_js:
- "6.1.0"

87
node_modules/android-versions/README.md generated vendored Normal file
View File

@@ -0,0 +1,87 @@
Android Versions
================
A node module to get Android versions by API level, NDK level, semantic version, or version name.
Versions are referenced from [source.android.com/source/build-numbers.html](https://source.android.com/source/build-numbers.html#platform-code-names-versions-api-levels-and-ndk-releases). The version for "Current Development Build" (`"CUR_DEVELOPMENT"`) is not included in the list of `VERSIONS`.
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[npm-image]: https://img.shields.io/npm/v/android-versions.svg?style=flat-square
[npm-url]: https://npmjs.org/package/android-versions
[travis-image]: https://img.shields.io/travis/dvoiss/android-versions.svg?style=flat-square
[travis-url]: https://travis-ci.org/dvoiss/android-versions
## Install
```bash
# NPM
npm install android-versions --save
# YARN
yarn add android-versions
```
## Usage
View the tests for more advanced usage.
```javascript
const android = require('android-versions')
```
#### Get by API level:
```javascript
console.log(android.get(23))
=> { api: 23, ndk: 8, semver: "6.0", name: "Marshmallow", versionCode: "M" }
```
#### Get by version:
```javascript
console.log(android.get("2.3.3"))
=> { api: 10, ndk: 5, semver: "2.3.3", name: "Gingerbread", versionCode: "GINGERBREAD_MR1" }
```
#### Get all by predicate:
```
android.getAll((version) => {
return version.ndk > 5 && version.api < 15
}).map((version) => version.versionCode)
=> [ "HONEYCOMB_MR1", "HONEYCOMB_MR2", "ICE_CREAM_SANDWICH" ]
```
#### Access a specific version with all info:
```
android.LOLLIPOP
=> { api: 21, ndk: 8, semver: "5.0", name: "Lollipop", versionCode: "LOLLIPOP" }
```
#### Access the complete reference of Android versions with all info:
```javascript
android.VERSIONS
=> {
BASE: { api: 1, ndk: 0, semver: "1.0", name: "(no code name)", versionCode: "BASE" },
...
N: { api: 24, ndk: 8, semver: "7.0", name: "Nougat", versionCode: "N" }
...
}
```
## Test
```bash
npm run test
```
## License
MIT

161
node_modules/android-versions/index.js generated vendored Normal file
View File

@@ -0,0 +1,161 @@
/**
* Copyright (c) 2016, David Voiss <davidvoiss@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose
* with or without fee is hereby granted, provided that the above copyright notice
* and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
*/
/* jshint node: true */
"use strict";
/**
* A module to get Android versions by API level, NDK level, semantic version, or version name.
*
* Versions are referenced from here:
* {@link https://source.android.com/source/build-numbers.html#platform-code-names-versions-api-levels-and-ndk-releases}
* {@link https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/Build.java}
*
* The version for "Current Development Build" ("CUR_DEVELOPMENT") is not included.
*
* @module android-versions
*/
var VERSIONS = {
BASE: { api: 1, ndk: 0, semver: "1.0", name: "(no code name)", },
BASE_1_1: { api: 2, ndk: 0, semver: "1.1", name: "(no code name)", },
CUPCAKE: { api: 3, ndk: 1, semver: "1.5", name: "Cupcake", },
DONUT: { api: 4, ndk: 2, semver: "1.6", name: "Donut", },
ECLAIR: { api: 5, ndk: 2, semver: "2.0", name: "Eclair", },
ECLAIR_0_1: { api: 6, ndk: 2, semver: "2.0.1", name: "Eclair", },
ECLAIR_MR1: { api: 7, ndk: 3, semver: "2.1", name: "Eclair", },
FROYO: { api: 8, ndk: 4, semver: "2.2.x", name: "Froyo", },
GINGERBREAD: { api: 9, ndk: 5, semver: "2.3.0 - 2.3.2", name: "Gingerbread", },
GINGERBREAD_MR1: { api: 10, ndk: 5, semver: "2.3.3 - 2.3.7", name: "Gingerbread", },
HONEYCOMB: { api: 11, ndk: 5, semver: "3.0", name: "Honeycomb", },
HONEYCOMB_MR1: { api: 12, ndk: 6, semver: "3.1", name: "Honeycomb", },
HONEYCOMB_MR2: { api: 13, ndk: 6, semver: "3.2.x", name: "Honeycomb", },
ICE_CREAM_SANDWICH: { api: 14, ndk: 7, semver: "4.0.1 - 4.0.2", name: "Ice Cream Sandwich", },
ICE_CREAM_SANDWICH_MR1: { api: 15, ndk: 8, semver: "4.0.3 - 4.0.4", name: "Ice Cream Sandwich", },
JELLY_BEAN: { api: 16, ndk: 8, semver: "4.1.x", name: "Jellybean", },
JELLY_BEAN_MR1: { api: 17, ndk: 8, semver: "4.2.x", name: "Jellybean", },
JELLY_BEAN_MR2: { api: 18, ndk: 8, semver: "4.3.x", name: "Jellybean", },
KITKAT: { api: 19, ndk: 8, semver: "4.4.0 - 4.4.4", name: "KitKat", },
KITKAT_WATCH: { api: 20, ndk: 8, semver: "4.4", name: "KitKat Watch", },
LOLLIPOP: { api: 21, ndk: 8, semver: "5.0", name: "Lollipop", },
LOLLIPOP_MR1: { api: 22, ndk: 8, semver: "5.1", name: "Lollipop", },
M: { api: 23, ndk: 8, semver: "6.0", name: "Marshmallow", },
N: { api: 24, ndk: 8, semver: "7.0", name: "Nougat", },
N_MR1: { api: 25, ndk: 8, semver: "7.1", name: "Nougat", },
O: { api: 26, ndk: 8, semver: "8.0.0", name: "Oreo", },
O_MR1: { api: 27, ndk: 8, semver: "8.1.0", name: "Oreo", },
P: { api: 28, ndk: 8, semver: "9", name: "Pie", }
}
// Add a key to each version of Android for the "versionCode".
// This is the same key we use in the VERSIONS map above.
Object.keys(VERSIONS).forEach(function(version) {
VERSIONS[version].versionCode = version
})
var semver = require('semver');
// semver format requires <major>.<minor>.<patch> but we allow just <major>.<minor> format.
// Coerce <major>.<minor> to <major>.<minor>.0
function formatSemver(semver) {
if (semver.match(/^\d+.\d+$/)) {
return semver + '.0'
} else {
return semver
}
}
// The default predicate compares against API level, semver, name, or code.
function getFromDefaultPredicate(arg) {
// Coerce arg to string for comparisons below.
arg = arg.toString()
return getFromPredicate(function(version) {
// Check API level before all else.
if (arg === version.api.toString()) {
return true
}
var argSemver = formatSemver(arg)
var versionSemver = formatSemver(version.semver)
if (semver.valid(argSemver) && semver.satisfies(argSemver, versionSemver)) {
return true
}
// Compare version name and code.
return arg === version.name || arg === version.versionCode
})
}
// The function to allow passing a predicate.
function getFromPredicate(predicate) {
if (predicate === null) {
return null
}
return Object.keys(VERSIONS).filter(function(version) {
return predicate(VERSIONS[version])
}).map(function(key) { return VERSIONS[key] })
}
/**
* The Android version codes available as keys for easier look-up.
*/
Object.keys(VERSIONS).forEach(function(name) {
exports[name] = VERSIONS[name]
})
/**
* The complete reference of Android versions for easier look-up.
*/
exports.VERSIONS = VERSIONS
/**
* Retrieve a single Android version.
*
* @param {object | Function} arg - The value or predicate to use to retrieve values.
*
* @return {object} An object representing the version found or null if none found.
*/
exports.get = function(arg) {
var result = exports.getAll(arg)
if (result === null || result.length === 0) {
return null
}
return result[0]
}
/**
* Retrieve all Android versions that meet the criteria of the argument.
*
* @param {object | Function} arg - The value or predicate to use to retrieve values.
*
* @return {object} An object representing the version found or null if none found.
*/
exports.getAll = function(arg) {
if (arg === null) {
return null
}
if (typeof arg === "function") {
return getFromPredicate(arg)
} else {
return getFromDefaultPredicate(arg)
}
}

68
node_modules/android-versions/package.json generated vendored Normal file
View File

@@ -0,0 +1,68 @@
{
"_from": "android-versions@1",
"_id": "android-versions@1.4.0",
"_inBundle": false,
"_integrity": "sha512-GnomfYsBq+nZh3c3UH/4r9Jt6FuTxdhUJbeHIdYOH5xBhQ8I0ZzC2/RM5IFFIjrzuNWSHb8JWP1lPK0/a26jrg==",
"_location": "/android-versions",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "android-versions@1",
"name": "android-versions",
"escapedName": "android-versions",
"rawSpec": "1",
"saveSpec": null,
"fetchSpec": "1"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.4.0.tgz",
"_shasum": "807ea2941d7e5780e6dd61c5d9b7b6f3c0706e09",
"_spec": "android-versions@1",
"_where": "/Users/brodybits/Documents/cordova/cordova-android",
"author": {
"name": "dvoiss"
},
"bugs": {
"url": "https://github.com/dvoiss/android-versions/issues"
},
"bundleDependencies": false,
"dependencies": {
"semver": "^5.4.1"
},
"deprecated": false,
"description": "Get the name, API level, version level, NDK level, or version code from any version of Android.",
"devDependencies": {
"jshint": "^2.9.2",
"tape": "^4.6.0"
},
"homepage": "https://github.com/dvoiss/android-versions#readme",
"keywords": [
"android",
"version",
"versions",
"ndk",
"nougat",
"marshmallow",
"api",
"level"
],
"license": "MIT",
"main": "index.js",
"name": "android-versions",
"pre-commit": [
"jshint"
],
"repository": {
"type": "git",
"url": "git+https://github.com/dvoiss/android-versions.git"
},
"scripts": {
"jshint": "jshint .",
"test": "tape tests/**/*.js"
},
"version": "1.4.0"
}

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