liuyuqi 2 years ago
commit
3c5a264a7c
100 changed files with 14330 additions and 0 deletions
  1. 1 0
      .gitignore
  2. 26 0
      myApp/config.xml
  3. 23 0
      myApp/hooks/README.md
  4. 393 0
      myApp/package-lock.json
  5. 31 0
      myApp/package.json
  6. 21 0
      myApp/platforms/android/.gitignore
  7. 22 0
      myApp/platforms/android/CordovaLib/AndroidManifest.xml
  8. 148 0
      myApp/platforms/android/CordovaLib/build.gradle
  9. 205 0
      myApp/platforms/android/CordovaLib/cordova.gradle
  10. 11 0
      myApp/platforms/android/CordovaLib/project.properties
  11. 69 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/AuthenticationToken.java
  12. 70 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/BuildHelper.java
  13. 142 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java
  14. 65 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CallbackMap.java
  15. 71 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/Config.java
  16. 145 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/ConfigXmlParser.java
  17. 521 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaActivity.java
  18. 113 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaArgs.java
  19. 187 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java
  20. 105 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaClientCertRequest.java
  21. 152 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaDialogsHelper.java
  22. 51 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaHttpAuthHandler.java
  23. 97 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterface.java
  24. 249 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterfaceImpl.java
  25. 422 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPlugin.java
  26. 101 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPreferences.java
  27. 472 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaResourceApi.java
  28. 142 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebView.java
  29. 85 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewEngine.java
  30. 617 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewImpl.java
  31. 407 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/CoreAndroid.java
  32. 31 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/ExposedJsApi.java
  33. 66 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaClientCertRequest.java
  34. 33 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaCookieManager.java
  35. 38 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaHttpAuthHandler.java
  36. 244 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/LOG.java
  37. 542 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/NativeToJsMessageQueue.java
  38. 87 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/PermissionHelper.java
  39. 70 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/PluginEntry.java
  40. 526 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/PluginManager.java
  41. 198 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/PluginResult.java
  42. 76 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/ResumeCallback.java
  43. 170 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/Whitelist.java
  44. 74 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemCookieManager.java
  45. 53 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemExposedJsApi.java
  46. 301 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebChromeClient.java
  47. 88 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebView.java
  48. 370 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewClient.java
  49. 319 0
      myApp/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewEngine.java
  50. 88 0
      myApp/platforms/android/android.json
  51. 358 0
      myApp/platforms/android/app/build.gradle
  52. 17 0
      myApp/platforms/android/app/src/main/AndroidManifest.xml
  53. 36 0
      myApp/platforms/android/app/src/main/assets/www/cordova-js-src/android/nativeapiprovider.js
  54. 35 0
      myApp/platforms/android/app/src/main/assets/www/cordova-js-src/android/promptbasednativeapi.js
  55. 286 0
      myApp/platforms/android/app/src/main/assets/www/cordova-js-src/exec.js
  56. 125 0
      myApp/platforms/android/app/src/main/assets/www/cordova-js-src/platform.js
  57. 108 0
      myApp/platforms/android/app/src/main/assets/www/cordova-js-src/plugin/android/app.js
  58. 1935 0
      myApp/platforms/android/app/src/main/assets/www/cordova.js
  59. 40 0
      myApp/platforms/android/app/src/main/assets/www/cordova_plugins.js
  60. 107 0
      myApp/platforms/android/app/src/main/assets/www/css/index.css
  61. BIN
      myApp/platforms/android/app/src/main/assets/www/img/logo.png
  62. 49 0
      myApp/platforms/android/app/src/main/assets/www/index.html
  63. 46 0
      myApp/platforms/android/app/src/main/assets/www/js/index.js
  64. 188 0
      myApp/platforms/android/app/src/main/assets/www/plugins/cordova-plugin-camera/www/Camera.js
  65. 104 0
      myApp/platforms/android/app/src/main/assets/www/plugins/cordova-plugin-camera/www/CameraConstants.js
  66. 35 0
      myApp/platforms/android/app/src/main/assets/www/plugins/cordova-plugin-camera/www/CameraPopoverHandle.js
  67. 59 0
      myApp/platforms/android/app/src/main/assets/www/plugins/cordova-plugin-camera/www/CameraPopoverOptions.js
  68. 41 0
      myApp/platforms/android/app/src/main/java/me/yoqi/myapp/MainActivity.java
  69. 1402 0
      myApp/platforms/android/app/src/main/java/org/apache/cordova/camera/CameraLauncher.java
  70. 104 0
      myApp/platforms/android/app/src/main/java/org/apache/cordova/camera/CordovaUri.java
  71. 185 0
      myApp/platforms/android/app/src/main/java/org/apache/cordova/camera/ExifHelper.java
  72. 330 0
      myApp/platforms/android/app/src/main/java/org/apache/cordova/camera/FileHelper.java
  73. 21 0
      myApp/platforms/android/app/src/main/java/org/apache/cordova/camera/FileProvider.java
  74. 161 0
      myApp/platforms/android/app/src/main/java/org/apache/cordova/whitelist/WhitelistPlugin.java
  75. BIN
      myApp/platforms/android/app/src/main/res/drawable-land-hdpi/screen.png
  76. BIN
      myApp/platforms/android/app/src/main/res/drawable-land-ldpi/screen.png
  77. BIN
      myApp/platforms/android/app/src/main/res/drawable-land-mdpi/screen.png
  78. BIN
      myApp/platforms/android/app/src/main/res/drawable-land-xhdpi/screen.png
  79. BIN
      myApp/platforms/android/app/src/main/res/drawable-land-xxhdpi/screen.png
  80. BIN
      myApp/platforms/android/app/src/main/res/drawable-land-xxxhdpi/screen.png
  81. BIN
      myApp/platforms/android/app/src/main/res/drawable-port-hdpi/screen.png
  82. BIN
      myApp/platforms/android/app/src/main/res/drawable-port-ldpi/screen.png
  83. BIN
      myApp/platforms/android/app/src/main/res/drawable-port-mdpi/screen.png
  84. BIN
      myApp/platforms/android/app/src/main/res/drawable-port-xhdpi/screen.png
  85. BIN
      myApp/platforms/android/app/src/main/res/drawable-port-xxhdpi/screen.png
  86. BIN
      myApp/platforms/android/app/src/main/res/drawable-port-xxxhdpi/screen.png
  87. 5 0
      myApp/platforms/android/app/src/main/res/mipmap-hdpi-v26/ic_launcher.xml
  88. BIN
      myApp/platforms/android/app/src/main/res/mipmap-hdpi-v26/ic_launcher_background.png
  89. BIN
      myApp/platforms/android/app/src/main/res/mipmap-hdpi-v26/ic_launcher_foreground.png
  90. BIN
      myApp/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  91. 5 0
      myApp/platforms/android/app/src/main/res/mipmap-ldpi-v26/ic_launcher.xml
  92. BIN
      myApp/platforms/android/app/src/main/res/mipmap-ldpi-v26/ic_launcher_background.png
  93. BIN
      myApp/platforms/android/app/src/main/res/mipmap-ldpi-v26/ic_launcher_foreground.png
  94. BIN
      myApp/platforms/android/app/src/main/res/mipmap-ldpi/ic_launcher.png
  95. 5 0
      myApp/platforms/android/app/src/main/res/mipmap-mdpi-v26/ic_launcher.xml
  96. BIN
      myApp/platforms/android/app/src/main/res/mipmap-mdpi-v26/ic_launcher_background.png
  97. BIN
      myApp/platforms/android/app/src/main/res/mipmap-mdpi-v26/ic_launcher_foreground.png
  98. BIN
      myApp/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  99. 5 0
      myApp/platforms/android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher.xml
  100. BIN
      myApp/platforms/android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher_background.png

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+node_modules

+ 26 - 0
myApp/config.xml

@@ -0,0 +1,26 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="me.yoqi.myapp" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>myApp</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <plugin name="cordova-plugin-whitelist" spec="1" />
+    <access origin="*" />
+    <allow-intent href="http://*/*" />
+    <allow-intent href="https://*/*" />
+    <allow-intent href="tel:*" />
+    <allow-intent href="sms:*" />
+    <allow-intent href="mailto:*" />
+    <allow-intent href="geo:*" />
+    <platform name="android">
+        <allow-intent href="market:*" />
+    </platform>
+    <platform name="ios">
+        <allow-intent href="itms:*" />
+        <allow-intent href="itms-apps:*" />
+    </platform>
+</widget>

+ 23 - 0
myApp/hooks/README.md

