Skip to content

Commit 73d6653

Browse files
Fatme HavaluovaFatme Havaluova
Fatme Havaluova
authored and
Fatme Havaluova
committed
Gradle support
1 parent 5050178 commit 73d6653

File tree

2 files changed

+57
-142
lines changed

2 files changed

+57
-142
lines changed

lib/services/android-project-service.ts

+57-139
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
1212
private static MIN_SUPPORTED_VERSION = 17;
1313
private SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22"]; // forbidden for now: "android-MNC"
1414
private static ANDROID_TARGET_PREFIX = "android";
15-
private static RES_DIRNAME = "res";
1615
private static VALUES_DIRNAME = "values";
1716
private static VALUES_VERSION_DIRNAME_PREFIX = AndroidProjectService.VALUES_DIRNAME + "-v";
1817
private static ANDROID_PLATFORM_NAME = "android";
1918
private static LIBS_FOLDER_NAME = "libs";
2019
private static MIN_JAVA_VERSION = "1.7.0";
2120

22-
private targetApi: string;
2321
private _androidProjectPropertiesManagers: IDictionary<IAndroidProjectPropertiesManager>;
2422

2523
constructor(private $androidEmulatorServices: Mobile.IEmulatorPlatformServices,
@@ -30,6 +28,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
3028
private $logger: ILogger,
3129
private $options: IOptions,
3230
private $projectData: IProjectData,
31+
private $projectDataService: IProjectDataService,
3332
private $propertiesParser: IPropertiesParser,
3433
private $sysInfo: ISysInfo,
3534
$fs: IFileSystem) {
@@ -45,19 +44,19 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
4544
this._platformData = {
4645
frameworkPackageName: "tns-android",
4746
normalizedPlatformName: "Android",
48-
appDestinationDirectoryPath: path.join(projectRoot, "assets"),
49-
appResourcesDestinationDirectoryPath: path.join(projectRoot, "res"),
47+
appDestinationDirectoryPath: path.join(projectRoot, "src", "main", "assets"),
48+
appResourcesDestinationDirectoryPath: path.join(projectRoot, "src", "main", "res"),
5049
platformProjectService: this,
5150
emulatorServices: this.$androidEmulatorServices,
5251
projectRoot: projectRoot,
53-
deviceBuildOutputPath: path.join(this.$projectData.platformsDir, "android", "bin"),
52+
deviceBuildOutputPath: path.join(projectRoot, "build", "outputs", "apk"),
5453
validPackageNamesForDevice: [
5554
`${this.$projectData.projectName}-debug.apk`,
5655
`${this.$projectData.projectName}-release.apk`
5756
],
5857
frameworkFilesExtensions: [".jar", ".dat", ".so"],
5958
configurationFileName: "AndroidManifest.xml",
60-
configurationFilePath: path.join(this.$projectData.platformsDir, "android", "AndroidManifest.xml"),
59+
configurationFilePath: path.join(projectRoot, "src", "main", "AndroidManifest.xml"),
6160
mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }, {"nodename": "application", "attrname": "*"}]
6261
};
6362
}
@@ -80,38 +79,28 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
8079
return (() => {
8180
this.$fs.ensureDirectoryExists(projectRoot).wait();
8281

83-
let newTarget = this.getAndroidTarget(frameworkDir).wait();
82+
let newTarget = this.getAndroidTarget().wait();
8483
this.$logger.trace(`Using Android SDK '${newTarget}'.`);
8584
let versionNumber = _.last(newTarget.split("-"));
8685
if(this.$options.symlink) {
8786
this.copyResValues(projectRoot, frameworkDir, versionNumber).wait();
88-
this.copy(projectRoot, frameworkDir, ".project AndroidManifest.xml project.properties custom_rules.xml", "-f").wait();
87+
this.copy(projectRoot, frameworkDir, "AndroidManifest.xml custom_rules.xml", "-f");
8988

90-
this.symlinkDirectory("assets", projectRoot, frameworkDir).wait();
89+
this.symlinkDirectory("build-tools", projectRoot, frameworkDir).wait();
9190
this.symlinkDirectory("libs", projectRoot, frameworkDir).wait();
91+
this.symlinkDirectory("src", projectRoot, frameworkDir).wait();
9292
} else {
9393
this.copyResValues(projectRoot, frameworkDir, versionNumber).wait();
94-
this.copy(projectRoot, frameworkDir, "assets libs", "-R").wait();
95-
this.copy(projectRoot, frameworkDir, ".project AndroidManifest.xml project.properties custom_rules.xml", "-f").wait();
94+
this.copy(projectRoot, frameworkDir, "build-tools libs src", "-R");
95+
this.copy(projectRoot, frameworkDir, "build.gradle", "-f");
9696
}
97-
98-
if(newTarget) {
99-
this.updateTarget(projectRoot, newTarget).wait();
100-
}
101-
102-
// Create src folder
103-
let packageName = this.$projectData.projectId;
104-
let packageAsPath = packageName.replace(/\./g, path.sep);
105-
let activityDir = path.join(projectRoot, 'src', packageAsPath);
106-
this.$fs.createDirectory(activityDir).wait();
107-
10897
}).future<any>()();
10998
}
11099

