mirror of
https://github.com/apache/cordova-android.git
synced 2026-01-30 00:05:28 +08:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f12080b7e2 | ||
|
|
51291f8985 | ||
|
|
112f0a61a8 | ||
|
|
6d3ce211dd | ||
|
|
f100809bf3 | ||
|
|
a1ed1c0af7 | ||
|
|
05e3e3cf8d | ||
|
|
8a957fb9c9 | ||
|
|
e188c61c86 | ||
|
|
ca19084b1c | ||
|
|
aea6b7f6f4 | ||
|
|
7a67e00b9f | ||
|
|
dc4e065f61 | ||
|
|
c3fd6bca4a | ||
|
|
13bd3f4a9f | ||
|
|
09c75237d9 | ||
|
|
b5e79b5a4d | ||
|
|
5db850890d | ||
|
|
b6c5db3e37 | ||
|
|
cba3410b17 | ||
|
|
565ac9c7b1 | ||
|
|
1636d70f25 | ||
|
|
4e5892c5ed | ||
|
|
e69ab6a687 | ||
|
|
a9171c3db6 | ||
|
|
90271301fb | ||
|
|
c11fcc10e8 | ||
|
|
5e50c1d611 | ||
|
|
38ca895459 | ||
|
|
0ce66249da | ||
|
|
291edcd24e | ||
|
|
4f44036d0a | ||
|
|
6081cc7442 |
44
README.md
44
README.md
@@ -28,22 +28,44 @@
|
||||
|
||||
Cordova Android is an Android application library that allows for Cordova-based projects to be built for the Android Platform. Cordova based applications are, at the core, applications written with web technology: HTML, CSS and JavaScript.
|
||||
|
||||
[Apache Cordova](https://cordova.apache.org) is a project of The Apache Software Foundation (ASF).
|
||||
[Apache Cordova](https://cordova.apache.org/) is a project of [The Apache Software Foundation (ASF)](https://apache.org/).
|
||||
|
||||
## Requires
|
||||
## Requirements
|
||||
|
||||
- Java JDK 1.8
|
||||
- Android SDK [http://developer.android.com](https://developer.android.com/)
|
||||
* Java Development Kit (JDK) 11
|
||||
* [Android SDK](https://developer.android.com/)
|
||||
* [Node.js](https://nodejs.org)
|
||||
|
||||
## Cordova Android Developer Tools
|
||||
## Create a Cordova project
|
||||
|
||||
Use the [Cordova command-line tool](https://www.npmjs.com/package/cordova) to create projects and install plugins.
|
||||
Follow the instructions in the [**Create your first Cordova app**](https://cordova.apache.org/docs/en/latest/guide/cli/index.html) section of [Apache Cordova Docs](https://cordova.apache.org/docs/en/latest/)
|
||||
|
||||
## Using Android Studio
|
||||
To use a **shared framework**, for example in development, link the appropriate cordova-android platform folder path:
|
||||
|
||||
1. Create a project
|
||||
2. Import it via "Non-Android Studio Project"
|
||||
```bash
|
||||
cordova platform add --link /path/to/cordova-android
|
||||
```
|
||||
|
||||
## Running the Native Tests
|
||||
## Updating a Cordova project
|
||||
|
||||
The `test/` directory in this project contains an Android test project that can be used to run different kinds of native tests. Check out the [README contained therein](test/README.md) for more details!
|
||||
When you install a new version of the [`Cordova CLI`](https://www.npmjs.com/package/cordova) that pins a new version of the [`Cordova-Android`](https://www.npmjs.com/package/cordova-android) platform, you can follow these simple upgrade steps within your project:
|
||||
|
||||
```bash
|
||||
cordova platform rm android
|
||||
cordova platform add android
|
||||
```
|
||||
|
||||
## Debugging in Android Studio
|
||||
|
||||
Import project in Android Studio through _File > Open_ and targeting `/path/to/your-cdv-project/platforms/android/`.
|
||||
|
||||
## How to Test Repo Development
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm test
|
||||
```
|
||||
|
||||
## Further reading
|
||||
|
||||
* [Apache Cordova](https://cordova.apache.org/)
|
||||
|
||||
@@ -20,6 +20,61 @@
|
||||
-->
|
||||
## Release Notes for Cordova (Android)
|
||||
|
||||
### 10.1.2 (Apr 11, 2022)
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1372](https://github.com/apache/cordova-android/pull/1372) fix(`AndroidManifest`): explicitly define the `activity` attribute `android:exported`
|
||||
* [GH-1406](https://github.com/apache/cordova-android/pull/1406) fix: detect `JAVA_HOME` with Java 11
|
||||
* [GH-1401](https://github.com/apache/cordova-android/pull/1401) fix(GH-1391): Reword minimum build tools version to make it more clear what is actually required.
|
||||
* [GH-1384](https://github.com/apache/cordova-android/pull/1384) fix: escape `strings.xml` app name
|
||||
|
||||
**Chores:**
|
||||
|
||||
* [GH-1413](https://github.com/apache/cordova-android/pull/1413) chore: update `package-lock` to satisfy `npm audit`
|
||||
* [GH-1348](https://github.com/apache/cordova-android/pull/1348) chore: `npmrc`
|
||||
|
||||
### 10.1.1 (Sep 13, 2021)
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1349](https://github.com/apache/cordova-android/pull/1349) fix(`PluginManager`): `AllowNavigation` default policy to handle scheme & hostname
|
||||
* [GH-1342](https://github.com/apache/cordova-android/pull/1342) fix(`AllowListPlugin`): Safely handle default allow navigation policy in allow request
|
||||
* [GH-1332](https://github.com/apache/cordova-android/pull/1332) fix(`PluginManager`): `AllowBridgeAccess` default policy to handle scheme & hostname
|
||||
|
||||
### 10.1.0 (Aug 13, 2021)
|
||||
|
||||
**Features:**
|
||||
|
||||
* [GH-1213](https://github.com/apache/cordova-android/pull/1213) feat: unify `create` default values & stop project name transform
|
||||
* [GH-1306](https://github.com/apache/cordova-android/pull/1306) feat: bump `ANDROIDX_APP_COMPAT@1.3.1`
|
||||
* [GH-1303](https://github.com/apache/cordova-android/pull/1303) feat: bump `Google Services Gradle Plugin@4.3.8`
|
||||
* [GH-1302](https://github.com/apache/cordova-android/pull/1302) feat: bump `kotlin@1.5.21`
|
||||
* [GH-1298](https://github.com/apache/cordova-android/pull/1298) feat: support `http` w/ `content` `src` fix
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1214](https://github.com/apache/cordova-android/pull/1214) fix: display project name in Android Studio
|
||||
* [GH-1300](https://github.com/apache/cordova-android/pull/1300) fix: fall back to project root `repositories.gradle`
|
||||
|
||||
**Docs:**
|
||||
|
||||
* [GH-1308](https://github.com/apache/cordova-android/pull/1308) doc: update `README` about development & testing
|
||||
|
||||
### 10.0.1 (Jul 27, 2021)
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* [GH-1295](https://github.com/apache/cordova-android/pull/1295) fix: `maven-publish` setup
|
||||
* [GH-1293](https://github.com/apache/cordova-android/pull/1293) fix: `gradle` build tools config
|
||||
* [GH-1294](https://github.com/apache/cordova-android/pull/1294) fix: automatic latest build tools finding
|
||||
* [GH-1287](https://github.com/apache/cordova-android/pull/1287) fix: Google Services Gradle Plugin version check failure
|
||||
|
||||
**Chores:**
|
||||
|
||||
* [GH-1291](https://github.com/apache/cordova-android/pull/1291) chore: add missing release notes
|
||||
* [GH-1286](https://github.com/apache/cordova-android/pull/1286) chore: update `README` requirements
|
||||
|
||||
### 10.0.0 (Jul 17, 2021)
|
||||
|
||||
**Breaking:**
|
||||
@@ -312,6 +367,38 @@
|
||||
* [CB-13830](https://issues.apache.org/jira/browse/CB-13830) Add handlers for plugins that use non-Java source files, such as Camera
|
||||
* [CB-13923](https://issues.apache.org/jira/browse/CB-13923) Fix -1 length for compressed files
|
||||
|
||||
### 7.1.4 (Nov 22, 2018)
|
||||
|
||||
* Update android-versions to `1.4.0`, with added support for Android Pie ([#573](https://github.com/apache/cordova-android/pull/573))
|
||||
* Output current package name if package name can't be validated ([#567](https://github.com/apache/cordova-android/pull/567))
|
||||
* Resolve issue with plugin `target-dir="*app*"` subdirs ([#572](https://github.com/apache/cordova-android/pull/572))
|
||||
|
||||
### 7.1.3 (Nov 19, 2018)
|
||||
|
||||
* [GH-495](https://github.com/apache/cordova-android/pull/495) Incorrect default sdk version issue fix
|
||||
* [GH-496](https://github.com/apache/cordova-android/pull/496) update comments in `build.gradle`
|
||||
* [GH-539](https://github.com/apache/cordova-android/pull/539) Fix dest overwrite, in case of of plugin `source-file` element with `target-dir` that does not need remapping
|
||||
* [GH-540](https://github.com/apache/cordova-android/issues/540) support plugin `source-file` element with any app `target-dir` value
|
||||
* [GH-547](https://github.com/apache/cordova-android/issues/547) Compatibility of old plugins with non-Java `source-file` entries (individual files)
|
||||
* [GH-551](https://github.com/apache/cordova-android/pull/551) add missing cast for cdvMinSdkVersion to `build.gradle`
|
||||
* [GH-552](https://github.com/apache/cordova-android/issues/552) check for `build-extras.gradle` in the parent app directory
|
||||
|
||||
### 7.1.2 (Nov 08, 2018)
|
||||
* [CB-14127](https://issues.apache.org/jira/browse/CB-14127): Always put the Google repo above jcenter
|
||||
* [CB-14165](https://issues.apache.org/jira/browse/CB-14165): Emulator: handle "device still connecting" error (#457)
|
||||
* [CB-14125](https://issues.apache.org/jira/browse/CB-14125): Increase old plugin compatibility
|
||||
* [CB-13830](https://issues.apache.org/jira/browse/CB-13830): Add handlers for plugins that use non-Java source files, such as Camera
|
||||
* [CB-14038](https://issues.apache.org/jira/browse/CB-14038): fix false positive detecting project type
|
||||
|
||||
### 7.1.1 (Jul 11, 2018)
|
||||
* Fix unsafe property access in run.js (#445)
|
||||
* Emit log event instead of logging directly (#452)
|
||||
* [CB-14101](https://issues.apache.org/jira/browse/CB-14101) Fix Java version check for Java >= 9 (#446)
|
||||
* [CB-14127](https://issues.apache.org/jira/browse/CB-14127) (android) Move google maven repo ahead of jcenter
|
||||
* [CB-13923](https://issues.apache.org/jira/browse/CB-13923) (android) fix -1 length for compressed files
|
||||
* [CB-14145](https://issues.apache.org/jira/browse/CB-14145) use cordova-common@2.2.5 and update other dependencies to resolve `npm audit` warnings
|
||||
* [CB-9366](https://issues.apache.org/jira/browse/CB-9366) log error.stack in cordova.js
|
||||
|
||||
### 7.1.0 (Feb 20, 2018)
|
||||
* [CB-13879](https://issues.apache.org/jira/browse/CB-13879) updated gradle tools dependency to 3.0.1 for project template
|
||||
* [CB-13831](https://issues.apache.org/jira/browse/CB-13831) Update `android-versions` to 1.3.0 to support SDK 27.
|
||||
|
||||
@@ -29,7 +29,13 @@ buildscript {
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply from: 'repositories.gradle'
|
||||
def hasRepositoriesGradle = file('repositories.gradle').exists()
|
||||
if (hasRepositoriesGradle) {
|
||||
apply from: 'repositories.gradle'
|
||||
} else {
|
||||
apply from: "${project.rootDir}/repositories.gradle"
|
||||
}
|
||||
|
||||
repositories repos
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
"MIN_SDK_VERSION": 22,
|
||||
"SDK_VERSION": 30,
|
||||
"GRADLE_VERSION": "7.1.1",
|
||||
"BUILD_TOOLS_VERSION": "30.0.3",
|
||||
"MIN_BUILD_TOOLS_VERSION": "30.0.3",
|
||||
"AGP_VERSION": "4.2.2",
|
||||
"KOTLIN_VERSION": "1.5.20",
|
||||
"ANDROIDX_APP_COMPAT_VERSION": "1.3.0",
|
||||
"KOTLIN_VERSION": "1.5.21",
|
||||
"ANDROIDX_APP_COMPAT_VERSION": "1.3.1",
|
||||
"ANDROIDX_WEBKIT_VERSION": "1.4.0",
|
||||
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.5",
|
||||
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.8",
|
||||
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
|
||||
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
String getCordovaAndroidVersion() {
|
||||
// Fetch Data from Cordova-Android package.json (Used only by framework build/publishing)
|
||||
@@ -29,6 +30,22 @@ String getCordovaAndroidVersion() {
|
||||
}
|
||||
}
|
||||
|
||||
// Enable signing by default when keyId and secretKeyRingFile is defined.
|
||||
ext.cdvEnableSigning = project.hasProperty('signing.keyId') && project.hasProperty('signing.secretKeyRingFile')
|
||||
if (cdvEnableSigning) {
|
||||
logger.debug('[Cordova] Signing has been enabled by default because the signing keyId & secretKeyRingFile has been defined.')
|
||||
}
|
||||
|
||||
if (project.hasProperty('signEnabled')) {
|
||||
if(!cdvEnableSigning && Boolean.valueOf(signEnabled)) {
|
||||
logger.debug("[Cordova] The \"signEnabled\" override can not be set to \"true\" when the signing properties are missing.")
|
||||
} else {
|
||||
// Override the default setting with the "signEnabled" property. (In this case it should only accept false)
|
||||
logger.debug("[Cordova] The \"signEnabled\" property has been detected and forcing enabled signing to \"$signEnabled\".")
|
||||
cdvEnableSigning = signEnabled
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
@@ -36,7 +53,7 @@ task sourcesJar(type: Jar) {
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
Cordova(MavenPublication) {
|
||||
mavenJava(MavenPublication) {
|
||||
groupId = 'org.apache.cordova'
|
||||
artifactId = 'framework'
|
||||
version = getCordovaAndroidVersion()
|
||||
@@ -76,4 +93,33 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
def releasesRepoUrl = 'https://repository.apache.org/content/repositories/releases'
|
||||
def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots'
|
||||
|
||||
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
|
||||
|
||||
credentials {
|
||||
if (project.hasProperty('apacheUsername') && project.hasProperty('apachePassword')) {
|
||||
username apacheUsername
|
||||
password apachePassword
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
if (Boolean.valueOf(cdvEnableSigning)) {
|
||||
sign publishing.publications.mavenJava
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.whenTaskAdded {task ->
|
||||
if(task.name.contains('sign')) {
|
||||
logger.debug("[Cordova] The task \"${task.name}\" is enabled? ${cdvEnableSigning}")
|
||||
task.enabled = cdvEnableSigning
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,24 +53,27 @@ String doFindLatestInstalledBuildTools(String minBuildToolsVersionString) {
|
||||
throw e
|
||||
}
|
||||
|
||||
def minBuildToolsVersion = new Version(minBuildToolsVersionString)
|
||||
def maxVersion = new Version((minBuildToolsVersion.getMajor() + 1) + ".0.0")
|
||||
|
||||
def highestBuildToolsVersion = buildToolsDirContents
|
||||
.collect { new Version(it) }
|
||||
// Invalid inputs will be handled as 0.0.0
|
||||
.findAll { it.isHigherThan('0.0.0') }
|
||||
.findAll { it.isHigherThan('0.0.0') && it.isLowerThan(maxVersion) }
|
||||
.max()
|
||||
|
||||
if (highestBuildToolsVersion == null) {
|
||||
throw new RuntimeException("""
|
||||
No installed build tools found. Install the Android build tools
|
||||
version ${minBuildToolsVersionString} or higher.
|
||||
No installed build tools found. Please install the Android build tools
|
||||
version ${minBuildToolsVersionString}.
|
||||
""".replaceAll(/\s+/, ' ').trim())
|
||||
}
|
||||
|
||||
if (highestBuildToolsVersion.isLowerThan(minBuildToolsVersionString)) {
|
||||
throw new RuntimeException("""
|
||||
No usable Android build tools found. Highest installed version is
|
||||
${highestBuildToolsVersion.getOriginalString()}; minimum version
|
||||
required is ${minBuildToolsVersionString}.
|
||||
No usable Android build tools found. Highest ${minBuildToolsVersion.getMajor()}.x installed version is
|
||||
${highestBuildToolsVersion.getOriginalString()}; Recommended version
|
||||
is ${minBuildToolsVersionString}.
|
||||
""".replaceAll(/\s+/, ' ').trim())
|
||||
}
|
||||
|
||||
@@ -171,10 +174,20 @@ def doApplyCordovaConfigCustomization() {
|
||||
cordovaConfig.ANDROIDX_WEBKIT_VERSION = cdvAndroidXWebKitVersion
|
||||
}
|
||||
|
||||
// Ensure the latest installed build tools is selected, with or without defined override
|
||||
cordovaConfig.LATEST_INSTALLED_BUILD_TOOLS = doFindLatestInstalledBuildTools(
|
||||
cordovaConfig.BUILD_TOOLS_VERSION
|
||||
)
|
||||
if (!cordovaConfig.BUILD_TOOLS_VERSION) {
|
||||
cordovaConfig.BUILD_TOOLS_VERSION = doFindLatestInstalledBuildTools(
|
||||
cordovaConfig.MIN_BUILD_TOOLS_VERSION
|
||||
)
|
||||
}
|
||||
|
||||
// Ensure the configured build tools version is at least our declared minimum
|
||||
def buildToolsVersion = new Version(cordovaConfig.BUILD_TOOLS_VERSION)
|
||||
if (buildToolsVersion.isLowerThan(cordovaConfig.MIN_BUILD_TOOLS_VERSION)) {
|
||||
throw new RuntimeException("""
|
||||
Expected Android Build Tools version >= ${cordovaConfig.MIN_BUILD_TOOLS_VERSION},
|
||||
but got Android Build Tools version ${cordovaConfig.BUILD_TOOLS_VERSION}. Please use version ${cordovaConfig.MIN_BUILD_TOOLS_VERSION} or later.
|
||||
""".replaceAll(/\s+/, ' ').trim())
|
||||
}
|
||||
}
|
||||
|
||||
// Properties exported here are visible to all plugins.
|
||||
|
||||
@@ -82,11 +82,6 @@ public class AllowListPlugin extends CordovaPlugin {
|
||||
if (strNode.equals("content")) {
|
||||
String startPage = xml.getAttributeValue(null, "src");
|
||||
allowedNavigations.addAllowListEntry(startPage, false);
|
||||
|
||||
// Allow origin for WebViewAssetLoader
|
||||
if (!this.prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
|
||||
allowedNavigations.addAllowListEntry("https://" + this.prefs.getString("hostname", "localhost"), false);
|
||||
}
|
||||
} else if (strNode.equals("allow-navigation")) {
|
||||
String origin = xml.getAttributeValue(null, "href");
|
||||
if ("*".equals(origin)) {
|
||||
@@ -127,7 +122,7 @@ public class AllowListPlugin extends CordovaPlugin {
|
||||
|
||||
@Override
|
||||
public Boolean shouldAllowRequest(String url) {
|
||||
return (this.shouldAllowNavigation(url) || this.allowedRequests.isUrlAllowListed(url))
|
||||
return (Boolean.TRUE.equals(this.shouldAllowNavigation(url)) || this.allowedRequests.isUrlAllowListed(url))
|
||||
? true
|
||||
: null; // default policy
|
||||
}
|
||||
|
||||
@@ -24,16 +24,19 @@ 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 = null;
|
||||
private static String SCHEME_HTTP = "http";
|
||||
private static String SCHEME_HTTPS = "https";
|
||||
private static String DEFAULT_HOSTNAME = "localhost";
|
||||
|
||||
private String launchUrl;
|
||||
private String contentSrc;
|
||||
private CordovaPreferences prefs = new CordovaPreferences();
|
||||
private ArrayList<PluginEntry> pluginEntries = new ArrayList<PluginEntry>(20);
|
||||
|
||||
@@ -47,11 +50,7 @@ public class ConfigXmlParser {
|
||||
|
||||
public String getLaunchUrl() {
|
||||
if (launchUrl == null) {
|
||||
launchUrl = "https://" + this.prefs.getString("hostname", "localhost");
|
||||
}
|
||||
|
||||
if (this.prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
|
||||
launchUrl = "file:///android_asset/www/index.html";
|
||||
setStartUrl(contentSrc);
|
||||
}
|
||||
|
||||
return launchUrl;
|
||||
@@ -130,7 +129,10 @@ public class ConfigXmlParser {
|
||||
else if (strNode.equals("content")) {
|
||||
String src = xml.getAttributeValue(null, "src");
|
||||
if (src != null) {
|
||||
setStartUrl(src);
|
||||
contentSrc = src;
|
||||
} else {
|
||||
// Default
|
||||
contentSrc = "index.html";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,20 +149,40 @@ public class ConfigXmlParser {
|
||||
}
|
||||
}
|
||||
|
||||
private String getLaunchUrlPrefix() {
|
||||
if (prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
|
||||
return "file:///android_asset/www/";
|
||||
} else {
|
||||
String scheme = prefs.getString("scheme", SCHEME_HTTPS).toLowerCase();
|
||||
String hostname = prefs.getString("hostname", DEFAULT_HOSTNAME);
|
||||
|
||||
if (!scheme.contentEquals(SCHEME_HTTP) && !scheme.contentEquals(SCHEME_HTTPS)) {
|
||||
LOG.d(TAG, "The provided scheme \"" + scheme + "\" is not valid. " +
|
||||
"Defaulting to \"" + SCHEME_HTTPS + "\". " +
|
||||
"(Valid Options=" + SCHEME_HTTP + "," + SCHEME_HTTPS + ")");
|
||||
|
||||
scheme = SCHEME_HTTPS;
|
||||
}
|
||||
|
||||
return scheme + "://" + hostname + '/';
|
||||
}
|
||||
}
|
||||
|
||||
private void setStartUrl(String src) {
|
||||
Pattern schemeRegex = Pattern.compile("^[a-z-]+://");
|
||||
Matcher matcher = schemeRegex.matcher(src);
|
||||
|
||||
if (matcher.find()) {
|
||||
launchUrl = src;
|
||||
} else {
|
||||
String launchUrlPrefix = getLaunchUrlPrefix();
|
||||
|
||||
// remove leading slash, "/", from content src if existing,
|
||||
if (src.charAt(0) == '/') {
|
||||
src = src.substring(1);
|
||||
}
|
||||
if (this.prefs.getBoolean("AndroidInsecureFileModeEnabled", false)) {
|
||||
launchUrl = "file:///android_asset/www/" + src;
|
||||
} else {
|
||||
launchUrl = "https://" + this.prefs.getString("hostname", "localhost") + "/" + src;
|
||||
}
|
||||
|
||||
launchUrl = launchUrlPrefix + src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
|
||||
* are not expected to implement it.
|
||||
*/
|
||||
public interface CordovaWebView {
|
||||
public static final String CORDOVA_VERSION = "10.0.0-dev";
|
||||
public static final String CORDOVA_VERSION = "10.1.2";
|
||||
|
||||
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
|
||||
|
||||
|
||||
@@ -41,6 +41,12 @@ import android.os.Build;
|
||||
*/
|
||||
public class PluginManager {
|
||||
private static String TAG = "PluginManager";
|
||||
|
||||
// @todo same as ConfigXmlParser. Research centralizing ideas, maybe create CordovaConstants
|
||||
private static String SCHEME_HTTPS = "https";
|
||||
// @todo same as ConfigXmlParser. Research centralizing ideas, maybe create CordovaConstants
|
||||
private static String DEFAULT_HOSTNAME = "localhost";
|
||||
|
||||
private static final int SLOW_EXEC_WARNING_THRESHOLD = Debug.isDebuggerConnected() ? 60 : 16;
|
||||
|
||||
// List of service entries
|
||||
@@ -366,6 +372,24 @@ public class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo should we move this somewhere public and accessible by all plugins?
|
||||
* For now, it is placed where it is used and kept private so we can decide later and move without causing a breaking change.
|
||||
* An ideal location might be in the "ConfigXmlParser" at the time it generates the "launchUrl".
|
||||
*
|
||||
* @todo should we be restrictive on the "file://" return? e.g. "file:///android_asset/www/"
|
||||
* Would be considered as a breaking change if we apply a more granular check.
|
||||
*/
|
||||
private String getLaunchUrlPrefix() {
|
||||
if (!app.getPreferences().getBoolean("AndroidInsecureFileModeEnabled", false)) {
|
||||
String scheme = app.getPreferences().getString("scheme", SCHEME_HTTPS).toLowerCase();
|
||||
String hostname = app.getPreferences().getString("hostname", DEFAULT_HOSTNAME);
|
||||
return scheme + "://" + hostname + '/';
|
||||
}
|
||||
|
||||
return "file://";
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the webview is going to request an external resource.
|
||||
*
|
||||
@@ -431,7 +455,7 @@ public class PluginManager {
|
||||
}
|
||||
|
||||
// Default policy:
|
||||
return url.startsWith("file://") || url.startsWith("about:blank");
|
||||
return url.startsWith(getLaunchUrlPrefix()) || url.startsWith("about:blank");
|
||||
}
|
||||
|
||||
|
||||
@@ -452,7 +476,7 @@ public class PluginManager {
|
||||
}
|
||||
|
||||
// Default policy:
|
||||
return url.startsWith("file://");
|
||||
return url.startsWith(getLaunchUrlPrefix());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -183,21 +183,29 @@ class ProjectBuilder {
|
||||
checkAndCopy(subProjects[i], this.root);
|
||||
}
|
||||
}
|
||||
var name = this.extractRealProjectNameFromManifest();
|
||||
var projectName = this.extractRealProjectNameFromManifest();
|
||||
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||
var settingsGradlePaths = subProjects.map(function (p) {
|
||||
var realDir = p.replace(/[/\\]/g, ':');
|
||||
var libName = realDir.replace(name + '-', '');
|
||||
var libName = realDir.replace(projectName + '-', '');
|
||||
var str = 'include ":' + libName + '"\n';
|
||||
if (realDir.indexOf(name + '-') !== -1) {
|
||||
if (realDir.indexOf(projectName + '-') !== -1) {
|
||||
str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n';
|
||||
}
|
||||
return str;
|
||||
});
|
||||
|
||||
// Update subprojects within settings.gradle.
|
||||
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
|
||||
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||
'include ":"\n' + settingsGradlePaths.join(''));
|
||||
'apply from: "cdv-gradle-name.gradle"\n' +
|
||||
'include ":"\n' +
|
||||
settingsGradlePaths.join(''));
|
||||
|
||||
// Touch empty cdv-gradle-name.gradle file if missing.
|
||||
if (!fs.pathExistsSync(path.join(this.root, 'cdv-gradle-name.gradle'))) {
|
||||
fs.writeFileSync(path.join(this.root, 'cdv-gradle-name.gradle'), '');
|
||||
}
|
||||
|
||||
// Update dependencies within build.gradle.
|
||||
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
|
||||
@@ -214,7 +222,7 @@ class ProjectBuilder {
|
||||
};
|
||||
subProjects.forEach(function (p) {
|
||||
events.emit('log', 'Subproject Path: ' + p);
|
||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||
var libName = p.replace(/[/\\]/g, ':').replace(projectName + '-', '');
|
||||
if (libName !== 'app') {
|
||||
depsList += ' implementation(project(path: ":' + libName + '"))';
|
||||
insertExclude(p);
|
||||
|
||||
@@ -37,7 +37,6 @@ exports.copyScripts = copyScripts;
|
||||
exports.copyBuildRules = copyBuildRules;
|
||||
exports.writeProjectProperties = writeProjectProperties;
|
||||
exports.prepBuildFiles = prepBuildFiles;
|
||||
exports.writeNameForAndroidStudio = writeNameForAndroidStudio;
|
||||
|
||||
function getFrameworkDir (projectPath, shared) {
|
||||
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
||||
@@ -176,19 +175,6 @@ function validateProjectName (project_name) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the name of the app in "platforms/android/.idea/.name" so that Android Studio can show that name in the
|
||||
* project listing. This is helpful to quickly look in the Android Studio listing if there are so many projects in
|
||||
* Android Studio.
|
||||
*
|
||||
* https://github.com/apache/cordova-android/issues/1172
|
||||
*/
|
||||
function writeNameForAndroidStudio (project_path, project_name) {
|
||||
const ideaPath = path.join(project_path, '.idea');
|
||||
fs.ensureDirSync(ideaPath);
|
||||
fs.writeFileSync(path.join(ideaPath, '.name'), project_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an android application with the given options.
|
||||
*
|
||||
@@ -211,15 +197,14 @@ exports.create = function (project_path, config, options, events) {
|
||||
options = options || {};
|
||||
|
||||
// Set default values for path, package and name
|
||||
project_path = path.relative(process.cwd(), (project_path || 'CordovaExample'));
|
||||
project_path = path.relative(process.cwd(), project_path);
|
||||
// Check if project already exists
|
||||
if (fs.existsSync(project_path)) {
|
||||
return Promise.reject(new CordovaError('Project already exists! Delete and recreate'));
|
||||
}
|
||||
|
||||
var package_name = config.android_packageName() || config.packageName() || 'my.cordova.project';
|
||||
var project_name = config.name()
|
||||
? config.name().replace(/[^\w.]/g, '_') : 'CordovaExample';
|
||||
var package_name = config.android_packageName() || config.packageName() || 'io.cordova.helloCordova';
|
||||
var project_name = config.name() || 'Hello Cordova';
|
||||
|
||||
var safe_activity_name = config.android_activityName() || options.activityName || 'MainActivity';
|
||||
var target_api = check_reqs.get_target(project_path);
|
||||
@@ -229,7 +214,7 @@ exports.create = function (project_path, config, options, events) {
|
||||
.then(function () {
|
||||
return exports.validateProjectName(project_name);
|
||||
}).then(function () {
|
||||
// Log the given values for the project
|
||||
// Log the given values for the project
|
||||
events.emit('log', 'Creating Cordova project for the Android platform:');
|
||||
events.emit('log', '\tPath: ' + project_path);
|
||||
events.emit('log', '\tPackage: ' + package_name);
|
||||
@@ -270,7 +255,7 @@ exports.create = function (project_path, config, options, events) {
|
||||
fs.ensureDirSync(activity_dir);
|
||||
fs.copySync(path.join(project_template_dir, 'Activity.java'), activity_path);
|
||||
utils.replaceFileContents(activity_path, /__ACTIVITY__/, safe_activity_name);
|
||||
utils.replaceFileContents(path.join(app_path, 'res', 'values', 'strings.xml'), /__NAME__/, project_name);
|
||||
utils.replaceFileContents(path.join(app_path, 'res', 'values', 'strings.xml'), /__NAME__/, utils.escape(project_name));
|
||||
utils.replaceFileContents(activity_path, /__ID__/, package_name);
|
||||
|
||||
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
||||
@@ -286,7 +271,6 @@ exports.create = function (project_path, config, options, events) {
|
||||
// Link it to local android install.
|
||||
exports.writeProjectProperties(project_path, target_api);
|
||||
exports.prepBuildFiles(project_path);
|
||||
exports.writeNameForAndroidStudio(project_path, project_name);
|
||||
events.emit('log', generateDoneMessage('create', options.link));
|
||||
}).then(() => project_path);
|
||||
};
|
||||
|
||||
3
lib/env/java.js
vendored
3
lib/env/java.js
vendored
@@ -99,7 +99,8 @@ const java = {
|
||||
} else {
|
||||
// See if we can derive it from javac's location.
|
||||
var maybeJavaHome = path.dirname(path.dirname(javacPath));
|
||||
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
||||
if (fs.existsSync(path.join(maybeJavaHome, 'bin', 'java')) ||
|
||||
fs.existsSync(path.join(maybeJavaHome, 'bin', 'java.exe'))) {
|
||||
environment.JAVA_HOME = maybeJavaHome;
|
||||
} else {
|
||||
throw new CordovaError(default_java_error_msg);
|
||||
|
||||
@@ -273,6 +273,11 @@ function updateProjectAccordingTo (platformConfig, locations) {
|
||||
fs.writeFileSync(locations.strings, strings.write({ indent: 4 }), 'utf-8');
|
||||
events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings);
|
||||
|
||||
// Update app name for gradle project
|
||||
fs.writeFileSync(path.join(locations.root, 'cdv-gradle-name.gradle'),
|
||||
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||
'rootProject.name = "' + name.replace(/[/\\:<>"?*|]/g, '_') + '"\n');
|
||||
|
||||
// Java packages cannot support dashes
|
||||
var androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
|
||||
|
||||
|
||||
18
lib/utils.js
18
lib/utils.js
@@ -66,3 +66,21 @@ exports.forgivingWhichSync = (cmd) => {
|
||||
|
||||
exports.isWindows = () => os.platform() === 'win32';
|
||||
exports.isDarwin = () => os.platform() === 'darwin';
|
||||
|
||||
const UNESCAPED_REGEX = /[&<>"']/g;
|
||||
|
||||
const escapes = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the characters "&", "<", ">", '"' and "'" in the given string to
|
||||
* their corresponding escaped value
|
||||
* @param {string} str the string to be escaped
|
||||
* @returns the escaped string
|
||||
*/
|
||||
exports.escape = (str) => UNESCAPED_REGEX.test(str) ? str.replace(UNESCAPED_REGEX, (key) => escapes[key]) : str;
|
||||
|
||||
6022
package-lock.json
generated
6022
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-android",
|
||||
"version": "10.0.0",
|
||||
"version": "10.1.2",
|
||||
"description": "cordova-android release",
|
||||
"main": "lib/Api.js",
|
||||
"repository": "github:apache/cordova-android",
|
||||
|
||||
@@ -132,7 +132,6 @@ describe('create', function () {
|
||||
spyOn(create, 'copyBuildRules');
|
||||
spyOn(create, 'writeProjectProperties');
|
||||
spyOn(create, 'prepBuildFiles');
|
||||
spyOn(create, 'writeNameForAndroidStudio');
|
||||
revert_manifest_mock = create.__set__('AndroidManifest', Manifest_mock);
|
||||
spyOn(fs, 'existsSync').and.returnValue(false);
|
||||
spyOn(fs, 'copySync');
|
||||
@@ -148,10 +147,10 @@ describe('create', function () {
|
||||
});
|
||||
|
||||
describe('parameter values and defaults', function () {
|
||||
it('should have a default package name of my.cordova.project', () => {
|
||||
it('should have a default package name of io.cordova.helloCordova', () => {
|
||||
config_mock.packageName.and.returnValue(undefined);
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validatePackageName).toHaveBeenCalledWith('my.cordova.project');
|
||||
expect(create.validatePackageName).toHaveBeenCalledWith('io.cordova.helloCordova');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -162,10 +161,10 @@ describe('create', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should have a default project name of CordovaExample', () => {
|
||||
it('should have a default project name of Hello Cordova', () => {
|
||||
config_mock.name.and.returnValue(undefined);
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('CordovaExample');
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('Hello Cordova');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -176,10 +175,10 @@ describe('create', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should replace any non-word characters (including unicode and spaces) in the ConfigParser-provided project name with underscores', () => {
|
||||
it('should keep non-word characters (including unicode and spaces) in the ConfigParser-provided project name', () => {
|
||||
config_mock.name.and.returnValue('応応応応 hello 用用用用');
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('_____hello_____');
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('応応応応 hello 用用用用');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -276,6 +275,13 @@ describe('create', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should interpolate the escaped project name into strings.xml', () => {
|
||||
config_mock.name.and.returnValue('<Incredible&App>');
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(utils.replaceFileContents).toHaveBeenCalledWith(path.join(app_path, 'res', 'values', 'strings.xml'), /__NAME__/, '<Incredible&App>');
|
||||
});
|
||||
});
|
||||
|
||||
it('should copy template scripts into generated project', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.copyScripts).toHaveBeenCalledWith(project_path);
|
||||
@@ -301,24 +307,4 @@ describe('create', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeNameForAndroidStudio', () => {
|
||||
const project_path = path.join('some', 'path');
|
||||
const appName = 'Test Cordova';
|
||||
|
||||
beforeEach(function () {
|
||||
spyOn(fs, 'ensureDirSync');
|
||||
spyOn(fs, 'writeFileSync');
|
||||
});
|
||||
|
||||
it('should call ensureDirSync with path', () => {
|
||||
create.writeNameForAndroidStudio(project_path, appName);
|
||||
expect(fs.ensureDirSync).toHaveBeenCalledWith(path.join(project_path, '.idea'));
|
||||
});
|
||||
|
||||
it('should call writeFileSync with content', () => {
|
||||
create.writeNameForAndroidStudio(project_path, appName);
|
||||
expect(fs.writeFileSync).toHaveBeenCalledWith(path.join(project_path, '.idea', '.name'), appName);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode">
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
|
||||
android:exported="true">
|
||||
<intent-filter android:label="@string/launcher_name">
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
@@ -46,7 +46,7 @@ buildscript {
|
||||
|
||||
if(cordovaConfig.IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED) {
|
||||
// Checks if the kotlin version format is valid.
|
||||
if(!cdvHelpers.isVersionValid(gradlePluginGoogleServicesVersion)) {
|
||||
if(!cdvHelpers.isVersionValid(cordovaConfig.GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION)) {
|
||||
throw new GradleException("The defined Google Services plugin version (${cordovaConfig.GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION}) does not appear to be a valid version.")
|
||||
}
|
||||
|
||||
@@ -60,7 +60,13 @@ buildscript {
|
||||
|
||||
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||
allprojects {
|
||||
apply from: 'repositories.gradle'
|
||||
def hasRepositoriesGradle = file('repositories.gradle').exists()
|
||||
if (hasRepositoriesGradle) {
|
||||
apply from: 'repositories.gradle'
|
||||
} else {
|
||||
apply from: "${project.rootDir}/repositories.gradle"
|
||||
}
|
||||
|
||||
repositories repos
|
||||
}
|
||||
|
||||
@@ -189,7 +195,7 @@ android {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
buildToolsVersion cordovaConfig.LATEST_INSTALLED_BUILD_TOOLS
|
||||
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
|
||||
|
||||
// This code exists for Crosswalk and other Native APIs.
|
||||
// By default, we multiply the existing version code in the
|
||||
|
||||
@@ -30,7 +30,13 @@ buildscript {
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply from: 'repositories.gradle'
|
||||
def hasRepositoriesGradle = file('repositories.gradle').exists()
|
||||
if (hasRepositoriesGradle) {
|
||||
apply from: 'repositories.gradle'
|
||||
} else {
|
||||
apply from: "${project.rootDir}/repositories.gradle"
|
||||
}
|
||||
|
||||
repositories repos
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user