blob: 4038365ee5cd93deb66d7d9ed24e2396c9c94dca [file]
/**
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var fs = require('fs'),
path = require('path'),
xml = require('../xml-helpers'),
util = require('../util'),
events = require('../events'),
shell = require('shelljs'),
child_process = require('child_process'),
project_config= require('../config'),
Q = require('q'),
config_parser = require('../config_parser');
var awv_interface='awv_interface.jar';
var default_prefs = {
"useBrowserHistory":"true",
"exit-on-suspend":"false"
};
module.exports = function android_parser(project) {
if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
throw new Error('The provided path "' + project + '" is not an Android project.');
}
this.path = project;
this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
this.manifest = path.join(this.path, 'AndroidManifest.xml');
this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
};
// Returns a promise.
module.exports.check_requirements = function(project_root) {
events.emit('log', 'Checking Android requirements...');
var command = 'android list target';
events.emit('verbose', 'Running "' + command + '" (output to follow)');
var d = Q.defer();
child_process.exec(command, function(err, output, stderr) {
events.emit('verbose', output);
if (err) {
d.reject(new Error('The command `android` failed. Make sure you have the latest Android SDK installed, and the `android` command (inside the tools/ folder) added to your path. Output: ' + output));
} else {
if (output.indexOf('android-17') == -1) {
d.reject(new Error('Please install Android target 17 (the Android 4.2 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.'));
} else {
var custom_path = project_config.has_custom_path(project_root, 'android');
var framework_path;
if (custom_path) {
framework_path = path.resolve(path.join(custom_path, 'framework'));
} else {
framework_path = path.join(util.libDirectory, 'amazon-fireos', 'cordova', require('../../platforms').android.version, 'framework');
}
var cmd = 'android update project -p "' + framework_path + '" -t android-17';
events.emit('verbose', 'Running "' + cmd + '" (output to follow)...');
var d2 = Q.defer();
child_process.exec(cmd, function(err, output, stderr) {
events.emit('verbose', output + stderr);
if (err) {
d2.reject(new Error('Error updating the Cordova library to work with your Android environment. Command run: "' + cmd + '", output: ' + output));
} else {
events.emit('log', 'Checking if ' + awv_interface + ' exists... in framework/libs folder');
var awv_interface_expected_path=path.join(framework_path,'libs');
if (!fs.existsSync(path.join(awv_interface_expected_path,awv_interface))) {
d2.reject(new Error('awv_interface.jar not found in ' + awv_interface_expected_path +' folder. \nPlease download the AmazonWebView SDK from http://developer.amazon.com/sdk/fire/IntegratingAWV.html#installawv and copy the awv_interface.jar file to this folder:' + awv_interface_expected_path + ' and re-run cordova platform add amazon-fireos command.'));
} else {
d2.resolve();
}
}
});
d.resolve(d2.promise);
}
}
});
return d.promise;
};
module.exports.prototype = {
update_from_config:function(config) {
if (config instanceof config_parser) {
} else throw new Error('update_from_config requires a config_parser object');
// Update app name by editing res/values/strings.xml
var name = config.name();
var strings = xml.parseElementtreeSync(this.strings);
strings.find('string[@name="app_name"]').text = name;
fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
var manifest = xml.parseElementtreeSync(this.manifest);
// Update the version by changing the AndroidManifest android:versionName
var version = config.version();
manifest.getroot().attrib["android:versionName"] = version;
// Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
var pkg = config.packageName();
pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
var orig_pkg = manifest.getroot().attrib.package;
manifest.getroot().attrib.package = pkg;
// Write out AndroidManifest.xml
fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
var orig_java_class = fs.readdirSync(orig_pkgDir).filter(function(f) {return f.indexOf('.svn') == -1;})[0];
var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
shell.mkdir('-p', pkgDir);
var orig_javs = path.join(orig_pkgDir, orig_java_class);
var new_javs = path.join(pkgDir, orig_java_class);
var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
fs.writeFileSync(new_javs, javs_contents, 'utf-8');
},
// Returns the platform-specific www directory.
www_dir:function() {
return path.join(this.path, 'assets', 'www');
},
staging_dir: function() {
return path.join(this.path, '.staging', 'www');
},
config_xml:function(){
return this.android_config;
},
// Used for creating platform_www in projects created by older versions.
cordovajs_path:function(libDir) {
var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
return path.resolve(jsPath);
},
update_www:function() {
var projectRoot = util.isCordova(this.path);
var www = util.projectWww(projectRoot);
var platformWww = path.join(this.path, 'assets');
// remove stock platform assets
shell.rm('-rf', this.www_dir());
// copy over all app www assets
shell.cp('-rf', www, platformWww);
// write out android lib's cordova.js
var custom_path = project_config.has_custom_path(projectRoot, 'android');
var jsPath;
if (custom_path) {
jsPath = path.resolve(path.join(custom_path, 'framework', 'assets', 'www', 'cordova.js'));
} else {
jsPath = path.join(util.libDirectory, 'amazon-fireos', 'cordova', require('../../platforms').android.version, 'framework', 'assets', 'www', 'cordova.js');
}
fs.writeFileSync(path.join(this.www_dir(), 'cordova.js'), fs.readFileSync(jsPath, 'utf-8'), 'utf-8');
},
// update the overrides folder into the www folder
update_overrides:function() {
var projectRoot = util.isCordova(this.path);
var merges_path = path.join(util.appDir(projectRoot), 'merges', 'amazon-fireos');
if (fs.existsSync(merges_path)) {
var overrides = path.join(merges_path, '*');
shell.cp('-rf', overrides, this.www_dir());
}
},
// update the overrides folder into the www folder
update_staging:function() {
if (fs.existsSync(this.staging_dir())) {
var staging = path.join(this.staging_dir(), '*');
shell.cp('-rf', staging, this.www_dir());
}
},
// Returns a promise.
update_project:function(cfg) {
var platformWww = path.join(this.path, 'assets');
try {
this.update_from_config(cfg);
} catch(e) {
return Q.reject(e);
}
this.update_overrides();
this.update_staging();
// delete any .svn folders copied over
util.deleteSvnFolders(platformWww);
return Q();
}
};