Compare commits

...

174 Commits

Author SHA1 Message Date
Joe Bowser 4b06eecf3e CB-13621: eslint error 2017-11-30 11:08:54 -08:00
Joe Bowser 5a9eb154e0 CB-13622: Testing commit 2017-11-30 10:56:40 -08:00
Joe Bowser 655c018272 CB-13621: Wrote similar warning to CB-12948 on iOS. We no longer support update. 2017-11-30 10:41:28 -08:00
Joe Bowser 214e857b20 Set VERSION to 7.0.0 (via coho) 2017-11-30 10:01:28 -08:00
Joe Bowser c7b0b93c9d Update JS snapshot to version 7.0.0 (via coho) 2017-11-30 10:01:28 -08:00
Joe Bowser e53a65ef07 CB-13620 Updated RELEASENOTES and Version for release 7.0.0 2017-11-30 09:42:11 -08:00
Joe Bowser 3642ffb57a CB-13741: Updating checked-in node_modules, otherwise plugin installation fails 2017-11-29 13:32:44 -08:00
Joe Bowser 3dcc319cd2 Merge pull request #419 from dpogue/signing-fix
CB-13615: Fix paths to signing properties files
2017-11-29 12:21:53 -08:00
Darryl Pogue 8484f7b906 CB-13615: Fix paths to signing properties files 2017-11-29 10:56:05 -08:00
Joe Bowser 59018ab632 Merge pull request #389 from infil00p/StudioProjectCompat
CB-11244: Studio Project Compatibility: Now with merge commit
2017-11-29 09:55:37 -08:00
Joe Bowser c6cfeb15f4 Fixed typo in the gradle file 2017-11-28 14:59:50 -08:00
Joe Bowser adc7dab377 CB-13612: eslint fix 2017-11-28 13:09:07 -08:00
Joe Bowser a9e01f4309 CB-13612: Fix the remapper so that XML files copy over and the Camera works again. 2017-11-28 12:57:00 -08:00
Joe Bowser 0269e532df CB-13741: Bump package.json so we can install plugins 2017-11-28 11:31:04 -08:00
Joe Bowser 4863320e45 Merge branch 'master' into StudioProjectCompat 2017-11-28 10:35:45 -08:00
Joe Bowser 3ad1ed7dbc Merge pull request #418 from dpogue/splash-compress
CB-13610: Compress the default app assets
2017-11-28 10:35:04 -08:00
Joe Bowser ae823e6c4e Merge pull request #385 from dreifachstein/master
CB-12835: add a Context getter in CordovaInterface
2017-11-28 10:34:19 -08:00
Darryl Pogue 9056e5a2dc CB-13610: Compress the default app assets 2017-11-27 22:46:02 -08:00
Joe Bowser 2b20802dbb Merge branch 'master' into StudioProjectCompat
Merge by hand CB-8976
2017-11-27 14:10:59 -08:00
Joe Bowser a972d1ef62 Merge pull request #401 from fabulant/CB-8976
CB-8976: Added the `cdvVersionCodeForceAbiDigit` property
2017-11-27 14:02:20 -08:00
Joe Bowser 30c3713dca Merge branch 'master' into StudioProjectCompat 2017-11-27 11:42:25 -08:00
Joe Bowser 6f58d4c474 Merge pull request #352 from Icenium/include-armeabi-dir
CB-12291: (android) Add x86_64, arm64 and armeabi architecture flavors
2017-11-27 11:35:47 -08:00
Joe Bowser 9d9bac397b CB-13602: We were setting the path wrong, this is hacky but it works 2017-11-22 13:18:38 -08:00
Joe Bowser d8f10c33dc CB-13601: Fixing lint error and mis-spelling of variable 2017-11-22 11:47:05 -08:00
Joe Bowser 5d57eff612 CB-13601: Fixing the standalone run scripts to make sure this works without using the CLI 2017-11-22 11:39:40 -08:00
Joe Bowser 43956c1bc8 Merge branch 'master' into StudioProjectCompat
Fixing conflict caused by merging #417 into master
2017-11-20 18:21:49 -08:00
Joe Bowser 2930900963 Merge branch 'master' into StudioProjectCompat 2017-11-20 13:53:00 -08:00
Joe Bowser 6404780186 Merge pull request #417 from DavidStrausz/master
CB-13580: (android) fix build for multiple apks (different product flavors)
2017-11-16 10:13:50 -08:00
David Strauß 5d99e50c4a CB-13580: (android) fix lint errors 2017-11-16 01:54:04 +01:00
David Strauß aaeb630eb1 CB-13580: fix build for multiple apks (different product flavors) 2017-11-16 01:27:20 +01:00
Joe Bowser 3acba59494 CB-13297: This just works once you bump the project structure. Java 1.8 compatibility baked-in 2017-11-15 11:39:32 -08:00
Joe Bowser 3760616639 Merge pull request #416 from infil00p/bintray_fix
CB-13558: Upgrading the gradle so we can upload the AAR
2017-11-15 10:42:00 -08:00
Joe Bowser 026dce563b CB-13558: Upgrading the gradle so we can upload the AAR 2017-11-09 11:14:47 -08:00
Joe Bowser b77febc7a7 Merge branch 'master' into StudioProjectCompat 2017-11-07 10:52:37 -08:00
Joe Bowser 83601dca2f Update JS snapshot to version 6.5.0-dev (via coho) 2017-11-06 11:44:23 -08:00
Joe Bowser 05aeaf1bd2 Set VERSION to 6.5.0-dev (via coho) 2017-11-06 11:44:20 -08:00
Joe Bowser b138867b78 CB-13528 Updated RELEASENOTES and Version for release 6.4.0 2017-11-06 11:43:47 -08:00
Joe Bowser a1195cefd5 Merge pull request #415 from infil00p/CB-13530
CB-13530: Fix the utility method for finding the built APK for generic APKs
2017-11-03 16:50:32 -07:00
Joe Bowser b83c3b3684 CB-13530: Removing debug console.logs 2017-11-02 14:45:51 -07:00
Joe Bowser 5502ddaf0d CB-13530: This fixes the basic APK installation 2017-11-02 14:42:39 -07:00
Joe Bowser f54336eb61 eslint fix 2017-11-01 17:18:41 -07:00
Joe Bowser 18d6884522 CB-11244: Android Studio 3 work, things have changed with how the platform is built 2017-11-01 17:09:00 -07:00
Joe Bowser 8ba0109e55 Completing merge which includes the fix for Android Studio 3.0 2017-11-01 13:46:23 -07:00
Joe Bowser f50ca85a95 CB-11244: Found bug where the gradle subproject changes weren't actually getting written to the correct gradle file 2017-11-01 13:22:22 -07:00
Joe Bowser 39e6765e64 Merge pull request #413 from infil00p/StudioThreeFix
CB-13289: This fixes the Cordova-Android build on cordova-android 6.x
2017-11-01 10:26:53 -07:00
Joe Bowser 47e20da631 CB-13289: Updating Travis and appveyor 2017-10-31 10:48:19 -07:00
Audrey bb7b47b063 Merge pull request #414 from audreyso/CB-13501
CB-13501 : update appveyor to support node 8
2017-10-30 16:11:50 -07:00
Joe Bowser a2618dcde5 CB-13289: eslint fix 2017-10-30 13:17:18 -07:00
Joe Bowser 9fdb126715 CB-13289: Fixing build problems with Studio Three, but keeping Windows Gradle fix for now, will be deprecated 2017-10-30 10:39:59 -07:00
Audrey So b2a81c09ec :CB-13501 : update appveyor node versions to support node 8 2017-10-30 10:01:50 -07:00
Jan Piotrowski 04fa5d3feb CB-13499: Remove duplicate "setting" in error strings 2017-10-26 22:28:38 +02:00
Joe Bowser d73108cc13 CB-13289: Fix test to work with new Google Android Gradle DSL 2017-10-25 11:38:07 -07:00
Joe Bowser 3ba00f91bb eslint errors 2017-10-19 13:37:43 -07:00
Joe Bowser cbee8580d0 CB-13470: Fix Clean so that it cleans the Android Studio structure 2017-10-19 13:31:16 -07:00
Joe Bowser 6ccd6b009b Redoing PR #411 over here because the changes were obliterated from earlier 2017-10-18 11:09:08 -07:00
Joe Bowser 6cf6e20d2e Merge branch 'master' into StudioProjectCompat, fixing conflicts, need
to re-add previous PR fix on the branch
2017-10-18 11:04:44 -07:00
Joe Bowser 93efe71080 Merge pull request #411 from Keyclic/master
CB-12802: (android) Fix build.gradle to sign when building with multiple APK is enable.
2017-10-16 11:23:29 -07:00
Joe Bowser 697c8f129c Merge pull request #410 from filmaj/emu-fixes
CB-13404, CB-13406: `best_image` function fixes when choosing emulator images to deploy to
2017-10-16 10:37:30 -07:00
Joe Bowser c12f7fef76 Close #379 2017-10-13 11:08:01 -07:00
Kevin cde238de94 Include missing values for task.name when 'cdvBuildMultipleApks' option is true, 'task.name' can have 'validateSigningArmv7Release' or 'validateSigningX86Release' values too. 2017-10-09 09:17:40 +02:00
filmaj ec83d481fa CB-13406: Fixed AVD API level comparison when choosing sub-par API level match. Added tests for the best_image method. 2017-10-05 15:18:42 -05:00
filmaj 1f12fdbeea CB-13404: add android-versions to bundledDependencies. Ignore best emulator selection when parsed AVD information does not include API level in the target 2017-10-05 15:17:31 -05:00
Joe Bowser 8743e88550 CB-11244: Fixing eslint errors 2017-10-03 15:06:54 -07:00
Joe Bowser f3c238db1c CB-11244: Adding specs for resource files inside an Android Studio Project 2017-10-03 14:16:27 -07:00
Joe Bowser 2534a3c767 CB-11244: Added remapping for drawables 2017-10-02 19:04:40 -07:00
Joe Bowser b1f527e682 Merge branch 'master' into StudioProjectCompat 2017-09-28 10:21:49 -07:00
Audrey 6fa16b615b Merge pull request #408 from audreyso/CB-12895-eslint
CB-12895 : eslint ignoring cordova.js
2017-09-28 08:47:50 -07:00
Audrey So e5c90badba CB-12895 : eslint ignoring cordova.js 2017-09-26 17:15:30 -07:00
Joe Bowser be6c6ba976 CB-12895: Temporarily disabling eslint since cordova-js does not have eslint yet. 2017-09-25 14:00:38 -07:00
Joe Bowser 7f3be98199 Update JS snapshot to version 6.4.0-dev (via coho) 2017-09-25 11:37:52 -07:00
Joe Bowser 0e498db735 Set VERSION to 6.4.0-dev (via coho) 2017-09-25 11:37:51 -07:00
Joe Bowser 7203b740fd CB-13323 Updated RELEASENOTES and Version for release 6.3.0 2017-09-25 11:35:59 -07:00
Joe Bowser 97aab900da CB-13323 Updated checked-in node_modules 2017-09-25 11:17:24 -07:00
Joe Bowser dddb2837dd CB-6936: Merge pull request #304 from uareurapid/master
CB-6936: fix crash when calling methods on a destroyed webview
2017-09-15 13:26:21 -07:00
Joe Bowser 7d282426c4 Merge branch 'master' into StudioProjectCompat
Another merge commit to track master changes
2017-09-14 11:45:57 -07:00
filmaj 1637937664 CB-12981: handle SDK 26.0.2 slightly different AVD list output for Android 8+ AVDs. Would cause "cannot read property replace of undefined" errors when trying to deploy an Android 8 emulator. 2017-09-14 11:26:18 -07:00
filmaj 03144eb160 Add a node and npm package.json script for running java unit tests. Include them in the top-level npm test script. Run java unit tests in travis. Small refactor in gradlebuilder to support building gradle wrapper more easily. Don't explicitly build gradlew on appveyor CI as now npm test will do it for you. 2017-09-14 09:57:37 -07:00
Joe Bowser 53210710ba Merge pull request #404 from mediathand/maven-repo-fix
Update maven repo to include most recent lib versions
2017-09-11 10:04:48 -07:00
Joe Bowser 0d98e09fb1 Merge branch 'master' into StudioProjectCompat 2017-09-05 11:05:42 -07:00
Steve Gill e7a972df77 updated bundled node_modules 2017-09-05 11:04:12 -07:00
Gil Pedersen cb2f396e33 Update maven repo to include most recent lib versions 2017-08-29 17:27:02 +02:00
Martin Bektchiev 2940d05209 CB-12291: (android) Add x86_64, arm64 and armeabi architecture flavors 2017-08-16 09:35:33 +03:00
Joe Bowser 2377aa7ac2 Merge pull request #403 from infil00p/api26
CB-13177: Updating to API Level 26
2017-08-15 14:17:09 -07:00
Joe Bowser f18086f83a Merge branch 'master' into StudioProjectCompat 2017-08-15 13:29:44 -07:00
Joe Bowser dce3b7ed6c Merge pull request #402 from macdonst/master
Revert CB-12015: initial-scale values less than 1.0 are ignored on Android
2017-08-15 13:22:22 -07:00
Simon MacDonald 5bda4df7fa Revert CB-12015: initial-scale values less than 1.0 are ignored on Android 2017-08-14 20:57:44 -04:00
Joe Bowser 1a8e36ccd3 CB-13177: Updating to API Level 26 2017-08-14 11:41:46 -07:00
Simon MacDonald 14816c7c81 Merge pull request #399 from macdonst/CB-12730
CB-12730: Compat - INTEGRATE
2017-08-11 10:38:06 -04:00
Joe Bowser 8fdb16c555 Fixing cordova-cli related bug 2017-08-04 12:00:39 -07:00
Fabian Eichinger 940439866e CB-8976: Added the cdvVersionCodeForceAbiDigit flag to the template build.gradle that appends 0 to the versionCode when cdvBuildMultipleApks is not set 2017-08-04 18:28:06 +02:00
Joe Bowser e91b19d006 Fixing error caused by merge commit 2017-07-31 14:10:14 -07:00
Joe Bowser 46905ebe99 Merge branch 'master' into StudioProjectCompat. Dealing with latest
commits merged into master.
2017-07-31 13:43:21 -07:00
Simon MacDonald d364f46baa CB-12730: Compat - INTEGRATE 2017-07-28 08:56:19 -04:00
Nikita Matrosov 2b53c98cf5 CB-12453: Remove unnecessary double quotes from .bat files which are the causes of crash if project path contains spaces
this closes #362
2017-07-28 14:23:53 +03:00
Nikita Matrosov 36d07d7a15 CB-13031: Fix bug with case-sensitivity of android-packageName
this closes #397
2017-07-28 14:05:53 +03:00
filmaj 458e479681 Trying AppVeyor-supplied workaround for current appveyor time out issues. See http://help.appveyor.com/discussions/problems/7159-builds-timing-out-after-an-hour 2017-07-27 14:33:16 -07:00
Joe Bowser 5fe95570d2 Merge branch 'master' into StudioProjectCompat 2017-07-25 15:07:56 -07:00
filmaj c3ce2f8a07 Closes #398 2017-07-24 10:11:21 -07:00
Joe Bowser d0dab4bb09 Merge branch 'master' into StudioProjectCompat
I fixed the master so it passes eslint.
2017-07-18 14:25:56 -07:00
Joe Bowser 893356abcd CB-13034: Fixing eslint error 2017-07-18 14:13:53 -07:00
Joe Bowser 00c879e27d It passed then failed. I'll change the test for now, because perfect is the enemy of good. 2017-07-18 11:53:44 -07:00
Joe Bowser b65af106ff Make the tests pass 2017-07-17 13:07:32 -07:00
Joe Bowser fdd7eb3446 Linting fix 2017-07-14 16:51:10 -07:00
Darryl Pogue 22645d9158 [CB-10916] Support display name for Android 2017-07-14 17:37:15 -02:30
filmaj 76dd8613ca CB-12423: make explicit JDK 1.8 or greater is needed in the README. 2017-07-14 11:13:52 -05:00
Joe Bowser 99f15c507d Updating paths in the unit tests, leaving the failing test and coding against that 2017-07-12 11:13:20 -07:00
Joe Bowser 849b887e20 Merge branch 'master' into StudioProjectCompat 2017-07-12 09:39:55 -07:00
Joe Bowser 245d9a1e46 Merge branch 'master' into StudioProjectCompat 2017-07-12 09:33:37 -07:00
filmaj 5917d4ef0b CB-13006: removed create and update end-to-end tests, and instead added more unit test coverage. tweaked code coverage invocation so that we get coverage details on the create.js module. slight changes to the create.js module so that it is slightly easier to test. 2017-07-11 12:54:15 -05:00
filmaj 90053eb9df CB-12950: lots of tweaks for end-to-end test runs, especially on CI:
- rename npm tasks to reflect what they do (npm run unit-tests, npm run e2e-tests). main `npm test` runs linter, unit tests and e2e tests now.
- locked jasmine down to ~2.6.0.
- consolidate gitignores.
- updated travis to run `npm test`. add android sdk installation to appveyor ci run.align android dpendencies across travis and appveyor. have appveyor install gradle. force gradle to version 3.4.1 in appveyor, as that seems to be the only version choco has. explicitly invoke sdkmanager to move license accepting process along.
2017-06-27 15:59:16 -05:00
Joe Bowser a7304b9a19 Finishing the linting 2017-06-27 13:15:04 -07:00
Nikita Matrosov 540929c6a0 CB-9971: Suppressed unwanted java stderr output when running gradle wrapper
this closes #388
2017-06-26 21:17:58 +03:00
Joe Bowser e456175a81 Merge branch 'master' into StudioProjectCompat
This will have to be linted
2017-06-26 10:29:31 -07:00
filmaj 3ff32092a3 CB-12954 🔪 remove jshint leftovers 2017-06-26 12:26:53 -05:00
Audrey So 55d7cf3865 CB-12895 : updated .eslintrc file in spec dir and set jasmine true and removed root is true 2017-06-23 08:44:08 -07:00
Audrey So ac4ac935f6 CB-12895 : added .eslintrc files to set up jasmine environment 2017-06-23 08:07:08 -07:00
Audrey So d83d49d83b CB-12895 : fixed eslint errors 2017-06-23 08:07:08 -07:00
Audrey So e36158a0da CB-12895 : added eslint and removed jshint 2017-06-23 08:07:07 -07:00
Joe Bowser b20028c42b The prepare step was broken, which breaks the CLI workflow. This was caused by hardcoding the Java directory, which is a very bad idea. 2017-06-22 13:46:18 -07:00
Jesse MacFadyen 5cc14b8031 CB-12605 In Windows get Android studio path from the registry
This closes #387
2017-06-22 10:55:39 -07:00
Joe Bowser 1cda7a9de0 CB-11244: Found bug in Api.js where xml/strings.xml is used instead of values/strings.xml 2017-06-19 14:34:03 -07:00
Joe Bowser 49b76f5c71 Fixing mangled commits that crept into this branch 2017-06-14 11:36:43 -07:00
Joe Bowser c0474e811d Bump for travis test 2017-06-14 10:16:05 -07:00
Joe Bowser 40c9709445 OK, Going back to the old build.gradle for legacy projects 2017-06-14 09:57:29 -07:00
Joe Bowser b67e9905bc This is probably a bad idea, but we need to split the gradle files into legacy and new style 2017-06-14 09:57:28 -07:00
Joe Bowser c74192d578 Adding conditional code into Gradle, this is a bit dirty since we can't explicitly test it but we'll just have to rely on jasmine 2017-06-14 09:57:28 -07:00
Joe Bowser 33feb00e8f Adding the if statement to see if we can support both structures with minimal editing, TODO: actually write tests for this somehow 2017-06-14 09:57:28 -07:00
Joe Bowser 8f16df4c90 Adding logic to upgrade both Classic and Android Studio style project structures 2017-06-14 09:57:28 -07:00
Joe Bowser fb6cb51e64 Fixing lint errors 2017-06-14 09:57:28 -07:00
Joe Bowser 28ebbb8f02 CB-11244: Setup Api.js to support multiple builders based on project structure 2017-06-14 09:57:28 -07:00
Joe Bowser bd4ddcdedd Updated AndroidStudio to only look for the app directory to determine studio status 2017-06-14 09:57:28 -07:00
Joe Bowser e621edfba7 Fixing the Android Studio detection and making it automatically pick the right builder, good for upgrading Cordova 2017-06-14 09:57:27 -07:00
Joe Bowser 304a899114 Fixed the specification of the builders in the run command by getting build to check what was being passed from run 2017-06-14 09:57:27 -07:00
Joe Bowser 8391af2e8f JsHint Fixes, deleting unused methods 2017-06-14 09:57:27 -07:00
Joe Bowser 69ab6a0e0d Changing the project to add the app directory as a dependency 2017-06-14 09:57:27 -07:00
Joe Bowser a216f0db75 CB-11244: Changing directory creation, will most likely hide this behind a flag for the next release of Cordova-Android, and then make it default in the next major pending feedback 2017-06-14 09:57:27 -07:00
Joe Bowser 69260fb96a Fix the overwriting of Fil's fix, blargh 2017-06-14 09:57:27 -07:00
Joe Bowser db87e0ae6a Made changes so cordova/build builds with the new project. Need to work on plugin installation. 2017-06-14 09:57:26 -07:00
Joe Bowser 8ead919fae Managed to get the project to mostly compile, still need to re-work the build command to add the app project 2017-06-14 09:57:26 -07:00
Joe Bowser b73c04f3c8 Updating gradle version in the build file 2017-06-14 09:57:26 -07:00
Joe Bowser f790aeb8f6 Setting up the create command so we actually have all the directories in the right place, and define default variables in the top level build.gradle 2017-06-14 09:57:26 -07:00
Joe Bowser 7b17abc555 Fixing linting issues 2017-06-14 09:57:26 -07:00
Joe Bowser ffadf5dd51 Changing this so we pass lint 2017-06-14 09:57:25 -07:00
Joe Bowser 23d8d99925 Moving Android Manifest finding to the Gradle and Studio builders. 2017-06-14 09:57:25 -07:00
Joe Bowser d88df59c32 Adding the Studio Builder to build a project based on Android Studio,
and deleting Ant, since Google does not support Ant Builds anymore.
Sorry guys!
2017-06-14 09:57:25 -07:00
Xiaolei Yu 17906735df CB-12835: add a Context getter in CordovaInterface
A custom engine may live outside of the Activity's lifecycle and the
Activity instance may not always be available. This getter allows
Context accesses in all cases.
2017-06-11 17:51:19 +08:00
Audrey So 3a6e898b12 CB-12762 : pointed package.json repo items to github mirrors instead of apache repos site
This closes #383
2017-06-07 09:28:22 -07:00
filmaj 0cc3df3747 CB-12859: document how to run the native tests. add a README to the test/ project. 2017-06-06 14:37:57 -05:00
Joe Bowser 2bc842a2b3 This commit should exist on the Crosswalk Plugin, Close #357 2017-05-29 13:04:17 -07:00
Joe Bowser 1c6f640026 Commit already merged, Close #378 2017-05-29 13:02:35 -07:00
Joe Bowser 6daad829cc Close #283 2017-05-29 09:53:49 -07:00
Darryl Pogue 7d926822ed CB-8980: Ensure copied resource-files are cleaned
This closes #377
2017-05-25 16:11:20 -07:00
Audrey So d4dcbb13fc CB-12617 : removed node0.x support for platforms and added engineStrict
This closes #372
2017-05-25 14:09:55 -07:00
filmaj f396712f59 CB-12847: added bugs entry to package.json. 2017-05-24 00:54:03 +02:00
filmaj d97250f968 Update JS snapshot to version 6.3.0-dev (via coho) 2017-05-02 16:19:21 -07:00
filmaj e7e8e95242 Set VERSION to 6.3.0-dev (via coho) 2017-05-02 16:19:19 -07:00
filmaj d518a655a8 CB-12746: updated release notes for impending 6.2.3 release, since some of the reported changes did not make it into 6.2.2. 2017-05-02 16:04:20 -07:00
filmaj b6a5844027 CB-12746: decrement working dev version on master to 6.2.4-dev, to align with impending patch release. 2017-05-02 16:04:20 -07:00
filmaj 9d9abea157 Start of GradleBuilder.js specs - puts it on the code coverage radar. 2017-05-02 15:31:26 -07:00
Simon MacDonald ee1165ea33 CB-12015: initial-scale values less than 1.0 are ignored on Android
This closes #376
2017-05-01 11:20:25 -07:00
Joe Bowser 2704ee54cf This closes #374 2017-05-01 10:51:50 -07:00
Steve Gill ad01d28351 Set VERSION to 6.3.0-dev (via coho) 2017-04-24 22:05:43 -07:00
Steve Gill a215c1cf30 CB-12697 Updated RELEASENOTES and Version for release 6.2.2 2017-04-24 22:04:56 -07:00
Steve Gill cadea2f6c3 CB-12697 Updated checked-in node_modules 2017-04-24 21:56:28 -07:00
filmaj e13e15d3e9 CB-12640: better handling of unrecognized commands on windows. removed error checking in emulator image listing when shelling out, as we already defensively dont shell out if the program is not on the PATH / not recognized. added additional test for windows unrecognized command errors for target listing. fixed up spying in a test. 2017-04-10 12:12:46 -07:00
filmaj 6ef2f67ae8 CB-12640: flipped avd parsing logic so that it always tries to use avdmanager to retrieve avds first, then falls back to android command if avdmanager cannot be found (and errors with ENOENT). updated tests - and added explicit tests to ensure to shell out to singular forms of sub-commands when executing android 2017-04-10 12:12:46 -07:00
filmaj 765c4ee9f6 CB-12640: support for android sdk tools 26.0.1. simplified target parsing by using avdmanager instead of sdkmanager. flipped target parsing logic so that it always tries to use avdmanager to retrieve targets first, then falls back to android command if avdmanager cannot be found (and errors with ENOENT). updated tests. 2017-04-10 12:12:46 -07:00
Steve Gill a4103d8dc8 updated version in build.gradle 2017-04-07 10:56:39 -07:00
Steve Gill 8e0f021cad Set VERSION to 6.3.0-dev (via coho) 2017-04-02 17:43:13 -05:00
Steve Gill 002ab85f76 CB-12627 Updated RELEASENOTES and Version for release 6.2.1 2017-04-02 17:40:35 -05:00
Steve Gill 4a0f69a3f0 CB-12621: reverted elementtree dep to 0.1.6 2017-04-02 17:11:17 -05:00
Steve Gill 8a2e96d995 Update JS snapshot to version 6.3.0-dev (via coho) 2017-03-28 15:23:50 -07:00
Steve Gill 13dbd2f5d4 Set VERSION to 6.3.0-dev (via coho) 2017-03-28 15:18:35 -07:00
PC Dreams (Paulo Cristo) bcf3f8611a fix crash when calling methods on a destroyed webview 2016-05-04 08:42:14 +01:00
244 changed files with 19975 additions and 6581 deletions
+1
View File
@@ -0,0 +1 @@
bin/templates/project/assets/www/cordova.js
+10
View File
@@ -0,0 +1,10 @@
root: true
extends: semistandard
rules:
indent:
- error
- 4
camelcase: off
padded-blocks: off
operator-linebreak: off
no-throw-literal: off
+19 -17
View File
@@ -1,11 +1,21 @@
.DS_Store
.gradle
.metadata
Thumbs.db
Desktop.ini
*.tmp
*.bak
*.swp
*.class
*.jar
default.properties
gen
assets/www/cordova.js
local.properties
proguard.cfg
proguard.cfg
proguard-project.txt
example
/coverage
/framework/lib
/framework/build
/framework/bin
@@ -15,30 +25,23 @@ proguard-project.txt
/framework/libs
/framework/javadoc-public
/framework/javadoc-private
/test/libs
example
/test/bin
/test/assets/www/.tmp*
/test/assets/www/cordova.js
/test/.externalNativeBuild
/test/build.gradle
/test/gradle
/test/gradlew
/test/gradlew.bat
/test/assets/www/.tmp*
/test/assets/www/cordova.js
/test/bin
/test/build
.gradle
/test/captures
/test/libs
tmp/**
.metadata
tmp/**/*
Thumbs.db
Desktop.ini
*.tmp
*.bak
*.swp
*.class
*.jar
!/spec/fixtures/org.test.plugins.dummyplugin/src/android/TestLib.jar
# IntelliJ IDEA files
**/.idea/**/*
*.iml
.idea
npm-debug.log
node_modules/jshint
node_modules/promise-matchers
@@ -130,4 +133,3 @@ node_modules/wordwrap/
node_modules/yargs/
node_modules/jasmine-core/
node_modules/fs.realpath/
/coverage
-3
View File
@@ -1,3 +0,0 @@
bin/node_modules/*
bin/templates/project/*
spec/fixtures/*
-10
View File
@@ -1,10 +0,0 @@
{
"node": true
, "bitwise": true
, "undef": true
, "trailing": true
, "quotmark": true
, "indent": 4
, "unused": "vars"
, "latedef": "nofunc"
}
+13 -7
View File
@@ -2,21 +2,27 @@ language: android
sudo: false
jdk:
- oraclejdk8
env:
global:
- ANDROID_TOOLS=${ANDROID_HOME}/tools
before_install:
- nvm install 6
# ensure at least gradle 3.3 is in place.
- wget http://services.gradle.org/distributions/gradle-3.3-bin.zip
- unzip gradle-3.3-bin.zip
- export GRADLE_HOME=$PWD/gradle-3.3
- export PATH=${GRADLE_HOME}/bin:${ANDROID_HOME}:${ANDROID_HOME}/emulator:${ANDROID_TOOLS}:${ANDROID_TOOLS}/bin:${ANDROID_HOME}/platform-tools:$PATH
- node --version
- gradle --version
install:
- npm install
- npm install -g codecov
- echo y | android update sdk -u --filter android-22,android-23,android-24,android-25
- 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
- tools
install:
- npm install
- npm install -g codecov
script:
- npm run jshint
- npm test
- npm run cover
- npm run test-build
after_script:
- codecov
+7 -1
View File
@@ -36,7 +36,7 @@ at the core, applications written with web technology: HTML, CSS and JavaScript.
## Requires
- Java JDK 1.6 or greater
- Java JDK 1.8 or greater
- Android SDK [http://developer.android.com](http://developer.android.com)
@@ -62,3 +62,9 @@ These commands live in a generated Cordova Android project. Any interactions wit
1. Create a project
2. Import it via "Non-Android Studio Project"
## Running the Native Tests
The `test/` directory in this project contains an Android test project that can
be used to run different kinds of native tests. Check out the
[README contained therein](test/README.md) for more details!
+61
View File
@@ -20,6 +20,67 @@
-->
## Release Notes for Cordova (Android) ##
### 7.0.0 (Nov 30, 2017)
* [CB-13612](https://issues.apache.org/jira/browse/CB-13612) Fix the remapper so that XML files copy over and the Camera works again.
* [CB-13741](https://issues.apache.org/jira/browse/CB-13741) Bump `package.json` so we can install plugins
* [CB-13610](https://issues.apache.org/jira/browse/CB-13610) Compress the default app assets
* [CB-12835](https://issues.apache.org/jira/browse/CB-12835) add a Context getter in CordovaInterface
* [CB-8976](https://issues.apache.org/jira/browse/CB-8976) Added the `cdvVersionCodeForceAbiDigit` flag to the template build.gradle that appends 0 to the versionCode when `cdvBuildMultipleApks` is not set
* [CB-12291](https://issues.apache.org/jira/browse/CB-12291) (android) Add x86_64, arm64 and armeabi architecture flavors
* [CB-13602](https://issues.apache.org/jira/browse/CB-13602) We were setting the path wrong, this is hacky but it works
* [CB-13601](https://issues.apache.org/jira/browse/CB-13601) Fixing the standalone run scripts to make sure this works without using the CLI
* [CB-13580](https://issues.apache.org/jira/browse/CB-13580) fix build for multiple apks (different product flavors)
* [CB-13558](https://issues.apache.org/jira/browse/CB-13558) Upgrading the gradle so we can upload the AAR
* [CB-13297](https://issues.apache.org/jira/browse/CB-13297) This just works once you bump the project structure. Java 1.8 compatibility baked-in
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) **Android** Studio 3 work, things have changed with how the platform is built
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Found bug where the gradle subproject changes weren't actually getting written to the correct gradle file
* [CB-13470](https://issues.apache.org/jira/browse/CB-13470) Fix Clean so that it cleans the **Android** Studio structure
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Adding specs for resource files inside an **Android** Studio Project
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Added remapping for drawables
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Found bug in Api.js where xml/strings.xml is used instead of values/strings.xml
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Setup Api.js to support multiple builders based on project structure
* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Changing directory creation, will most likely hide this behind a flag for the next release of `cordova-android`, and then make it default in the next major pending feedback
* Adding the Studio Builder to build a project based on **Android** Studio, and deleting Ant, since Google does not support Ant Builds anymore. Sorry guys!
### 6.4.0 (Nov 06, 2017)
* [CB-13289](https://issues.apache.org/jira/browse/CB-13289) Fixing build problems with Studio Three, but keeping **Windows** Gradle fix for now, will be deprecated
* [CB-13289](https://issues.apache.org/jira/browse/CB-13289) Fix test to work with new Google **Android** Gradle DSL
* :CB-13501 : update appveyor node versions to support node 8
* [CB-13499](https://issues.apache.org/jira/browse/CB-13499) Remove duplicate "setting" in error strings
* Include missing values for task.name when 'cdvBuildMultipleApks' option is true, 'task.name' can have 'validateSigningArmv7Release' or 'validateSigningX86Release' values too.
* [CB-13406](https://issues.apache.org/jira/browse/CB-13406) Fixed AVD API level comparison when choosing sub-par API level match. Added tests for the best_image method.
* [CB-13404](https://issues.apache.org/jira/browse/CB-13404) add **Android**-versions to bundledDependencies. Ignore best emulator selection when parsed AVD information does not include API level in the target
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) : eslint ignoring cordova.js
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) Temporarily disabling eslint since cordova-js does not have eslint yet.
### 6.3.0 (Sep 25, 2017)
* [CB-6936](https://issues.apache.org/jira/browse/CB-6936) fix crash when calling methods on a destroyed webview
* [CB-12981](https://issues.apache.org/jira/browse/CB-12981) handle SDK 26.0.2 slightly different AVD list output for **Android** 8+ AVDs. Would cause "cannot read property replace of undefined" errors when trying to deploy an **Android** 8 emulator.
* Updated maven repo to include most recent lib versions
* [CB-13177](https://issues.apache.org/jira/browse/CB-13177) Updating to API Level 26
* Revert [CB-12015](https://issues.apache.org/jira/browse/CB-12015) initial-scale values less than 1.0 are ignored on **Android**
* [CB-12730](https://issues.apache.org/jira/browse/CB-12730) The Cordova Compatibility Plugin is now integrated into cordova-android
* [CB-12453](https://issues.apache.org/jira/browse/CB-12453) Remove unnecessary double quotes from .bat files which are the causes of crash if project path contains spaces
* [CB-13031](https://issues.apache.org/jira/browse/CB-13031) Fix bug with case-sensitivity of **Android**-packageName
* [CB-10916](https://issues.apache.org/jira/browse/CB-10916) Support display name for **Android**
* [CB-12423](https://issues.apache.org/jira/browse/CB-12423) make explicit JDK 1.8 or greater is needed in the `README`, we require 1.8 for compilation, but do not have 1.8 Java features yet
* [CB-13006](https://issues.apache.org/jira/browse/CB-13006) removed create and update end-to-end tests, and instead added more unit test coverage. tweaked code coverage invocation so that we get coverage details on the create.js module. slight changes to the create.js module so that it is slightly easier to test.
* [CB-12950](https://issues.apache.org/jira/browse/CB-12950) lots of tweaks for end-to-end test runs, especially on CI: - rename npm tasks to reflect what they do (npm run unit-tests, npm run e2e-tests). main `npm test` runs linter, unit tests and e2e tests now. - locked jasmine down to ~2.6.0. - consolidate gitignores. - updated travis to run `npm test`. add **Android** sdk installation to appveyor ci run.align **Android** dpendencies across travis and appveyor. have appveyor install gradle. force gradle to version 3.4.1 in appveyor, as that seems to be the only version choco has. explicitly invoke sdkmanager to move license accepting process along.
* [CB-12605](https://issues.apache.org/jira/browse/CB-12605) In **Windows** get **Android** studio path from the registry
* [CB-12762](https://issues.apache.org/jira/browse/CB-12762) : pointed `package.json` repo items to github mirrors instead of apache repos site
* [CB-12617](https://issues.apache.org/jira/browse/CB-12617) : removed node0.x support for platforms and added engineStrict
### 6.2.3 (May 2, 2017)
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) better handling of unrecognized Android SDK commands on **Windows**.
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) flipped avd parsing logic so that it always tries to use avdmanager to retrieve avds first, then falls back to android command if avdmanager cannot be found (and errors with ENOENT). updated tests - and added explicit tests to ensure to shell out to singular forms of sub-commands when executing `android`
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) support for android sdk tools 26.0.1.
### 6.2.2 (Apr 24, 2017)
* [CB-12697](https://issues.apache.org/jira/browse/CB-12697) Updated checked-in `node_modules`
### 6.2.1 (Apr 02, 2017)
* [CB-12621](https://issues.apache.org/jira/browse/CB-12621) reverted elementtree dep to 0.1.6
### 6.2.0 (Mar 28, 2017)
* [CB-12614](https://issues.apache.org/jira/browse/CB-12614) Adding headers to tests
* [CB-8978](https://issues.apache.org/jira/browse/CB-8978) Prepare copy `resource-files` from `config.xml`
+1 -1
View File
@@ -1 +1 @@
6.2.0-dev
7.0.0
+24 -6
View File
@@ -1,20 +1,38 @@
image:
- Previous Visual Studio 2015
environment:
ANDROID_HOME: "C:\\android"
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.12"
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
init:
- mkdir "%ANDROID_HOME%
- cd "%ANDROID_HOME%"
- appveyor DownloadFile "https://dl.google.com/android/repository/tools_r25.2.3-windows.zip"
- 7z x "tools_r25.2.3-windows.zip" > nul
- cd "C:\projects\cordova-android"
install:
# - cinst android-sdk
# - echo y | android update sdk -u --filter android-22,android-23
- choco install gradle -version 3.4.1
- gradle -version
- echo y | "%ANDROID_HOME%\tools\android.bat" --silent update sdk --no-ui --all --filter platform-tools,tools,build-tools-26.0.2,android-26,android-25,extra-google-m2repository,extra-android-m2repository
# on windows we need to accept sublicenses for the new tooling, wee. 30 is an arbitrary number,
# but should be the maximum number of licenses we explicitly need to type "Y ENTER" for.
# also, the sdkmanager in all its glory leaks a bit of output to stderr, and powershell
# and appveyor interpret that as errors, and blows up. so, when piping in our "Y ENTER"
# responses, we invoke cmd so we can redirect stderr to stdout, and tell it to --update itself.
- ps: for($i=0;$i -lt 30;$i++) { $response += "y`n"}; $response | cmd /c 'C:\android\tools\bin\sdkmanager.bat 2>&1' --update
- ps: Install-Product node $env:nodejs_version
- npm install
# below is a workaround on using gradle installed via choco on appveyor
- set path=C:\ProgramData\chocolatey\lib\gradle\tools\gradle-3.4.1\bin;%path%
build: off
test_script:
- node --version
- npm --version
- npm run test
# - npm run test-build
- npm test
+1 -1
View File
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0android_sdk_version"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'android_sdk_version' script in 'bin' folder, aborting...>&2
+1 -1
View File
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0check_reqs"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
+81 -62
View File
@@ -19,18 +19,28 @@
under the License.
*/
var shell = require('shelljs'),
Q = require('q'),
path = require('path'),
fs = require('fs'),
check_reqs = require('./../templates/cordova/lib/check_reqs'),
ROOT = path.join(__dirname, '..', '..');
var MIN_SDK_VERSION = 16;
var shell = require('shelljs');
var Q = require('q');
var path = require('path');
var fs = require('fs');
var check_reqs = require('./../templates/cordova/lib/check_reqs');
var ROOT = path.join(__dirname, '..', '..');
var CordovaError = require('cordova-common').CordovaError;
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
// Export all helper functions, and make sure internally within this module, we
// reference these methods via the `exports` object - this helps with testing
// (since we can then mock and control behaviour of all of these functions)
exports.validatePackageName = validatePackageName;
exports.validateProjectName = validateProjectName;
exports.setShellFatal = setShellFatal;
exports.copyJsAndLibrary = copyJsAndLibrary;
exports.copyScripts = copyScripts;
exports.copyBuildRules = copyBuildRules;
exports.writeProjectProperties = writeProjectProperties;
exports.prepBuildFiles = prepBuildFiles;
function setShellFatal (value, func) {
var oldVal = shell.config.fatal;
shell.config.fatal = value;
@@ -42,10 +52,16 @@ function getFrameworkDir(projectPath, shared) {
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
}
function copyJsAndLibrary(projectPath, shared, projectName) {
function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) {
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
shell.cp('-f', srcCordovaJsPath, path.join(projectPath, 'assets', 'www', 'cordova.js'));
var app_path = path.join(projectPath, 'app', 'src', 'main');
if (isLegacy) {
app_path = projectPath;
}
shell.cp('-f', srcCordovaJsPath, path.join(app_path, 'assets', 'www', 'cordova.js'));
// Copy the cordova.js file to platforms/<platform>/platform_www/
// The www dir is nuked on each prepare so we keep cordova.js in platform_www
@@ -57,8 +73,8 @@ function copyJsAndLibrary(projectPath, shared, projectName) {
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
// Don't fail if there are no old jars.
setShellFatal(false, function() {
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function(oldJar) {
exports.setShellFatal(false, function () {
shell.ls(path.join(app_path, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
console.log('Deleting ' + oldJar);
shell.rm('-f', oldJar);
});
@@ -110,9 +126,8 @@ function writeProjectProperties(projectPath, target_api) {
var subProjects = extractSubProjectPaths(data);
subProjects = subProjects.filter(function (p) {
return !(/^CordovaLib$/m.exec(p) ||
/[\\\/]cordova-android[\\\/]framework$/m.exec(p) ||
/^(\.\.[\\\/])+framework$/m.exec(p)
);
/[\\/]cordova-android[\\/]framework$/m.exec(p) ||
/^(\.\.[\\/])+framework$/m.exec(p));
});
subProjects.unshift('CordovaLib');
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
@@ -125,16 +140,24 @@ function writeProjectProperties(projectPath, target_api) {
fs.writeFileSync(dstPath, data);
}
function prepBuildFiles(projectPath) {
// This makes no sense, what if you're building with a different build system?
function prepBuildFiles (projectPath, builder) {
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
buildModule.getBuilder('gradle').prepBuildFiles();
buildModule.getBuilder(builder).prepBuildFiles();
}
function copyBuildRules(projectPath) {
function copyBuildRules (projectPath, isLegacy) {
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
if (isLegacy) {
// The project's build.gradle is identical to the earlier build.gradle, so it should still work
shell.cp('-f', path.join(srcDir, 'legacy', 'build.gradle'), projectPath);
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
} else {
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
shell.cp('-f', path.join(srcDir, 'app', 'build.gradle'), path.join(projectPath, 'app'));
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
}
}
function copyScripts (projectPath) {
@@ -169,6 +192,7 @@ function validatePackageName(package_name) {
// http://developer.android.com/guide/topics/manifest/manifest-element.html#package
// Enforce underscore limitation
var msg = 'Error validating package name. ';
if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) {
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
}
@@ -235,7 +259,7 @@ exports.create = function(project_path, config, options, events) {
return Q.reject(new CordovaError('Project already exists! Delete and recreate'));
}
var package_name = config.packageName() || 'my.cordova.project';
var package_name = config.android_packageName() || config.packageName() || 'my.cordova.project';
var project_name = config.name() ?
config.name().replace(/[^\w.]/g, '_') : 'CordovaExample';
@@ -243,9 +267,9 @@ exports.create = function(project_path, config, options, events) {
var target_api = check_reqs.get_target();
// Make the package conform to Java package types
return validatePackageName(package_name)
return exports.validatePackageName(package_name)
.then(function () {
validateProjectName(project_name);
exports.validateProjectName(project_name);
}).then(function () {
// Log the given values for the project
events.emit('log', 'Creating Cordova project for the Android platform:');
@@ -257,27 +281,39 @@ exports.create = function(project_path, config, options, events) {
events.emit('verbose', 'Copying android template project to ' + project_path);
setShellFatal(true, function() {
exports.setShellFatal(true, function () {
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
var app_path = path.join(project_path, 'app', 'src', 'main');
// copy project template
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
shell.mkdir('-p', app_path);
shell.cp('-r', path.join(project_template_dir, 'assets'), app_path);
shell.cp('-r', path.join(project_template_dir, 'res'), app_path);
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
// Manually create directories that would be empty within the template (since git doesn't track directories).
shell.mkdir(path.join(project_path, 'libs'));
shell.mkdir(path.join(app_path, 'libs'));
// copy cordova.js, cordova.jar
copyJsAndLibrary(project_path, options.link, safe_activity_name);
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
// Set up ther Android Studio paths
var java_path = path.join(app_path, 'java');
var assets_path = path.join(app_path, 'assets');
var resource_path = path.join(app_path, 'res');
shell.mkdir('-p', java_path);
shell.mkdir('-p', assets_path);
shell.mkdir('-p', resource_path);
// interpolate the activity name and package
var packagePath = package_name.replace(/\./g, path.sep);
var activity_dir = path.join(project_path, 'src', packagePath);
var activity_dir = path.join(java_path, packagePath);
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
shell.mkdir('-p', activity_dir);
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
shell.sed('-i', /__NAME__/, project_name, path.join(app_path, 'res', 'values', 'strings.xml'));
shell.sed('-i', /__ID__/, package_name, activity_path);
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
@@ -285,22 +321,22 @@ exports.create = function(project_path, config, options, events) {
.setTargetSdkVersion(target_api.split('-')[1])
.getActivity().setName(safe_activity_name);
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
var manifest_path = path.join(app_path, 'AndroidManifest.xml');
manifest.write(manifest_path);
copyScripts(project_path);
copyBuildRules(project_path);
exports.copyScripts(project_path);
exports.copyBuildRules(project_path);
});
// Link it to local android install.
writeProjectProperties(project_path, target_api);
prepBuildFiles(project_path);
exports.writeProjectProperties(project_path, target_api);
exports.prepBuildFiles(project_path, 'studio');
events.emit('log', generateDoneMessage('create', options.link));
}).thenResolve(project_path);
};
function generateDoneMessage (type, link) {
var pkg = require('../../package');
var msg = 'Android project ' + (type == 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
var msg = 'Android project ' + (type === 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
if (link) {
msg += ' and has a linked CordovaLib';
}
@@ -309,33 +345,16 @@ function generateDoneMessage(type, link) {
// Returns a promise.
exports.update = function (projectPath, options, events) {
options = options || {};
return Q()
.then(function() {
var errorString =
'An in-place platform update is not supported. \n' +
'The `platforms` folder is always treated as a build artifact in the CLI workflow.\n' +
'To update your platform, you have to remove, then add your android platform again.\n' +
'Make sure you save your plugins beforehand using `cordova plugin save`, and save \n' + 'a copy of the platform first if you had manual changes in it.\n' +
'\tcordova plugin save\n' +
'\tcordova platform rm android\n' +
'\tcordova platform add android\n'
;
var manifest = new AndroidManifest(path.join(projectPath, 'AndroidManifest.xml'));
if (Number(manifest.getMinSdkVersion()) < MIN_SDK_VERSION) {
events.emit('verbose', 'Updating minSdkVersion to ' + MIN_SDK_VERSION + ' in AndroidManifest.xml');
manifest.setMinSdkVersion(MIN_SDK_VERSION);
}
manifest.setDebuggable(false).write();
var projectName = manifest.getActivity().getName();
var target_api = check_reqs.get_target();
copyJsAndLibrary(projectPath, options.link, projectName);
copyScripts(projectPath);
copyBuildRules(projectPath);
writeProjectProperties(projectPath, target_api);
prepBuildFiles(projectPath);
events.emit('log', generateDoneMessage('update', options.link));
}).thenResolve(projectPath);
return Q.reject(errorString);
};
// For testing
exports.validatePackageName = validatePackageName;
exports.validateProjectName = validateProjectName;
-10
View File
@@ -1,10 +0,0 @@
{
"node": true
, "bitwise": true
, "undef": true
, "trailing": true
, "quotmark": true
, "indent": 4
, "unused": "vars"
, "latedef": "nofunc"
}
+33 -37
View File
@@ -29,7 +29,6 @@ var selfEvents = require('cordova-common').events;
var PLATFORM = 'android';
function setupEvents (externalEventEmitter) {
if (externalEventEmitter) {
// This will make the platform internal events visible outside
@@ -43,7 +42,6 @@ function setupEvents(externalEventEmitter) {
return selfEvents;
}
/**
* Class, that acts as abstraction over particular platform. Encapsulates the
* platform's properties and methods.
@@ -58,6 +56,7 @@ function setupEvents(externalEventEmitter) {
function Api (platform, platformRootDir, events) {
this.platform = PLATFORM;
this.root = path.resolve(__dirname, '..');
this.builder = 'gradle';
setupEvents(events);
@@ -73,6 +72,7 @@ function Api(platform, platformRootDir, events) {
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'
@@ -81,10 +81,13 @@ function Api(platform, platformRootDir, events) {
// 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/xml/strings.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');
}
@@ -112,14 +115,11 @@ Api.createPlatform = function (destination, config, options, events) {
events = setupEvents(events);
var result;
try {
result = require('../../lib/create')
.create(destination, config, options, events)
.then(function (destination) {
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
return new PlatformApi(PLATFORM, destination, events);
});
}
catch (e) {
} catch (e) {
events.emit('error', 'createPlatform is not callable from the android project API.');
throw (e);
}
@@ -146,14 +146,11 @@ Api.updatePlatform = function (destination, options, events) {
events = setupEvents(events);
var result;
try {
result = require('../../lib/create')
.update(destination, options, events)
.then(function (destination) {
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
return new PlatformApi('android', destination, events);
});
}
catch (e) {
} catch (e) {
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
throw (e);
}
@@ -230,12 +227,10 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
installOptions.android_studio = true;
}
return Q()
.then(function () {
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.
@@ -248,16 +243,13 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
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 () {
}).then(function () {
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
}).then(function () {
if (plugin.getFrameworks(this.platform).length === 0) return;
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
// This should pick the correct builder, not just get gradle
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
}.bind(this))
// CB-11022 Return truthy value to prevent running prepare after
.thenResolve(true);
@@ -290,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('gradle').prepBuildFiles();
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
}.bind(this))
// CB-11022 Return truthy value to prevent running prepare after
.thenResolve(true);
@@ -343,11 +335,12 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
*/
Api.prototype.build = function (buildOptions) {
var self = this;
return require('./lib/check_reqs').run()
.then(function () {
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) {
}).then(function (buildResults) {
// Cast build result to array of build artifacts
return buildResults.apkPaths.map(function (apkPath) {
return {
@@ -374,8 +367,7 @@ Api.prototype.build = function (buildOptions) {
*/
Api.prototype.run = function (runOptions) {
var self = this;
return require('./lib/check_reqs').run()
.then(function () {
return require('./lib/check_reqs').run().then(function () {
return require('./lib/run').run.call(self, runOptions);
});
};
@@ -389,17 +381,21 @@ Api.prototype.run = function(runOptions) {
*/
Api.prototype.clean = function (cleanOptions) {
var self = this;
return require('./lib/check_reqs').run()
.then(function () {
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 () {
return require('./lib/build').runClean.call(self, cleanOptions);
})
.then(function () {
}).then(function () {
return require('./lib/prepare').clean.call(self, cleanOptions);
});
};
/**
* Performs a requirements check for current platform. Each platform defines its
* own set of requirements, which should be resolved before platform can be
+4 -8
View File
@@ -44,8 +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);
@@ -59,8 +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/)) {
@@ -86,8 +84,7 @@ 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));
});
@@ -95,8 +92,7 @@ Adb.shell = function (target, shellCommand) {
Adb.start = function (target, activityName) {
events.emit('verbose', 'Starting application "' + activityName + '" on target ' + target + '...');
return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName)
.catch(function (output) {
return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName).catch(function (output) {
return Q.reject(new CordovaError('Failed to start application "' +
activityName + '"" on device: ' + output));
});
+1 -2
View File
@@ -102,8 +102,7 @@ AndroidManifest.prototype.getActivity = function() {
};
};
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion']
.forEach(function(sdkPrefName) {
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function (sdkPrefName) {
// Copy variable reference to avoid closure issues
var prefName = sdkPrefName;
+2 -3
View File
@@ -28,8 +28,7 @@ var projectFileCache = {};
function addToPropertyList (projectProperties, key, value) {
var i = 1;
while (projectProperties.get(key + '.' + i))
i++;
while (projectProperties.get(key + '.' + i)) { i++; }
projectProperties.set(key + '.' + i, value);
projectProperties.dirty = true;
@@ -54,7 +53,7 @@ function removeFromPropertyList(projectProperties, key, value) {
function getRelativeLibraryPath (parentDir, subDir) {
var libraryPath = path.relative(parentDir, subDir);
return (path.sep == '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
return (path.sep === '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
}
function AndroidProject (projectDir) {
+2 -2
View File
@@ -11,8 +11,8 @@ var fs = require('fs');
var CordovaError = require('cordova-common').CordovaError;
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res', 'project.properties', 'platform_www'];
var androidStudioFiles = ['app', 'gradle', 'app/src/main/res'];
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res'];
var androidStudioFiles = ['app', 'app/src/main'];
// assume it is an AS project and not an Eclipse project
var isEclipse = false;
+19 -53
View File
@@ -1,5 +1,3 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,8 +17,8 @@
under the License.
*/
var Q = require('q'),
superspawn = require('cordova-common').superspawn;
var Q = require('q');
var superspawn = require('cordova-common').superspawn;
var suffix_number_regex = /(\d+)$/;
// Used for sorting Android targets, example strings to sort:
@@ -46,8 +44,7 @@ function sort_by_largest_numerical_suffix(a, b) {
}
module.exports.print_newest_available_sdk_target = function () {
return module.exports.list_targets()
.then(function(targets) {
return module.exports.list_targets().then(function (targets) {
targets.sort(sort_by_largest_numerical_suffix);
console.log(targets[0]);
});
@@ -68,63 +65,32 @@ module.exports.version_string_to_api_level = {
'7.1.1': 25
};
module.exports.list_targets_with_android = function() {
return superspawn.spawn('android', ['list', 'targets'])
.then(function(stdout) {
var target_out = stdout.split('\n');
function parse_targets (output) {
var target_out = output.split('\n');
var targets = [];
for (var i = target_out.length - 1; i >= 0; i--) {
if(target_out[i].match(/id:/)) {
targets.push(target_out[i].match(/"(.+)"/)[1]);
if (target_out[i].match(/id:/)) { // if "id:" is in the line...
targets.push(target_out[i].match(/"(.+)"/)[1]); // .. match whatever is in quotes.
}
}
return targets;
});
}
module.exports.list_targets_with_android = function () {
return superspawn.spawn('android', ['list', 'target']).then(parse_targets);
};
module.exports.list_targets_with_sdkmanager = function() {
return superspawn.spawn('sdkmanager', ['--list'])
.then(function(stdout) {
var parsing_installed_packages = false;
var lines = stdout.split('\n');
var targets = [];
for (var i = 0, l = lines.length; i < l; i++) {
var line = lines[i];
if (line.match(/Installed packages/)) {
parsing_installed_packages = true;
} else if (line.match(/Available Packages/) || line.match(/Available Updates/)) {
// we are done working through installed packages, exit
break;
}
if (parsing_installed_packages) {
// Match stock android platform
if (line.match(/platforms;android-\d+/)) {
targets.push(line.match(/(android-\d+)/)[1]);
}
// Match Google APIs
if (line.match(/addon-google_apis-google-\d+/)) {
var description = lines[i + 1];
// munge description to match output from old android sdk tooling
var api_level = description.match(/Android (\d+)/); //[1];
if (api_level) {
targets.push('Google Inc.:Google APIs:' + api_level[1]);
}
}
// TODO: match anything else?
}
}
return targets;
});
module.exports.list_targets_with_avdmanager = function () {
return superspawn.spawn('avdmanager', ['list', 'target']).then(parse_targets);
};
module.exports.list_targets = function () {
return module.exports.list_targets_with_android()
.catch(function(err) {
// there's a chance `android` no longer works.
// lets see if `sdkmanager` is available and we can figure it out
var avail_regex = /"?android"? command is no longer available/;
if (err.code && ((err.stdout && err.stdout.match(avail_regex)) || (err.stderr && err.stderr.match(avail_regex)))) {
return module.exports.list_targets_with_sdkmanager();
return module.exports.list_targets_with_avdmanager().catch(function (err) {
// If there's an error, like avdmanager could not be found, we can try
// as a last resort, to run `android`, in case this is a super old
// SDK installation.
if (err && (err.code === 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
return module.exports.list_targets_with_android();
} else throw err;
}).then(function (targets) {
if (targets.length === 0) {
+29 -36
View File
@@ -19,10 +19,10 @@
under the License.
*/
var Q = require('q'),
path = require('path'),
fs = require('fs'),
nopt = require('nopt');
var Q = require('q');
var path = require('path');
var fs = require('fs');
var nopt = require('nopt');
var Adb = require('./Adb');
@@ -35,7 +35,7 @@ function parseOpts(options, resolvedTarget, projectRoot) {
options = options || {};
options.argv = nopt({
gradle: Boolean,
ant: Boolean,
studio: Boolean,
prepenv: Boolean,
versionCode: String,
minSdkVersion: String,
@@ -47,24 +47,28 @@ function parseOpts(options, resolvedTarget, projectRoot) {
keystoreType: String
}, {}, options.argv, 0);
// Android Studio Build method is the default
var ret = {
buildType: options.release ? 'release' : 'debug',
buildMethod: process.env.ANDROID_BUILD || 'gradle',
buildMethod: process.env.ANDROID_BUILD || 'studio',
prepEnv: options.argv.prepenv,
arch: resolvedTarget && resolvedTarget.arch,
extraArgs: []
};
if (options.argv.ant || options.argv.gradle)
ret.buildMethod = options.argv.ant ? 'ant' : 'gradle';
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.versionCode) { ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); }
if (options.argv.minSdkVersion)
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion);
if (options.argv.minSdkVersion) { ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); }
if (options.argv.gradleArg) {
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
@@ -72,12 +76,10 @@ function parseOpts(options, resolvedTarget, projectRoot) {
var packageArgs = {};
if (options.argv.keystore)
packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore));
if (options.argv.keystore) { packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); }
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (flagName) {
if (options.argv[flagName])
packageArgs[flagName] = options.argv[flagName];
if (options.argv[flagName]) { packageArgs[flagName] = options.argv[flagName]; }
});
var buildConfig = options.buildConfig;
@@ -128,8 +130,7 @@ function parseOpts(options, resolvedTarget, projectRoot) {
module.exports.runClean = function (options) {
var opts = parseOpts(options, null, this.root);
var builder = builders.getBuilder(opts.buildMethod);
return builder.prepEnv(opts)
.then(function() {
return builder.prepEnv(opts).then(function () {
return builder.clean(opts);
});
};
@@ -148,15 +149,14 @@ module.exports.runClean = function(options) {
*/
module.exports.run = function (options, optResolvedTarget) {
var opts = parseOpts(options, optResolvedTarget, this.root);
console.log(opts.buildMethod);
var builder = builders.getBuilder(opts.buildMethod);
return builder.prepEnv(opts)
.then(function() {
return builder.prepEnv(opts).then(function () {
if (opts.prepEnv) {
events.emit('verbose', 'Build file successfully prepared.');
return;
}
return builder.build(opts)
.then(function() {
return builder.build(opts).then(function () {
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
return {
@@ -174,31 +174,24 @@ module.exports.run = function(options, optResolvedTarget) {
*/
module.exports.detectArchitecture = function (target) {
function helper () {
return Adb.shell(target, 'cat /proc/cpuinfo')
.then(function(output) {
return Adb.shell(target, 'cat /proc/cpuinfo').then(function (output) {
return /intel/i.exec(output) ? 'x86' : 'arm';
});
}
// It sometimes happens (at least on OS X), that this command will hang forever.
// To fix it, either unplug & replug device, or restart adb server.
return helper()
.timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.'))
.then(null, function(err) {
return helper().timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.')).then(null, function (err) {
if (/timed out/.exec('' + err)) {
// adb kill-server doesn't seem to do the trick.
// Could probably find a x-platform version of killall, but I'm not actually
// sure that this scenario even happens on non-OSX machines.
events.emit('verbose', 'adb timed out while detecting device/emulator architecture. Killing adb and trying again.');
return spawn('killall', ['adb'])
.then(function() {
return helper()
.then(null, function() {
return spawn('killall', ['adb']).then(function () {
return helper().then(null, function () {
// The double kill is sadly often necessary, at least on mac.
events.emit('warn', 'adb timed out a second time while detecting device/emulator architecture. Killing adb and trying again.');
return spawn('killall', ['adb'])
.then(function() {
return helper()
.then(null, function() {
return spawn('killall', ['adb']).then(function () {
return helper().then(null, function () {
return Q.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.'));
});
});
@@ -215,7 +208,7 @@ module.exports.detectArchitecture = function(target) {
module.exports.findBestApkForArchitecture = function (buildResults, arch) {
var paths = buildResults.apkPaths.filter(function (p) {
var apkName = path.basename(p);
if (buildResults.buildType == 'debug') {
if (buildResults.buildType === 'debug') {
return /-debug/.exec(apkName);
}
return !/-debug/.exec(apkName);
-156
View File
@@ -1,156 +0,0 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var Q = require('q');
var fs = require('fs');
var path = require('path');
var util = require('util');
var shell = require('shelljs');
var spawn = require('cordova-common').superspawn.spawn;
var CordovaError = require('cordova-common').CordovaError;
var check_reqs = require('../check_reqs');
var SIGNING_PROPERTIES = '-signing.properties';
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
var TEMPLATE =
'# This file is automatically generated.\n' +
'# Do not modify this file -- ' + MARKER + '\n';
var GenericBuilder = require('./GenericBuilder');
function AntBuilder (projectRoot) {
GenericBuilder.call(this, projectRoot);
this.binDirs = {ant: this.binDirs.ant};
}
util.inherits(AntBuilder, GenericBuilder);
AntBuilder.prototype.getArgs = function(cmd, opts) {
var args = [cmd, '-f', path.join(this.root, 'build.xml')];
// custom_rules.xml is required for incremental builds.
if (hasCustomRules(this.root)) {
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
}
if(opts.packageInfo) {
args.push('-propertyfile=' + path.join(this.root, opts.buildType + SIGNING_PROPERTIES));
}
return args;
};
AntBuilder.prototype.prepEnv = function(opts) {
var self = this;
return check_reqs.check_ant()
.then(function() {
// Copy in build.xml on each build so that:
// A) we don't require the Android SDK at project creation time, and
// B) we always use the SDK's latest version of it.
/*jshint -W069 */
var sdkDir = process.env['ANDROID_HOME'];
/*jshint +W069 */
var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8');
function writeBuildXml(projectPath) {
var newData = buildTemplate.replace('PROJECT_NAME', self.extractRealProjectNameFromManifest());
fs.writeFileSync(path.join(projectPath, 'build.xml'), newData);
if (!fs.existsSync(path.join(projectPath, 'local.properties'))) {
fs.writeFileSync(path.join(projectPath, 'local.properties'), TEMPLATE);
}
}
writeBuildXml(self.root);
var propertiesObj = self.readProjectProperties();
var subProjects = propertiesObj.libs;
for (var i = 0; i < subProjects.length; ++i) {
writeBuildXml(path.join(self.root, subProjects[i]));
}
if (propertiesObj.systemLibs.length > 0) {
throw new CordovaError('Project contains at least one plugin that requires a system library. This is not supported with ANT. Use gradle instead.');
}
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
var propertiesFilePath = path.join(self.root, propertiesFile);
if (opts.packageInfo) {
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
} else if(isAutoGenerated(propertiesFilePath)) {
shell.rm('-f', propertiesFilePath);
}
});
};
/*
* Builds the project with ant.
* Returns a promise.
*/
AntBuilder.prototype.build = function(opts) {
// Without our custom_rules.xml, we need to clean before building.
var ret = Q();
if (!hasCustomRules(this.root)) {
// clean will call check_ant() for us.
ret = this.clean(opts);
}
var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts);
return check_reqs.check_ant()
.then(function() {
return spawn('ant', args, {stdio: 'pipe'});
}).progress(function (stdio){
if (stdio.stderr) {
process.stderr.write(stdio.stderr);
} else {
process.stdout.write(stdio.stdout);
}
}).catch(function (error) {
if (error.toString().indexOf('Unable to resolve project target') >= 0) {
return check_reqs.check_android_target(error).then(function() {
// If due to some odd reason - check_android_target succeeds
// we should still fail here.
return Q.reject(error);
});
}
return Q.reject(error);
});
};
AntBuilder.prototype.clean = function(opts) {
var args = this.getArgs('clean', opts);
var self = this;
return check_reqs.check_ant()
.then(function() {
return spawn('ant', args, {stdio: 'inherit'});
})
.then(function () {
shell.rm('-rf', path.join(self.root, 'out'));
['debug', 'release'].forEach(function(config) {
var propertiesFilePath = path.join(self.root, config + SIGNING_PROPERTIES);
if(isAutoGenerated(propertiesFilePath)){
shell.rm('-f', propertiesFilePath);
}
});
});
};
module.exports = AntBuilder;
function hasCustomRules(projectRoot) {
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
}
function isAutoGenerated(file) {
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
}
+25 -48
View File
@@ -16,26 +16,23 @@
specific language governing permissions and limitations
under the License.
*/
/* eslint no-self-assign: 0 */
/* eslint no-unused-vars: 0 */
var Q = require('q');
var fs = require('fs');
var path = require('path');
var shell = require('shelljs');
var events = require('cordova-common').events;
var CordovaError = require('cordova-common').CordovaError;
function GenericBuilder (projectDir) {
this.root = projectDir || path.resolve(__dirname, '../../..');
this.binDirs = {
ant: path.join(this.root, hasCustomRules(this.root) ? 'ant-build' : 'bin'),
studio: path.join(this.root, 'app', 'build', 'outputs', 'apk'),
gradle: path.join(this.root, 'build', 'outputs', 'apk')
};
}
function hasCustomRules(projectRoot) {
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
}
GenericBuilder.prototype.prepEnv = function () {
return Q();
};
@@ -51,48 +48,23 @@ GenericBuilder.prototype.clean = function() {
GenericBuilder.prototype.findOutputApks = function (build_type, arch) {
var self = this;
return Object.keys(this.binDirs)
.reduce(function (result, builderName) {
return Object.keys(this.binDirs).reduce(function (result, builderName) {
var binDir = self.binDirs[builderName];
return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
}, [])
.sort(apkSorter);
};
GenericBuilder.prototype.readProjectProperties = function () {
function findAllUniq(data, r) {
var s = {};
var m;
while ((m = r.exec(data))) {
s[m[1]] = 1;
}
return Object.keys(s);
}
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
return {
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
};
};
GenericBuilder.prototype.extractRealProjectNameFromManifest = function () {
var manifestPath = path.join(this.root, 'AndroidManifest.xml');
var manifestData = fs.readFileSync(manifestPath, 'utf8');
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
if (!m) {
throw new CordovaError('Could not find package name in ' + manifestPath);
}
var packageName=m[1];
var lastDotIndex = packageName.lastIndexOf('.');
return packageName.substring(lastDotIndex + 1);
}, []).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)) {
@@ -101,7 +73,7 @@ function apkSorter(fileA, fileB) {
return -1;
}
var timeDiff = fs.statSync(fileA).mtime - fs.statSync(fileB).mtime;
var timeDiff = fs.statSync(fileB).mtime - fs.statSync(fileA).mtime;
return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
}
@@ -109,8 +81,14 @@ function findOutputApksHelper(dir, build_type, arch) {
var shellSilent = shell.config.silent;
shell.config.silent = true;
var ret = shell.ls(path.join(dir, '*.apk'))
.filter(function(candidate) {
// 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') {
@@ -120,8 +98,7 @@ function findOutputApksHelper(dir, build_type, arch) {
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
}
return true;
})
.sort(apkSorter);
}).sort(apkSorter);
shellSilent = shellSilent;
@@ -133,13 +110,13 @@ function findOutputApksHelper(dir, build_type, arch) {
// 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;
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 path.basename(p).indexOf('-' + arch) !== -1;
});
}
+90 -39
View File
@@ -22,7 +22,7 @@ var fs = require('fs');
var util = require('util');
var path = require('path');
var shell = require('shelljs');
var spawn = require('cordova-common').superspawn.spawn;
var superspawn = require('cordova-common').superspawn;
var CordovaError = require('cordova-common').CordovaError;
var check_reqs = require('../check_reqs');
@@ -43,9 +43,9 @@ function GradleBuilder (projectRoot) {
util.inherits(GradleBuilder, GenericBuilder);
GradleBuilder.prototype.getArgs = function (cmd, opts) {
if (cmd == 'release') {
if (cmd === 'release') {
cmd = 'cdvBuildRelease';
} else if (cmd == 'debug') {
} else if (cmd === 'debug') {
cmd = 'cdvBuildDebug';
}
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
@@ -69,16 +69,53 @@ GradleBuilder.prototype.getArgs = function(cmd, opts) {
* This returns a promise
*/
GradleBuilder.prototype.runGradleWrapper = function(gradle_cmd) {
GradleBuilder.prototype.runGradleWrapper = function (gradle_cmd, gradle_file) {
var gradlePath = path.join(this.root, 'gradlew');
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
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 spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], {stdio: 'inherit'});
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 () {
@@ -86,6 +123,9 @@ GradleBuilder.prototype.prepBuildFiles = function() {
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
@@ -96,19 +136,22 @@ GradleBuilder.prototype.prepBuildFiles = function() {
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') {
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';
if (realDir.indexOf(name + '-') !== -1) { str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n'; }
return str;
});
@@ -120,24 +163,27 @@ GradleBuilder.prototype.prepBuildFiles = function() {
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) {
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
depsList += '{\n exclude module:("CordovaLib")\n }\n';
}
else {
} else {
depsList += '\n';
}
};
subProjects.forEach(function (p) {
console.log('Subproject Path: ' + p);
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
depsList += ' debugCompile(project(path: "' + libName + '", configuration: "debug"))';
insertExclude(p);
depsList += ' releaseCompile(project(path: "' + libName + '", configuration: "release"))';
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:+'],
@@ -162,6 +208,9 @@ GradleBuilder.prototype.prepBuildFiles = function() {
}
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) {
@@ -173,8 +222,7 @@ GradleBuilder.prototype.prepBuildFiles = function() {
GradleBuilder.prototype.prepEnv = function (opts) {
var self = this;
return check_reqs.check_gradle()
.then(function(gradlePath) {
return check_reqs.check_gradle().then(function (gradlePath) {
return self.runGradleWrapper(gradlePath);
}).then(function () {
return self.prepBuildFiles();
@@ -199,7 +247,7 @@ GradleBuilder.prototype.prepEnv = function(opts) {
// 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-3.3-all.zip';
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);
@@ -221,26 +269,11 @@ GradleBuilder.prototype.prepEnv = function(opts) {
*/
GradleBuilder.prototype.build = function (opts) {
var wrapper = path.join(this.root, 'gradlew');
var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts);
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
return spawn(wrapper, args, {stdio: 'pipe'})
return superspawn.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);
}
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 () {
@@ -258,9 +291,8 @@ GradleBuilder.prototype.clean = function(opts) {
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 () {
return superspawn.spawn(wrapper, args, { stdio: 'inherit' });
}).then(function () {
shell.rm('-rf', path.join(builder.root, 'out'));
['debug', 'release'].forEach(function (config) {
@@ -274,6 +306,25 @@ GradleBuilder.prototype.clean = function(opts) {
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;
}
+302
View File
@@ -0,0 +1,302 @@
/*
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 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) {
console.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;
}
+2 -3
View File
@@ -20,8 +20,8 @@
var CordovaError = require('cordova-common').CordovaError;
var knownBuilders = {
ant: 'AntBuilder',
gradle: 'GradleBuilder',
studio: 'StudioBuilder',
none: 'GenericBuilder'
};
@@ -35,8 +35,7 @@ var knownBuilders = {
* @return {Builder} A builder instance for specified build type.
*/
module.exports.getBuilder = function (builderType, projectRoot) {
if (!knownBuilders[builderType])
throw new CordovaError('Builder ' + builderType + ' is not supported.');
if (!knownBuilders[builderType]) { throw new CordovaError('Builder ' + builderType + ' is not supported.'); }
try {
var Builder = require('./' + knownBuilders[builderType]);
+49 -49
View File
@@ -21,14 +21,14 @@
/* jshint sub:true */
var shelljs = require('shelljs'),
child_process = require('child_process'),
Q = require('q'),
path = require('path'),
fs = require('fs'),
os = require('os'),
REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'),
PROJECT_ROOT = path.join(__dirname, '..', '..');
var shelljs = require('shelljs');
var child_process = require('child_process');
var Q = require('q');
var path = require('path');
var fs = require('fs');
var os = require('os');
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
var PROJECT_ROOT = path.join(__dirname, '..', '..');
var CordovaError = require('cordova-common').CordovaError;
var superspawn = require('cordova-common').superspawn;
var android_sdk = require('./android_sdk');
@@ -53,11 +53,11 @@ function tryCommand(cmd, errMsg, catchStderr) {
}
module.exports.isWindows = function () {
return (os.platform() == 'win32');
return (os.platform() === 'win32');
};
module.exports.isDarwin = function () {
return (os.platform() == 'darwin');
return (os.platform() === 'darwin');
};
// Get valid target from framework/project.properties if run from this repo
@@ -84,12 +84,13 @@ module.exports.get_target = function() {
// Returns a promise. Called only by build and clean commands.
module.exports.check_ant = function () {
return superspawn.spawn('ant', ['-version'])
.then(function(output) {
return superspawn.spawn('ant', ['-version']).then(function (output) {
// Parse Ant version from command output
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
}).catch(function (err) {
if (err) {
throw new CordovaError('Failed to run `ant -version`. Make sure you have `ant` on your $PATH.');
}
});
};
@@ -98,16 +99,14 @@ module.exports.get_gradle_wrapper = function() {
var i = 0;
var foundStudio = false;
var program_dir;
if (module.exports.isDarwin()) {
program_dir = fs.readdirSync('/Applications');
while (i < program_dir.length && !foundStudio) {
if (program_dir[i].startsWith('Android Studio')) {
//TODO: Check for a specific Android Studio version, make sure it's not Canary
androidStudioPath = path.join('/Applications', program_dir[i], 'Contents', 'gradle');
foundStudio = true;
} else { ++i; }
}
} else if (module.exports.isWindows()) {
// OK, This hack only works on Windows, not on Mac OS or Linux. We will be deleting this eventually!
if (module.exports.isWindows()) {
var result = child_process.spawnSync(path.join(__dirname, 'getASPath.bat'));
// console.log('result.stdout =' + result.stdout.toString());
// console.log('result.stderr =' + result.stderr.toString());
if (result.stderr.toString().length > 0) {
var androidPath = path.join(process.env['ProgramFiles'], 'Android') + '/';
if (fs.existsSync(androidPath)) {
program_dir = fs.readdirSync(androidPath);
@@ -118,11 +117,17 @@ module.exports.get_gradle_wrapper = function() {
} else { ++i; }
}
}
} else {
// console.log('got android studio path from registry');
// remove the (os independent) new line char at the end of stdout
// add gradle to match the above.
androidStudioPath = path.join(result.stdout.toString().split('\r\n')[0], 'gradle');
}
}
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
var dirs = fs.readdirSync(androidStudioPath);
if(dirs[0].split('-')[0] == 'gradle') {
if (dirs[0].split('-')[0] === 'gradle') {
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
}
} else {
@@ -135,17 +140,17 @@ module.exports.get_gradle_wrapper = function() {
module.exports.check_gradle = function () {
var sdkDir = process.env['ANDROID_HOME'];
var d = Q.defer();
if (!sdkDir)
if (!sdkDir) {
return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
}
var gradlePath = module.exports.get_gradle_wrapper();
if (gradlePath.length !== 0)
d.resolve(gradlePath);
else
if (gradlePath.length !== 0) { d.resolve(gradlePath); } else {
d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
'or on your system to install the gradle wrapper. Please include gradle \n' +
'in your path, or install Android Studio'));
}
return d.promise;
};
@@ -163,13 +168,14 @@ module.exports.check_java = function() {
if (javacPath) {
// OS X has a command for finding JAVA_HOME.
var find_java = '/usr/libexec/java_home';
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting it manually.';
if (fs.existsSync(find_java)) {
return superspawn.spawn(find_java)
.then(function(stdout) {
return superspawn.spawn(find_java).then(function (stdout) {
process.env['JAVA_HOME'] = stdout.trim();
}).catch(function (err) {
if (err) {
throw new CordovaError(default_java_error_msg);
}
});
} else {
// See if we can derive it from javac's location.
@@ -209,8 +215,7 @@ module.exports.check_java = function() {
}
// We use tryCommand with catchStderr = true, because
// javac writes version info to stderr instead of stdout
return tryCommand('javac -version', msg, true)
.then(function (output) {
return tryCommand('javac -version', msg, true).then(function (output) {
// Let's check for at least Java 8, and keep it future proof so we can support Java 10
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
return match && match[1];
@@ -265,10 +270,10 @@ module.exports.check_android = function() {
if (androidCmdPath) {
parentDir = path.dirname(androidCmdPath);
grandParentDir = path.dirname(parentDir);
if (path.basename(parentDir) == 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
if (path.basename(parentDir) === 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
maybeSetAndroidHome(grandParentDir);
} else {
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
}
@@ -276,10 +281,10 @@ module.exports.check_android = function() {
if (adbInPath) {
parentDir = path.dirname(adbInPath);
grandParentDir = path.dirname(parentDir);
if (path.basename(parentDir) == 'platform-tools') {
if (path.basename(parentDir) === 'platform-tools') {
maybeSetAndroidHome(grandParentDir);
} else {
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
}
@@ -287,17 +292,17 @@ module.exports.check_android = function() {
if (avdmanagerInPath) {
parentDir = path.dirname(avdmanagerInPath);
grandParentDir = path.dirname(parentDir);
if (path.basename(parentDir) == 'bin' && path.basename(grandParentDir) == 'tools') {
if (path.basename(parentDir) === 'bin' && path.basename(grandParentDir) === 'tools') {
maybeSetAndroidHome(path.dirname(grandParentDir));
} else {
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
}
}
}
if (!process.env['ANDROID_HOME']) {
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
}
if (!fs.existsSync(process.env['ANDROID_HOME'])) {
@@ -337,8 +342,7 @@ module.exports.check_android_target = function(originalError) {
// Google Inc.:Google APIs:20
// Google Inc.:Glass Development Kit Preview:20
var desired_api_level = module.exports.get_target();
return android_sdk.list_targets()
.then(function(targets) {
return android_sdk.list_targets().then(function (targets) {
if (targets.indexOf(desired_api_level) >= 0) {
return targets;
}
@@ -358,8 +362,7 @@ 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) {
return Q.all([this.check_java(), this.check_android()]).then(function (values) {
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
@@ -373,7 +376,6 @@ module.exports.run = function() {
});
};
/**
* Object thar represents one of requirements for current platform.
* @param {String} id The unique identifier for this requirements.
@@ -387,7 +389,7 @@ var Requirement = function (id, name, version, installed) {
this.name = name;
this.installed = installed || false;
this.metadata = {
version: version,
version: version
};
};
@@ -417,15 +419,13 @@ module.exports.check_all = function() {
return checkFns.reduce(function (promise, checkFn, idx) {
// Update each requirement with results
var requirement = requirements[idx];
return promise.then(checkFn)
.then(function (version) {
return promise.then(checkFn).then(function (version) {
requirement.installed = true;
requirement.metadata.version = version;
}, function (err) {
requirement.metadata.reason = err instanceof Error ? err.message : err;
});
}, Q())
.then(function () {
}, Q()).then(function () {
// When chain is completed, return requirements array to upstream API
return requirements;
});
+12 -20
View File
@@ -19,8 +19,8 @@
under the License.
*/
var Q = require('q'),
build = require('./build');
var Q = require('q');
var build = require('./build');
var path = require('path');
var Adb = require('./Adb');
var AndroidManifest = require('./AndroidManifest');
@@ -33,14 +33,12 @@ var events = require('cordova-common').events;
* @param lookHarder When true, try restarting adb if no devices are found.
*/
module.exports.list = function (lookHarder) {
return Adb.devices()
.then(function(list) {
return Adb.devices().then(function (list) {
if (list.length === 0 && lookHarder) {
// adb kill-server doesn't seem to do the trick.
// Could probably find a x-platform version of killall, but I'm not actually
// sure that this scenario even happens on non-OSX machines.
return spawn('killall', ['adb'])
.then(function() {
return spawn('killall', ['adb']).then(function () {
events.emit('verbose', 'Restarting adb to see if more devices are detected.');
return Adb.devices();
}, function () {
@@ -53,8 +51,7 @@ module.exports.list = function(lookHarder) {
};
module.exports.resolveTarget = function (target) {
return this.list(true)
.then(function(device_list) {
return this.list(true).then(function (device_list) {
if (!device_list || !device_list.length) {
return Q.reject(new CordovaError('Failed to deploy to device, no devices found.'));
}
@@ -65,8 +62,7 @@ module.exports.resolveTarget = function(target) {
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
}
return build.detectArchitecture(target)
.then(function(arch) {
return build.detectArchitecture(target).then(function (arch) {
return { target: target, arch: arch, isEmulator: false };
});
});
@@ -79,36 +75,32 @@ module.exports.resolveTarget = function(target) {
*/
module.exports.install = function (target, buildResults) {
return Q().then(function () {
if (target && typeof target == 'object') {
if (target && typeof target === 'object') {
return target;
}
return module.exports.resolveTarget(target);
}).then(function (resolvedTarget) {
var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch);
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
var manifest = new AndroidManifest(path.join(__dirname, '../../app/src/main/AndroidManifest.xml'));
var pkgName = manifest.getPackageId();
var launchName = pkgName + '/.' + manifest.getActivity().getName();
events.emit('log', 'Using apk: ' + apk_path);
events.emit('log', 'Package name: ' + pkgName);
return Adb.install(resolvedTarget.target, apk_path, {replace: true})
.catch(function (error) {
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;
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
'installed app already signed with different key');
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
// or the app doesn't installed at all, so no error catching needed.
return Adb.uninstall(resolvedTarget.target, pkgName)
.then(function() {
return Adb.uninstall(resolvedTarget.target, pkgName).then(function () {
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
});
})
.then(function() {
}).then(function () {
// unlock screen
return Adb.shell(resolvedTarget.target, 'input keyevent 82');
}).then(function () {
+55 -64
View File
@@ -21,6 +21,7 @@
/* jshint sub:true */
var android_versions = require('android-versions');
var retry = require('./retry');
var build = require('./build');
var path = require('path');
@@ -55,8 +56,7 @@ function forgivingWhichSync(cmd) {
}
module.exports.list_images_using_avdmanager = function () {
return superspawn.spawn('avdmanager', ['list', 'avd'])
.then(function(output) {
return superspawn.spawn('avdmanager', ['list', 'avd']).then(function (output) {
var response = output.split('\n');
var emulator_list = [];
for (var i = 1; i < response.length; i++) {
@@ -116,8 +116,7 @@ module.exports.list_images_using_avdmanager = function () {
};
module.exports.list_images_using_android = function () {
return superspawn.spawn('android', ['list', 'avds'])
.then(function(output) {
return superspawn.spawn('android', ['list', 'avd']).then(function (output) {
var response = output.split('\n');
var emulator_list = [];
for (var i = 1; i < response.length; i++) {
@@ -171,25 +170,29 @@ module.exports.list_images_using_android = function() {
}
*/
module.exports.list_images = function () {
if (forgivingWhichSync('android')) {
return module.exports.list_images_using_android()
.catch(function(err) {
// try to use `avdmanager` in case `android` reports it is no longer available.
// this likely means the target machine is using a newer version of
// the android sdk, and possibly `avdmanager` is available.
if (err.code == 1 && err.stdout.indexOf('android command is no longer available')) {
return module.exports.list_images_using_avdmanager();
} else {
throw err;
}
});
} else if (forgivingWhichSync('avdmanager')) {
return Q.fcall(function () {
if (forgivingWhichSync('avdmanager')) {
return module.exports.list_images_using_avdmanager();
} else if (forgivingWhichSync('android')) {
return module.exports.list_images_using_android();
} else {
return Q().then(function () {
throw new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?');
});
}
}).then(function (avds) {
// In case we're missing the Android OS version string from the target description, add it.
return avds.map(function (avd) {
if (avd.target && avd.target.indexOf('Android API') > -1 && avd.target.indexOf('API level') < 0) {
var api_level = avd.target.match(/\d+/);
if (api_level) {
var level = android_versions.get(api_level);
avd.target = 'Android ' + level.semver + ' (API level ' + api_level + ')';
}
}
return avd;
});
});
};
/**
@@ -198,19 +201,18 @@ module.exports.list_images = function() {
* Returns a promise.
*/
module.exports.best_image = function () {
return this.list_images()
.then(function(images) {
return this.list_images().then(function (images) {
// Just return undefined if there is no images
if (images.length === 0) return;
var closest = 9999;
var best = images[0];
var project_target = check_reqs.get_target().replace('android-', '');
var project_target = parseInt(check_reqs.get_target().replace('android-', ''));
for (var i in images) {
var target = images[i].target;
if(target) {
var num = target.split('(API level ')[1].replace(')', '');
if (num == project_target) {
if (target && target.indexOf('API level') > -1) {
var num = parseInt(target.split('(API level ')[1].replace(')', ''));
if (num === project_target) {
return images[i];
} else if (project_target - num < closest && project_target > num) {
closest = project_target - num;
@@ -228,9 +230,9 @@ module.exports.list_started = function() {
};
// 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--) {
@@ -249,8 +251,7 @@ module.exports.list_targets = function() {
module.exports.get_available_port = function () {
var self = this;
return self.list_started()
.then(function (emulators) {
return self.list_started().then(function (emulators) {
for (var p = 5584; p >= 5554; p -= 2) {
if (emulators.indexOf('emulator-' + p) === -1) {
events.emit('verbose', 'Found available port: ' + p);
@@ -277,8 +278,7 @@ module.exports.start = function(emulator_ID, boot_timeout) {
return Q().then(function () {
if (emulator_ID) return Q(emulator_ID);
return self.best_image()
.then(function(best) {
return self.best_image().then(function (best) {
if (best && best.name) {
events.emit('warn', 'No emulator specified, defaulting to ' + best.name);
return best.name;
@@ -291,8 +291,7 @@ module.exports.start = function(emulator_ID, boot_timeout) {
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'));
});
}).then(function (emulatorId) {
return self.get_available_port()
.then(function (port) {
return self.get_available_port().then(function (port) {
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
// Workaround for https://code.google.com/p/android/issues/detail?id=235461
var emulator_dir = path.dirname(shelljs.which('emulator'));
@@ -307,18 +306,15 @@ module.exports.start = function(emulator_ID, boot_timeout) {
return self.wait_for_emulator(port);
});
}).then(function (emulatorId) {
if (!emulatorId)
return Q.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)...');
return self.wait_for_boot(emulatorId, boot_timeout)
.then(function(success) {
return self.wait_for_boot(emulatorId, boot_timeout).then(function (success) {
if (success) {
events.emit('log', 'BOOT COMPLETE');
// unlock screen
return Adb.shell(emulatorId, 'input keyevent 82')
.then(function() {
return Adb.shell(emulatorId, 'input keyevent 82').then(function () {
// return the new emulator id for the started emulators
return emulatorId;
});
@@ -338,16 +334,15 @@ module.exports.wait_for_emulator = function(port) {
var self = this;
return Q().then(function () {
var emulator_id = 'emulator-' + port;
return Adb.shell(emulator_id, 'getprop dev.bootcomplete')
.then(function (output) {
return Adb.shell(emulator_id, 'getprop dev.bootcomplete').then(function (output) {
if (output.indexOf('1') >= 0) {
return emulator_id;
}
return self.wait_for_emulator(port);
}, function (error) {
if (error && error.message &&
(error.message.indexOf('not found') > -1) ||
error.message.indexOf('device offline') > -1) {
if ((error && error.message &&
(error.message.indexOf('not found') > -1)) ||
(error.message.indexOf('device offline') > -1)) {
// emulator not yet started, continue waiting
return self.wait_for_emulator(port);
} else {
@@ -365,8 +360,7 @@ module.exports.wait_for_emulator = function(port) {
*/
module.exports.wait_for_boot = function (emulator_id, time_remaining) {
var self = this;
return Adb.shell(emulator_id, 'ps')
.then(function(output) {
return Adb.shell(emulator_id, 'ps').then(function (output) {
if (output.match(/android\.process\.acore/)) {
return true;
} else if (time_remaining === 0) {
@@ -391,16 +385,15 @@ module.exports.wait_for_boot = function(emulator_id, time_remaining) {
module.exports.create_image = function (name, target) {
console.log('Creating new avd named ' + name);
if (target) {
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', target])
.then(null, function(error) {
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', target]).then(null, function (error) {
console.error('ERROR : Failed to create emulator image : ');
console.error(' Do you have the latest android targets including ' + target + '?');
console.error(error);
});
} else {
console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]])
.then(function() {
// TODO: there's a more robust method for finding targets in android_sdk.js
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]]).then(function () {
// TODO: This seems like another error case, even though it always happens.
console.error('ERROR : Unable to create an avd emulator, no targets found.');
console.error('Ensure you have targets available by running the "android" command');
@@ -413,8 +406,7 @@ module.exports.create_image = function(name, target) {
};
module.exports.resolveTarget = function (target) {
return this.list_started()
.then(function(emulator_list) {
return this.list_started().then(function (emulator_list) {
if (emulator_list.length < 1) {
return Q.reject('No running Android emulators found, please start an emulator before deploying your project.');
}
@@ -425,8 +417,7 @@ module.exports.resolveTarget = function(target) {
return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
}
return build.detectArchitecture(target)
.then(function(arch) {
return build.detectArchitecture(target).then(function (arch) {
return {target: target, arch: arch, isEmulator: true};
});
});
@@ -441,12 +432,17 @@ module.exports.resolveTarget = function(target) {
module.exports.install = function (givenTarget, buildResults) {
var target;
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
// We need to find the proper path to the Android Manifest
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 Q().then(function () {
if (givenTarget && typeof givenTarget == 'object') {
if (givenTarget && typeof givenTarget === 'object') {
return givenTarget;
} else {
return module.exports.resolveTarget(givenTarget);
@@ -460,8 +456,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 Q.when()
.then(function() {
return Q.when().then(function () {
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
var execOptions = {
@@ -502,27 +497,23 @@ module.exports.install = function(givenTarget, buildResults) {
}
function installPromise () {
return adbInstallWithOptions(target.target, apk_path, execOptions)
.catch(function (error) {
return adbInstallWithOptions(target.target, apk_path, execOptions).catch(function (error) {
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
// is already installed on device was signed w/different certificate
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
throw error;
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
events.emit('warn', 'Uninstalling app from device and reinstalling it because the ' +
'currently installed app was signed with different key');
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
// or the app doesn't installed at all, so no error catching needed.
return Adb.uninstall(target.target, pkgName)
.then(function() {
return Adb.uninstall(target.target, pkgName).then(function () {
return adbInstallWithOptions(target.target, apk_path, execOptions);
});
});
}
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise)
.then(function (output) {
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise).then(function (output) {
events.emit('log', 'INSTALL SUCCESS');
});
});
+3
View File
@@ -0,0 +1,3 @@
@ECHO OFF
for /f "tokens=2*" %%a in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio" /v Path') do set "ASPath=%%~b"
ECHO %ASPath%
+1 -1
View File
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0install-device"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0install-emulator"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2
+1 -1
View File
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0list-devices"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0list-emulator-images"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-emulator-images' script in 'cordova\lib' folder, aborting...>&2
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0list-started-emulators"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2
+5 -5
View File
@@ -19,11 +19,11 @@
under the License.
*/
var path = require('path'),
os = require('os'),
Q = require('q'),
child_process = require('child_process'),
ROOT = path.join(__dirname, '..', '..');
var path = require('path');
var os = require('os');
var Q = require('q');
var child_process = require('child_process');
var ROOT = path.join(__dirname, '..', '..');
/*
* Starts running logcat in the shell.
@@ -20,8 +20,10 @@
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
url "https://maven.google.com"
}
}
// Switch the Android Gradle plugin version requirement depending on the
+29 -17
View File
@@ -1,7 +1,4 @@
/*
*
* Copyright 2013 Anis Kadri
*
* Licensed 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
@@ -33,8 +30,19 @@ var handlers = {
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) {
// If a Java file is using the new directory structure, don't penalize it
if (!obj.targetDir.includes('app/src/main')) {
if (obj.src.endsWith('.java')) {
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
} else if (obj.src.endsWith('.xml')) {
// We are making a huge assumption here that XML files will be going to res/xml or values/xml
dest = path.join('app/src/main', obj.targetDir, path.basename(obj.src));
}
}
}
if (options && options.force) {
@@ -71,10 +79,18 @@ var handlers = {
},
'resource-file': {
install: function (obj, plugin, project, options) {
copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), !!(options && options.link));
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) {
removeFile(project.projectDir, path.normalize(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);
}
},
'framework': {
@@ -95,9 +111,9 @@ var handlers = {
subDir = src;
}
if (obj.type == 'gradleReference') {
if (obj.type === 'gradleReference') {
project.addGradleReference(parentDir, subDir);
} else if (obj.type == 'sys') {
} else if (obj.type === 'sys') {
project.addSystemLibrary(parentDir, subDir);
} else {
project.addSubProject(parentDir, subDir);
@@ -125,9 +141,9 @@ var handlers = {
subDir = src;
}
if (obj.type == 'gradleReference') {
if (obj.type === 'gradleReference') {
project.removeGradleReference(parentDir, subDir);
} else if (obj.type == 'sys') {
} else if (obj.type === 'sys') {
project.removeSystemLibrary(parentDir, subDir);
} else {
project.removeSubProject(parentDir, subDir);
@@ -221,14 +237,12 @@ function copyFile (plugin_dir, src, project_dir, dest, link) {
// check that src path is inside plugin directory
var real_path = fs.realpathSync(src);
var real_plugin_path = fs.realpathSync(plugin_dir);
if (real_path.indexOf(real_plugin_path) !== 0)
throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"');
if (real_path.indexOf(real_plugin_path) !== 0) { throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"'); }
dest = path.resolve(project_dir, dest);
// check that dest path is located in project directory
if (dest.indexOf(project_dir) !== 0)
throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project');
if (dest.indexOf(project_dir) !== 0) { throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project'); }
shell.mkdir('-p', path.dirname(dest));
if (link) {
@@ -244,8 +258,7 @@ function copyFile (plugin_dir, src, project_dir, dest, link) {
// Same as copy file but throws error if target exists
function copyNewFile (plugin_dir, src, project_dir, dest, link) {
var target_path = path.resolve(project_dir, dest);
if (fs.existsSync(target_path))
throw new CordovaError('"' + target_path + '" already exists!');
if (fs.existsSync(target_path)) { throw new CordovaError('"' + target_path + '" already exists!'); }
copyFile(plugin_dir, src, project_dir, dest, !!link);
}
@@ -260,8 +273,7 @@ function symlinkFileOrDirTree(src, dest) {
fs.readdirSync(src).forEach(function (entry) {
symlinkFileOrDirTree(path.join(src, entry), path.join(dest, entry));
});
}
else {
} else {
fs.symlinkSync(path.relative(fs.realpathSync(path.dirname(dest)), src), dest);
}
}
+31 -22
View File
@@ -16,6 +16,7 @@
specific language governing permissions and limitations
under the License.
*/
/* eslint no-useless-escape: 0 */
var Q = require('q');
var fs = require('fs');
@@ -23,6 +24,7 @@ var path = require('path');
var shell = require('shelljs');
var events = require('cordova-common').events;
var AndroidManifest = require('./AndroidManifest');
var checkReqs = require('./check_reqs');
var xmlHelpers = require('cordova-common').xmlHelpers;
var CordovaError = require('cordova-common').CordovaError;
var ConfigParser = require('cordova-common').ConfigParser;
@@ -40,17 +42,14 @@ module.exports.prepare = function (cordovaProject, options) {
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
// Update own www dir with project's www assets and plugins' assets and js-files
return Q.when(updateWww(cordovaProject, this.locations))
.then(function () {
return Q.when(updateWww(cordovaProject, this.locations)).then(function () {
// update project according to config.xml changes.
return updateProjectAccordingTo(self._config, self.locations);
})
.then(function () {
}).then(function () {
updateIcons(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
updateSplashes(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
updateFileResources(cordovaProject, path.relative(cordovaProject.root, self.locations.root));
})
.then(function () {
}).then(function () {
events.emit('verbose', 'Prepared android project successfully');
});
};
@@ -169,17 +168,24 @@ function cleanWww(projectRoot, locations) {
*/
function updateProjectAccordingTo (platformConfig, locations) {
// Update app name by editing res/values/strings.xml
var name = platformConfig.name();
var strings = xmlHelpers.parseElementtreeSync(locations.strings);
var name = platformConfig.name();
strings.find('string[@name="app_name"]').text = name.replace(/\'/g, '\\\'');
var shortName = platformConfig.shortName && platformConfig.shortName();
if (shortName && shortName !== name) {
strings.find('string[@name="launcher_name"]').text = shortName.replace(/\'/g, '\\\'');
}
fs.writeFileSync(locations.strings, strings.write({indent: 4}), 'utf-8');
events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings);
// Java packages cannot support dashes
var pkg = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
var androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
var manifest = new AndroidManifest(locations.manifest);
var orig_pkg = manifest.getPackageId();
var manifestId = manifest.getPackageId();
manifest.getActivity()
.setOrientation(platformConfig.getPreference('orientation'))
@@ -187,13 +193,14 @@ function updateProjectAccordingTo(platformConfig, locations) {
manifest.setVersionName(platformConfig.version())
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
.setPackageId(pkg)
.setPackageId(androidPkgName)
.setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android'))
.setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android'))
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
.write();
var javaPattern = path.join(locations.root, 'src', orig_pkg.replace(/\./g, '/'), '*.java');
// Java file paths shouldn't be hard coded
var javaPattern = path.join(locations.javaSrc, manifestId.replace(/\./g, '/'), '*.java');
var java_files = shell.ls(javaPattern).filter(function (f) {
return shell.grep(/extends\s+CordovaActivity/g, f);
});
@@ -204,12 +211,16 @@ function updateProjectAccordingTo(platformConfig, locations) {
events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]);
}
var destFile = path.join(locations.root, 'src', pkg.replace(/\./g, '/'), path.basename(java_files[0]));
var destFile = path.join(locations.root, 'app', 'src', 'main', 'java', androidPkgName.replace(/\./g, '/'), path.basename(java_files[0]));
shell.mkdir('-p', path.dirname(destFile));
shell.sed(/package [\w\.]*;/, 'package ' + pkg + ';', java_files[0]).to(destFile);
events.emit('verbose', 'Wrote out Android package name "' + pkg + '" to ' + destFile);
shell.sed(/package [\w\.]*;/, 'package ' + androidPkgName + ';', java_files[0]).to(destFile);
events.emit('verbose', 'Wrote out Android package name "' + androidPkgName + '" to ' + destFile);
if (orig_pkg !== pkg) {
var removeOrigPkg = checkReqs.isWindows() || checkReqs.isDarwin() ?
manifestId.toUpperCase() !== androidPkgName.toUpperCase() :
manifestId !== androidPkgName;
if (removeOrigPkg) {
// If package was name changed we need to remove old java with main activity
shell.rm('-Rf', java_files[0]);
// remove any empty directories
@@ -270,7 +281,7 @@ function updateSplashes(cordovaProject, platformResourcesDir) {
if (!resource.density) {
return;
}
if (resource.density == 'mdpi') {
if (resource.density === 'mdpi') {
hadMdpi = true;
}
var targetPath = getImageResourcePath(
@@ -395,15 +406,13 @@ function cleanIcons(projectRoot, projectConfig, platformResourcesDir) {
*/
function mapImageResources (rootDir, subDir, type, resourceName) {
var pathMap = {};
shell.ls(path.join(rootDir, subDir, type + '-*'))
.forEach(function (drawableFolder) {
shell.ls(path.join(rootDir, subDir, type + '-*')).forEach(function (drawableFolder) {
var imagePath = path.join(subDir, path.basename(drawableFolder), resourceName);
pathMap[imagePath] = null;
});
return pathMap;
}
function updateFileResources (cordovaProject, platformDir) {
var files = cordovaProject.projectConfig.getFileResources('android');
@@ -424,9 +433,8 @@ function updateFileResources(cordovaProject, platformDir) {
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
}
function cleanFileResources (projectRoot, projectConfig, platformDir) {
var files = projectConfig.getFileResources('android');
var files = projectConfig.getFileResources('android', true);
if (files.length > 0) {
events.emit('verbose', 'Cleaning resource files at ' + platformDir);
@@ -437,7 +445,8 @@ function cleanFileResources(projectRoot, projectConfig, platformDir) {
});
FileUpdater.updatePaths(
resourceMap, { rootDir: projectRoot, all: true}, logFileOp);
resourceMap, {
rootDir: projectRoot, all: true}, logFileOp);
}
}
+18 -27
View File
@@ -21,12 +21,12 @@
/* jshint loopfunc:true */
var path = require('path'),
build = require('./build'),
emulator = require('./emulator'),
device = require('./device'),
Q = require('q'),
events = require('cordova-common').events;
var path = require('path');
var build = require('./build');
var emulator = require('./emulator');
var device = require('./device');
var Q = require('q');
var events = require('cordova-common').events;
function getInstallTarget (runOptions) {
var install_target;
@@ -56,12 +56,10 @@ function getInstallTarget(runOptions) {
var self = this;
var install_target = getInstallTarget(runOptions);
return Q()
.then(function() {
return Q().then(function () {
if (!install_target) {
// no target given, deploy to device if available, otherwise use the emulator.
return device.list()
.then(function(device_list) {
return device.list().then(function (device_list) {
if (device_list.length > 0) {
events.emit('warn', 'No target specified, deploying to device \'' + device_list[0] + '\'.');
install_target = device_list[0];
@@ -72,35 +70,30 @@ function getInstallTarget(runOptions) {
});
}
}).then(function () {
if (install_target == '--device') {
if (install_target === '--device') {
return device.resolveTarget(null);
} else if (install_target == '--emulator') {
} else if (install_target === '--emulator') {
// Give preference to any already started emulators. Else, start one.
return emulator.list_started()
.then(function(started) {
return emulator.list_started().then(function (started) {
return started && started.length > 0 ? started[0] : emulator.start();
}).then(function (emulatorId) {
return emulator.resolveTarget(emulatorId);
});
}
// They specified a specific device/emulator ID.
return device.list()
.then(function(devices) {
return device.list().then(function (devices) {
if (devices.indexOf(install_target) > -1) {
return device.resolveTarget(install_target);
}
return emulator.list_started()
.then(function(started_emulators) {
return emulator.list_started().then(function (started_emulators) {
if (started_emulators.indexOf(install_target) > -1) {
return emulator.resolveTarget(install_target);
}
return emulator.list_images()
.then(function(avds) {
return emulator.list_images().then(function (avds) {
// if target emulator isn't started, then start it.
for (var avd in avds) {
if (avds[avd].name == install_target) {
return emulator.start(install_target)
.then(function(emulatorId) {
if (avds[avd].name === install_target) {
return emulator.start(install_target).then(function (emulatorId) {
return emulator.resolveTarget(emulatorId);
});
}
@@ -114,11 +107,9 @@ function getInstallTarget(runOptions) {
// 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) {
return build.run.call(self, runOptions, resolvedTarget).then(function (buildResults) {
if (resolvedTarget.isEmulator) {
return emulator.wait_for_boot(resolvedTarget.target)
.then(function () {
return emulator.wait_for_boot(resolvedTarget.target).then(function () {
return emulator.install(resolvedTarget, buildResults);
});
}
+1 -1
View File
@@ -18,7 +18,7 @@
@ECHO OFF
SET script_path="%~dp0start-emulator"
IF EXIST %script_path% (
node "%script_path%" %*
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2
+1 -1
View File
@@ -20,7 +20,7 @@
*/
// Coho updates this line:
var VERSION = "6.2.0-dev";
var VERSION = "7.0.0";
module.exports.version = VERSION;
+324
View File
@@ -0,0 +1,324 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
apply plugin: 'com.android.application'
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
url "https://maven.google.com"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
}
}
// Allow plugins to declare Maven dependencies via build-extras.gradle.
allprojects {
repositories {
mavenCentral();
jcenter()
}
}
task wrapper(type: Wrapper) {
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;
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = null;
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = null
}
// Whether to append a 0 "abi digit" to versionCode when only a single APK is build
if (!project.hasProperty('cdvVersionCodeForceAbiDigit')) {
cdvVersionCodeForceAbiDigit = null
}
// .properties files to use for release signing.
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
cdvReleaseSigningPropertiesFile = null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
cdvDebugSigningPropertiesFile = null
}
// Set by build.js script.
if (!project.hasProperty('cdvBuildArch')) {
cdvBuildArch = null
}
// Plugin gradle extensions can append to this to have code run at the end.
cdvPluginPostBuildExtras = []
}
// PLUGIN GRADLE EXTENSIONS START
// PLUGIN GRADLE EXTENSIONS END
def hasBuildExtras = file('build-extras.gradle').exists()
if (hasBuildExtras) {
apply from: 'build-extras.gradle'
}
// Set property defaults after extension .gradle files.
if (ext.cdvCompileSdkVersion == null) {
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
//ext.cdvCompileSdkVersion = project.ext.defaultCompileSdkVersion
}
if (ext.cdvBuildToolsVersion == null) {
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
//ext.cdvBuildToolsVersion = project.ext.defaultBuildToolsVersion
}
if (ext.cdvDebugSigningPropertiesFile == null && file('../debug-signing.properties').exists()) {
ext.cdvDebugSigningPropertiesFile = '../debug-signing.properties'
}
if (ext.cdvReleaseSigningPropertiesFile == null && file('../release-signing.properties').exists()) {
ext.cdvReleaseSigningPropertiesFile = '../release-signing.properties'
}
// Cast to appropriate types.
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : defaultMinSdkVersion
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
def computeBuildTargetName(debugBuild) {
def ret = 'assemble'
if (cdvBuildMultipleApks && cdvBuildArch) {
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
}
return ret + (debugBuild ? 'Debug' : 'Release')
}
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
task cdvBuildDebug
cdvBuildDebug.dependsOn {
return computeBuildTargetName(true)
}
task cdvBuildRelease
cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}
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")
if (cdvMinSdkVersion != null) {
minSdkVersion cdvMinSdkVersion
}
}
lintOptions {
abortOnError false;
}
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
//This code exists for Crosswalk and other Native APIs.
//By default, we multiply the existing version code in the Android Manifest by 10 and
//add a number for each architecture. If you are not using Crosswalk or SQLite, you can
//ignore this chunk of code, and your version codes will be respected.
if (Boolean.valueOf(cdvBuildMultipleApks)) {
flavorDimensions "default"
productFlavors {
armeabi {
versionCode defaultConfig.versionCode*10 + 1
ndk {
abiFilters = ["armeabi"]
}
}
armv7 {
versionCode defaultConfig.versionCode*10 + 2
ndk {
abiFilters = ["armeabi-v7a"]
}
}
arm64 {
versionCode defaultConfig.versionCode*10 + 3
ndk {
abiFilters = ["arm64-v8a"]
}
}
x86 {
versionCode defaultConfig.versionCode*10 + 4
ndk {
abiFilters = ["x86"]
}
}
x86_64 {
versionCode defaultConfig.versionCode*10 + 5
ndk {
abiFilters = ["x86_64"]
}
}
}
} else if (Boolean.valueOf(cdvVersionCodeForceAbiDigit)) {
// This provides compatibility to the default logic for versionCode before cordova-android 5.2.0
defaultConfig {
versionCode defaultConfig.versionCode*10
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
if (cdvReleaseSigningPropertiesFile) {
signingConfigs {
release {
// These must be set or Gradle will complain (even if they are overridden).
keyAlias = ""
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
storeFile = null
storePassword = "__unset"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (cdvDebugSigningPropertiesFile) {
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}
}
/*
* WARNING: Cordova Lib and platform scripts do management inside of this code here,
* if you are adding the dependencies manually, do so outside the comments, otherwise
* the Cordova tools will overwrite them
*/
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
debugCompile(project(path: ":CordovaLib", configuration: "debug"))
releaseCompile(project(path: ":CordovaLib", configuration: "release"))
// SUB-PROJECT DEPENDENCIES END
}
def promptForReleaseKeyPassword() {
if (!cdvReleaseSigningPropertiesFile) {
return;
}
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
}
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
}
}
gradle.taskGraph.whenReady { taskGraph ->
taskGraph.getAllTasks().each() { task ->
if(['validateReleaseSigning', 'validateSigningRelease', 'validateSigningArmv7Release', 'validateSigningX76Release'].contains(task.name)) {
promptForReleaseKeyPassword()
}
}
}
def addSigningProps(propsFilePath, signingConfig) {
def propsFile = file(propsFilePath)
def props = new Properties()
propsFile.withReader { reader ->
props.load(reader)
}
def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
if (!storeFile.isAbsolute()) {
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
}
if (!storeFile.exists()) {
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
}
signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))
signingConfig.storeFile = storeFile
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
def storeType = props.get('storeType', props.get('key.store.type', ''))
if (!storeType) {
def filename = storeFile.getName().toLowerCase();
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
storeType = 'pkcs12'
} else {
storeType = signingConfig.storeType // "jks"
}
}
signingConfig.storeType = storeType
}
for (def func : cdvPluginPostBuildExtras) {
func()
}
// This can be defined within build-extras.gradle as:
// ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
+121 -141
View File
@@ -1,5 +1,5 @@
// Platform: android
// 7c5fcc5a5adfbf3fb8ceaf36fbdd4bd970bd9c20
// 4450a4cea50616e080a82e8ede9e3d6a1fe3c3ec
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,31 +19,29 @@
under the License.
*/
;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '6.2.0-dev';
var PLATFORM_VERSION_BUILD_LABEL = '7.0.0';
// file: src/scripts/require.js
/* jshint -W079 */
/* jshint -W020 */
var require,
define;
var require;
var define;
(function () {
var modules = {},
var modules = {};
// Stack of moduleIds currently being built.
requireStack = [],
var requireStack = [];
// Map of module ID -> index into requireStack of modules currently being built.
inProgressModules = {},
SEPARATOR = ".";
var inProgressModules = {};
var SEPARATOR = '.';
function build (module) {
var factory = module.factory,
localRequire = function (id) {
var factory = module.factory;
var localRequire = function (id) {
var resultantId = id;
// Its a relative path, so lop off the last portion and add the id (minus "./")
if (id.charAt(0) === ".") {
if (id.charAt(0) === '.') {
resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2);
}
return require(resultantId);
@@ -56,10 +54,10 @@ var require,
require = function (id) {
if (!modules[id]) {
throw "module " + id + " not found";
throw 'module ' + id + ' not found';
} else if (id in inProgressModules) {
var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
throw "Cycle in require graph: " + cycle;
throw 'Cycle in require graph: ' + cycle;
}
if (modules[id].factory) {
try {
@@ -76,7 +74,7 @@ var require,
define = function (id, factory) {
if (modules[id]) {
throw "module " + id + " already defined";
throw 'module ' + id + ' already defined';
}
modules[id] = {
@@ -93,7 +91,7 @@ var require,
})();
// Export for use in node
if (typeof module === "object" && typeof require === "function") {
if (typeof module === 'object' && typeof require === 'function') {
module.exports.require = require;
module.exports.define = define;
}
@@ -103,15 +101,13 @@ define("cordova", function(require, exports, module) {
// Workaround for Windows 10 in hosted environment case
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
throw new Error("cordova already defined");
if (window.cordova && !(window.cordova instanceof HTMLElement)) { // eslint-disable-line no-undef
throw new Error('cordova already defined');
}
var channel = require('cordova/channel');
var platform = require('cordova/platform');
/**
* Intercept calls to addEventListener + removeEventListener and handle deviceready,
* resume, and pause events.
@@ -124,12 +120,12 @@ var m_window_removeEventListener = window.removeEventListener;
/**
* Houses custom event handlers to intercept on document + window event listeners.
*/
var documentEventHandlers = {},
windowEventHandlers = {};
var documentEventHandlers = {};
var windowEventHandlers = {};
document.addEventListener = function (evt, handler, capture) {
var e = evt.toLowerCase();
if (typeof documentEventHandlers[e] != 'undefined') {
if (typeof documentEventHandlers[e] !== 'undefined') {
documentEventHandlers[e].subscribe(handler);
} else {
m_document_addEventListener.call(document, evt, handler, capture);
@@ -138,7 +134,7 @@ document.addEventListener = function(evt, handler, capture) {
window.addEventListener = function (evt, handler, capture) {
var e = evt.toLowerCase();
if (typeof windowEventHandlers[e] != 'undefined') {
if (typeof windowEventHandlers[e] !== 'undefined') {
windowEventHandlers[e].subscribe(handler);
} else {
m_window_addEventListener.call(window, evt, handler, capture);
@@ -148,7 +144,7 @@ window.addEventListener = function(evt, handler, capture) {
document.removeEventListener = function (evt, handler, capture) {
var e = evt.toLowerCase();
// If unsubscribing from an event that is handled by a plugin
if (typeof documentEventHandlers[e] != "undefined") {
if (typeof documentEventHandlers[e] !== 'undefined') {
documentEventHandlers[e].unsubscribe(handler);
} else {
m_document_removeEventListener.call(document, evt, handler, capture);
@@ -158,7 +154,7 @@ document.removeEventListener = function(evt, handler, capture) {
window.removeEventListener = function (evt, handler, capture) {
var e = evt.toLowerCase();
// If unsubscribing from an event that is handled by a plugin
if (typeof windowEventHandlers[e] != "undefined") {
if (typeof windowEventHandlers[e] !== 'undefined') {
windowEventHandlers[e].unsubscribe(handler);
} else {
m_window_removeEventListener.call(window, evt, handler, capture);
@@ -178,13 +174,16 @@ function createEvent(type, data) {
return event;
}
/* eslint-disable no-undef */
var cordova = {
define: define,
require: require,
version: PLATFORM_VERSION_BUILD_LABEL,
platformVersion: PLATFORM_VERSION_BUILD_LABEL,
platformId: platform.id,
/* eslint-enable no-undef */
/**
* Methods to add/remove your own addEventListener hijacking on document + window.
*/
@@ -218,14 +217,13 @@ var cordova = {
*/
fireDocumentEvent: function (type, data, bNoDetach) {
var evt = createEvent(type, data);
if (typeof documentEventHandlers[type] != 'undefined') {
if (typeof documentEventHandlers[type] !== 'undefined') {
if (bNoDetach) {
documentEventHandlers[type].fire(evt);
}
else {
} else {
setTimeout(function () {
// Fire deviceready on listeners that were registered before cordova.js was loaded.
if (type == 'deviceready') {
if (type === 'deviceready') {
document.dispatchEvent(evt);
}
documentEventHandlers[type].fire(evt);
@@ -237,7 +235,7 @@ var cordova = {
},
fireWindowEvent: function (type, data) {
var evt = createEvent(type, data);
if (typeof windowEventHandlers[type] != 'undefined') {
if (typeof windowEventHandlers[type] !== 'undefined') {
setTimeout(function () {
windowEventHandlers[type].fire(evt);
}, 0);
@@ -289,7 +287,7 @@ var cordova = {
try {
var callback = cordova.callbacks[callbackId];
if (callback) {
if (isSuccess && status == cordova.callbackStatus.OK) {
if (isSuccess && status === cordova.callbackStatus.OK) {
callback.success && callback.success.apply(null, args);
} else if (!isSuccess) {
callback.fail && callback.fail.apply(null, args);
@@ -306,11 +304,10 @@ var cordova = {
delete cordova.callbacks[callbackId];
}
}
}
catch (err) {
var msg = "Error in " + (isSuccess ? "Success" : "Error") + " callbackId: " + callbackId + " : " + err;
} catch (err) {
var msg = 'Error in ' + (isSuccess ? 'Success' : 'Error') + ' callbackId: ' + callbackId + ' : ' + err;
console && console.log && console.log(msg);
cordova.fireWindowEvent("cordovacallbackerror", { 'message': msg });
cordova.fireWindowEvent('cordovacallbackerror', { 'message': msg });
throw err;
}
},
@@ -319,18 +316,17 @@ var cordova = {
try {
func();
} catch (e) {
console.log("Failed to run constructor: " + e);
console.log('Failed to run constructor: ' + e);
}
});
}
};
module.exports = cordova;
});
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
define("cordova/android/nativeapiprovider", function(require, exports, module) {
/**
@@ -353,7 +349,7 @@ module.exports = {
});
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
define("cordova/android/promptbasednativeapi", function(require, exports, module) {
/**
@@ -402,18 +398,18 @@ function checkArgs(spec, functionName, args, opt_callee) {
var errMsg = null;
var typeName;
for (var i = 0; i < spec.length; ++i) {
var c = spec.charAt(i),
cUpper = c.toUpperCase(),
arg = args[i];
var c = spec.charAt(i);
var cUpper = c.toUpperCase();
var arg = args[i];
// Asterix means allow anything.
if (c == '*') {
if (c === '*') {
continue;
}
typeName = utils.typeName(arg);
if ((arg === null || arg === undefined) && c == cUpper) {
if ((arg === null || arg === undefined) && c === cUpper) {
continue;
}
if (typeName != typeMap[cUpper]) {
if (typeName !== typeMap[cUpper]) {
errMsg = 'Expected ' + typeMap[cUpper];
break;
}
@@ -422,7 +418,7 @@ function checkArgs(spec, functionName, args, opt_callee) {
errMsg += ', but got ' + typeName + '.';
errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
// Don't log when running unit tests.
if (typeof jasmine == 'undefined') {
if (typeof jasmine === 'undefined') {
console.error(errMsg);
}
throw TypeError(errMsg);
@@ -437,7 +433,6 @@ moduleExports.checkArgs = checkArgs;
moduleExports.getValue = getValue;
moduleExports.enableChecks = true;
});
// file: src/common/base64.js
@@ -451,7 +446,7 @@ base64.fromArrayBuffer = function(arrayBuffer) {
};
base64.toArrayBuffer = function (str) {
var decodedStr = typeof atob != 'undefined' ? atob(str) : new Buffer(str,'base64').toString('binary');
var decodedStr = typeof atob !== 'undefined' ? atob(str) : Buffer.from(str, 'base64').toString('binary'); // eslint-disable-line no-undef
var arrayBuffer = new ArrayBuffer(decodedStr.length);
var array = new Uint8Array(arrayBuffer);
for (var i = 0, len = decodedStr.length; i < len; i++) {
@@ -467,7 +462,7 @@ base64.toArrayBuffer = function(str) {
* platforms tested.
*/
var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64_6bit = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var b64_12bit;
var b64_12bitTable = function () {
@@ -483,7 +478,7 @@ var b64_12bitTable = function() {
function uint8ToBase64 (rawData) {
var numBytes = rawData.byteLength;
var output="";
var output = '';
var segment;
var table = b64_12bitTable();
for (var i = 0; i < numBytes - 2; i += 3) {
@@ -491,12 +486,12 @@ function uint8ToBase64(rawData) {
output += table[segment >> 12];
output += table[segment & 0xfff];
}
if (numBytes - i == 2) {
if (numBytes - i === 2) {
segment = (rawData[i] << 16) + (rawData[i + 1] << 8);
output += table[segment >> 12];
output += b64_6bit[(segment & 0xfff) >> 6];
output += '=';
} else if (numBytes - i == 1) {
} else if (numBytes - i === 1) {
segment = (rawData[i] << 16);
output += table[segment >> 12];
output += '==';
@@ -568,7 +563,7 @@ function include(parent, objects, clobber, merge) {
result = parent[key];
} else {
// Overwrite if not currently defined.
if (typeof parent[key] == 'undefined') {
if (typeof parent[key] === 'undefined') {
assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
} else {
// Set result to what already exists, so we can build children into it if they exist.
@@ -627,8 +622,8 @@ exports.replaceHookForTesting = function() {};
// file: src/common/channel.js
define("cordova/channel", function(require, exports, module) {
var utils = require('cordova/utils'),
nextGuid = 1;
var utils = require('cordova/utils');
var nextGuid = 1;
/**
* Custom pub-sub "channel" that can have functions subscribed to it
@@ -681,16 +676,16 @@ var Channel = function(type, sticky) {
// Function that is called when the first listener is subscribed, or when
// the last listener is unsubscribed.
this.onHasSubscribersChange = null;
},
channel = {
};
var channel = {
/**
* Calls the provided function only after all of the channels specified
* have been fired. All channels must be sticky channels.
*/
join: function (h, c) {
var len = c.length,
i = len,
f = function() {
var len = c.length;
var i = len;
var f = function () {
if (!(--i)) h();
};
for (var j = 0; j < len; j++) {
@@ -701,13 +696,14 @@ var Channel = function(type, sticky) {
}
if (!len) h();
},
/* eslint-disable no-return-assign */
create: function (type) {
return channel[type] = new Channel(type, false);
},
createSticky: function (type) {
return channel[type] = new Channel(type, true);
},
/* eslint-enable no-return-assign */
/**
* cordova Channels that must fire before "deviceready" is fired.
*/
@@ -743,10 +739,10 @@ var Channel = function(type, sticky) {
};
function checkSubscriptionArgument (argument) {
if (typeof argument !== "function" && typeof argument.handleEvent !== "function") {
if (typeof argument !== 'function' && typeof argument.handleEvent !== 'function') {
throw new Error(
"Must provide a function or an EventListener object " +
"implementing the handleEvent interface."
'Must provide a function or an EventListener object ' +
'implementing the handleEvent interface.'
);
}
}
@@ -762,7 +758,7 @@ Channel.prototype.subscribe = function(eventListenerOrFunction, eventListener) {
checkSubscriptionArgument(eventListenerOrFunction);
var handleEvent, guid;
if (eventListenerOrFunction && typeof eventListenerOrFunction === "object") {
if (eventListenerOrFunction && typeof eventListenerOrFunction === 'object') {
// Received an EventListener object implementing the handleEvent interface
handleEvent = eventListenerOrFunction.handleEvent;
eventListener = eventListenerOrFunction;
@@ -771,13 +767,13 @@ Channel.prototype.subscribe = function(eventListenerOrFunction, eventListener) {
handleEvent = eventListenerOrFunction;
}
if (this.state == 2) {
if (this.state === 2) {
handleEvent.apply(eventListener || this, this.fireArgs);
return;
}
guid = eventListenerOrFunction.observer_guid;
if (typeof eventListener === "object") {
if (typeof eventListener === 'object') {
handleEvent = utils.close(eventListener, handleEvent);
}
@@ -792,7 +788,7 @@ Channel.prototype.subscribe = function(eventListenerOrFunction, eventListener) {
if (!this.handlers[guid]) {
this.handlers[guid] = handleEvent;
this.numHandlers++;
if (this.numHandlers == 1) {
if (this.numHandlers === 1) {
this.onHasSubscribersChange && this.onHasSubscribersChange();
}
}
@@ -805,7 +801,7 @@ Channel.prototype.unsubscribe = function(eventListenerOrFunction) {
checkSubscriptionArgument(eventListenerOrFunction);
var handleEvent, guid, handler;
if (eventListenerOrFunction && typeof eventListenerOrFunction === "object") {
if (eventListenerOrFunction && typeof eventListenerOrFunction === 'object') {
// Received an EventListener object implementing the handleEvent interface
handleEvent = eventListenerOrFunction.handleEvent;
} else {
@@ -828,10 +824,10 @@ Channel.prototype.unsubscribe = function(eventListenerOrFunction) {
* Calls all functions subscribed to this channel.
*/
Channel.prototype.fire = function (e) {
var fail = false,
fireArgs = Array.prototype.slice.call(arguments);
var fail = false; // eslint-disable-line no-unused-vars
var fireArgs = Array.prototype.slice.call(arguments);
// Apply stickiness.
if (this.state == 1) {
if (this.state === 1) {
this.state = 2;
this.fireArgs = fireArgs;
}
@@ -845,7 +841,7 @@ Channel.prototype.fire = function(e) {
for (var i = 0; i < toCall.length; ++i) {
toCall[i].apply(this, fireArgs);
}
if (this.state == 2 && this.numHandlers) {
if (this.state === 2 && this.numHandlers) {
this.numHandlers = 0;
this.handlers = {};
this.onHasSubscribersChange && this.onHasSubscribersChange();
@@ -853,7 +849,6 @@ Channel.prototype.fire = function(e) {
}
};
// defining them here so they are ready super fast!
// DOM event that is received when the web page is loaded and parsed.
channel.createSticky('onDOMContentLoaded');
@@ -886,7 +881,7 @@ module.exports = channel;
});
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/exec.js
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) {
/**
@@ -1171,7 +1166,6 @@ module.exports = androidExec;
// file: src/common/exec/proxy.js
define("cordova/exec/proxy", function(require, exports, module) {
// internal map of proxy function
var CommandProxyMap = {};
@@ -1179,7 +1173,7 @@ module.exports = {
// example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
add: function (id, proxyObj) {
console.log("adding proxy for " + id);
console.log('adding proxy for ' + id);
CommandProxyMap[id] = proxyObj;
return proxyObj;
},
@@ -1196,6 +1190,7 @@ module.exports = {
return (CommandProxyMap[service] ? CommandProxyMap[service][action] : null);
}
};
});
// file: src/common/init.js
@@ -1212,14 +1207,14 @@ var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
function logUnfiredChannels (arr) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i].state != 2) {
if (arr[i].state !== 2) {
console.log('Channel not fired: ' + arr[i].type);
}
}
}
window.setTimeout(function () {
if (channel.onDeviceReady.state != 2) {
if (channel.onDeviceReady.state !== 2) {
console.log('deviceready has not fired after 5 seconds.');
logUnfiredChannels(platformInitChannelsArray);
logUnfiredChannels(channel.deviceReadyChannelsArray);
@@ -1236,10 +1231,9 @@ function replaceNavigator(origNavigator) {
// Without it, APIs such as getGamepads() break.
if (CordovaNavigator.bind) {
for (var key in origNavigator) {
if (typeof origNavigator[key] == 'function') {
if (typeof origNavigator[key] === 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
}
else {
} else {
(function (k) {
utils.defineGetterSetter(newNavigator, key, function () {
return origNavigator[k];
@@ -1262,7 +1256,7 @@ if (!window.console) {
}
if (!window.console.warn) {
window.console.warn = function (msg) {
this.log("warn: " + msg);
this.log('warn: ' + msg);
};
}
@@ -1273,7 +1267,7 @@ 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') {
if (document.readyState === 'complete' || document.readyState === 'interactive') {
channel.onDOMContentLoaded.fire();
} else {
document.addEventListener('DOMContentLoaded', function () {
@@ -1323,7 +1317,6 @@ channel.join(function() {
}, platformInitChannelsArray);
});
// file: src/common/init_b.js
@@ -1343,14 +1336,14 @@ cordova.exec = require('cordova/exec');
function logUnfiredChannels (arr) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i].state != 2) {
if (arr[i].state !== 2) {
console.log('Channel not fired: ' + arr[i].type);
}
}
}
window.setTimeout(function () {
if (channel.onDeviceReady.state != 2) {
if (channel.onDeviceReady.state !== 2) {
console.log('deviceready has not fired after 5 seconds.');
logUnfiredChannels(platformInitChannelsArray);
logUnfiredChannels(channel.deviceReadyChannelsArray);
@@ -1367,10 +1360,9 @@ function replaceNavigator(origNavigator) {
// Without it, APIs such as getGamepads() break.
if (CordovaNavigator.bind) {
for (var key in origNavigator) {
if (typeof origNavigator[key] == 'function') {
if (typeof origNavigator[key] === 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
}
else {
} else {
(function (k) {
utils.defineGetterSetter(newNavigator, key, function () {
return origNavigator[k];
@@ -1392,7 +1384,7 @@ if (!window.console) {
}
if (!window.console.warn) {
window.console.warn = function (msg) {
this.log("warn: " + msg);
this.log('warn: ' + msg);
};
}
@@ -1403,7 +1395,7 @@ 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') {
if (document.readyState === 'complete' || document.readyState === 'interactive') {
channel.onDOMContentLoaded.fire();
} else {
document.addEventListener('DOMContentLoaded', function () {
@@ -1454,10 +1446,10 @@ channel.join(function() {
// file: src/common/modulemapper.js
define("cordova/modulemapper", function(require, exports, module) {
var builder = require('cordova/builder'),
moduleMap = define.moduleMap,
symbolList,
deprecationMap;
var builder = require('cordova/builder');
var moduleMap = define.moduleMap; // eslint-disable-line no-undef
var symbolList;
var deprecationMap;
exports.reset = function () {
symbolList = [];
@@ -1497,7 +1489,7 @@ function prepareNamespace(symbolPath, context) {
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
cur = cur[part] = cur[part] || {};
}
return cur;
@@ -1511,7 +1503,7 @@ exports.mapModules = function(context) {
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
if (strategy === 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
@@ -1523,9 +1515,9 @@ exports.mapModules = function(context) {
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
if (strategy === 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
} else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
@@ -1549,15 +1541,14 @@ exports.getOriginalSymbol = function(context, symbolPath) {
exports.reset();
});
// file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder'),
symbolList = [],
deprecationMap;
var builder = require('cordova/builder');
var symbolList = [];
var deprecationMap;
exports.reset = function () {
symbolList = [];
@@ -1594,7 +1585,7 @@ function prepareNamespace(symbolPath, context) {
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
cur = cur[part] = cur[part] || {};
}
return cur;
@@ -1608,7 +1599,7 @@ exports.mapModules = function(context) {
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
if (strategy === 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
@@ -1620,9 +1611,9 @@ exports.mapModules = function(context) {
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
if (strategy === 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
} else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
@@ -1646,10 +1637,9 @@ exports.getOriginalSymbol = function(context, symbolPath) {
exports.reset();
});
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js
// file: /Users/jbowser/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.
@@ -1759,7 +1749,7 @@ function onMessageFromNative(msg) {
});
// file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/plugin/android/app.js
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/plugin/android/app.js
define("cordova/plugin/android/app", function(require, exports, module) {
var exec = require('cordova/exec');
@@ -1856,12 +1846,11 @@ module.exports = {
define("cordova/pluginloader", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
var urlutil = require('cordova/urlutil');
// Helper function to inject a <script> tag.
// Exported for testing.
exports.injectScript = function (url, onload, onerror) {
var script = document.createElement("script");
var script = document.createElement('script');
// onload fires even when script fails loads with an error.
script.onload = onload;
// onerror fires for malformed URLs.
@@ -1872,11 +1861,11 @@ exports.injectScript = function(url, onload, onerror) {
function injectIfNecessary (id, url, onload, onerror) {
onerror = onerror || onload;
if (id in define.moduleMap) {
if (id in define.moduleMap) { // eslint-disable-line no-undef
onload();
} else {
exports.injectScript(url, function () {
if (id in define.moduleMap) {
if (id in define.moduleMap) { // eslint-disable-line no-undef
onload();
} else {
onerror();
@@ -1887,7 +1876,7 @@ function injectIfNecessary(id, url, onload, onerror) {
function onScriptLoadingComplete (moduleList, finishPluginLoading) {
// Loop through all the plugins and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
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]);
@@ -1938,7 +1927,7 @@ function findCordovaPath() {
var term = '/cordova.js';
for (var n = scripts.length - 1; n > -1; n--) {
var src = scripts[n].src.replace(/\?.*$/, ''); // Strip any query param (CB-6007).
if (src.indexOf(term) == (src.length - term.length)) {
if (src.indexOf(term) === (src.length - term.length)) {
path = src.substring(0, src.length - term.length) + '/';
break;
}
@@ -1956,12 +1945,11 @@ exports.load = function(callback) {
pathPrefix = '';
}
injectIfNecessary('cordova/plugin_list', pathPrefix + 'cordova_plugins.js', function () {
var moduleList = require("cordova/plugin_list");
var moduleList = require('cordova/plugin_list');
handlePluginsObject(pathPrefix, moduleList, callback);
}, callback);
};
});
// file: src/common/pluginloader_b.js
@@ -1978,7 +1966,7 @@ function handlePluginsObject(moduleList) {
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
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]);
@@ -2003,19 +1991,17 @@ function handlePluginsObject(moduleList) {
// 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");
var moduleList = require('cordova/plugin_list');
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) {
/**
* For already absolute URLs, returns what is passed in.
* For relative URLs, converts them to absolute ones.
@@ -2026,7 +2012,6 @@ exports.makeAbsolute = function makeAbsolute(url) {
return anchorEl.href;
};
});
// file: src/common/utils.js
@@ -2066,7 +2051,7 @@ utils.arrayIndexOf = function(a, item) {
}
var len = a.length;
for (var i = 0; i < len; ++i) {
if (a[i] == item) {
if (a[i] === item) {
return i;
}
}
@@ -2078,10 +2063,10 @@ utils.arrayIndexOf = function(a, item) {
*/
utils.arrayRemove = function (a, item) {
var index = utils.arrayIndexOf(a, item);
if (index != -1) {
if (index !== -1) {
a.splice(index, 1);
}
return index != -1;
return index !== -1;
};
utils.typeName = function (val) {
@@ -2092,7 +2077,7 @@ utils.typeName = function(val) {
* Returns an indication of whether the argument is an array or not
*/
utils.isArray = Array.isArray ||
function(a) {return utils.typeName(a) == 'Array';};
function (a) { return utils.typeName(a) === 'Array'; };
/**
* Returns an indication of whether the argument is a Date or not
@@ -2105,7 +2090,7 @@ utils.isDate = function(d) {
* Does a deep clone of the object.
*/
utils.clone = function (obj) {
if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
if (!obj || typeof obj === 'function' || utils.isDate(obj) || typeof obj !== 'object') {
return obj;
}
@@ -2124,7 +2109,7 @@ utils.clone = function(obj) {
// https://issues.apache.org/jira/browse/CB-11522 'unknown' type may be returned in
// custom protocol activation case on Windows Phone 8.1 causing "No such interface supported" exception
// on cloning.
if((!(i in retVal) || retVal[i] != obj[i]) && typeof obj[i] != 'undefined' && typeof obj[i] != 'unknown') {
if ((!(i in retVal) || retVal[i] !== obj[i]) && typeof obj[i] !== 'undefined' && typeof obj[i] !== 'unknown') { // eslint-disable-line valid-typeof
retVal[i] = utils.clone(obj[i]);
}
}
@@ -2143,11 +2128,11 @@ utils.close = function(context, func, params) {
// ------------------------------------------------------------------------------
function UUIDcreatePart (length) {
var uuidpart = "";
var uuidpart = '';
for (var i = 0; i < length; i++) {
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
if (uuidchar.length == 1) {
uuidchar = "0" + uuidchar;
if (uuidchar.length === 1) {
uuidchar = '0' + uuidchar;
}
uuidpart += uuidchar;
}
@@ -2165,7 +2150,6 @@ utils.createUUID = function() {
UUIDcreatePart(6);
};
/**
* Extends a child object from a parent object using classical inheritance
* pattern.
@@ -2194,10 +2178,6 @@ utils.alert = function(msg) {
}
};
});
window.cordova = require('cordova');
+21 -278
View File
@@ -1,5 +1,4 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
/* 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
@@ -17,295 +16,39 @@
under the License.
*/
apply plugin: 'com.android.application'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
url "https://maven.google.com"
}
}
// Switch the Android Gradle plugin version requirement depending on the
// installed version of Gradle. This dependency is documented at
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
// and https://issues.apache.org/jira/browse/CB-8143
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.android.tools.build:gradle:3.0.0'
}
}
// Allow plugins to declare Maven dependencies via build-extras.gradle.
allprojects {
repositories {
mavenCentral();
jcenter()
maven {
url "https://maven.google.com"
}
}
//This replaces project.properties w.r.t. build settings
project.ext {
defaultBuildToolsVersion="25.0.2" //String
defaultMinSdkVersion=19 //Integer - Minimum requirement is Android 4.4
defaultTargetSdkVersion=26 //Integer - We ALWAYS target the latest by default
defaultCompileSdkVersion=26 //Integer - We ALWAYS compile with the latest by default
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14.1'
}
// 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;
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = null;
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = null
}
// .properties files to use for release signing.
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
cdvReleaseSigningPropertiesFile = null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
cdvDebugSigningPropertiesFile = null
}
// Set by build.js script.
if (!project.hasProperty('cdvBuildArch')) {
cdvBuildArch = null
}
// Plugin gradle extensions can append to this to have code run at the end.
cdvPluginPostBuildExtras = []
}
// PLUGIN GRADLE EXTENSIONS START
// PLUGIN GRADLE EXTENSIONS END
def hasBuildExtras = file('build-extras.gradle').exists()
if (hasBuildExtras) {
apply from: 'build-extras.gradle'
}
// Set property defaults after extension .gradle files.
if (ext.cdvCompileSdkVersion == null) {
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
}
if (ext.cdvBuildToolsVersion == null) {
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
}
if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) {
ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
}
if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.properties').exists()) {
ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties'
}
// Cast to appropriate types.
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
def computeBuildTargetName(debugBuild) {
def ret = 'assemble'
if (cdvBuildMultipleApks && cdvBuildArch) {
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
}
return ret + (debugBuild ? 'Debug' : 'Release')
}
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
task cdvBuildDebug
cdvBuildDebug.dependsOn {
return computeBuildTargetName(true)
}
task cdvBuildRelease
cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}
task cdvPrintProps << {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
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 {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
defaultConfig {
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
applicationId privateHelpers.extractStringFromManifest("package")
if (cdvMinSdkVersion != null) {
minSdkVersion cdvMinSdkVersion
}
}
lintOptions {
abortOnError false;
}
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
if (Boolean.valueOf(cdvBuildMultipleApks)) {
productFlavors {
armv7 {
versionCode defaultConfig.versionCode*10 + 2
ndk {
abiFilters "armeabi-v7a", ""
}
}
x86 {
versionCode defaultConfig.versionCode*10 + 4
ndk {
abiFilters "x86", ""
}
}
all {
ndk {
abiFilters "all", ""
}
}
}
}
/*
ELSE NOTHING! DON'T MESS WITH THE VERSION CODE IF YOU DON'T HAVE TO!
else if (!cdvVersionCode) {
def minSdkVersion = cdvMinSdkVersion ?: privateHelpers.extractIntFromManifest("minSdkVersion")
// Vary versionCode by the two most common API levels:
// 14 is ICS, which is the lowest API level for many apps.
// 20 is Lollipop, which is the lowest API level for the updatable system webview.
if (minSdkVersion >= 20) {
defaultConfig.versionCode += 9
} else if (minSdkVersion >= 14) {
defaultConfig.versionCode += 8
}
}
*/
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
if (cdvReleaseSigningPropertiesFile) {
signingConfigs {
release {
// These must be set or Gradle will complain (even if they are overridden).
keyAlias = ""
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
storeFile = null
storePassword = "__unset"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (cdvDebugSigningPropertiesFile) {
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
// SUB-PROJECT DEPENDENCIES END
}
def promptForReleaseKeyPassword() {
if (!cdvReleaseSigningPropertiesFile) {
return;
}
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
}
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
}
}
gradle.taskGraph.whenReady { taskGraph ->
taskGraph.getAllTasks().each() { task ->
if (task.name == 'validateReleaseSigning' || task.name == 'validateSigningRelease') {
promptForReleaseKeyPassword()
}
}
}
def addSigningProps(propsFilePath, signingConfig) {
def propsFile = file(propsFilePath)
def props = new Properties()
propsFile.withReader { reader ->
props.load(reader)
}
def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
if (!storeFile.isAbsolute()) {
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
}
if (!storeFile.exists()) {
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
}
signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))
signingConfig.storeFile = storeFile
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
def storeType = props.get('storeType', props.get('key.store.type', ''))
if (!storeType) {
def filename = storeFile.getName().toLowerCase();
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
storeType = 'pkcs12'
} else {
storeType = signingConfig.storeType // "jks"
}
}
signingConfig.storeType = storeType
}
for (def func : cdvPluginPostBuildExtras) {
func()
}
// This can be defined within build-extras.gradle as:
// ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
task clean(type: Delete) {
delete rootProject.buildDir
}
+311
View File
@@ -0,0 +1,311 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
apply plugin: 'com.android.application'
buildscript {
repositories {
mavenCentral()
jcenter()
}
// Switch the Android Gradle plugin version requirement depending on the
// installed version of Gradle. This dependency is documented at
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
// and https://issues.apache.org/jira/browse/CB-8143
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
}
}
// Allow plugins to declare Maven dependencies via build-extras.gradle.
allprojects {
repositories {
mavenCentral();
jcenter()
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14.1'
}
// 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;
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = null;
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = null
}
// .properties files to use for release signing.
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
cdvReleaseSigningPropertiesFile = null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
cdvDebugSigningPropertiesFile = null
}
// Set by build.js script.
if (!project.hasProperty('cdvBuildArch')) {
cdvBuildArch = null
}
// Plugin gradle extensions can append to this to have code run at the end.
cdvPluginPostBuildExtras = []
}
// PLUGIN GRADLE EXTENSIONS START
// PLUGIN GRADLE EXTENSIONS END
def hasBuildExtras = file('build-extras.gradle').exists()
if (hasBuildExtras) {
apply from: 'build-extras.gradle'
}
// Set property defaults after extension .gradle files.
if (ext.cdvCompileSdkVersion == null) {
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
}
if (ext.cdvBuildToolsVersion == null) {
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
}
if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) {
ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
}
if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.properties').exists()) {
ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties'
}
// Cast to appropriate types.
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
def computeBuildTargetName(debugBuild) {
def ret = 'assemble'
if (cdvBuildMultipleApks && cdvBuildArch) {
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
}
return ret + (debugBuild ? 'Debug' : 'Release')
}
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
task cdvBuildDebug
cdvBuildDebug.dependsOn {
return computeBuildTargetName(true)
}
task cdvBuildRelease
cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}
task cdvPrintProps << {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
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 {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
defaultConfig {
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
applicationId privateHelpers.extractStringFromManifest("package")
if (cdvMinSdkVersion != null) {
minSdkVersion cdvMinSdkVersion
}
}
lintOptions {
abortOnError false;
}
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
if (Boolean.valueOf(cdvBuildMultipleApks)) {
productFlavors {
armv7 {
versionCode defaultConfig.versionCode*10 + 2
ndk {
abiFilters "armeabi-v7a", ""
}
}
x86 {
versionCode defaultConfig.versionCode*10 + 4
ndk {
abiFilters "x86", ""
}
}
all {
ndk {
abiFilters "all", ""
}
}
}
}
/*
ELSE NOTHING! DON'T MESS WITH THE VERSION CODE IF YOU DON'T HAVE TO!
else if (!cdvVersionCode) {
def minSdkVersion = cdvMinSdkVersion ?: privateHelpers.extractIntFromManifest("minSdkVersion")
// Vary versionCode by the two most common API levels:
// 14 is ICS, which is the lowest API level for many apps.
// 20 is Lollipop, which is the lowest API level for the updatable system webview.
if (minSdkVersion >= 20) {
defaultConfig.versionCode += 9
} else if (minSdkVersion >= 14) {
defaultConfig.versionCode += 8
}
}
*/
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
if (cdvReleaseSigningPropertiesFile) {
signingConfigs {
release {
// These must be set or Gradle will complain (even if they are overridden).
keyAlias = ""
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
storeFile = null
storePassword = "__unset"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (cdvDebugSigningPropertiesFile) {
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
// SUB-PROJECT DEPENDENCIES END
}
def promptForReleaseKeyPassword() {
if (!cdvReleaseSigningPropertiesFile) {
return;
}
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
}
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
}
}
gradle.taskGraph.whenReady { taskGraph ->
taskGraph.getAllTasks().each() { task ->
if (task.name == 'validateReleaseSigning' || task.name == 'validateSigningRelease') {
promptForReleaseKeyPassword()
}
}
}
def addSigningProps(propsFilePath, signingConfig) {
def propsFile = file(propsFilePath)
def props = new Properties()
propsFile.withReader { reader ->
props.load(reader)
}
def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
if (!storeFile.isAbsolute()) {
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
}
if (!storeFile.exists()) {
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
}
signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))
signingConfig.storeFile = storeFile
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
def storeType = props.get('storeType', props.get('key.store.type', ''))
if (!storeType) {
def filename = storeFile.getName().toLowerCase();
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
storeType = 'pkcs12'
} else {
storeType = signingConfig.storeType // "jks"
}
}
signingConfig.storeType = storeType
}
for (def func : cdvPluginPostBuildExtras) {
func()
}
// This can be defined within build-extras.gradle as:
// ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
+9 -11
View File
@@ -1,15 +1,13 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# This file was originally created by the Android Tools, but is now
# used by cordova-android to manage the state of the various third party
# libraries used in your application
# This is the Library Module that contains the Cordova Library, this is not
# required when using an AAR
android.library.reference.1=CordovaLib
# This is the application project. This is only required for Android Studio Gradle projects
android.library.reference.2=app
# Project target.
target=This_gets_replaced
Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

+1 -1
View File
@@ -19,5 +19,5 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
<uses-sdk android:minSdkVersion="14" />
<uses-sdk android:minSdkVersion="16" />
</manifest>
+9 -7
View File
@@ -24,12 +24,14 @@ ext {
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
url "https://maven.google.com"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
}
@@ -40,7 +42,7 @@ apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
group = 'org.apache.cordova'
version = '6.2.0'
version = '7.0.0'
android {
compileSdkVersion cdvCompileSdkVersion
@@ -48,8 +50,8 @@ android {
publishNonDefault true
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
@@ -127,9 +129,9 @@ bintray {
licenses = ['Apache-2.0']
labels = ['android', 'cordova', 'phonegap']
version {
name = '6.2.0'
name = '7.0.0'
released = new Date()
vcsTag = '6.2.0'
vcsTag = '7.0.0'
}
}
}
+5 -1
View File
@@ -29,7 +29,11 @@ String doEnsureValueExists(filePath, props, key) {
String doGetProjectTarget() {
def props = new Properties()
file('project.properties').withReader { reader ->
def propertiesFile = 'project.properties';
if(!(file(propertiesFile).exists())) {
propertiesFile = '../project.properties';
}
file(propertiesFile).withReader { reader ->
props.load(reader)
}
return doEnsureValueExists('project.properties', props, 'target')
+2 -2
View File
@@ -1,6 +1,6 @@
#Mon Dec 28 10:00:20 PST 2015
#Thu Nov 09 10:50:25 PST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
+1 -1
View File
@@ -10,7 +10,7 @@
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-25
target=android-26
apk-configurations=
renderscript.opt.level=O0
android.library=true
@@ -0,0 +1,70 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package org.apache.cordova;
/*
* This is a utility class that allows us to get the BuildConfig variable, which is required
* for the use of different providers. This is not guaranteed to work, and it's better for this
* to be set in the build step in config.xml
*
*/
import android.app.Activity;
import android.content.Context;
import java.lang.reflect.Field;
public class BuildHelper {
private static String TAG="BuildHelper";
/*
* This needs to be implemented if you wish to use the Camera Plugin or other plugins
* that read the Build Configuration.
*
* Thanks to Phil@Medtronic and Graham Borland for finding the answer and posting it to
* StackOverflow. This is annoying as hell! However, this method does not work with
* ProGuard, and you should use the config.xml to define the application_id
*
*/
public static Object getBuildConfigValue(Context ctx, String key)
{
try
{
Class<?> clazz = Class.forName(ctx.getPackageName() + ".BuildConfig");
Field field = clazz.getField(key);
return field.get(null);
} catch (ClassNotFoundException e) {
LOG.d(TAG, "Unable to get the BuildConfig, is this built with ANT?");
e.printStackTrace();
} catch (NoSuchFieldException e) {
LOG.d(TAG, key + " is not a valid field. Check your build.gradle");
} catch (IllegalAccessException e) {
LOG.d(TAG, "Illegal Access Exception: Let's print a stack trace.");
e.printStackTrace();
}
return null;
}
}
@@ -319,6 +319,7 @@ public class CordovaActivity extends Activity {
/**
* Called when view focus is changed
*/
@SuppressLint("InlinedApi")
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
@@ -18,6 +18,8 @@
*/
package org.apache.cordova;
import android.annotation.SuppressLint;
import java.security.SecureRandom;
import org.json.JSONArray;
@@ -110,6 +112,9 @@ public class CordovaBridge {
}
/** Called by cordova.js to initialize the bridge. */
//On old Androids SecureRandom isn't really secure, this is the least of your problems if
//you're running Android 4.3 and below in 2017
@SuppressLint("TrulyRandom")
int generateBridgeSecret() {
SecureRandom randGen = new SecureRandom();
expectedBridgeSecret = randGen.nextInt(Integer.MAX_VALUE);
@@ -22,10 +22,12 @@ import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import android.annotation.SuppressLint;
import android.webkit.ClientCertRequest;
/**
* Implementation of the ICordovaClientCertRequest for Android WebView.
*
*/
public class CordovaClientCertRequest implements ICordovaClientCertRequest {
@@ -38,6 +40,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
/**
* Cancel this request
*/
@SuppressLint("NewApi")
public void cancel()
{
request.cancel();
@@ -46,6 +49,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
/*
* Returns the host name of the server requesting the certificate.
*/
@SuppressLint("NewApi")
public String getHost()
{
return request.getHost();
@@ -54,6 +58,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
/*
* Returns the acceptable types of asymmetric keys (can be null).
*/
@SuppressLint("NewApi")
public String[] getKeyTypes()
{
return request.getKeyTypes();
@@ -62,6 +67,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
/*
* Returns the port number of the server requesting the certificate.
*/
@SuppressLint("NewApi")
public int getPort()
{
return request.getPort();
@@ -70,6 +76,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
/*
* Returns the acceptable certificate issuers for the certificate matching the private key (can be null).
*/
@SuppressLint("NewApi")
public Principal[] getPrincipals()
{
return request.getPrincipals();
@@ -78,6 +85,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
/*
* Ignore the request for now. Do not remember user's choice.
*/
@SuppressLint("NewApi")
public void ignore()
{
request.ignore();
@@ -89,6 +97,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
* @param privateKey The privateKey
* @param chain The certificate chain
*/
@SuppressLint("NewApi")
public void proceed(PrivateKey privateKey, X509Certificate[] chain)
{
request.proceed(privateKey, chain);
@@ -19,6 +19,7 @@
package org.apache.cordova;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import org.apache.cordova.CordovaPlugin;
@@ -51,10 +52,18 @@ public interface CordovaInterface {
/**
* Get the Android activity.
*
* If a custom engine lives outside of the Activity's lifecycle the return value may be null.
*
* @return the Activity
*/
public abstract Activity getActivity();
/**
* Get the Android context.
*
* @return the Context
*/
public Context getContext();
/**
* Called when a message is sent to plugin.
@@ -19,7 +19,9 @@
package org.apache.cordova;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
@@ -84,6 +86,11 @@ public class CordovaInterfaceImpl implements CordovaInterface {
return activity;
}
@Override
public Context getContext() {
return activity;
}
@Override
public Object onMessage(String id, Object data) {
if ("exit".equals(id)) {
@@ -221,6 +228,7 @@ public class CordovaInterfaceImpl implements CordovaInterface {
requestPermissions(plugin, requestCode, permissions);
}
@SuppressLint("NewApi")
public void requestPermissions(CordovaPlugin plugin, int requestCode, String [] permissions) {
int mappedRequestCode = permissionResultCallbacks.registerCallback(plugin, requestCode);
getActivity().requestPermissions(permissions, mappedRequestCode);
@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
* are not expected to implement it.
*/
public interface CordovaWebView {
public static final String CORDOVA_VERSION = "6.2.0-dev";
public static final String CORDOVA_VERSION = "7.0.0";
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
@@ -18,6 +18,7 @@
*/
package org.apache.cordova;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -91,6 +92,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
init(cordova, new ArrayList<PluginEntry>(), new CordovaPreferences());
}
@SuppressLint("Assert")
@Override
public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {
if (this.cordova != null) {
@@ -0,0 +1,87 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package org.apache.cordova;
import java.util.Arrays;
import org.json.JSONException;
import android.content.pm.PackageManager;
/**
* This class provides reflective methods for permission requesting and checking so that plugins
* written for cordova-android 5.0.0+ can still compile with earlier cordova-android versions.
*/
public class PermissionHelper {
private static final String LOG_TAG = "CordovaPermissionHelper";
/**
* Requests a "dangerous" permission for the application at runtime. This is a helper method
* alternative to cordovaInterface.requestPermission() that does not require the project to be
* built with cordova-android 5.0.0+
*
* @param plugin The plugin the permission is being requested for
* @param requestCode A requestCode to be passed to the plugin's onRequestPermissionResult()
* along with the result of the permission request
* @param permission The permission to be requested
*/
public static void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
PermissionHelper.requestPermissions(plugin, requestCode, new String[] {permission});
}
/**
* Requests "dangerous" permissions for the application at runtime. This is a helper method
* alternative to cordovaInterface.requestPermissions() that does not require the project to be
* built with cordova-android 5.0.0+
*
* @param plugin The plugin the permissions are being requested for
* @param requestCode A requestCode to be passed to the plugin's onRequestPermissionResult()
* along with the result of the permissions request
* @param permissions The permissions to be requested
*/
public static void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {
plugin.cordova.requestPermissions(plugin, requestCode, permissions);
}
/**
* Checks at runtime to see if the application has been granted a permission. This is a helper
* method alternative to cordovaInterface.hasPermission() that does not require the project to
* be built with cordova-android 5.0.0+
*
* @param plugin The plugin the permission is being checked against
* @param permission The permission to be checked
*
* @return True if the permission has already been granted and false otherwise
*/
public static boolean hasPermission(CordovaPlugin plugin, String permission) {
return plugin.cordova.hasPermission(permission);
}
private static void deliverPermissionResult(CordovaPlugin plugin, int requestCode, String[] permissions) {
// Generate the request results
int[] requestResults = new int[permissions.length];
Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);
try {
plugin.onRequestPermissionResult(requestCode, permissions, requestResults);
} catch (JSONException e) {
LOG.e(LOG_TAG, "JSONException when delivering permissions results", e);
}
}
}
@@ -110,8 +110,12 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() {
@Override
public void setNetworkAvailable(boolean value) {
//sometimes this can be called after calling webview.destroy() on destroy()
//thus resulting in a NullPointerException
if(webView!=null) {
webView.setNetworkAvailable(value);
}
}
@Override
public void runOnUiThread(Runnable r) {
SystemWebViewEngine.this.cordova.getActivity().runOnUiThread(r);
@@ -250,6 +254,9 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
}
}
// Yeah, we know, which is why we makes ure that we don't do this if the bridge is
// below JELLYBEAN_MR1. It'd be great if lint was just a little smarter.
@SuppressLint("AddJavascriptInterface")
private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
+31
View File
@@ -1,3 +1,8 @@
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
@@ -13,3 +18,29 @@ 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.
+18 -13
View File
@@ -10,23 +10,23 @@
"spec": ">=1.0.0 <2.0.0",
"type": "range"
},
"/Users/steveng/repo/cordova/cordova-android/node_modules/nopt"
"/Users/jbowser/cordova/cordova-android/node_modules/nopt"
]
],
"_from": "abbrev@>=1.0.0 <2.0.0",
"_id": "abbrev@1.1.0",
"_id": "abbrev@1.1.1",
"_inCache": true,
"_location": "/abbrev",
"_nodeVersion": "8.0.0-pre",
"_nodeVersion": "8.5.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/abbrev-1.1.0.tgz_1487054000015_0.9229173036292195"
"host": "s3://npm-registry-packages",
"tmp": "tmp/abbrev-1.1.1.tgz_1506566833068_0.05750026390887797"
},
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
"_npmVersion": "4.3.0",
"_npmVersion": "5.4.2",
"_phantomChildren": {},
"_requested": {
"raw": "abbrev@1",
@@ -40,11 +40,11 @@
"_requiredBy": [
"/nopt"
],
"_resolved": "http://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
"_shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f",
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"_shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8",
"_shrinkwrap": null,
"_spec": "abbrev@1",
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/nopt",
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/nopt",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me"
@@ -59,17 +59,22 @@
},
"directories": {},
"dist": {
"shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f",
"tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz"
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8",
"tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz"
},
"files": [
"abbrev.js"
],
"gitHead": "7136d4d95449dc44115d4f78b80ec907724f64e0",
"gitHead": "a9ee72ebc8fe3975f1b0c7aeb3a8f2a806a432eb",
"homepage": "https://github.com/isaacs/abbrev-js#readme",
"license": "ISC",
"main": "abbrev.js",
"maintainers": [
{
"name": "gabra",
"email": "jerry+1@npmjs.com"
},
{
"name": "isaacs",
"email": "i@izs.me"
@@ -88,5 +93,5 @@
"preversion": "npm test",
"test": "tap test.js --100"
},
"version": "1.1.0"
"version": "1.1.1"
}
+8
View File
@@ -0,0 +1,8 @@
.git/
node_modules/
coverage/
build/
assets/
dist/
docs/
tests/
+28
View File
@@ -0,0 +1,28 @@
{
"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
View File
@@ -0,0 +1,3 @@
language: node_js
node_js:
- "6.1.0"
+87
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
+153
View File
@@ -0,0 +1,153 @@
/**
* 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)", versionCode: "BASE" },
BASE_1_1: { api: 2, ndk: 0, semver: "1.1", name: "(no code name)", versionCode: "BASE_1_1" },
CUPCAKE: { api: 3, ndk: 1, semver: "1.5", name: "Cupcake", versionCode: "CUPCAKE" },
DONUT: { api: 4, ndk: 2, semver: "1.6", name: "Donut", versionCode: "DONUT" },
ECLAIR: { api: 5, ndk: 2, semver: "2.0", name: "Eclair", versionCode: "ECLAIR" },
ECLAIR_0_1: { api: 6, ndk: 2, semver: "2.0.1", name: "Eclair", versionCode: "ECLAIR_0_1" },
ECLAIR_MR1: { api: 7, ndk: 3, semver: "2.1", name: "Eclair", versionCode: "ECLAIR_MR1" },
FROYO: { api: 8, ndk: 4, semver: "2.2", name: "Froyo", versionCode: "FROYO" },
GINGERBREAD: { api: 9, ndk: 5, semver: "2.3", name: "Gingerbread", versionCode: "GINGERBREAD" },
GINGERBREAD_MR1: { api: 10, ndk: 5, semver: "2.3.3", name: "Gingerbread", versionCode: "GINGERBREAD_MR1" },
HONEYCOMB: { api: 11, ndk: 5, semver: "3.0", name: "Honeycomb", versionCode: "HONEYCOMB" },
HONEYCOMB_MR1: { api: 12, ndk: 6, semver: "3.1", name: "Honeycomb", versionCode: "HONEYCOMB_MR1" },
HONEYCOMB_MR2: { api: 13, ndk: 6, semver: "3.2", name: "Honeycomb", versionCode: "HONEYCOMB_MR2" },
ICE_CREAM_SANDWICH: { api: 14, ndk: 7, semver: "4.0", name: "Ice Cream Sandwich", versionCode: "ICE_CREAM_SANDWICH" },
ICE_CREAM_SANDWICH_MR1: { api: 15, ndk: 8, semver: "4.0.3", name: "Ice Cream Sandwich", versionCode: "ICE_CREAM_SANDWICH_MR1" },
JELLY_BEAN: { api: 16, ndk: 8, semver: "4.1", name: "Jellybean", versionCode: "JELLY_BEAN" },
JELLY_BEAN_MR1: { api: 17, ndk: 8, semver: "4.2", name: "Jellybean", versionCode: "JELLY_BEAN_MR1" },
JELLY_BEAN_MR2: { api: 18, ndk: 8, semver: "4.3", name: "Jellybean", versionCode: "JELLY_BEAN_MR2" },
KITKAT: { api: 19, ndk: 8, semver: "4.4", name: "KitKat", versionCode: "KITKAT" },
KITKAT_WATCH: { api: 20, ndk: 8, semver: "4.4", name: "KitKat Watch", versionCode: "KITKAT_WATCH" },
LOLLIPOP: { api: 21, ndk: 8, semver: "5.0", name: "Lollipop", versionCode: "LOLLIPOP" },
LOLLIPOP_MR1: { api: 22, ndk: 8, semver: "5.1", name: "Lollipop", versionCode: "LOLLIPOP_MR1" },
M: { api: 23, ndk: 8, semver: "6.0", name: "Marshmallow", versionCode: "M" },
N: { api: 24, ndk: 8, semver: "7.0", name: "Nougat", versionCode: "N" },
N_MR1: { api: 25, ndk: 8, semver: "7.1", name: "Nougat", versionCode: "N_MR1" },
O: { api: 26, ndk: 8, semver: "8.0.0", name: "Oreo", versionCode: "O" }
}
// This altSemVer accomodates the variations of semantic versions in the table above.
// For instance, Oreo is 8.0.0 while N is 7.0, searching for "8.0" or "8.0.0" will
// return Oreo, or searching for "7.0" or "7.0.0" will return N. "2.2.0" will return Froyo.
function getAlternateSemVer(semver) {
if (semver.match(/\d+.\d+.0/)) {
return semver.replace(/.\d+$/, '')
} else 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
}
// Compare semver and alternate semver (see above).
var altSemVer = getAlternateSemVer(arg)
if (version.semver === arg || version.semver === altSemVer) {
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)
}
}
+103
View File
@@ -0,0 +1,103 @@
{
"_args": [
[
{
"raw": "android-versions@^1.2.1",
"scope": null,
"escapedName": "android-versions",
"name": "android-versions",
"rawSpec": "^1.2.1",
"spec": ">=1.2.1 <2.0.0",
"type": "range"
},
"/Users/jbowser/cordova/cordova-android"
]
],
"_from": "android-versions@>=1.2.1 <2.0.0",
"_id": "android-versions@1.2.1",
"_inCache": true,
"_location": "/android-versions",
"_nodeVersion": "8.0.0",
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/android-versions-1.2.1.tgz_1505373302036_0.5689644906669855"
},
"_npmUser": {
"name": "dvoiss",
"email": "davidvoiss@gmail.com"
},
"_npmVersion": "5.4.0",
"_phantomChildren": {},
"_requested": {
"raw": "android-versions@^1.2.1",
"scope": null,
"escapedName": "android-versions",
"name": "android-versions",
"rawSpec": "^1.2.1",
"spec": ">=1.2.1 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.2.1.tgz",
"_shasum": "3f50baf693e73a512c3c5403542291cead900063",
"_shrinkwrap": null,
"_spec": "android-versions@^1.2.1",
"_where": "/Users/jbowser/cordova/cordova-android",
"author": {
"name": "dvoiss"
},
"bugs": {
"url": "https://github.com/dvoiss/android-versions/issues"
},
"dependencies": {},
"description": "Get the name, API level, version level, NDK level, or version code from any version of Android.",
"devDependencies": {
"jsdoc": "^3.4.0",
"jshint": "^2.9.2",
"tape": "^4.6.0"
},
"directories": {},
"dist": {
"integrity": "sha512-k6zlrtWbJ3tx1ZsyyJ0Bo3r6cqPA3JUnFGv7pnIaLr1XVxSi2Tcem2lg3kBebFp27v/A40tZqdlouPyakpyKrw==",
"shasum": "3f50baf693e73a512c3c5403542291cead900063",
"tarball": "https://registry.npmjs.org/android-versions/-/android-versions-1.2.1.tgz"
},
"gitHead": "7e2def6e70634a4ebcaaa639a4c4955ae2a566e7",
"homepage": "https://github.com/dvoiss/android-versions#readme",
"keywords": [
"android",
"version",
"versions",
"ndk",
"nougat",
"marshmallow",
"api",
"level"
],
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"name": "dvoiss",
"email": "davidvoiss@gmail.com"
}
],
"name": "android-versions",
"optionalDependencies": {},
"pre-commit": [
"jshint"
],
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/dvoiss/android-versions.git"
},
"scripts": {
"docs": "jsdoc index.js -d ./docs/ -R README.md --debug",
"jshint": "jshint .",
"test": "tape tests/**/*.js"
},
"version": "1.2.1"
}
+3 -3
View File
@@ -10,7 +10,7 @@
"spec": ">=0.3.1 <0.4.0",
"type": "range"
},
"/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common"
"/Users/jbowser/cordova/cordova-android/node_modules/cordova-common"
]
],
"_from": "ansi@>=0.3.1 <0.4.0",
@@ -36,11 +36,11 @@
"_requiredBy": [
"/cordova-common"
],
"_resolved": "http://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
"_resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
"_shasum": "0c42d4fb17160d5a9af1e484bace1c66922c1b21",
"_shrinkwrap": null,
"_spec": "ansi@^0.3.1",
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common",
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/cordova-common",
"author": {
"name": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
+1
View File
@@ -1,3 +1,4 @@
'use strict';
module.exports = balanced;
function balanced(a, b, str) {
if (a instanceof RegExp) a = maybeMatch(a, str);
+23 -21
View File
@@ -2,49 +2,49 @@
"_args": [
[
{
"raw": "balanced-match@^0.4.1",
"raw": "balanced-match@^1.0.0",
"scope": null,
"escapedName": "balanced-match",
"name": "balanced-match",
"rawSpec": "^0.4.1",
"spec": ">=0.4.1 <0.5.0",
"rawSpec": "^1.0.0",
"spec": ">=1.0.0 <2.0.0",
"type": "range"
},
"/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion"
"/Users/jbowser/cordova/cordova-android/node_modules/brace-expansion"
]
],
"_from": "balanced-match@>=0.4.1 <0.5.0",
"_id": "balanced-match@0.4.2",
"_from": "balanced-match@>=1.0.0 <2.0.0",
"_id": "balanced-match@1.0.0",
"_inCache": true,
"_location": "/balanced-match",
"_nodeVersion": "4.4.7",
"_nodeVersion": "7.8.0",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/balanced-match-0.4.2.tgz_1468834991581_0.6590619895141572"
"host": "s3://npm-registry-packages",
"tmp": "tmp/balanced-match-1.0.0.tgz_1497251909645_0.8755026108119637"
},
"_npmUser": {
"name": "juliangruber",
"email": "julian@juliangruber.com"
},
"_npmVersion": "2.15.8",
"_npmVersion": "4.2.0",
"_phantomChildren": {},
"_requested": {
"raw": "balanced-match@^0.4.1",
"raw": "balanced-match@^1.0.0",
"scope": null,
"escapedName": "balanced-match",
"name": "balanced-match",
"rawSpec": "^0.4.1",
"spec": ">=0.4.1 <0.5.0",
"rawSpec": "^1.0.0",
"spec": ">=1.0.0 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/brace-expansion"
],
"_resolved": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
"_shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838",
"_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767",
"_shrinkwrap": null,
"_spec": "balanced-match@^0.4.1",
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion",
"_spec": "balanced-match@^1.0.0",
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/brace-expansion",
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
@@ -56,14 +56,15 @@
"dependencies": {},
"description": "Match balanced character pairs, like \"{\" and \"}\"",
"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"
},
"directories": {},
"dist": {
"shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838",
"tarball": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz"
"shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767",
"tarball": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
},
"gitHead": "57c2ea29d89a2844ae3bdcc637c6e2cbb73725e2",
"gitHead": "d701a549a7653a874eebce7eca25d3577dc868ac",
"homepage": "https://github.com/juliangruber/balanced-match",
"keywords": [
"match",
@@ -88,6 +89,7 @@
"url": "git://github.com/juliangruber/balanced-match.git"
},
"scripts": {
"bench": "make bench",
"test": "make test"
},
"testling": {
@@ -106,5 +108,5 @@
"android-browser/4.2..latest"
]
},
"version": "0.4.2"
"version": "1.0.0"
}
+3 -3
View File
@@ -10,7 +10,7 @@
"spec": "0.0.8",
"type": "version"
},
"/Users/steveng/repo/cordova/cordova-android/node_modules/plist"
"/Users/jbowser/cordova/cordova-android/node_modules/plist"
]
],
"_from": "base64-js@0.0.8",
@@ -36,11 +36,11 @@
"_requiredBy": [
"/plist"
],
"_resolved": "http://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
"_resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
"_shasum": "1101e9544f4a76b1bc3b26d452ca96d7a35e7978",
"_shrinkwrap": null,
"_spec": "base64-js@0.0.8",
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/plist",
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/plist",
"author": {
"name": "T. Jameson Little",
"email": "t.jameson.little@gmail.com"
+2369
View File
File diff suppressed because it is too large Load Diff
+74 -37
View File
@@ -118,7 +118,7 @@ var bigInt = (function (undefined) {
}
BigInteger.prototype.add = function (v) {
var value, n = parseValue(v);
var n = parseValue(v);
if (this.sign !== n.sign) {
return this.subtract(n.negate());
}
@@ -177,7 +177,7 @@ var bigInt = (function (undefined) {
}
function subtractAny(a, b, sign) {
var value, isSmall;
var value;
if (compareAbs(a, b) >= 0) {
value = subtract(a,b);
} else {
@@ -326,7 +326,7 @@ var bigInt = (function (undefined) {
}
BigInteger.prototype.multiply = function (v) {
var value, n = parseValue(v),
var n = parseValue(v),
a = this.value, b = n.value,
sign = this.sign !== n.sign,
abs;
@@ -467,6 +467,7 @@ var bigInt = (function (undefined) {
guess, xlen, highx, highy, check;
while (a_l) {
part.unshift(a[--a_l]);
trim(part);
if (compareAbs(part, b) < 0) {
result.push(0);
continue;
@@ -837,8 +838,12 @@ var bigInt = (function (undefined) {
if (t.compare(0) === -1) {
t = t.add(n);
}
return t;
if (this.isNegative()) {
return t.negate();
}
return t;
};
SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
BigInteger.prototype.next = function () {
@@ -868,7 +873,7 @@ var bigInt = (function (undefined) {
};
var powersOfTwo = [1];
while (powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
function shift_isSmall(n) {
@@ -915,31 +920,29 @@ var bigInt = (function (undefined) {
var xSign = x.isNegative(), ySign = y.isNegative();
var xRem = xSign ? x.not() : x,
yRem = ySign ? y.not() : y;
var xBits = [], yBits = [];
var xStop = false, yStop = false;
while (!xStop || !yStop) {
if (xRem.isZero()) { // virtual sign extension for simulating two's complement
xStop = true;
xBits.push(xSign ? 1 : 0);
}
else if (xSign) xBits.push(xRem.isEven() ? 1 : 0); // two's complement for negative numbers
else xBits.push(xRem.isEven() ? 0 : 1);
if (yRem.isZero()) {
yStop = true;
yBits.push(ySign ? 1 : 0);
}
else if (ySign) yBits.push(yRem.isEven() ? 1 : 0);
else yBits.push(yRem.isEven() ? 0 : 1);
xRem = xRem.over(2);
yRem = yRem.over(2);
}
var xDigit = 0, yDigit = 0;
var xDivMod = null, yDivMod = null;
var result = [];
for (var i = 0; i < xBits.length; i++) result.push(fn(xBits[i], yBits[i]));
var sum = bigInt(result.pop()).negate().times(bigInt(2).pow(result.length));
while (result.length) {
sum = sum.add(bigInt(result.pop()).times(bigInt(2).pow(result.length)));
while (!xRem.isZero() || !yRem.isZero()) {
xDivMod = divModAny(xRem, highestPower2);
xDigit = xDivMod[1].toJSNumber();
if (xSign) {
xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
}
yDivMod = divModAny(yRem, highestPower2);
yDigit = yDivMod[1].toJSNumber();
if (ySign) {
yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
}
xRem = xDivMod[0];
yRem = yDivMod[0];
result.push(fn(xDigit, yDigit));
}
var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
for (var i = result.length - 1; i >= 0; i -= 1) {
sum = sum.multiply(highestPower2).add(bigInt(result[i]));
}
return sum;
}
@@ -1018,8 +1021,8 @@ var bigInt = (function (undefined) {
a = parseValue(a);
b = parseValue(b);
var low = min(a, b), high = max(a, b);
var range = high.subtract(low);
if (range.isSmall) return low.add(Math.round(Math.random() * range));
var range = high.subtract(low).add(1);
if (range.isSmall) return low.add(Math.floor(Math.random() * range));
var length = range.value.length - 1;
var result = [], restricted = true;
for (var i = length; i >= 0; i--) {
@@ -1032,16 +1035,32 @@ var bigInt = (function (undefined) {
return low.add(typeof result === "number" ? new SmallInteger(result) : new BigInteger(result, false));
}
var parseBase = function (text, base) {
var val = Integer[0], pow = Integer[1],
length = text.length;
var length = text.length;
var i;
var absBase = Math.abs(base);
for(var i = 0; i < length; i++) {
var c = text[i].toLowerCase();
if(c === "-") continue;
if(/[a-z0-9]/.test(c)) {
if(/[0-9]/.test(c) && +c >= absBase) {
if(c === "1" && absBase === 1) continue;
throw new Error(c + " is not a valid digit in base " + base + ".");
} else if(c.charCodeAt(0) - 87 >= absBase) {
throw new Error(c + " is not a valid digit in base " + base + ".");
}
}
}
if (2 <= base && base <= 36) {
if (length <= LOG_MAX_INT / Math.log(base)) {
var result = parseInt(text, base);
if(isNaN(result)) {
throw new Error(c + " is not a valid digit in base " + base + ".");
}
return new SmallInteger(parseInt(text, base));
}
}
base = parseValue(base);
var digits = [];
var i;
var isNegative = text[0] === "-";
for (i = isNegative ? 1 : 0; i < text.length; i++) {
var c = text[i].toLowerCase(),
@@ -1055,13 +1074,17 @@ var bigInt = (function (undefined) {
}
else throw new Error(c + " is not a valid character");
}
digits.reverse();
for (i = 0; i < digits.length; i++) {
return parseBaseFromArray(digits, base, isNegative);
};
function parseBaseFromArray(digits, base, isNegative) {
var val = Integer[0], pow = Integer[1], i;
for (i = digits.length - 1; i >= 0; i--) {
val = val.add(digits[i].times(pow));
pow = pow.times(base);
}
return isNegative ? val.negate() : val;
};
}
function stringify(digit) {
var v = digit.value;
@@ -1118,11 +1141,13 @@ var bigInt = (function (undefined) {
var sign = this.sign ? "-" : "";
return sign + str;
};
SmallInteger.prototype.toString = function (radix) {
if (radix === undefined) radix = 10;
if (radix != 10) return toBase(this, radix);
return String(this.value);
};
BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function() { return this.toString(); }
BigInteger.prototype.valueOf = function () {
return +this.toString();
@@ -1205,6 +1230,11 @@ var bigInt = (function (undefined) {
Integer.lcm = lcm;
Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger; };
Integer.randBetween = randBetween;
Integer.fromArray = function (digits, base, isNegative) {
return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
};
return Integer;
})();
@@ -1212,3 +1242,10 @@ var bigInt = (function (undefined) {
if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
module.exports = bigInt;
}
//amd check
if ( typeof define === "function" && define.amd ) {
define( "big-integer", [], function() {
return bigInt;
});
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+8 -1
View File
@@ -211,7 +211,7 @@ Returns `true` if the number is prime, `false` otherwise.
#### `isProbablePrime([iterations])`
Returns `true` if the number is very likely to be positive, `false` otherwise.
Returns `true` if the number is very likely to be prime, `false` otherwise.
Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive.
This uses the [Fermat primality test](https://en.wikipedia.org/wiki/Fermat_primality_test).
@@ -421,6 +421,13 @@ Performs the bitwise XOR operation. The operands are treated as if they were rep
### Static Methods
#### `fromArray(digits, base = 10, isNegative?)`
Constructs a bigInt from an array of digits in base `base`. The optional `isNegative` flag will make the number negative.
- `bigInt.fromArray([1, 2, 3, 4, 5], 10)` => `12345`
- `bigInt.fromArray([1, 0, 0], 2, true)` => `-4`
#### `gcd(a, b)`
Finds the greatest common denominator of `a` and `b`.
-1
View File
@@ -24,7 +24,6 @@
"bower_components",
"test",
"coverage",
"spec",
"tests"
]
}
+22 -15
View File
@@ -10,23 +10,23 @@
"spec": ">=1.6.7 <2.0.0",
"type": "range"
},
"/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser"
"/Users/jbowser/cordova/cordova-android/node_modules/bplist-parser"
]
],
"_from": "big-integer@>=1.6.7 <2.0.0",
"_id": "big-integer@1.6.17",
"_id": "big-integer@1.6.26",
"_inCache": true,
"_location": "/big-integer",
"_nodeVersion": "4.4.5",
"_nodeVersion": "6.10.3",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/big-integer-1.6.17.tgz_1478721202721_0.8068355675786734"
"host": "s3://npm-registry-packages",
"tmp": "tmp/big-integer-1.6.26.tgz_1510889021794_0.842821853235364"
},
"_npmUser": {
"name": "peterolson",
"email": "peter.e.c.olson+npm@gmail.com"
},
"_npmVersion": "2.15.5",
"_npmVersion": "3.10.10",
"_phantomChildren": {},
"_requested": {
"raw": "big-integer@^1.6.7",
@@ -40,11 +40,11 @@
"_requiredBy": [
"/bplist-parser"
],
"_resolved": "http://registry.npmjs.org/big-integer/-/big-integer-1.6.17.tgz",
"_shasum": "f0dcf5109a949e42a993ee3e8fb2070452817b51",
"_resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.26.tgz",
"_shasum": "3af1672fa62daf2d5ecafacf6e5aa0d25e02c1c8",
"_shrinkwrap": null,
"_spec": "big-integer@^1.6.7",
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser",
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/bplist-parser",
"author": {
"name": "Peter Olson",
"email": "peter.e.c.olson+npm@gmail.com"
@@ -57,23 +57,28 @@
"dependencies": {},
"description": "An arbitrary length integer library for Javascript",
"devDependencies": {
"@types/lodash": "^4.14.64",
"@types/node": "^7.0.22",
"coveralls": "^2.11.4",
"jasmine": "2.1.x",
"jasmine-core": "^2.3.4",
"karma": "^0.13.3",
"karma-coverage": "^0.4.2",
"karma-jasmine": "^0.3.6",
"karma-phantomjs-launcher": "~0.1"
"karma-phantomjs-launcher": "^1.0.4",
"lodash": "^4.17.4",
"typescript": "^2.3.3",
"uglifyjs": "^2.4.10"
},
"directories": {},
"dist": {
"shasum": "f0dcf5109a949e42a993ee3e8fb2070452817b51",
"tarball": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.17.tgz"
"shasum": "3af1672fa62daf2d5ecafacf6e5aa0d25e02c1c8",
"tarball": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.26.tgz"
},
"engines": {
"node": ">=0.6"
},
"gitHead": "d25d0bfcd96f31001ec8572c8d01de4770d99e63",
"gitHead": "b1c6e0e95eca0a0d19ebbb9cc81ec492448a9e8a",
"homepage": "https://github.com/peterolson/BigInteger.js#readme",
"keywords": [
"math",
@@ -102,7 +107,9 @@
"url": "git+ssh://git@github.com/peterolson/BigInteger.js.git"
},
"scripts": {
"test": "karma start my.conf.js"
"minify": "uglifyjs BigInteger.js -o BigInteger.min.js",
"test": "tsc && node_modules/.bin/karma start my.conf.js && node spec/tsDefinitions.js"
},
"version": "1.6.17"
"typings": "./BigInteger.d.ts",
"version": "1.6.26"
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"baseUrl": "./",
"moduleResolution": "node",
"allowJs": true,
"typeRoots": [
"./"
],
"types": [
"node"
],
"forceConsistentCasingInFileNames": true
},
"files": [
"BigInteger.d.ts",
"spec/tsDefinitions.ts"
]
}
+3 -3
View File
@@ -10,7 +10,7 @@
"spec": ">=0.1.0 <0.2.0",
"type": "range"
},
"/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common"
"/Users/jbowser/cordova/cordova-android/node_modules/cordova-common"
]
],
"_from": "bplist-parser@>=0.1.0 <0.2.0",
@@ -36,11 +36,11 @@
"_requiredBy": [
"/cordova-common"
],
"_resolved": "http://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz",
"_resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz",
"_shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6",
"_shrinkwrap": null,
"_spec": "bplist-parser@^0.1.0",
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common",
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/cordova-common",
"author": {
"name": "Joe Ferner",
"email": "joe.ferner@nearinfinity.com"

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