111100
private copyResValues(projectRoot: string, frameworkDir: string, versionNumber: string): IFuture<void> {
112101
return (() => {
113-
let resSourceDir = path.join(frameworkDir, AndroidProjectService.RES_DIRNAME);
114-
let resDestinationDir = path.join(projectRoot, AndroidProjectService.RES_DIRNAME);
102+
let resSourceDir = path.join(frameworkDir, "src", "main", "res");
103+
let resDestinationDir = this.platformData.appResourcesDestinationDirectoryPath;
115104
this.$fs.createDirectory(resDestinationDir).wait();
116105
let versionDirName = AndroidProjectService.VALUES_VERSION_DIRNAME_PREFIX + versionNumber;
117106
let directoriesToCopy = [AndroidProjectService.VALUES_DIRNAME];
@@ -133,43 +122,38 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
133122
directoriesToCopy.push(versionDir);
134123
}
135124

136-
this.copy(resDestinationDir, resSourceDir, directoriesToCopy.join(" "), "-R").wait();
125+
this.copy(resDestinationDir, resSourceDir, directoriesToCopy.join(" "), "-R");
137126
}).future<void>()();
138127
}
139128

140129
public interpolateData(projectRoot: string): IFuture<void> {
141130
return (() => {
142131
// Interpolate the activity name and package
143-
let manifestPath = path.join(projectRoot, "AndroidManifest.xml");
132+
let manifestPath = this.platformData.configurationFilePath;
144133
shell.sed('-i', /__PACKAGE__/, this.$projectData.projectId, manifestPath);
145-
shell.sed('-i', /__APILEVEL__/, this.getTarget(projectRoot).wait().split('-')[1], manifestPath);
134+
shell.sed('-i', /__APILEVEL__/, this.getApiLevel().wait(), manifestPath);
146135

147-
let stringsFilePath = path.join(projectRoot, 'res', 'values', 'strings.xml');
136+
let stringsFilePath = path.join(this.platformData.appResourcesDestinationDirectoryPath, 'values', 'strings.xml');
148137
shell.sed('-i', /__NAME__/, this.$projectData.projectName, stringsFilePath);
149138
shell.sed('-i', /__TITLE_ACTIVITY__/, this.$projectData.projectName, stringsFilePath);
150-
shell.sed('-i', /__NAME__/, this.$projectData.projectName, path.join(projectRoot, '.project'));
151139
}).future<void>()();
152140
}
153141