@@ -0,0 +1,23 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+# Cordova Hooks
+
+Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system  to customize cordova commands. See Hooks Guide for more details:  http://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html#Hooks%20Guide.

+ 393 - 0
myApp/package-lock.json

@@ -0,0 +1,393 @@
+{
+    "name": "me.yoqi.myapp",
+    "version": "1.0.0",
+    "lockfileVersion": 1,
+    "requires": true,
+    "dependencies": {
+        "abbrev": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz",
+            "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg="
+        },
+        "android-versions": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npm.taobao.org/android-versions/download/android-versions-1.5.0.tgz",
+            "integrity": "sha1-d5C8dOCBKq/Wn7GtDLTbRHSlJdY=",
+            "requires": {
+                "semver": "^5.4.1"
+            }
+        },
+        "ansi": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npm.taobao.org/ansi/download/ansi-0.3.1.tgz",
+            "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE="
+        },
+        "array-ify": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npm.taobao.org/array-ify/download/array-ify-1.0.0.tgz",
+            "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4="
+        },
+        "balanced-match": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz",
+            "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+        },
+        "base64-js": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz",
+            "integrity": "sha1-WOzoy3XdB+ce0IxzarxfrE2/jfE="
+        },
+        "big-integer": {
+            "version": "1.6.48",
+            "resolved": "https://registry.npm.taobao.org/big-integer/download/big-integer-1.6.48.tgz",
+            "integrity": "sha1-j9iL0WMsukocjD49cVnwi7lbS54="
+        },
+        "bplist-parser": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npm.taobao.org/bplist-parser/download/bplist-parser-0.1.1.tgz",
+            "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=",
+            "requires": {
+                "big-integer": "^1.6.7"
+            }
+        },
+        "brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz",
+            "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
+            "requires": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "compare-func": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npm.taobao.org/compare-func/download/compare-func-1.3.2.tgz",
+            "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=",
+            "requires": {
+                "array-ify": "^1.0.0",
+                "dot-prop": "^3.0.0"
+            }
+        },
+        "concat-map": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
+            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+        },
+        "cordova-android": {
+            "version": "8.1.0",
+            "resolved": "https://registry.npm.taobao.org/cordova-android/download/cordova-android-8.1.0.tgz",
+            "integrity": "sha1-2a6mK75KTI0i/fIWFoaUOc0claA=",
+            "requires": {
+                "android-versions": "^1.4.0",
+                "compare-func": "^1.3.2",
+                "cordova-common": "^3.2.0",
+                "nopt": "^4.0.1",
+                "properties-parser": "^0.3.1",
+                "q": "^1.5.1",
+                "shelljs": "^0.5.3"
+            }
+        },
+        "cordova-common": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npm.taobao.org/cordova-common/download/cordova-common-3.2.1.tgz",
+            "integrity": "sha1-9P2+tA2QSf4ooJ+pAXVu1m0kZmE=",
+            "requires": {
+                "ansi": "^0.3.1",
+                "bplist-parser": "^0.1.0",
+                "cross-spawn": "^6.0.5",
+                "elementtree": "0.1.7",
+                "endent": "^1.1.1",
+                "fs-extra": "^8.0.0",
+                "glob": "^7.1.2",
+                "minimatch": "^3.0.0",
+                "plist": "^3.0.1",
+                "q": "^1.4.1",
+                "strip-bom": "^3.0.0",
+                "underscore": "^1.8.3",
+                "which": "^1.3.0"
+            }
+        },
+        "cordova-plugin-camera": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npm.taobao.org/cordova-plugin-camera/download/cordova-plugin-camera-4.1.0.tgz",
+            "integrity": "sha1-ZHSj4IDEZiqgD9dCVwXTAcaT3cA="
+        },
+        "cordova-plugin-whitelist": {
+            "version": "1.3.4",
+            "resolved": "https://registry.npm.taobao.org/cordova-plugin-whitelist/download/cordova-plugin-whitelist-1.3.4.tgz",
+            "integrity": "sha1-MZOFRcfD5941wgqwjCw6+gboo/k=",
+            "dev": true
+        },
+        "cross-spawn": {
+            "version": "6.0.5",
+            "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz",
+            "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=",
+            "requires": {
+                "nice-try": "^1.0.4",
+                "path-key": "^2.0.1",
+                "semver": "^5.5.0",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            }
+        },
+        "dedent": {
+            "version": "0.7.0",
+            "resolved": "https://registry.npm.taobao.org/dedent/download/dedent-0.7.0.tgz",
+            "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw="
+        },
+        "dot-prop": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npm.taobao.org/dot-prop/download/dot-prop-3.0.0.tgz?cache=0&sync_timestamp=1587903572045&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-prop%2Fdownload%2Fdot-prop-3.0.0.tgz",
+            "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=",
+            "requires": {
+                "is-obj": "^1.0.0"
+            }
+        },
+        "elementtree": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npm.taobao.org/elementtree/download/elementtree-0.1.7.tgz",
+            "integrity": "sha1-mskb5uUvtuYkTE5UpKw+2K6OKcA=",
+            "requires": {
+                "sax": "1.1.4"
+            }
+        },
+        "endent": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npm.taobao.org/endent/download/endent-1.4.1.tgz",
+            "integrity": "sha1-xYzBPfxDLQssf690wT/9ymCy0cg=",
+            "requires": {
+                "dedent": "^0.7.0",
+                "fast-json-parse": "^1.0.3",
+                "objectorarray": "^1.0.4"
+            }
+        },
+        "fast-json-parse": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npm.taobao.org/fast-json-parse/download/fast-json-parse-1.0.3.tgz",
+            "integrity": "sha1-Q+XGHuTvqSZWMwRrdw+2gqdXfE0="
+        },
+        "fs-extra": {
+            "version": "8.1.0",
+            "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-8.1.0.tgz",
+            "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=",
+            "requires": {
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^4.0.0",
+                "universalify": "^0.1.0"
+            }
+        },
+        "fs.realpath": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz",
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+        },
+        "glob": {
+            "version": "7.1.6",
+            "resolved": "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1587903587792&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz",
+            "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=",
+            "requires": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.0.4",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            }
+        },
+        "graceful-fs": {
+            "version": "4.2.4",
+            "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.4.tgz?cache=0&sync_timestamp=1588086876757&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.4.tgz",
+            "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs="
+        },
+        "inflight": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz",
+            "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+            "requires": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "inherits": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz",
+            "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w="
+        },
+        "is-obj": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz?cache=0&sync_timestamp=1587903567618&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-obj%2Fdownload%2Fis-obj-1.0.1.tgz",
+            "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
+        },
+        "isexe": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz?cache=0&sync_timestamp=1587903588227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisexe%2Fdownload%2Fisexe-2.0.0.tgz",
+            "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+        },
+        "jsonfile": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz",
+            "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+            "requires": {
+                "graceful-fs": "^4.1.6"
+            }
+        },
+        "minimatch": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz",
+            "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+            "requires": {
+                "brace-expansion": "^1.1.7"
+            }
+        },
+        "nice-try": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npm.taobao.org/nice-try/download/nice-try-1.0.5.tgz",
+            "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y="
+        },
+        "nopt": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npm.taobao.org/nopt/download/nopt-4.0.3.tgz",
+            "integrity": "sha1-o3XK2dAv2SEnjZVMIlTVqlfhXkg=",
+            "requires": {
+                "abbrev": "1",
+                "osenv": "^0.1.4"
+            }
+        },
+        "objectorarray": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npm.taobao.org/objectorarray/download/objectorarray-1.0.4.tgz",
+            "integrity": "sha1-1psvD/fcJwGQPTCLuFiC9N20lIM="
+        },
+        "once": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz",
+            "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+            "requires": {
+                "wrappy": "1"
+            }
+        },
+        "os-homedir": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npm.taobao.org/os-homedir/download/os-homedir-1.0.2.tgz",
+            "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+        },
+        "os-tmpdir": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz",
+            "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+        },
+        "osenv": {
+            "version": "0.1.5",
+            "resolved": "https://registry.npm.taobao.org/osenv/download/osenv-0.1.5.tgz",
+            "integrity": "sha1-hc36+uso6Gd/QW4odZK18/SepBA=",
+            "requires": {
+                "os-homedir": "^1.0.0",
+                "os-tmpdir": "^1.0.0"
+            }
+        },
+        "path-is-absolute": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz",
+            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+        },
+        "path-key": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-2.0.1.tgz",
+            "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+        },
+        "plist": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npm.taobao.org/plist/download/plist-3.0.1.tgz",
+            "integrity": "sha1-qbkx0XwwTokS7wujvdYYK68uH4w=",
+            "requires": {
+                "base64-js": "^1.2.3",
+                "xmlbuilder": "^9.0.7",
+                "xmldom": "0.1.x"
+            }
+        },
+        "properties-parser": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npm.taobao.org/properties-parser/download/properties-parser-0.3.1.tgz",
+            "integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=",
+            "requires": {
+                "string.prototype.codepointat": "^0.2.0"
+            }
+        },
+        "q": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz",
+            "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
+        },
+        "sax": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npm.taobao.org/sax/download/sax-1.1.4.tgz",
+            "integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk="
+        },
+        "semver": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1587903571112&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz",
+            "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc="
+        },
+        "shebang-command": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz",
+            "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+            "requires": {
+                "shebang-regex": "^1.0.0"
+            }
+        },
+        "shebang-regex": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz",
+            "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+        },
+        "shelljs": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npm.taobao.org/shelljs/download/shelljs-0.5.3.tgz",
+            "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM="
+        },
+        "string.prototype.codepointat": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npm.taobao.org/string.prototype.codepointat/download/string.prototype.codepointat-0.2.1.tgz",
+            "integrity": "sha1-AErUTIr8cnUnsQjNRitNlxzUabw="
+        },
+        "strip-bom": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npm.taobao.org/strip-bom/download/strip-bom-3.0.0.tgz?cache=0&sync_timestamp=1587903564630&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz",
+            "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
+        },
+        "underscore": {
+            "version": "1.10.2",
+            "resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.10.2.tgz",
+            "integrity": "sha1-c9aqNmjzGI5K2w8ZQ70Sz9fvqq8="
+        },
+        "universalify": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz",
+            "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY="
+        },
+        "which": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1587903591553&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz",
+            "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=",
+            "requires": {
+                "isexe": "^2.0.0"
+            }
+        },
+        "wrappy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz",
+            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+        },
+        "xmlbuilder": {
+            "version": "9.0.7",
+            "resolved": "https://registry.npm.taobao.org/xmlbuilder/download/xmlbuilder-9.0.7.tgz",
+            "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+        },
+        "xmldom": {
+            "version": "0.1.31",
+            "resolved": "https://registry.npm.taobao.org/xmldom/download/xmldom-0.1.31.tgz",
+            "integrity": "sha1-t2yaG9nwqXN+WnLcNyMc84N14v8="
+        }
+    }
+}

