commonroutesServer/www/platforms/android/cordova/Api.js
www/platforms/android/cordova/Api.jsRaw
1/**
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18*/
19
20var path = require('path');
21
22var AndroidProject = require('./lib/AndroidProject');
23var PluginManager = require('cordova-common').PluginManager;
24
25var CordovaLogger = require('cordova-common').CordovaLogger;
26var selfEvents = require('cordova-common').events;
27
28var PLATFORM = 'android';
29
30function setupEvents(externalEventEmitter) {
31 if (externalEventEmitter) {
32 // This will make the platform internal events visible outside
33 selfEvents.forwardEventsTo(externalEventEmitter);
34 return externalEventEmitter;
35 }
36
37 // There is no logger if external emitter is not present,
38 // so attach a console logger
39 CordovaLogger.get().subscribe(selfEvents);
40 return selfEvents;
41}
42
43/**
44 * Class, that acts as abstraction over particular platform. Encapsulates the
45 * platform's properties and methods.
46 *
47 * Platform that implements own PlatformApi instance _should implement all
48 * prototype methods_ of this class to be fully compatible with cordova-lib.
49 *
50 * The PlatformApi instance also should define the following field:
51 *
52 * * platform: String that defines a platform name.
53 */
54function Api(platform, platformRootDir, events) {
55 this.platform = PLATFORM;
56 this.root = path.resolve(__dirname, '..');
57
58 setupEvents(events);
59
60 var self = this;
61
62 this.locations = {
63 root: self.root,
64 www: path.join(self.root, 'assets/www'),
65 platformWww: path.join(self.root, 'platform_www'),
66 configXml: path.join(self.root, 'res/xml/config.xml'),
67 defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'),
68 strings: path.join(self.root, 'res/values/strings.xml'),
69 manifest: path.join(self.root, 'AndroidManifest.xml'),
70 // NOTE: Due to platformApi spec we need to return relative paths here
71 cordovaJs: 'bin/templates/project/assets/www/cordova.js',
72 cordovaJsSrc: 'cordova-js-src'
73 };
74}
75
76/**
77 * Installs platform to specified directory and creates a platform project.
78 *
79 * @param {String} destination Destination directory, where insatll platform to
80 * @param {ConfigParser} [config] ConfgiParser instance, used to retrieve
81 * project creation options, such as package id and project name.
82 * @param {Object} [options] An options object. The most common options are:
83 * @param {String} [options.customTemplate] A path to custom template, that
84 * should override the default one from platform.
85 * @param {Boolean} [options.link] Flag that indicates that platform's
86 * sources will be linked to installed platform instead of copying.
87 * @param {EventEmitter} [events] An EventEmitter instance that will be used for
88 * logging purposes. If no EventEmitter provided, all events will be logged to
89 * console
90 *
91 * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
92 * instance or rejected with CordovaError.
93 */
94Api.createPlatform = function (destination, config, options, events) {
95 events = setupEvents(events);
96
97 return require('../../lib/create')
98 .create(destination, config, options, events)
99 .then(function (destination) {
100 var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
101 return new PlatformApi(PLATFORM, destination, events);
102 });
103};
104
105/**
106 * Updates already installed platform.
107 *
108 * @param {String} destination Destination directory, where platform installed
109 * @param {Object} [options] An options object. The most common options are:
110 * @param {String} [options.customTemplate] A path to custom template, that
111 * should override the default one from platform.
112 * @param {Boolean} [options.link] Flag that indicates that platform's
113 * sources will be linked to installed platform instead of copying.
114 * @param {EventEmitter} [events] An EventEmitter instance that will be used for
115 * logging purposes. If no EventEmitter provided, all events will be logged to
116 * console
117 *
118 * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
119 * instance or rejected with CordovaError.
120 */
121Api.updatePlatform = function (destination, options, events) {
122 events = setupEvents(events);
123
124 return require('../../lib/create')
125 .update(destination, options, events)
126 .then(function (destination) {
127 var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
128 return new PlatformApi('android', destination, events);
129 });
130};
131
132/**
133 * Gets a CordovaPlatform object, that represents the platform structure.
134 *
135 * @return {CordovaPlatform} A structure that contains the description of
136 * platform's file structure and other properties of platform.
137 */
138Api.prototype.getPlatformInfo = function () {
139 var result = {};
140 result.locations = this.locations;
141 result.root = this.root;
142 result.name = this.platform;
143 result.version = require('./version');
144 result.projectConfig = this._config;
145
146 return result;
147};
148
149/**
150 * Updates installed platform with provided www assets and new app
151 * configuration. This method is required for CLI workflow and will be called
152 * each time before build, so the changes, made to app configuration and www
153 * code, will be applied to platform.
154 *
155 * @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a
156 * project structure and configuration, that should be applied to platform
157 * (contains project's www location and ConfigParser instance for project's
158 * config).
159 *
160 * @return {Promise} Return a promise either fulfilled, or rejected with
161 * CordovaError instance.
162 */
163Api.prototype.prepare = function (cordovaProject, prepareOptions) {
164 return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
165};
166
167/**
168 * Installs a new plugin into platform. This method only copies non-www files
169 * (sources, libs, etc.) to platform. It also doesn't resolves the
170 * dependencies of plugin. Both of handling of www files, such as assets and
171 * js-files and resolving dependencies are the responsibility of caller.
172 *
173 * @param {PluginInfo} plugin A PluginInfo instance that represents plugin
174 * that will be installed.
175 * @param {Object} installOptions An options object. Possible options below:
176 * @param {Boolean} installOptions.link: Flag that specifies that plugin
177 * sources will be symlinked to app's directory instead of copying (if
178 * possible).
179 * @param {Object} installOptions.variables An object that represents
180 * variables that will be used to install plugin. See more details on plugin
181 * variables in documentation:
182 * https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html
183 *
184 * @return {Promise} Return a promise either fulfilled, or rejected with
185 * CordovaError instance.
186 */
187Api.prototype.addPlugin = function (plugin, installOptions) {
188 var project = AndroidProject.getProjectFile(this.root);
189
190 installOptions = installOptions || {};
191 installOptions.variables = installOptions.variables || {};
192 // Add PACKAGE_NAME variable into vars
193 if (!installOptions.variables.PACKAGE_NAME) {
194 installOptions.variables.PACKAGE_NAME = project.getPackageName();
195 }
196
197 return PluginManager.get(this.platform, this.locations, project)
198 .addPlugin(plugin, installOptions)
199 .then(function () {
200 if (plugin.getFrameworks(this.platform).length === 0) return;
201
202 selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
203 require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
204 }.bind(this))
205 // CB-11022 Return truthy value to prevent running prepare after
206 .thenResolve(true);
207};
208
209/**
210 * Removes an installed plugin from platform.
211 *
212 * Since method accepts PluginInfo instance as input parameter instead of plugin
213 * id, caller shoud take care of managing/storing PluginInfo instances for
214 * future uninstalls.
215 *
216 * @param {PluginInfo} plugin A PluginInfo instance that represents plugin
217 * that will be installed.
218 *
219 * @return {Promise} Return a promise either fulfilled, or rejected with
220 * CordovaError instance.
221 */
222Api.prototype.removePlugin = function (plugin, uninstallOptions) {
223 var project = AndroidProject.getProjectFile(this.root);
224 return PluginManager.get(this.platform, this.locations, project)
225 .removePlugin(plugin, uninstallOptions)
226 .then(function () {
227 if (plugin.getFrameworks(this.platform).length === 0) return;
228
229 selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
230 require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
231 }.bind(this))
232 // CB-11022 Return truthy value to prevent running prepare after
233 .thenResolve(true);
234};
235
236/**
237 * Builds an application package for current platform.
238 *
239 * @param {Object} buildOptions A build options. This object's structure is
240 * highly depends on platform's specific. The most common options are:
241 * @param {Boolean} buildOptions.debug Indicates that packages should be
242 * built with debug configuration. This is set to true by default unless the
243 * 'release' option is not specified.
244 * @param {Boolean} buildOptions.release Indicates that packages should be
245 * built with release configuration. If not set to true, debug configuration
246 * will be used.
247 * @param {Boolean} buildOptions.device Specifies that built app is intended
248 * to run on device
249 * @param {Boolean} buildOptions.emulator: Specifies that built app is
250 * intended to run on emulator
251 * @param {String} buildOptions.target Specifies the device id that will be
252 * used to run built application.
253 * @param {Boolean} buildOptions.nobuild Indicates that this should be a
254 * dry-run call, so no build artifacts will be produced.
255 * @param {String[]} buildOptions.archs Specifies chip architectures which
256 * app packages should be built for. List of valid architectures is depends on
257 * platform.
258 * @param {String} buildOptions.buildConfig The path to build configuration
259 * file. The format of this file is depends on platform.
260 * @param {String[]} buildOptions.argv Raw array of command-line arguments,
261 * passed to `build` command. The purpose of this property is to pass a
262 * platform-specific arguments, and eventually let platform define own
263 * arguments processing logic.
264 *
265 * @return {Promise<Object[]>} A promise either fulfilled with an array of build
266 * artifacts (application packages) if package was built successfully,
267 * or rejected with CordovaError. The resultant build artifact objects is not
268 * strictly typed and may conatin arbitrary set of fields as in sample below.
269 *
270 * {
271 * architecture: 'x86',
272 * buildType: 'debug',
273 * path: '/path/to/build',
274 * type: 'app'
275 * }
276 *
277 * The return value in most cases will contain only one item but in some cases
278 * there could be multiple items in output array, e.g. when multiple
279 * arhcitectures is specified.
280 */
281Api.prototype.build = function (buildOptions) {
282 var self = this;
283 return require('./lib/check_reqs').run()
284 .then(function () {
285 return require('./lib/build').run.call(self, buildOptions);
286 })
287 .then(function (buildResults) {
288 // Cast build result to array of build artifacts
289 return buildResults.apkPaths.map(function (apkPath) {
290 return {
291 buildType: buildResults.buildType,
292 buildMethod: buildResults.buildMethod,
293 path: apkPath,
294 type: 'apk'
295 };
296 });
297 });
298};
299
300/**
301 * Builds an application package for current platform and runs it on
302 * specified/default device. If no 'device'/'emulator'/'target' options are
303 * specified, then tries to run app on default device if connected, otherwise
304 * runs the app on emulator.
305 *
306 * @param {Object} runOptions An options object. The structure is the same
307 * as for build options.
308 *
309 * @return {Promise} A promise either fulfilled if package was built and ran
310 * successfully, or rejected with CordovaError.
311 */
312Api.prototype.run = function(runOptions) {
313 var self = this;
314 return require('./lib/check_reqs').run()
315 .then(function () {
316 return require('./lib/run').run.call(self, runOptions);
317 });
318};
319
320/**
321 * Cleans out the build artifacts from platform's directory.
322 *
323 * @return {Promise} Return a promise either fulfilled, or rejected with
324 * CordovaError.
325 */
326Api.prototype.clean = function(cleanOptions) {
327 var self = this;
328 return require('./lib/check_reqs').run()
329 .then(function () {
330 return require('./lib/build').runClean.call(self, cleanOptions);
331 })
332 .then(function () {
333 return require('./lib/prepare').clean.call(self, cleanOptions);
334 });
335};
336
337/**
338 * Performs a requirements check for current platform. Each platform defines its
339 * own set of requirements, which should be resolved before platform can be
340 * built successfully.
341 *
342 * @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
343 * objects for current platform.
344 */
345Api.prototype.requirements = function() {
346 return require('./lib/check_reqs').check_all();
347};
348
349module.exports = Api;