154142
public afterCreateProject(projectRoot: string): IFuture<void> {
155143
return (() => {
156-
let targetApi = this.getTarget(projectRoot).wait();
157-
this.$logger.trace("Android target: %s", targetApi);
158-
this.runAndroidUpdate(projectRoot, targetApi).wait();
159-
this.adjustMinSdk(projectRoot);
144+
let targetApi = this.getAndroidTarget().wait();
145+
this.$logger.trace(`Adroid target: ${targetApi}`);
146+
this.adjustMinSdk(projectRoot).wait();
160147
}).future<void>()();
161148
}
162149

163-
private adjustMinSdk(projectRoot: string): void {
164-
let manifestPath = path.join(projectRoot, "AndroidManifest.xml");
165-
let apiLevel = this.getTarget(projectRoot).wait().split('-')[1];
166-
if (apiLevel === "MNC") { // MNC SDK requires that minSdkVersion is set to "MNC"
167-
shell.sed('-i', /android:minSdkVersion=".*?"/, `android:minSdkVersion="${apiLevel}"`, manifestPath);
168-
}
169-
}
170-
171-
public getDebugOnDeviceSetup(): Mobile.IDebugOnDeviceSetup {
172-
return { };
150+
private adjustMinSdk(projectRoot: string): IFuture<void> {
151+
return (() => {
152+
let apiLevel = this.getApiLevel().wait();
153+
if (apiLevel === "MNC") { // MNC SDK requires that minSdkVersion is set to "MNC"
154+
shell.sed('-i', /android:minSdkVersion=".*?"/, `android:minSdkVersion="${apiLevel}"`, this.platformData.configurationFilePath);
155+
}
156+
}).future<void>()();
173157
}
174158

175159
public canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean> {
@@ -181,13 +165,29 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
181165
}
182166

183167
public buildProject(projectRoot: string): IFuture<void> {
184-
let buildConfiguration = this.$options.release ? "release" : "debug";
185-
let args = this.getAntArgs(buildConfiguration, projectRoot);
186-
return this.spawn('ant', args);
168+
return (() => {
169+
this.$projectDataService.initialize(this.$projectData.projectDir);
170+
let frameworkVersion = this.$projectDataService.getValue(this.platformData.frameworkPackageName).wait().version;
171+
if(semver.lt(frameworkVersion, "1.3.0")) {
172+
let args = this.getAntArgs(this.$options.release ? "release" : "debug", projectRoot);
173+
this.spawn('ant', args).wait();
174+
} else { // Gradle build
175+
let buildOptions = ["buildapk"];
176+
if(this.$options.release) {
177+
buildOptions.push("-Prelease");
178+
buildOptions.push(`-PksPath=${this.$options.keyStorePath}`);
179+
buildOptions.push(`-PksPassword=${this.$options.keyStorePassword}`);
180+
buildOptions.push(`-Palias=${this.$options.keyStoreAlias}`);
181+
buildOptions.push(`-Ppass=${this.$options.keyStoreAliasPassword}`);
182+
}
183+
184+
this.$childProcess.spawnFromEvent("gradle", buildOptions, "close", { stdio: "inherit", cwd: this.platformData.projectRoot }).wait();
185+
}
186+
}).future<void>()();
187187
}
188188

189189
public isPlatformPrepared(projectRoot: string): IFuture<boolean> {
190-
return this.$fs.exists(path.join(projectRoot, "assets", constants.APP_FOLDER_NAME));
190+
return this.$fs.exists(path.join(this.platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME));
191191
}
192192

193193
private getProjectPropertiesManager(filePath: string): IAndroidProjectPropertiesManager {
@@ -197,32 +197,6 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
197197

198198
return this._androidProjectPropertiesManagers[filePath];
199199
}
200-
201-
private parseProjectProperties(projDir: string, destDir: string): IFuture<void> { // projDir is libraryPath, targetPath is the path to lib folder
202-
return (() => {
203-
projDir = projDir.trim();
204-
let projProp = path.join(projDir, "project.properties");
205-
if (!this.$fs.exists(projProp).wait()) {
206-
this.$logger.warn("Warning: File %s does not exist", projProp);
207-
return;
208-
}
209-
210-
let projectPropertiesManager = this.getProjectPropertiesManager(projDir);
211-
let references = projectPropertiesManager.getProjectReferences().wait();
212-
_.each(references, reference => {
213-
let adjustedPath = this.$fs.isRelativePath(reference.path) ? path.join(projDir, reference.path) : reference.path;
214-
this.parseProjectProperties(adjustedPath, destDir).wait();
215-
});
216-
217-
this.$logger.info("Copying %s", projDir);
218-
shell.cp("-Rf", projDir, destDir);
219-
220-
let targetDir = path.join(destDir, path.basename(projDir));
221-
let targetSdk = `android-${this.$options.sdk || AndroidProjectService.MIN_SUPPORTED_VERSION}`;
222-
this.$logger.info("Generate build.xml for %s", targetDir);
223-
this.runAndroidUpdate(targetDir, targetSdk).wait();
224-
}).future<void>()();
225-
}
226200

227201
public addLibrary(libraryPath: string): IFuture<void> {
228202
return (() => {
@@ -232,20 +206,10 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
232206
let targetPath = path.dirname(targetLibPath);
233207
this.$fs.ensureDirectoryExists(targetPath).wait();
234208

235-
if(this.$fs.exists(path.join(libraryPath, "project.properties")).wait()) {
236-
this.parseProjectProperties(libraryPath, targetPath).wait();
237-
}
238-
239209
shell.cp("-f", path.join(libraryPath, "*.jar"), targetPath);
240210
let projectLibsDir = path.join(this.platformData.projectRoot, "libs");
241211
this.$fs.ensureDirectoryExists(projectLibsDir).wait();
242212
shell.cp("-f", path.join(libraryPath, "*.jar"), projectLibsDir);
243-
244-
let libProjProp = path.join(libraryPath, "project.properties");
245-
if (this.$fs.exists(libProjProp).wait()) {
246-
this.updateProjectReferences(this.platformData.projectRoot, targetLibPath).wait();
247-
this.runAndroidUpdate(targetLibPath, this.getTarget(this.platformData.projectRoot).wait()).wait();
248-
}
249213
}).future<void>()();
250214
}
251215

@@ -311,25 +275,16 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
311275
return path.join(this.$projectData.projectDir, "lib", this.platformData.normalizedPlatformName, libraryName);
312276
}
313277