+ 31 - 0
myApp/package.json

@@ -0,0 +1,31 @@
+{
+  "name": "me.yoqi.myapp",
+  "displayName": "myApp",
+  "version": "1.0.0",
+  "description": "A sample Apache Cordova application that responds to the deviceready event.",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [
+    "ecosystem:cordova"
+  ],
+  "author": "Apache Cordova Team",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "cordova-android": "8.1.0",
+    "cordova-plugin-camera": "4.1.0"
+  },
+  "cordova": {
+    "plugins": {
+      "cordova-plugin-camera": {},
+      "cordova-plugin-whitelist": {}
+    },
+    "platforms": [
+      "android"
+    ]
+  },
+  "devDependencies": {
+    "cordova-plugin-whitelist": "^1.3.4"
+  }
+}

+ 21 - 0
myApp/platforms/android/.gitignore

@@ -0,0 +1,21 @@
+# Non-project-specific build files:
+build.xml
+local.properties
+/gradlew
+/gradlew.bat
+/gradle
+# Ant builds
+ant-build
+ant-gen
+# Eclipse builds
+gen
+out
+# Gradle build artifacts
+.gradle
+.gradletasknamecache
+/build
+/CordovaLib/build
+/app/build
+gradle-app.setting
+# Android Studio
+.idea

+ 22 - 0
myApp/platforms/android/CordovaLib/AndroidManifest.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
+</manifest>

+ 148 - 0
myApp/platforms/android/CordovaLib/build.gradle

@@ -0,0 +1,148 @@
+/* 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.
+*/
+
+ext {
+    apply from: 'cordova.gradle'
+    cdvCompileSdkVersion = privateHelpers.getProjectTarget()
+    cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
+}
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+
+    dependencies {
+        // The gradle plugin and the maven plugin have to be updated after each version of Android
+        // studio comes out
+        classpath 'com.android.tools.build:gradle:3.3.0'
+        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
+        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+apply plugin: 'com.jfrog.bintray'
+
+group = 'org.apache.cordova'
+version = '8.1.0'
+
+android {
+    compileSdkVersion cdvCompileSdkVersion
+    buildToolsVersion cdvBuildToolsVersion
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    // For the Android Cordova Lib, we will hardcode the minSdkVersion and not allow changes.
+    defaultConfig {
+        minSdkVersion 19
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            java.srcDirs = ['src']
+            resources.srcDirs = ['src']
+            aidl.srcDirs = ['src']
+            renderscript.srcDirs = ['src']
+            res.srcDirs = ['res']
+            assets.srcDirs = ['assets']
+        }
+    }
+
+    packagingOptions {
+        exclude 'META-INF/LICENSE'
+        exclude 'META-INF/LICENSE.txt'
+        exclude 'META-INF/DEPENDENCIES'
+        exclude 'META-INF/NOTICE'
+    }
+}
+
+install {
+    repositories.mavenInstaller {
+        pom {
+            project {
+                packaging 'aar'
+                name 'Cordova'
+                url 'https://cordova.apache.org'
+                licenses {
+                    license {
+                        name 'The Apache Software License, Version 2.0'
+                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+                    }
+                }
+                developers {
+                    developer {
+                        id 'stevengill'
+                        name 'Steve Gill'
+                    }
+                }
+                scm {
+                    connection 'scm:git:https://github.com/apache/cordova-android.git'
+                    developerConnection 'scm:git:git@github.com:apache/cordova-android.git'
+                    url 'https://github.com/apache/cordova-android'
+
+                }
+            }
+        }
+    }
+}
+
+task sourcesJar(type: Jar) {
+    from android.sourceSets.main.java.srcDirs
+    classifier = 'sources'
+}
+
+artifacts {
+    archives sourcesJar
+}
+
+bintray {
+    user = System.getenv('BINTRAY_USER')
+    key = System.getenv('BINTRAY_KEY')
+    configurations = ['archives']
+    pkg {
+        repo = 'maven'
+        name = 'cordova-android'
+        userOrg = 'cordova'
+        licenses = ['Apache-2.0']
+        vcsUrl = 'https://github.com/apache/cordova-android'
+        websiteUrl = 'https://cordova.apache.org'
+        issueTrackerUrl = 'https://github.com/apache/cordova-android/issues'
+        publicDownloadNumbers = true
+        licenses = ['Apache-2.0']
+        labels = ['android', 'cordova', 'phonegap']
+        version {
+            name = '8.1.0'
+            released  = new Date()
+            vcsTag = '8.1.0'
+        }
+    }
+}

+ 205 - 0
myApp/platforms/android/CordovaLib/cordova.gradle

