23
23
24
24
import processing .app .Base ;
25
25
import processing .app .Platform ;
26
+ import processing .app .Preferences ;
27
+ import processing .app .exec .LineProcessor ;
28
+ import processing .app .exec .StreamPump ;
26
29
import processing .core .PApplet ;
27
30
28
31
import java .awt .Frame ;
@@ -74,12 +77,12 @@ public class AVD {
74
77
protected String name ;
75
78
76
79
/** "system-images;android-25;google_apis;x86" */
77
- protected String sdkId ;
78
-
80
+ protected ArrayList <String > watchImages ;
81
+ protected ArrayList <String > phoneImages ;
82
+
79
83
protected String device ;
80
84
protected String skin ;
81
85
82
- static boolean invalidPackage ;
83
86
static ArrayList <String > avdList ;
84
87
static ArrayList <String > badList ;
85
88
// static ArrayList<String> skinList;
@@ -89,25 +92,23 @@ public class AVD {
89
92
/** Default virtual device used by Processing. */
90
93
static public final AVD mobileAVD =
91
94
new AVD ("processing-phone" ,
92
- "system-images;" + AndroidBuild .TARGET_PLATFORM + ";" +
93
- SysImageDownloader .SYSTEM_IMAGE_TAG + ";x86" ,
94
95
DEVICE_DEFINITION , DEVICE_SKIN );
95
96
96
97
/** Default virtual wear device used by Processing. */
97
98
static public final AVD wearAVD =
98
99
new AVD ("processing-watch" ,
99
- "system-images;" + AndroidBuild .TARGET_PLATFORM + ";" +
100
- SysImageDownloader .SYSTEM_IMAGE_WEAR_TAG + ";x86" ,
101
100
DEVICE_WEAR_DEFINITION , DEVICE_WEAR_SKIN );
102
101
103
102
104
- public AVD (final String name , final String sdkId ,
105
- final String device , final String skin ) {
103
+ public AVD (final String name , final String device , final String skin ) {
106
104
this .name = name ;
107
- this .sdkId = sdkId ;
108
105
this .device = device ;
109
106
this .skin = skin ;
110
- //initializeAbiList(tag);
107
+
108
+ if (name .contains ("phone" ))
109
+ phoneImages = new ArrayList <>();
110
+ else
111
+ watchImages = new ArrayList <>();
111
112
}
112
113
113
114
@@ -123,14 +124,16 @@ static protected void list(final AndroidSDK sdk) throws IOException {
123
124
pb .redirectErrorStream (true );
124
125
125
126
process = pb .start ();
126
- InputStream stdout = process .getInputStream ();
127
- BufferedReader reader = new BufferedReader (new InputStreamReader (stdout ));
127
+
128
+ StringWriter outWriter = new StringWriter ();
129
+ new StreamPump (process .getInputStream (), "out: " ).addTarget (outWriter ).start ();
128
130
process .waitFor ();
129
131
132
+ String [] lines = PApplet .split (outWriter .toString (), '\n' );
133
+
130
134
if (process .exitValue () == 0 ) {
131
135
boolean badness = false ;
132
- String line ;
133
- while ((line = reader .readLine ()) != null ) {
136
+ for (String line : lines ) {
134
137
String [] m = PApplet .match (line , "\\ s+Name\\ :\\ s+(\\ S+)" );
135
138
if (m != null ) {
136
139
if (!badness ) {
@@ -154,9 +157,7 @@ static protected void list(final AndroidSDK sdk) throws IOException {
154
157
}
155
158
} else {
156
159
System .err .println ("Unhappy inside exists()" );
157
- String line ;
158
- while ((line = reader .readLine ()) != null )
159
- System .err .println (line );
160
+ System .err .println (outWriter .toString ());
160
161
}
161
162
} catch (final InterruptedException ie ) { }
162
163
finally {
@@ -195,6 +196,65 @@ protected boolean badness() {
195
196
return false ;
196
197
}
197
198
199
+ protected void getImages (AndroidSDK sdk ) throws IOException {
200
+ // Dummy avdmanager creation command to get the list of installed images
201
+ // TODO : Find a better way to get the list of installed images
202
+ ProcessBuilder pb = new ProcessBuilder (
203
+ sdk .getAvdManagerPath (),
204
+ "create" , "avd" ,
205
+ "-n" , "dummy" ,
206
+ "-k" , "dummy"
207
+ );
208
+
209
+ Map <String , String > env = pb .environment ();
210
+ env .clear ();
211
+ env .put ("JAVA_HOME" , Platform .getJavaHome ().getCanonicalPath ());
212
+ pb .redirectErrorStream (true );
213
+
214
+ try {
215
+ process = pb .start ();
216
+
217
+ StreamPump output = new StreamPump (process .getInputStream (), "out: " );
218
+ output .addTarget (new LineProcessor () {
219
+ @ Override
220
+ public void processLine (String line ) {
221
+ if (phoneImages != null && line .contains (AndroidBuild .TARGET_PLATFORM ) &&
222
+ line .contains (SysImageDownloader .SYSTEM_IMAGE_TAG ))
223
+ phoneImages .add (line );
224
+ else if (watchImages != null && line .contains (AndroidBuild .TARGET_PLATFORM ) &&
225
+ line .contains (SysImageDownloader .SYSTEM_IMAGE_WEAR_TAG ))
226
+ watchImages .add (line );
227
+ }
228
+ }).start ();
229
+
230
+ process .waitFor ();
231
+ } catch (final InterruptedException ie ) {
232
+ ie .printStackTrace ();
233
+ } finally {
234
+ process .destroy ();
235
+ }
236
+ }
237
+
238
+ protected String getSdkId () throws IOException {
239
+ if (Preferences .get ("android.system.image.type" ) == null )
240
+ Preferences .set ("android.system.image.type" , "x86" ); // Prefer x86
241
+
242
+ if (this .name .contains ("phone" )) {
243
+ for (String image : phoneImages ) {
244
+ if (image .contains (Preferences .get ("android.system.image.type" )))
245
+ return image ;
246
+ }
247
+ } else {
248
+ for (String image : watchImages ) {
249
+ if (image .contains (Preferences .get ("android.system.image.type" )))
250
+ return image ;
251
+ }
252
+ }
253
+
254
+ // Could not find any suitable package
255
+ return "null" ;
256
+ }
257
+
198
258
199
259
protected boolean create (final AndroidSDK sdk ) throws IOException {
200
260
//initTargets(sdk);
@@ -207,7 +267,7 @@ protected boolean create(final AndroidSDK sdk) throws IOException {
207
267
sdk .getAvdManagerPath (),
208
268
"create" , "avd" ,
209
269
"-n" , name ,
210
- "-k" , sdkId ,
270
+ "-k" , getSdkId () ,
211
271
"-c" , DEFAULT_SDCARD_SIZE ,
212
272
"-d" , device ,
213
273
"-p" , avdPath .getAbsolutePath (),
@@ -227,9 +287,6 @@ protected boolean create(final AndroidSDK sdk) throws IOException {
227
287
try {
228
288
process = pb .start ();
229
289
230
- InputStream stdout = process .getInputStream ();
231
- BufferedReader reader = new BufferedReader (new InputStreamReader (stdout ));
232
-
233
290
// Passes 'no' to "Do you wish to create a custom hardware profile [no]"
234
291
OutputStream os = process .getOutputStream ();
235
292
PrintWriter pw = new PrintWriter (new OutputStreamWriter (os ));
@@ -238,7 +295,10 @@ protected boolean create(final AndroidSDK sdk) throws IOException {
238
295
pw .close ();
239
296
os .flush ();
240
297
os .close ();
241
-
298
+
299
+ StringWriter outWriter = new StringWriter ();
300
+ new StreamPump (process .getInputStream (), "out: " ).addTarget (outWriter ).start ();
301
+
242
302
process .waitFor ();
243
303
244
304
if (process .exitValue () == 0 ) {
@@ -253,21 +313,15 @@ protected boolean create(final AndroidSDK sdk) throws IOException {
253
313
return true ;
254
314
}
255
315
256
- String line ;
257
- StringBuilder output = new StringBuilder ();
258
- while ((line = reader .readLine ()) != null ) {
259
- output .append (line );
260
- }
261
- if (output .toString ().contains ("Package path is not valid" )) {
316
+ if (outWriter .toString ().contains ("Package path is not valid" )) {
262
317
// They didn't install the Google APIs
263
318
AndroidUtil .showMessage (AVD_TARGET_TITLE , AVD_TARGET_MESSAGE );
264
- invalidPackage = true ;
265
319
} else {
266
320
// Just generally not working
267
321
AndroidUtil .showMessage (AVD_CREATE_TITLE ,
268
322
String .format (AVD_CREATE_MESSAGE , AndroidBuild .TARGET_SDK ));
269
323
}
270
- System .out .println (output .toString ());
324
+ System .err .println (outWriter .toString ());
271
325
//System.err.println(createAvdResult);
272
326
} catch (final InterruptedException ie ) {
273
327
ie .printStackTrace ();
@@ -299,20 +353,19 @@ static public boolean ensureProperAVD(final Frame window, final AndroidMode mode
299
353
AndroidUtil .showMessage (AVD_LOAD_TITLE , AVD_LOAD_MESSAGE );
300
354
return false ;
301
355
}
302
- if (wearAVD .create (sdk )) {
303
- return true ;
304
- }
305
- if (invalidPackage ) {
356
+ wearAVD .getImages (sdk );
357
+ if (wearAVD .watchImages .isEmpty ()) {
306
358
boolean res = AndroidSDK .locateSysImage (window , mode , true );
307
359
if (!res ) {
308
360
return false ;
309
361
} else {
310
- // Try again
311
- if (wearAVD .create (sdk )) {
312
- return true ;
313
- }
362
+ // Refresh images list
363
+ wearAVD .getImages (sdk );
314
364
}
315
365
}
366
+ if (wearAVD .create (sdk )) {
367
+ return true ;
368
+ }
316
369
} else {
317
370
if (mobileAVD .exists (sdk )) {
318
371
return true ;
@@ -321,20 +374,19 @@ static public boolean ensureProperAVD(final Frame window, final AndroidMode mode
321
374
AndroidUtil .showMessage (AVD_LOAD_TITLE , AVD_LOAD_MESSAGE );
322
375
return false ;
323
376
}
324
- if (mobileAVD .create (sdk )) {
325
- return true ;
326
- }
327
- if (invalidPackage ) {
377
+ mobileAVD .getImages (sdk );
378
+ if (mobileAVD .phoneImages .isEmpty ()) {
328
379
boolean res = AndroidSDK .locateSysImage (window , mode , false );
329
380
if (!res ) {
330
381
return false ;
331
382
} else {
332
- // Try again
333
- if (mobileAVD .create (sdk )) {
334
- return true ;
335
- }
383
+ // Refresh images list
384
+ mobileAVD .getImages (sdk );
336
385
}
337
386
}
387
+ if (mobileAVD .create (sdk )) {
388
+ return true ;
389
+ }
338
390
}
339
391
} catch (final Exception e ) {
340
392
e .printStackTrace ();
0 commit comments