@@ -12,14 +12,12 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
12
12
private static MIN_SUPPORTED_VERSION = 17 ;
13
13
private SUPPORTED_TARGETS = [ "android-17" , "android-18" , "android-19" , "android-21" , "android-22" ] ; // forbidden for now: "android-MNC"
14
14
private static ANDROID_TARGET_PREFIX = "android" ;
15
- private static RES_DIRNAME = "res" ;
16
15
private static VALUES_DIRNAME = "values" ;
17
16
private static VALUES_VERSION_DIRNAME_PREFIX = AndroidProjectService . VALUES_DIRNAME + "-v" ;
18
17
private static ANDROID_PLATFORM_NAME = "android" ;
19
18
private static LIBS_FOLDER_NAME = "libs" ;
20
19
private static MIN_JAVA_VERSION = "1.7.0" ;
21
20
22
- private targetApi : string ;
23
21
private _androidProjectPropertiesManagers : IDictionary < IAndroidProjectPropertiesManager > ;
24
22
25
23
constructor ( private $androidEmulatorServices : Mobile . IEmulatorPlatformServices ,
@@ -30,6 +28,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
30
28
private $logger : ILogger ,
31
29
private $options : IOptions ,
32
30
private $projectData : IProjectData ,
31
+ private $projectDataService : IProjectDataService ,
33
32
private $propertiesParser : IPropertiesParser ,
34
33
private $sysInfo : ISysInfo ,
35
34
$fs : IFileSystem ) {
@@ -45,19 +44,19 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
45
44
this . _platformData = {
46
45
frameworkPackageName : "tns-android" ,
47
46
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") ,
50
49
platformProjectService : this ,
51
50
emulatorServices : this . $androidEmulatorServices ,
52
51
projectRoot : projectRoot ,
53
- deviceBuildOutputPath : path . join ( this . $projectData . platformsDir , "android " , "bin " ) ,
52
+ deviceBuildOutputPath : path . join ( projectRoot , "build " , "outputs" , "apk ") ,
54
53
validPackageNamesForDevice : [
55
54
`${ this . $projectData . projectName } -debug.apk` ,
56
55
`${ this . $projectData . projectName } -release.apk`
57
56
] ,
58
57
frameworkFilesExtensions : [ ".jar" , ".dat" , ".so" ] ,
59
58
configurationFileName : "AndroidManifest.xml" ,
60
- configurationFilePath : path . join ( this . $projectData . platformsDir , "android " , "AndroidManifest.xml" ) ,
59
+ configurationFilePath : path . join ( projectRoot , "src" , "main ", "AndroidManifest.xml" ) ,
61
60
mergeXmlConfig : [ { "nodename" : "manifest" , "attrname" : "*" } , { "nodename" : "application" , "attrname" : "*" } ]
62
61
} ;
63
62
}
@@ -80,38 +79,28 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
80
79
return ( ( ) => {
81
80
this . $fs . ensureDirectoryExists ( projectRoot ) . wait ( ) ;
82
81
83
- let newTarget = this . getAndroidTarget ( frameworkDir ) . wait ( ) ;
82
+ let newTarget = this . getAndroidTarget ( ) . wait ( ) ;
84
83
this . $logger . trace ( `Using Android SDK '${ newTarget } '.` ) ;
85
84
let versionNumber = _ . last ( newTarget . split ( "-" ) ) ;
86
85
if ( this . $options . symlink ) {
87
86
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" ) ;
89
88
90
- this . symlinkDirectory ( "assets " , projectRoot , frameworkDir ) . wait ( ) ;
89
+ this . symlinkDirectory ( "build-tools " , projectRoot , frameworkDir ) . wait ( ) ;
91
90
this . symlinkDirectory ( "libs" , projectRoot , frameworkDir ) . wait ( ) ;
91
+ this . symlinkDirectory ( "src" , projectRoot , frameworkDir ) . wait ( ) ;
92
92
} else {
93
93
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" ) ;
96
96
}
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
-
108
97
} ) . future < any > ( ) ( ) ;
109
98
}
110
99
111
100
private copyResValues ( projectRoot : string , frameworkDir : string , versionNumber : string ) : IFuture < void > {
112
101
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 ;
115
104
this . $fs . createDirectory ( resDestinationDir ) . wait ( ) ;
116
105
let versionDirName = AndroidProjectService . VALUES_VERSION_DIRNAME_PREFIX + versionNumber ;
117
106
let directoriesToCopy = [ AndroidProjectService . VALUES_DIRNAME ] ;
@@ -133,43 +122,38 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
133
122
directoriesToCopy . push ( versionDir ) ;
134
123
}
135
124
136
- this . copy ( resDestinationDir , resSourceDir , directoriesToCopy . join ( " " ) , "-R" ) . wait ( ) ;
125
+ this . copy ( resDestinationDir , resSourceDir , directoriesToCopy . join ( " " ) , "-R" ) ;
137
126
} ) . future < void > ( ) ( ) ;
138
127
}
139
128
140
129
public interpolateData ( projectRoot : string ) : IFuture < void > {
141
130
return ( ( ) => {
142
131
// Interpolate the activity name and package
143
- let manifestPath = path . join ( projectRoot , "AndroidManifest.xml" ) ;
132
+ let manifestPath = this . platformData . configurationFilePath ;
144
133
shell . sed ( '-i' , / _ _ P A C K A G E _ _ / , this . $projectData . projectId , manifestPath ) ;
145
- shell . sed ( '-i' , / _ _ A P I L E V E L _ _ / , this . getTarget ( projectRoot ) . wait ( ) . split ( '-' ) [ 1 ] , manifestPath ) ;
134
+ shell . sed ( '-i' , / _ _ A P I L E V E L _ _ / , this . getApiLevel ( ) . wait ( ) , manifestPath ) ;
146
135
147
- let stringsFilePath = path . join ( projectRoot , 'res' , 'values' , 'strings.xml' ) ;
136
+ let stringsFilePath = path . join ( this . platformData . appResourcesDestinationDirectoryPath , 'values' , 'strings.xml' ) ;
148
137
shell . sed ( '-i' , / _ _ N A M E _ _ / , this . $projectData . projectName , stringsFilePath ) ;
149
138
shell . sed ( '-i' , / _ _ T I T L E _ A C T I V I T Y _ _ / , this . $projectData . projectName , stringsFilePath ) ;
150
- shell . sed ( '-i' , / _ _ N A M E _ _ / , this . $projectData . projectName , path . join ( projectRoot , '.project' ) ) ;
151
139
} ) . future < void > ( ) ( ) ;
152
140
}
153
141
154
142
public afterCreateProject ( projectRoot : string ) : IFuture < void > {
155
143
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 ( ) ;
160
147
} ) . future < void > ( ) ( ) ;
161
148
}
162
149
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' , / a n d r o i d : m i n S d k V e r s i o n = " .* ?" / , `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' , / a n d r o i d : m i n S d k V e r s i o n = " .* ?" / , `android:minSdkVersion="${ apiLevel } "` , this . platformData . configurationFilePath ) ;
155
+ }
156
+ } ) . future < void > ( ) ( ) ;
173
157
}
174
158
175
159
public canUpdatePlatform ( currentVersion : string , newVersion : string ) : IFuture < boolean > {
@@ -181,13 +165,29 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
181
165
}
182
166
183
167
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 > ( ) ( ) ;
187
187
}
188
188
189
189
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 ) ) ;
191
191
}
192
192
193
193
private getProjectPropertiesManager ( filePath : string ) : IAndroidProjectPropertiesManager {
@@ -197,32 +197,6 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
197
197
198
198
return this . _androidProjectPropertiesManagers [ filePath ] ;
199
199
}
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
- }
226
200
227
201
public addLibrary ( libraryPath : string ) : IFuture < void > {
228
202
return ( ( ) => {
@@ -232,20 +206,10 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
232
206
let targetPath = path . dirname ( targetLibPath ) ;
233
207
this . $fs . ensureDirectoryExists ( targetPath ) . wait ( ) ;
234
208
235
- if ( this . $fs . exists ( path . join ( libraryPath , "project.properties" ) ) . wait ( ) ) {
236
- this . parseProjectProperties ( libraryPath , targetPath ) . wait ( ) ;
237
- }
238
-
239
209
shell . cp ( "-f" , path . join ( libraryPath , "*.jar" ) , targetPath ) ;
240
210
let projectLibsDir = path . join ( this . platformData . projectRoot , "libs" ) ;
241
211
this . $fs . ensureDirectoryExists ( projectLibsDir ) . wait ( ) ;
242
212
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
- }
249
213
} ) . future < void > ( ) ( ) ;
250
214
}
251
215
@@ -311,25 +275,16 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
311
275
return path . join ( this . $projectData . projectDir , "lib" , this . platformData . normalizedPlatformName , libraryName ) ;
312
276
}
313
277
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
-
321
278
private getAllLibrariesForPlugin ( pluginData : IPluginData ) : IFuture < string [ ] > {
322
279
return ( ( ) => {
323
280
let filterCallback = ( fileName : string , pluginPlatformsFolderPath : string ) => fileName !== AndroidProjectService . LIBS_FOLDER_NAME && this . $fs . exists ( path . join ( pluginPlatformsFolderPath , fileName , "project.properties" ) ) . wait ( ) ;
324
281
return this . getAllNativeLibrariesForPlugin ( pluginData , AndroidProjectService . ANDROID_PLATFORM_NAME , filterCallback ) . wait ( ) ;
325
282
} ) . future < string [ ] > ( ) ( ) ;
326
283
}
327
284
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 ) ;
333
288
}
334
289
335
290
private spawn ( command : string , args : string [ ] ) : IFuture < void > {
@@ -367,16 +322,6 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
367
322
return args ;
368
323
}
369
324
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
-
380
325
private validatePackageName ( packageName : string ) : void {
381
326
//Make the package conform to Java package types
382
327
//Enforce underscore limitation
@@ -401,9 +346,9 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
401
346
}
402
347
}
403
348
404
- private getAndroidTarget ( frameworkDir : string ) : IFuture < string > {
349
+ private getAndroidTarget ( ) : IFuture < string > {
405
350
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 ( ) ;
407
352
if ( ! _ . contains ( this . SUPPORTED_TARGETS , newTarget ) ) {
408
353
let versionNumber = parseInt ( _ . last ( newTarget . split ( "-" ) ) ) ;
409
354
if ( versionNumber && ( versionNumber < AndroidProjectService . MIN_SUPPORTED_VERSION ) ) {
@@ -421,7 +366,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
421
366
} ) . future < string > ( ) ( ) ;
422
367
}
423
368
424
- private getLatestValidAndroidTarget ( frameworkDir : string ) : IFuture < string > {
369
+ private getLatestValidAndroidTarget ( ) : IFuture < string > {
425
370
return ( ( ) => {
426
371
let installedTargets = this . getInstalledTargets ( ) . wait ( ) ;
427
372
@@ -436,23 +381,11 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
436
381
return newTarget ;
437
382
} ) . future < string > ( ) ( ) ;
438
383
}
439
-
440
- private updateTarget ( projectRoot : string , newTarget : string ) : IFuture < void > {
384
+
385
+ private getApiLevel ( ) : IFuture < string > {
441
386
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 > ( ) ( ) ;
456
389
}
457
390
458
391
private installedTargetsCache : string [ ] = null ;
@@ -466,21 +399,6 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
466
399
return this . installedTargetsCache ;
467
400
} ) . future < string [ ] > ( ) ( ) ;
468
401
}
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
- }
484
402
485
403
private checkJava ( ) : IFuture < void > {
486
404
return ( ( ) => {
0 commit comments