@@ -0,0 +1,205 @@
+/*
+       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.
+*/
+
+import java.util.regex.Pattern
+import groovy.swing.SwingBuilder
+
+String doEnsureValueExists(filePath, props, key) {
+    if (props.get(key) == null) {
+        throw new GradleException(filePath + ': Missing key required "' + key + '"')
+    }
+    return props.get(key)
+}
+
+String doGetProjectTarget() {
+    def props = new Properties()
+    def propertiesFile = 'project.properties';
+    if(!(file(propertiesFile).exists())) {
+      propertiesFile = '../project.properties';
+    }
+    file(propertiesFile).withReader { reader ->
+        props.load(reader)
+    }
+    return doEnsureValueExists('project.properties', props, 'target')
+}
+
+String[] getAvailableBuildTools() {
+    def buildToolsDir = new File(getAndroidSdkDir(), "build-tools")
+    buildToolsDir.list()
+        .findAll { it ==~ /[0-9.]+/ }
+        .sort { a, b -> compareVersions(b, a) }
+}
+
+String doFindLatestInstalledBuildTools(String minBuildToolsVersion) {
+    def availableBuildToolsVersions
+    try {
+        availableBuildToolsVersions = getAvailableBuildTools()
+    } catch (e) {
+        println "An exception occurred while trying to find the Android build tools."
+        throw e
+    }
+    if (availableBuildToolsVersions.length > 0) {
+        def highestBuildToolsVersion = availableBuildToolsVersions[0]
+        if (compareVersions(highestBuildToolsVersion, minBuildToolsVersion) < 0) {
+            throw new RuntimeException(
+                "No usable Android build tools found. Highest installed version is " +
+                highestBuildToolsVersion + "; minimum version required is " +
+                minBuildToolsVersion + ".")
+        }
+        highestBuildToolsVersion
+    } else {
+        throw new RuntimeException(
+            "No installed build tools found. Install the Android build tools version " +
+            minBuildToolsVersion + " or higher.")
+    }
+}
+
+// Return the first non-zero result of subtracting version list elements
+// pairwise. If they are all identical, return the difference in length of
+// the two lists.
+int compareVersionList(Collection aParts, Collection bParts) {
+    def pairs = ([aParts, bParts]).transpose()
+    pairs.findResult(aParts.size()-bParts.size()) {it[0] - it[1] != 0 ? it[0] - it[1] : null}
+}
+
+// Compare two version strings, such as "19.0.0" and "18.1.1.0". If all matched
+// elements are identical, the longer version is the largest by this method.
+// Examples:
+//   "19.0.0" > "19"
+//   "19.0.1" > "19.0.0"
+//   "19.1.0" > "19.0.1"
+//   "19" > "18.999.999"
+int compareVersions(String a, String b) {
+    def aParts = a.tokenize('.').collect {it.toInteger()}
+    def bParts = b.tokenize('.').collect {it.toInteger()}
+    compareVersionList(aParts, bParts)
+}
+
+String getAndroidSdkDir() {
+    def rootDir = project.rootDir
+    def androidSdkDir = null
+    String envVar = System.getenv("ANDROID_HOME")
+    def localProperties = new File(rootDir, 'local.properties')
+    String systemProperty = System.getProperty("android.home")
+    if (envVar != null) {
+        androidSdkDir = envVar
+    } else if (localProperties.exists()) {
+        Properties properties = new Properties()
+        localProperties.withInputStream { instr ->
+            properties.load(instr)
+        }
+        def sdkDirProp = properties.getProperty('sdk.dir')
+        if (sdkDirProp != null) {
+            androidSdkDir = sdkDirProp
+        } else {
+            sdkDirProp = properties.getProperty('android.dir')
+            if (sdkDirProp != null) {
+                androidSdkDir = (new File(rootDir, sdkDirProp)).getAbsolutePath()
+            }
+        }
+    }
+    if (androidSdkDir == null && systemProperty != null) {
+        androidSdkDir = systemProperty
+    }
+    if (androidSdkDir == null) {
+        throw new RuntimeException(
+            "Unable to determine Android SDK directory.")
+    }
+    androidSdkDir
+}
+
+def doExtractIntFromManifest(name) {
+    def manifestFile = file(android.sourceSets.main.manifest.srcFile)
+    def pattern = Pattern.compile(name + "=\"(\\d+)\"")
+    def matcher = pattern.matcher(manifestFile.getText())
+    matcher.find()
+    return new BigInteger(matcher.group(1))
+}
+
+def doExtractStringFromManifest(name) {
+    def manifestFile = file(android.sourceSets.main.manifest.srcFile)
+    def pattern = Pattern.compile(name + "=\"(\\S+)\"")
+    def matcher = pattern.matcher(manifestFile.getText())
+    matcher.find()
+    return matcher.group(1)
+}
+
+def doPromptForPassword(msg) {
+    if (System.console() == null) {
+        def ret = null
+        new SwingBuilder().edt {
+            dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {
+                vbox {
+                    label(text: msg)
+                    def input = passwordField()
+                    button(defaultButton: true, text: 'OK', actionPerformed: {
+                        ret = input.password;
+                        dispose();
+                    })
+                }
+            }
+        }
+        if (!ret) {
+            throw new GradleException('User canceled build')
+        }
+        return new String(ret)
+    } else {
+        return System.console().readPassword('\n' + msg);
+    }
+}
+
+def doGetConfigXml() {
+    def xml = file("src/main/res/xml/config.xml").getText()
+    // Disable namespace awareness since Cordova doesn't use them properly
+    return new XmlParser(false, false).parseText(xml)
+}
+
+def doGetConfigPreference(name, defaultValue) {
+    name = name.toLowerCase()
+    def root = doGetConfigXml()
+
+    def ret = defaultValue
+    root.preference.each { it ->
+        def attrName = it.attribute("name")
+        if (attrName && attrName.toLowerCase() == name) {
+            ret = it.attribute("value")
+        }
+    }
+    return ret
+}
+
+// Properties exported here are visible to all plugins.
+ext {
+    // These helpers are shared, but are not guaranteed to be stable / unchanged.
+    privateHelpers = {}
+    privateHelpers.getProjectTarget = { doGetProjectTarget() }
+    privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') }
+    privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
+    privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
+    privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) }
+    privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
+
+    // These helpers can be used by plugins / projects and will not change.
+    cdvHelpers = {}
+    // Returns a XmlParser for the config.xml. Added in 4.1.0.
+    cdvHelpers.getConfigXml = { doGetConfigXml() }
+    // Returns the value for the desired <preference>. Added in 4.1.0.
+    cdvHelpers.getConfigPreference = { name, defaultValue -> doGetConfigPreference(name, defaultValue) }
+}
+

+ 11 - 0
myApp/platforms/android/CordovaLib/project.properties

@@ -0,0 +1,11 @@
+# This file was originally created by the Android Tools, but is now
+# used by cordova-android to manage the project configuration.
+
+# Indicates whether an apk should be generated for each density.
+split.density=false
+
+# Project target.
+target=android-28
+apk-configurations=
+renderscript.opt.level=O0
+android.library=true

+ 69 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/AuthenticationToken.java

@@ -0,0 +1,69 @@
+/*
+       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;
+
+/**
+ * The Class AuthenticationToken defines the userName and password to be used for authenticating a web resource
+ */
+public class AuthenticationToken {
+    private String userName;
+    private String password;
+
+    /**
+     * Gets the user name.
+     *
+     * @return the user name
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    /**
+     * Sets the user name.
+     *
+     * @param userName
+     *            the new user name
+     */
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    /**
+     * Gets the password.
+     *
+     * @return the password
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * Sets the password.
+     *
+     * @param password
+     *            the new password
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+
+
+
+}

+ 70 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/BuildHelper.java

@@ -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;
+    }
+
+}

+ 142 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java

@@ -0,0 +1,142 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import org.json.JSONArray;
+
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.PluginResult;
+import org.json.JSONObject;
+
+public class CallbackContext {
+    private static final String LOG_TAG = "CordovaPlugin";
+
+    private String callbackId;
+    private CordovaWebView webView;
+    protected boolean finished;
+    private int changingThreads;
+
+    public CallbackContext(String callbackId, CordovaWebView webView) {
+        this.callbackId = callbackId;
+        this.webView = webView;
+    }
+
+    public boolean isFinished() {
+        return finished;
+    }
+
+    public boolean isChangingThreads() {
+        return changingThreads > 0;
+    }
+
+    public String getCallbackId() {
+        return callbackId;
+    }
+
+    public void sendPluginResult(PluginResult pluginResult) {
+        synchronized (this) {
+            if (finished) {
+                LOG.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage());
+                return;
+            } else {
+                finished = !pluginResult.getKeepCallback();
+            }
+        }
+        webView.sendPluginResult(pluginResult, callbackId);
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(JSONObject message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(String message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(JSONArray message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(byte[] message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(int message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     */
+    public void success() {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK));
+    }
+
+    /**
+     * Helper for error callbacks that just returns the Status.ERROR by default
+     *
+     * @param message           The message to add to the error result.
+     */
+    public void error(JSONObject message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+    }
+
+    /**
+     * Helper for error callbacks that just returns the Status.ERROR by default
+     *
+     * @param message           The message to add to the error result.
+     */
+    public void error(String message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+    }
+
+    /**
+     * Helper for error callbacks that just returns the Status.ERROR by default
+     *
+     * @param message           The message to add to the error result.
+     */
+    public void error(int message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+    }
+}

+ 65 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CallbackMap.java