314-
private updateProjectReferences(projDir: string, libraryPath: string): IFuture<void> {
315-
let relLibDir = this.getLibraryRelativePath(projDir, libraryPath);
316-
317-
let projectPropertiesManager = this.getProjectPropertiesManager(projDir);
318-
return projectPropertiesManager.addProjectReference(relLibDir);
319-
}
320-
321278
private getAllLibrariesForPlugin(pluginData: IPluginData): IFuture<string[]> {
322279
return (() => {
323280
let filterCallback = (fileName: string, pluginPlatformsFolderPath: string) => fileName !== AndroidProjectService.LIBS_FOLDER_NAME && this.$fs.exists(path.join(pluginPlatformsFolderPath, fileName, "project.properties")).wait();
324281
return this.getAllNativeLibrariesForPlugin(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME, filterCallback).wait();
325282
}).future<string[]>()();
326283
}
327284

328-
private copy(projectRoot: string, frameworkDir: string, files: string, cpArg: string): IFuture<void> {
329-
return (() => {
330-
let paths = files.split(' ').map(p => path.join(frameworkDir, p));
331-
shell.cp(cpArg, paths, projectRoot);
332-
}).future<void>()();
285+
private copy(projectRoot: string, frameworkDir: string, files: string, cpArg: string): void {
286+
let paths = files.split(' ').map(p => path.join(frameworkDir, p));
287+
shell.cp(cpArg, paths, projectRoot);
333288
}
334289

335290
private spawn(command: string, args: string[]): IFuture<void> {
@@ -367,16 +322,6 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
367322
return args;
368323
}
369324

370-
private runAndroidUpdate(projectPath: string, targetApi: string): IFuture<void> {
371-
let args = [
372-
"--path", projectPath,
373-
"--target", targetApi,
374-
"--name", this.$projectData.projectName
375-
];
376-
377-
return this.spawn("android", ['update', 'project'].concat(args));
378-
}
379-
380325
private validatePackageName(packageName: string): void {
381326
//Make the package conform to Java package types
382327
//Enforce underscore limitation
@@ -401,9 +346,9 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
401346
}
402347
}
403348

