41
41
import java .io .IOException ;
42
42
import java .io .InputStream ;
43
43
import java .io .OutputStream ;
44
+ import java .nio .file .DirectoryStream ;
45
+ import java .nio .file .Files ;
46
+ import java .nio .file .Path ;
47
+ import java .nio .file .Paths ;
44
48
import java .text .DateFormat ;
45
49
import java .text .ParseException ;
46
50
import java .text .SimpleDateFormat ;
47
51
import java .util .ArrayList ;
48
52
import java .util .Date ;
53
+ import java .nio .file .attribute .PosixFilePermission ;
49
54
50
55
import java .io .PrintWriter ;
56
+ import java .util .HashSet ;
57
+ import java .util .Set ;
51
58
52
59
/**
53
60
* Class holding all needed references (path, tools, etc) to the SDK used by
@@ -69,6 +76,7 @@ class AndroidSDK {
69
76
private final File cmdlineTools ;
70
77
private final File avdManager ;
71
78
private final File sdkManager ;
79
+ private final File adb ;
72
80
73
81
private File emulator ;
74
82
@@ -133,29 +141,50 @@ public AndroidSDK(File folder) throws BadSDKException, IOException {
133
141
134
142
// Retrieve the highest platform from the available targets
135
143
ArrayList <SDKTarget > targets = getAvailableSdkTargets ();
136
- int highest = 1 ;
144
+ int highestIncremental = 1 ;
145
+ int highestTarget = 1 ;
146
+ String highestName = "" ;
137
147
for (SDKTarget targ : targets ) {
138
- if (highest < targ .version ) {
139
- highest = targ .version ;
148
+ if (highestIncremental < targ .version_incremental ) {
149
+ highestIncremental = targ .version_incremental ;
150
+ highestTarget = targ .version_sdk ;
151
+ highestName = targ .name ;
140
152
}
141
153
}
142
154
143
- if (highest < PApplet .parseInt (AndroidBuild .TARGET_SDK )) {
155
+ if (highestTarget < PApplet .parseInt (AndroidBuild .TARGET_SDK )) {
144
156
throw new BadSDKException (AndroidMode .getTextString ("android_sdk.error.missing_target_platform" ,
145
157
AndroidBuild .TARGET_SDK , platforms .getAbsolutePath ()));
146
158
}
147
-
148
- highestPlatform = new File (platforms , "android-" + highest );
159
+
160
+ // Find the platform folder with the correct android.jar file.
161
+ // Path platformPath = Paths.get(platforms.getAbsolutePath());
162
+ // String highestPrefix = "android-" + highest;
163
+ // File tmpFile;
164
+ // try (DirectoryStream<Path> stream = Files.newDirectoryStream(platformPath, highestPrefix + "*")) {
165
+ // for (Path entry: stream) {
166
+ // if (Files.isDirectory(entry) && entry.getFileName().toString().startsWith(highestPrefix)) {
167
+ // tmpFile = new File(entry.toString(), "android.jar");
168
+ // if (tmpFile.exists()) {
169
+ // System.out.println(tmpFile);
170
+ // }
171
+ // }
172
+ // }
173
+ // }
174
+
175
+ highestPlatform = new File (platforms , highestName );
149
176
150
177
androidJar = new File (highestPlatform , "android.jar" );
151
178
if (!androidJar .exists ()) {
152
179
throw new BadSDKException (AndroidMode .getTextString ("android_sdk.error.missing_android_jar" ,
153
180
AndroidBuild .TARGET_SDK , highestPlatform .getAbsolutePath ()));
154
181
}
155
182
183
+ // Collecting the tools needed by the mode
184
+ adb = findCliTool (platformTools , "adb" );
156
185
avdManager = findCliTool (new File (cmdlineTools , "bin" ), "avdmanager" );
157
186
sdkManager = findCliTool (new File (cmdlineTools , "bin" ), "sdkmanager" );
158
-
187
+
159
188
initEmu ();
160
189
161
190
String path = Platform .getenv ("PATH" );
@@ -392,18 +421,44 @@ static public File getGoogleDriverFolder() {
392
421
* for the SDK installation. Also figures out the name of android/android.bat/android.exe
393
422
* so that it can be called explicitly.
394
423
*/
395
- private static File findCliTool (final File tools , String name )
424
+ private static File findCliTool (final File toolDir , String toolName )
396
425
throws BadSDKException {
397
- if (new File (tools , name + ".bat" ).exists ()) {
398
- return new File (tools , name + ".bat" );
426
+ File toolFile = Platform .isWindows () ? new File (toolDir , toolName + ".exe" ) : new File (toolDir , toolName );
427
+ if (!toolFile .exists ()) {
428
+ throw new BadSDKException ("Cannot find " + toolName + " in " + toolDir );
399
429
}
400
- if (new File (tools , name + ".exe" ).exists ()) {
401
- return new File (tools , name + ".exe" );
402
- }
403
- if (new File (tools , name ).exists ()) {
404
- return new File (tools , name );
430
+
431
+ if (!Platform .isWindows ()) {
432
+ try {
433
+ // Get the POSIX file permissions
434
+ Path toolPath = Paths .get (toolFile .getAbsolutePath ());
435
+ Set <PosixFilePermission > permissions = Files .getPosixFilePermissions (toolPath );
436
+
437
+ // Print the file permissions
438
+ System .out .println ("File permissions for " + toolPath + ":" );
439
+ for (PosixFilePermission permission : permissions ) {
440
+ System .out .println (permission );
441
+ }
442
+
443
+ boolean addedPerm = false ;
444
+ if (!permissions .contains (PosixFilePermission .OWNER_EXECUTE )) {
445
+ permissions .add (PosixFilePermission .OWNER_EXECUTE );
446
+ addedPerm = true ;
447
+ }
448
+ if (!permissions .contains (PosixFilePermission .GROUP_EXECUTE )) {
449
+ permissions .add (PosixFilePermission .GROUP_EXECUTE );
450
+ addedPerm = true ;
451
+ }
452
+
453
+ if (addedPerm ) {
454
+ Files .setPosixFilePermissions (toolPath , permissions );
455
+ }
456
+ } catch (Exception e ) {
457
+ e .printStackTrace ();
458
+ }
405
459
}
406
- throw new BadSDKException ("Cannot find " + name + " in " + tools );
460
+
461
+ return toolFile ;
407
462
}
408
463
409
464
@@ -773,25 +828,20 @@ static public File selectFolder(String prompt, File folder, Frame frame) {
773
828
private static final String ADB_DAEMON_MSG_1 = "daemon not running" ;
774
829
private static final String ADB_DAEMON_MSG_2 = "daemon started successfully" ;
775
830
776
- public ProcessResult runADB (final String ... cmd )
831
+ public ProcessResult runAdb (final String ... cmd )
777
832
throws InterruptedException , IOException {
778
833
779
834
if (adbDisabled ) {
780
835
throw new IOException ("adb is currently disabled" );
781
836
}
782
-
783
- final String [] adbCmd ;
784
- if (!cmd [0 ].contains ("adb" )) {
785
- File abdPath = Platform .isWindows () ? new File (platformTools , "adb.exe" ) :
786
- new File (platformTools , "adb" );
787
- adbCmd = PApplet .splice (cmd , abdPath .getCanonicalPath (), 0 );
788
- } else {
789
- adbCmd = cmd ;
790
- }
791
- // printing this here to see if anyone else is killing the adb server
837
+
838
+ final String [] adbCmd = PApplet .splice (cmd , adb .getCanonicalPath (), 0 );
839
+
792
840
if (processing .app .Base .DEBUG ) {
841
+ // printing this here to see if anyone else is killing the adb server
793
842
PApplet .printArray (adbCmd );
794
843
}
844
+
795
845
try {
796
846
ProcessResult adbResult = new ProcessHelper (adbCmd ).execute ();
797
847
// Ignore messages about starting up an adb daemon
@@ -821,12 +871,41 @@ public ProcessResult runADB(final String... cmd)
821
871
}
822
872
}
823
873
824
- static class SDKTarget {
825
- public int version = 0 ;
826
- public String name ;
874
+ public Process getAdbProcess (final String ... cmd )
875
+ throws IOException {
876
+
877
+ if (adbDisabled ) {
878
+ throw new IOException ("adb is currently disabled" );
879
+ }
880
+
881
+ final String [] adbCmd = PApplet .splice (cmd , adb .getCanonicalPath (), 0 );
882
+
883
+ if (processing .app .Base .DEBUG ) {
884
+ // printing this here to see if anyone else is killing the adb server
885
+ PApplet .printArray (adbCmd );
886
+ }
887
+
888
+ try {
889
+ Process process = Runtime .getRuntime ().exec (adbCmd );
890
+ return process ;
891
+ } catch (IOException ioe ) {
892
+ if (-1 < ioe .getMessage ().indexOf ("Permission denied" )) {
893
+ Messages .showWarning (AndroidMode .getTextString ("android_sdk.warn.cannot_run_adb_title" ),
894
+ AndroidMode .getTextString ("android_sdk.warn.cannot_run_adb_body" ));
895
+ adbDisabled = true ;
896
+ }
897
+ throw ioe ;
898
+ }
899
+ }
900
+
901
+ static private class SDKTarget {
902
+ public int version_sdk = 0 ;
903
+ public String version_release = "" ;
904
+ public int version_incremental = 0 ;
905
+ public String name = "" ;
827
906
}
828
907
829
- public ArrayList <SDKTarget > getAvailableSdkTargets () throws IOException {
908
+ private ArrayList <SDKTarget > getAvailableSdkTargets () throws IOException {
830
909
ArrayList <SDKTarget > targets = new ArrayList <SDKTarget >();
831
910
832
911
for (File platform : platforms .listFiles ()) {
@@ -839,18 +918,24 @@ public ArrayList<SDKTarget> getAvailableSdkTargets() throws IOException {
839
918
String line ;
840
919
while ((line = br .readLine ()) != null ) {
841
920
String [] lineData = line .split ("=" );
842
- if (lineData [0 ].equals ("ro.build.version.sdk" )) {
843
- target .version = Integer .valueOf (lineData [1 ]);
921
+
922
+ if (lineData [0 ].equals ("ro.system.build.version.incremental" )) {
923
+ target .version_incremental = Integer .valueOf (lineData [1 ]);
844
924
}
845
925
846
926
if (lineData [0 ].equals ("ro.build.version.release" )) {
847
- target .name = lineData [1 ];
848
- break ;
927
+ target .version_release = lineData [1 ];
928
+ }
929
+
930
+ if (lineData [0 ].equals ("ro.build.version.sdk" )) {
931
+ target .version_sdk = Integer .valueOf (lineData [1 ]);
849
932
}
933
+
934
+ target .name = platform .getName ();
850
935
}
851
936
br .close ();
852
937
853
- if (target .version != 0 && target .name != null ) targets .add (target );
938
+ if (target .version_sdk != 0 && target .version_incremental != 0 && target . name != "" ) targets .add (target );
854
939
}
855
940
856
941
return targets ;
0 commit comments