@@ -0,0 +1,65 @@
+/*
+       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 android.util.Pair;
+import android.util.SparseArray;
+
+/**
+ * Provides a collection that maps unique request codes to CordovaPlugins and Integers.
+ * Used to ensure that when plugins make requests for runtime permissions, those requests do not
+ * collide with requests from other plugins that use the same request code value.
+ */
+public class CallbackMap {
+    private int currentCallbackId = 0;
+    private SparseArray<Pair<CordovaPlugin, Integer>> callbacks;
+
+    public CallbackMap() {
+        this.callbacks = new SparseArray<Pair<CordovaPlugin, Integer>>();
+    }
+
+    /**
+     * Stores a CordovaPlugin and request code and returns a new unique request code to use
+     * in a permission request.
+     *
+     * @param receiver      The plugin that is making the request
+     * @param requestCode   The original request code used by the plugin
+     * @return              A unique request code that can be used to retrieve this callback
+     *                      with getAndRemoveCallback()
+     */
+    public synchronized int registerCallback(CordovaPlugin receiver, int requestCode) {
+        int mappedId = this.currentCallbackId++;
+        callbacks.put(mappedId, new Pair<CordovaPlugin, Integer>(receiver, requestCode));
+        return mappedId;
+    }
+
+    /**
+     * Retrieves and removes a callback stored in the map using the mapped request code
+     * obtained from registerCallback()
+     *
+     * @param mappedId      The request code obtained from registerCallback()
+     * @return              The CordovaPlugin and orignal request code that correspond to the
+     *                      given mappedCode
+     */
+    public synchronized Pair<CordovaPlugin, Integer> getAndRemoveCallback(int mappedId) {
+        Pair<CordovaPlugin, Integer> callback = callbacks.get(mappedId);
+        callbacks.remove(mappedId);
+        return callback;
+    }
+}

+ 71 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/Config.java