404-
private getAndroidTarget(frameworkDir: string): IFuture<string> {
349+
private getAndroidTarget(): IFuture<string> {
405350
return ((): string => {
406-
let newTarget = this.$options.sdk ? `${AndroidProjectService.ANDROID_TARGET_PREFIX}-${this.$options.sdk}` : this.getLatestValidAndroidTarget(frameworkDir).wait();
351+
let newTarget = this.$options.sdk ? `${AndroidProjectService.ANDROID_TARGET_PREFIX}-${this.$options.sdk}` : this.getLatestValidAndroidTarget().wait();
407352
if(!_.contains(this.SUPPORTED_TARGETS, newTarget)) {
408353
let versionNumber = parseInt(_.last(newTarget.split("-")));
409354
if(versionNumber && (versionNumber < AndroidProjectService.MIN_SUPPORTED_VERSION)) {
@@ -421,7 +366,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
421366
}).future<string>()();
422367
}
423368

424-
private getLatestValidAndroidTarget(frameworkDir: string): IFuture<string> {
369+
private getLatestValidAndroidTarget(): IFuture<string> {
425370
return (() => {
426371
let installedTargets = this.getInstalledTargets().wait();
427372

@@ -436,23 +381,11 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
436381
return newTarget;
437382
}).future<string>()();
438383
}
439-
440-
private updateTarget(projectRoot: string, newTarget: string): IFuture<void> {
384+
385+
private getApiLevel(): IFuture<string> {
441386
return (() => {
442-
let file = path.join(projectRoot, "project.properties");
443-
let editor = this.$propertiesParser.createEditor(file).wait();
444-
editor.set("target", newTarget);
445-
let future = new Future<void>();
446-
editor.save((err:any) => {
447-
if (err) {
448-
future.throw(err);
449-
} else {
450-
this.targetApi = null; // so that later we can repopulate the cache
451-
future.return();
452-
}
453-
});
454-
future.wait();
455-
}).future<void>()();
387+
return this.getAndroidTarget().wait().split('-')[1];
388+
}).future<string>()();
456389
}
457390

458391
private installedTargetsCache: string[] = null;
@@ -466,21 +399,6 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
466399
return this.installedTargetsCache;
467400
}).future<string[]>()();
468401
}
469-
470-
private getTarget(projectRoot: string): IFuture<string> {
471-
return (() => {
472-
if(!this.targetApi) {
473-
let projectPropertiesFilePath = path.join(projectRoot, "project.properties");
474-
475-
if (this.$fs.exists(projectPropertiesFilePath).wait()) {
476-
let properties = this.$propertiesParser.createEditor(projectPropertiesFilePath).wait();
477-
this.targetApi = properties.get("target");
478-
}
479-
}
480-
481-
return this.targetApi;
482-
}).future<string>()();
483-
}
484402

485403
private checkJava(): IFuture<void> {
486404
return (() => {

test/stubs.ts

-3
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,6 @@ export class PlatformProjectServiceStub implements IPlatformProjectService {
301301
addLibrary(libraryPath: string): IFuture<void> {
302302
return Future.fromResult();
303303
}
304-
getDebugOnDeviceSetup(): Mobile.IDebugOnDeviceSetup {
305-
return null;
306-
}
307304
canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean> {
308305
return Future.fromResult(false);
309306
}

0 commit comments

Comments
 (0)