@@ -0,0 +1,71 @@
+/*
+       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.List;
+
+import android.app.Activity;
+
+@Deprecated // Use Whitelist, CordovaPrefences, etc. directly.
+public class Config {
+    private static final String TAG = "Config";
+
+    static ConfigXmlParser parser;
+
+    private Config() {
+    }
+
+    public static void init(Activity action) {
+        parser = new ConfigXmlParser();
+        parser.parse(action);
+        //TODO: Add feature to bring this back.  Some preferences should be overridden by intents, but not all
+        parser.getPreferences().setPreferencesBundle(action.getIntent().getExtras());
+    }
+
+    // Intended to be used for testing only; creates an empty configuration.
+    public static void init() {
+        if (parser == null) {
+            parser = new ConfigXmlParser();
+        }
+    }
+
+    public static String getStartUrl() {
+        if (parser == null) {
+            return "file:///android_asset/www/index.html";
+        }
+        return parser.getLaunchUrl();
+    }
+
+    public static String getErrorUrl() {
+        return parser.getPreferences().getString("errorurl", null);
+    }
+
+    public static List<PluginEntry> getPluginEntries() {
+        return parser.getPluginEntries();
+    }
+
+    public static CordovaPreferences getPreferences() {
+        return parser.getPreferences();
+    }
+
+    public static boolean isInitialized() {
+        return parser != null;
+    }
+}

+ 145 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/ConfigXmlParser.java

@@ -0,0 +1,145 @@
+/*
+       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.io.IOException;
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+
+public class ConfigXmlParser {
+    private static String TAG = "ConfigXmlParser";
+
+    private String launchUrl = "file:///android_asset/www/index.html";
+    private CordovaPreferences prefs = new CordovaPreferences();
+    private ArrayList<PluginEntry> pluginEntries = new ArrayList<PluginEntry>(20);
+
+    public CordovaPreferences getPreferences() {
+        return prefs;
+    }
+
+    public ArrayList<PluginEntry> getPluginEntries() {
+        return pluginEntries;
+    }
+
+    public String getLaunchUrl() {
+        return launchUrl;
+    }
+
+    public void parse(Context action) {
+        // First checking the class namespace for config.xml
+        int id = action.getResources().getIdentifier("config", "xml", action.getClass().getPackage().getName());
+        if (id == 0) {
+            // If we couldn't find config.xml there, we'll look in the namespace from AndroidManifest.xml
+            id = action.getResources().getIdentifier("config", "xml", action.getPackageName());
+            if (id == 0) {
+                LOG.e(TAG, "res/xml/config.xml is missing!");
+                return;
+            }
+        }
+        parse(action.getResources().getXml(id));
+    }
+
+    boolean insideFeature = false;
+    String service = "", pluginClass = "", paramType = "";
+    boolean onload = false;
+
+    public void parse(XmlPullParser xml) {
+        int eventType = -1;
+
+        while (eventType != XmlPullParser.END_DOCUMENT) {
+            if (eventType == XmlPullParser.START_TAG) {
+                handleStartTag(xml);
+            }
+            else if (eventType == XmlPullParser.END_TAG)
+            {
+                handleEndTag(xml);
+            }
+            try {
+                eventType = xml.next();
+            } catch (XmlPullParserException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void handleStartTag(XmlPullParser xml) {
+        String strNode = xml.getName();
+        if (strNode.equals("feature")) {
+            //Check for supported feature sets  aka. plugins (Accelerometer, Geolocation, etc)
+            //Set the bit for reading params
+            insideFeature = true;
+            service = xml.getAttributeValue(null, "name");
+        }
+        else if (insideFeature && strNode.equals("param")) {
+            paramType = xml.getAttributeValue(null, "name");
+            if (paramType.equals("service")) // check if it is using the older service param
+                service = xml.getAttributeValue(null, "value");
+            else if (paramType.equals("package") || paramType.equals("android-package"))
+                pluginClass = xml.getAttributeValue(null,"value");
+            else if (paramType.equals("onload"))
+                onload = "true".equals(xml.getAttributeValue(null, "value"));
+        }
+        else if (strNode.equals("preference")) {
+            String name = xml.getAttributeValue(null, "name").toLowerCase(Locale.ENGLISH);
+            String value = xml.getAttributeValue(null, "value");
+            prefs.set(name, value);
+        }
+        else if (strNode.equals("content")) {
+            String src = xml.getAttributeValue(null, "src");
+            if (src != null) {
+                setStartUrl(src);
+            }
+        }
+    }
+
+    public void handleEndTag(XmlPullParser xml) {
+        String strNode = xml.getName();
+        if (strNode.equals("feature")) {
+            pluginEntries.add(new PluginEntry(service, pluginClass, onload));
+
+            service = "";
+            pluginClass = "";
+            insideFeature = false;
+            onload = false;
+        }
+    }
+
+    private void setStartUrl(String src) {
+        Pattern schemeRegex = Pattern.compile("^[a-z-]+://");
+        Matcher matcher = schemeRegex.matcher(src);
+        if (matcher.find()) {
+            launchUrl = src;
+        } else {
+            if (src.charAt(0) == '/') {
+                src = src.substring(1);
+            }
+            launchUrl = "file:///android_asset/www/" + src;
+        }
+    }
+}

+ 521 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaActivity.java

@@ -0,0 +1,521 @@
+/*
+       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.ArrayList;
+import java.util.Locale;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.annotation.SuppressLint;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.media.AudioManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.webkit.WebViewClient;
+import android.widget.FrameLayout;
+
+/**
+ * This class is the main Android activity that represents the Cordova
+ * application. It should be extended by the user to load the specific
+ * html file that contains the application.
+ *
+ * As an example:
+ *
+ * <pre>
+ *     package org.apache.cordova.examples;
+ *
+ *     import android.os.Bundle;
+ *     import org.apache.cordova.*;
+ *
+ *     public class Example extends CordovaActivity {
+ *       &#64;Override
+ *       public void onCreate(Bundle savedInstanceState) {
+ *         super.onCreate(savedInstanceState);
+ *         super.init();
+ *         // Load your application
+ *         loadUrl(launchUrl);
+ *       }
+ *     }
+ * </pre>
+ *
+ * Cordova xml configuration: Cordova uses a configuration file at
+ * res/xml/config.xml to specify its settings. See "The config.xml File"
+ * guide in cordova-docs at http://cordova.apache.org/docs for the documentation
+ * for the configuration. The use of the set*Property() methods is
+ * deprecated in favor of the config.xml file.
+ *
+ */
+public class CordovaActivity extends Activity {
+    public static String TAG = "CordovaActivity";
+
+    // The webview for our app
+    protected CordovaWebView appView;
+
+    private static int ACTIVITY_STARTING = 0;
+    private static int ACTIVITY_RUNNING = 1;
+    private static int ACTIVITY_EXITING = 2;
+
+    // Keep app running when pause is received. (default = true)
+    // If true, then the JavaScript and native code continue to run in the background
+    // when another application (activity) is started.
+    protected boolean keepRunning = true;
+
+    // Flag to keep immersive mode if set to fullscreen
+    protected boolean immersiveMode;
+
+    // Read from config.xml:
+    protected CordovaPreferences preferences;
+    protected String launchUrl;
+    protected ArrayList<PluginEntry> pluginEntries;
+    protected CordovaInterfaceImpl cordovaInterface;
+
+    /**
+     * Called when the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        // need to activate preferences before super.onCreate to avoid "requestFeature() must be called before adding content" exception
+        loadConfig();
+
+        String logLevel = preferences.getString("loglevel", "ERROR");
+        LOG.setLogLevel(logLevel);
+
+        LOG.i(TAG, "Apache Cordova native platform version " + CordovaWebView.CORDOVA_VERSION + " is starting");
+        LOG.d(TAG, "CordovaActivity.onCreate()");
+
+        if (!preferences.getBoolean("ShowTitle", false)) {
+            getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        }
+
+        if (preferences.getBoolean("SetFullscreen", false)) {
+            LOG.d(TAG, "The SetFullscreen configuration is deprecated in favor of Fullscreen, and will be removed in a future version.");
+            preferences.set("Fullscreen", true);
+        }
+        if (preferences.getBoolean("Fullscreen", false)) {
+            // NOTE: use the FullscreenNotImmersive configuration key to set the activity in a REAL full screen
+            // (as was the case in previous cordova versions)
+            if (!preferences.getBoolean("FullscreenNotImmersive", false)) {
+                immersiveMode = true;
+            } else {
+                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
+            }
+        } else {
+            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
+                    WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        }
+
+        super.onCreate(savedInstanceState);
+
+        cordovaInterface = makeCordovaInterface();
+        if (savedInstanceState != null) {
+            cordovaInterface.restoreInstanceState(savedInstanceState);
+        }
+    }
+
+    protected void init() {
+        appView = makeWebView();
+        createViews();
+        if (!appView.isInitialized()) {
+            appView.init(cordovaInterface, pluginEntries, preferences);
+        }
+        cordovaInterface.onCordovaInit(appView.getPluginManager());
+
+        // Wire the hardware volume controls to control media if desired.
+        String volumePref = preferences.getString("DefaultVolumeStream", "");
+        if ("media".equals(volumePref.toLowerCase(Locale.ENGLISH))) {
+            setVolumeControlStream(AudioManager.STREAM_MUSIC);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void loadConfig() {
+        ConfigXmlParser parser = new ConfigXmlParser();
+        parser.parse(this);
+        preferences = parser.getPreferences();
+        preferences.setPreferencesBundle(getIntent().getExtras());
+        launchUrl = parser.getLaunchUrl();
+        pluginEntries = parser.getPluginEntries();
+        Config.parser = parser;
+    }
+
+    //Suppressing warnings in AndroidStudio
+    @SuppressWarnings({"deprecation", "ResourceType"})
+    protected void createViews() {
+        //Why are we setting a constant as the ID? This should be investigated
+        appView.getView().setId(100);
+        appView.getView().setLayoutParams(new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+
+        setContentView(appView.getView());
+
+        if (preferences.contains("BackgroundColor")) {
+            try {
+                int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK);
+                // Background of activity:
+                appView.getView().setBackgroundColor(backgroundColor);
+            }
+            catch (NumberFormatException e){
+                e.printStackTrace();
+            }
+        }
+
+        appView.getView().requestFocusFromTouch();
+    }
+
+    /**
+     * Construct the default web view object.
+     * <p/>
+     * Override this to customize the webview that is used.
+     */
+    protected CordovaWebView makeWebView() {
+        return new CordovaWebViewImpl(makeWebViewEngine());
+    }
+
+    protected CordovaWebViewEngine makeWebViewEngine() {
+        return CordovaWebViewImpl.createEngine(this, preferences);
+    }
+
+    protected CordovaInterfaceImpl makeCordovaInterface() {
+        return new CordovaInterfaceImpl(this) {
+            @Override
+            public Object onMessage(String id, Object data) {
+                // Plumb this to CordovaActivity.onMessage for backwards compatibility
+                return CordovaActivity.this.onMessage(id, data);
+            }
+        };
+    }
+
+    /**
+     * Load the url into the webview.
+     */
+    public void loadUrl(String url) {
+        if (appView == null) {
+            init();
+        }
+
+        // If keepRunning
+        this.keepRunning = preferences.getBoolean("KeepRunning", true);
+
+        appView.loadUrlIntoView(url, true);
+    }
+
+    /**
+     * Called when the system is about to start resuming a previous activity.
+     */
+    @Override
+    protected void onPause() {
+        super.onPause();
+        LOG.d(TAG, "Paused the activity.");
+
+        if (this.appView != null) {
+            // CB-9382 If there is an activity that started for result and main activity is waiting for callback
+            // result, we shoudn't stop WebView Javascript timers, as activity for result might be using them
+            boolean keepRunning = this.keepRunning || this.cordovaInterface.activityResultCallback != null;
+            this.appView.handlePause(keepRunning);
+        }
+    }
+
+    /**
+     * Called when the activity receives a new intent
+     */
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        //Forward to plugins
+        if (this.appView != null)
+            this.appView.onNewIntent(intent);
+    }
+
+    /**
+     * Called when the activity will start interacting with the user.
+     */
+    @Override
+    protected void onResume() {
+        super.onResume();
+        LOG.d(TAG, "Resumed the activity.");
+
+        if (this.appView == null) {
+            return;
+        }
+        if (! this.getWindow().getDecorView().hasFocus()) {
+            // Force window to have focus, so application always
+            // receive user input. Workaround for some devices (Samsung Galaxy Note 3 at least)
+            this.getWindow().getDecorView().requestFocus();
+        }
+
+        this.appView.handleResume(this.keepRunning);
+    }
+
+    /**
+     * Called when the activity is no longer visible to the user.
+     */
+    @Override
+    protected void onStop() {
+        super.onStop();
+        LOG.d(TAG, "Stopped the activity.");
+
+        if (this.appView == null) {
+            return;
+        }
+        this.appView.handleStop();
+    }
+
+    /**
+     * Called when the activity is becoming visible to the user.
+     */
+    @Override
+    protected void onStart() {
+        super.onStart();
+        LOG.d(TAG, "Started the activity.");
+
+        if (this.appView == null) {
+            return;
+        }
+        this.appView.handleStart();
+    }
+
+    /**
+     * The final call you receive before your activity is destroyed.
+     */
+    @Override
+    public void onDestroy() {
+        LOG.d(TAG, "CordovaActivity.onDestroy()");
+        super.onDestroy();
+
+        if (this.appView != null) {
+            appView.handleDestroy();
+        }
+    }
+
+    /**
+     * Called when view focus is changed
+     */
+    @SuppressLint("InlinedApi")
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        if (hasFocus && immersiveMode) {
+            final int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+
+            getWindow().getDecorView().setSystemUiVisibility(uiOptions);
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
+        // Capture requestCode here so that it is captured in the setActivityResultCallback() case.
+        cordovaInterface.setActivityResultRequestCode(requestCode);
+        super.startActivityForResult(intent, requestCode, options);
+    }
+
+    /**
+     * Called when an activity you launched exits, giving you the requestCode you started it with,
+     * the resultCode it returned, and any additional data from it.
+     *
+     * @param requestCode The request code originally supplied to startActivityForResult(),
+     *                    allowing you to identify who this result came from.
+     * @param resultCode  The integer result code returned by the child activity through its setResult().
+     * @param intent      An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        LOG.d(TAG, "Incoming Result. Request code = " + requestCode);
+        super.onActivityResult(requestCode, resultCode, intent);
+        cordovaInterface.onActivityResult(requestCode, resultCode, intent);
+    }
+
+    /**
+     * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable).
+     * The errorCode parameter corresponds to one of the ERROR_* constants.
+     *
+     * @param errorCode   The error code corresponding to an ERROR_* value.
+     * @param description A String describing the error.
+     * @param failingUrl  The url that failed to load.
+     */
+    public void onReceivedError(final int errorCode, final String description, final String failingUrl) {
+        final CordovaActivity me = this;
+
+        // If errorUrl specified, then load it
+        final String errorUrl = preferences.getString("errorUrl", null);
+        if ((errorUrl != null) && (!failingUrl.equals(errorUrl)) && (appView != null)) {
+            // Load URL on UI thread
+            me.runOnUiThread(new Runnable() {
+                public void run() {
+                    me.appView.showWebPage(errorUrl, false, true, null);
+                }
+            });
+        }
+        // If not, then display error dialog
+        else {
+            final boolean exit = !(errorCode == WebViewClient.ERROR_HOST_LOOKUP);
+            me.runOnUiThread(new Runnable() {
+                public void run() {
+                    if (exit) {
+                        me.appView.getView().setVisibility(View.GONE);
+                        me.displayError("Application Error", description + " (" + failingUrl + ")", "OK", exit);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Display an error dialog and optionally exit application.
+     */
+    public void displayError(final String title, final String message, final String button, final boolean exit) {
+        final CordovaActivity me = this;
+        me.runOnUiThread(new Runnable() {
+            public void run() {
+                try {
+                    AlertDialog.Builder dlg = new AlertDialog.Builder(me);
+                    dlg.setMessage(message);
+                    dlg.setTitle(title);
+                    dlg.setCancelable(false);
+                    dlg.setPositiveButton(button,
+                            new AlertDialog.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int which) {
+                                    dialog.dismiss();
+                                    if (exit) {
+                                        finish();
+                                    }
+                                }
+                            });
+                    dlg.create();
+                    dlg.show();
+                } catch (Exception e) {
+                    finish();
+                }
+            }
+        });
+    }
+
+    /*
+     * Hook in Cordova for menu plugins
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        if (appView != null) {
+            appView.getPluginManager().postMessage("onCreateOptionsMenu", menu);
+        }
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        if (appView != null) {
+            appView.getPluginManager().postMessage("onPrepareOptionsMenu", menu);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (appView != null) {
+            appView.getPluginManager().postMessage("onOptionsItemSelected", item);
+        }
+        return true;
+    }
+
+    /**
+     * Called when a message is sent to plugin.
+     *
+     * @param id   The message id
+     * @param data The message data
+     * @return Object or null
+     */
+    public Object onMessage(String id, Object data) {
+        if ("onReceivedError".equals(id)) {
+            JSONObject d = (JSONObject) data;
+            try {
+                this.onReceivedError(d.getInt("errorCode"), d.getString("description"), d.getString("url"));
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        } else if ("exit".equals(id)) {
+            finish();
+        }
+        return null;
+    }
+
+    protected void onSaveInstanceState(Bundle outState) {
+        cordovaInterface.onSaveInstanceState(outState);
+        super.onSaveInstanceState(outState);
+    }
+
+    /**
+     * Called by the system when the device configuration changes while your activity is running.
+     *
+     * @param newConfig The new device configuration
+     */
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (this.appView == null) {
+            return;
+        }
+        PluginManager pm = this.appView.getPluginManager();
+        if (pm != null) {
+            pm.onConfigurationChanged(newConfig);
+        }
+    }
+
+    /**
+     * Called by the system when the user grants permissions
+     *
+     * @param requestCode
+     * @param permissions
+     * @param grantResults
+     */
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String permissions[],
+                                           int[] grantResults) {
+        try
+        {
+            cordovaInterface.onRequestPermissionResult(requestCode, permissions, grantResults);
+        }
+        catch (JSONException e)
+        {
+            LOG.d(TAG, "JSONException: Parameters fed into the method are not valid");
+            e.printStackTrace();
+        }
+
+    }
+
+}

+ 113 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaArgs.java

@@ -0,0 +1,113 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.util.Base64;
+
+public class CordovaArgs {
+    private JSONArray baseArgs;
+
+    public CordovaArgs(JSONArray args) {
+        this.baseArgs = args;
+    }
+
+
+    // Pass through the basics to the base args.
+    public Object get(int index) throws JSONException {
+        return baseArgs.get(index);
+    }
+
+    public boolean getBoolean(int index) throws JSONException {
+        return baseArgs.getBoolean(index);
+    }
+
+    public double getDouble(int index) throws JSONException {
+        return baseArgs.getDouble(index);
+    }
+
+    public int getInt(int index) throws JSONException {
+        return baseArgs.getInt(index);
+    }
+
+    public JSONArray getJSONArray(int index) throws JSONException {
+        return baseArgs.getJSONArray(index);
+    }
+
+    public JSONObject getJSONObject(int index) throws JSONException {
+        return baseArgs.getJSONObject(index);
+    }
+
+    public long getLong(int index) throws JSONException {
+        return baseArgs.getLong(index);
+    }
+
+    public String getString(int index) throws JSONException {
+        return baseArgs.getString(index);
+    }
+
+
+    public Object opt(int index) {
+        return baseArgs.opt(index);
+    }
+
+    public boolean optBoolean(int index) {
+        return baseArgs.optBoolean(index);
+    }
+
+    public double optDouble(int index) {
+        return baseArgs.optDouble(index);
+    }
+
+    public int optInt(int index) {
+        return baseArgs.optInt(index);
+    }
+
+    public JSONArray optJSONArray(int index) {
+        return baseArgs.optJSONArray(index);
+    }
+
+    public JSONObject optJSONObject(int index) {
+        return baseArgs.optJSONObject(index);
+    }
+
+    public long optLong(int index) {
+        return baseArgs.optLong(index);
+    }
+
+    public String optString(int index) {
+        return baseArgs.optString(index);
+    }
+
+    public boolean isNull(int index) {
+        return baseArgs.isNull(index);
+    }
+
+
+    // The interesting custom helpers.
+    public byte[] getArrayBuffer(int index) throws JSONException {
+        String encoded = baseArgs.getString(index);
+        return Base64.decode(encoded, Base64.DEFAULT);
+    }
+}
+
+

+ 187 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java

@@ -0,0 +1,187 @@
+/*
+       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 android.annotation.SuppressLint;
+
+import java.security.SecureRandom;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+/**
+ * Contains APIs that the JS can call. All functions in here should also have
+ * an equivalent entry in CordovaChromeClient.java, and be added to
+ * cordova-js/lib/android/plugin/android/promptbasednativeapi.js
+ */
+public class CordovaBridge {
+    private static final String LOG_TAG = "CordovaBridge";
+    private PluginManager pluginManager;
+    private NativeToJsMessageQueue jsMessageQueue;
+    private volatile int expectedBridgeSecret = -1; // written by UI thread, read by JS thread.
+
+    public CordovaBridge(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue) {
+        this.pluginManager = pluginManager;
+        this.jsMessageQueue = jsMessageQueue;
+    }
+
+    public String jsExec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
+        if (!verifySecret("exec()", bridgeSecret)) {
+            return null;
+        }
+        // If the arguments weren't received, send a message back to JS.  It will switch bridge modes and try again.  See CB-2666.
+        // We send a message meant specifically for this case.  It starts with "@" so no other message can be encoded into the same string.
+        if (arguments == null) {
+            return "@Null arguments.";
+        }
+
+        jsMessageQueue.setPaused(true);
+        try {
+            // Tell the resourceApi what thread the JS is running on.
+            CordovaResourceApi.jsThread = Thread.currentThread();
+
+            pluginManager.exec(service, action, callbackId, arguments);
+            String ret = null;
+            if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
+                ret = jsMessageQueue.popAndEncode(false);
+            }
+            return ret;
+        } catch (Throwable e) {
+            e.printStackTrace();
+            return "";
+        } finally {
+            jsMessageQueue.setPaused(false);
+        }
+    }
+
+    public void jsSetNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
+        if (!verifySecret("setNativeToJsBridgeMode()", bridgeSecret)) {
+            return;
+        }
+        jsMessageQueue.setBridgeMode(value);
+    }
+
+    public String jsRetrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
+        if (!verifySecret("retrieveJsMessages()", bridgeSecret)) {
+            return null;
+        }
+        return jsMessageQueue.popAndEncode(fromOnlineEvent);
+    }
+
+    private boolean verifySecret(String action, int bridgeSecret) throws IllegalAccessException {
+        if (!jsMessageQueue.isBridgeEnabled()) {
+            if (bridgeSecret == -1) {
+                LOG.d(LOG_TAG, action + " call made before bridge was enabled.");
+            } else {
+                LOG.d(LOG_TAG, "Ignoring " + action + " from previous page load.");
+            }
+            return false;
+        }
+        // Bridge secret wrong and bridge not due to it being from the previous page.
+        if (expectedBridgeSecret < 0 || bridgeSecret != expectedBridgeSecret) {
+            LOG.e(LOG_TAG, "Bridge access attempt with wrong secret token, possibly from malicious code. Disabling exec() bridge!");
+            clearBridgeSecret();
+            throw new IllegalAccessException();
+        }
+        return true;
+    }
+
+    /** Called on page transitions */
+    void clearBridgeSecret() {
+        expectedBridgeSecret = -1;
+    }
+
+    public boolean isSecretEstablished() {
+        return expectedBridgeSecret != -1;
+    }
+
+    /** 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);
+        return expectedBridgeSecret;
+    }
+
+    public void reset() {
+        jsMessageQueue.reset();
+        clearBridgeSecret();
+    }
+
+    public String promptOnJsPrompt(String origin, String message, String defaultValue) {
+        if (defaultValue != null && defaultValue.length() > 3 && defaultValue.startsWith("gap:")) {
+            JSONArray array;
+            try {
+                array = new JSONArray(defaultValue.substring(4));
+                int bridgeSecret = array.getInt(0);
+                String service = array.getString(1);
+                String action = array.getString(2);
+                String callbackId = array.getString(3);
+                String r = jsExec(bridgeSecret, service, action, callbackId, message);
+                return r == null ? "" : r;
+            } catch (JSONException e) {
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            return "";
+        }
+        // Sets the native->JS bridge mode.
+        else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) {
+            try {
+                int bridgeSecret = Integer.parseInt(defaultValue.substring(16));
+                jsSetNativeToJsBridgeMode(bridgeSecret, Integer.parseInt(message));
+            } catch (NumberFormatException e){
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            return "";
+        }
+        // Polling for JavaScript messages
+        else if (defaultValue != null && defaultValue.startsWith("gap_poll:")) {
+            int bridgeSecret = Integer.parseInt(defaultValue.substring(9));
+            try {
+                String r = jsRetrieveJsMessages(bridgeSecret, "1".equals(message));
+                return r == null ? "" : r;
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            return "";
+        }
+        else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
+            // Protect against random iframes being able to talk through the bridge.
+            // Trust only pages which the app would have been allowed to navigate to anyway.
+            if (pluginManager.shouldAllowBridgeAccess(origin)) {
+                // Enable the bridge
+                int bridgeMode = Integer.parseInt(defaultValue.substring(9));
+                jsMessageQueue.setBridgeMode(bridgeMode);
+                // Tell JS the bridge secret.
+                int secret = generateBridgeSecret();
+                return ""+secret;
+            } else {
+                LOG.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
+            }
+            return "";
+        }
+        return null;
+    }
+}

+ 105 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaClientCertRequest.java

@@ -0,0 +1,105 @@
+/*
+       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.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 {
+
+    private final ClientCertRequest request;
+
+    public CordovaClientCertRequest(ClientCertRequest request) {
+        this.request = request;
+    }
+    
+    /**
+     * Cancel this request
+     */
+    @SuppressLint("NewApi")
+    public void cancel()
+    {
+        request.cancel();
+    }
+    
+    /*
+     * Returns the host name of the server requesting the certificate.
+     */
+    @SuppressLint("NewApi")
+    public String getHost()
+    {
+        return request.getHost();
+    }
+    
+    /*
+     * Returns the acceptable types of asymmetric keys (can be null).
+     */
+    @SuppressLint("NewApi")
+    public String[] getKeyTypes()
+    {
+        return request.getKeyTypes();
+    }
+    
+    /*
+     * Returns the port number of the server requesting the certificate.
+     */
+    @SuppressLint("NewApi")
+    public int getPort()
+    {
+        return request.getPort();
+    }
+    
+    /*
+     * Returns the acceptable certificate issuers for the certificate matching the private key (can be null).
+     */
+    @SuppressLint("NewApi")
+    public Principal[] getPrincipals()
+    {
+        return request.getPrincipals();
+    }
+    
+    /*
+     * Ignore the request for now. Do not remember user's choice.
+     */
+    @SuppressLint("NewApi")
+    public void ignore()
+    {
+        request.ignore();
+    }
+    
+    /*
+     * Proceed with the specified private key and client certificate chain. Remember the user's positive choice and use it for future requests.
+     * 
+     * @param privateKey The privateKey
+     * @param chain The certificate chain 
+     */
+    @SuppressLint("NewApi")
+    public void proceed(PrivateKey privateKey, X509Certificate[] chain)
+    {
+        request.proceed(privateKey, chain);
+    }
+}

+ 152 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaDialogsHelper.java

@@ -0,0 +1,152 @@
+/*
+       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 android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.view.KeyEvent;
+import android.widget.EditText;
+
+/**
+ * Helper class for WebViews to implement prompt(), alert(), confirm() dialogs.
+ */
+public class CordovaDialogsHelper {
+    private final Context context;
+    private AlertDialog lastHandledDialog;
+
+    public CordovaDialogsHelper(Context context) {
+        this.context = context;
+    }
+
+    public void showAlert(String message, final Result result) {
+        AlertDialog.Builder dlg = new AlertDialog.Builder(context);
+        dlg.setMessage(message);
+        dlg.setTitle("Alert");
+        //Don't let alerts break the back button
+        dlg.setCancelable(true);
+        dlg.setPositiveButton(android.R.string.ok,
+                new AlertDialog.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        result.gotResult(true, null);
+                    }
+                });
+        dlg.setOnCancelListener(
+                new DialogInterface.OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        result.gotResult(false, null);
+                    }
+                });
+        dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
+            //DO NOTHING
+            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                if (keyCode == KeyEvent.KEYCODE_BACK)
+                {
+                    result.gotResult(true, null);
+                    return false;
+                }
+                else
+                    return true;
+            }
+        });
+        lastHandledDialog = dlg.show();
+    }
+
+    public void showConfirm(String message, final Result result) {
+        AlertDialog.Builder dlg = new AlertDialog.Builder(context);
+        dlg.setMessage(message);
+        dlg.setTitle("Confirm");
+        dlg.setCancelable(true);
+        dlg.setPositiveButton(android.R.string.ok,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        result.gotResult(true, null);
+                    }
+                });
+        dlg.setNegativeButton(android.R.string.cancel,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        result.gotResult(false, null);
+                    }
+                });
+        dlg.setOnCancelListener(
+                new DialogInterface.OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        result.gotResult(false, null);
+                    }
+                });
+        dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
+            //DO NOTHING
+            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                if (keyCode == KeyEvent.KEYCODE_BACK)
+                {
+                    result.gotResult(false, null);
+                    return false;
+                }
+                else
+                    return true;
+            }
+        });
+        lastHandledDialog = dlg.show();
+    }
+
+    /**
+     * Tell the client to display a prompt dialog to the user.
+     * If the client returns true, WebView will assume that the client will
+     * handle the prompt dialog and call the appropriate JsPromptResult method.
+     *
+     * Since we are hacking prompts for our own purposes, we should not be using them for
+     * this purpose, perhaps we should hack console.log to do this instead!
+     */
+    public void showPrompt(String message, String defaultValue, final Result result) {
+        // Returning false would also show a dialog, but the default one shows the origin (ugly).
+        AlertDialog.Builder dlg = new AlertDialog.Builder(context);
+        dlg.setMessage(message);
+        final EditText input = new EditText(context);
+        if (defaultValue != null) {
+            input.setText(defaultValue);
+        }
+        dlg.setView(input);
+        dlg.setCancelable(false);
+        dlg.setPositiveButton(android.R.string.ok,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        String userText = input.getText().toString();
+                        result.gotResult(true, userText);
+                    }
+                });
+        dlg.setNegativeButton(android.R.string.cancel,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        result.gotResult(false, null);
+                    }
+                });
+        lastHandledDialog = dlg.show();
+    }
+
+    public void destroyLastDialog(){
+        if (lastHandledDialog != null){
+            lastHandledDialog.cancel();
+        }
+    }
+
+    public interface Result {
+        public void gotResult(boolean success, String value);
+    }
+}

+ 51 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaHttpAuthHandler.java

@@ -0,0 +1,51 @@
+/*
+       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 android.webkit.HttpAuthHandler;
+
+/**
+ * Specifies interface for HTTP auth handler object which is used to handle auth requests and
+ * specifying user credentials.
+ */
+public class CordovaHttpAuthHandler implements ICordovaHttpAuthHandler {
+
+    private final HttpAuthHandler handler;
+
+    public CordovaHttpAuthHandler(HttpAuthHandler handler) {
+        this.handler = handler;
+    }
+    
+    /**
+     * Instructs the WebView to cancel the authentication request.
+     */
+    public void cancel () {
+        this.handler.cancel();
+    }
+    
+    /**
+     * Instructs the WebView to proceed with the authentication with the given credentials.
+     * 
+     * @param username
+     * @param password
+     */
+    public void proceed (String username, String password) {
+        this.handler.proceed(username, password);
+    }
+}

+ 97 - 0
myApp/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterface.java

@@ -0,0 +1,97 @@
+/*
+       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 android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+
+import org.apache.cordova.CordovaPlugin;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * The Activity interface that is implemented by CordovaActivity.
+ * It is used to isolate plugin development, and remove dependency on entire Cordova library.
+ */
+public interface CordovaInterface {
+
+    /**
+     * Launch an activity for which you would like a result when it finished. When this activity exits,
+     * your onActivityResult() method will be called.
+     *
+     * @param command     The command object
+     * @param intent      The intent to start
+     * @param requestCode   The request code that is passed to callback to identify the activity
+     */
+    abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode);
+
+    /**
+     * Set the plugin to be called when a sub-activity exits.
+     *
+     * @param plugin      The plugin on which onActivityResult is to be called
+     */
+    abstract public void setActivityResultCallback(CordovaPlugin plugin);
+
+    /**
+     * 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();
+
+    /**