2626import java .net .MalformedURLException ;
2727import java .net .URL ;
2828import java .util .ArrayList ;
29- import java .util .Arrays ;
3029import java .util .Collections ;
3130import java .util .List ;
3231import java .util .regex .Matcher ;
3332import java .util .regex .Pattern ;
34- import java .util .stream .Collectors ;
3533
3634import static airsquared .blobsaver .app .Utils .containsIgnoreCase ;
3735import static airsquared .blobsaver .app .Utils .executeProgram ;
3836import static airsquared .blobsaver .app .Utils .extractBuildManifest ;
3937import static airsquared .blobsaver .app .Utils .getFirmwareList ;
4038import static airsquared .blobsaver .app .Utils .getSignedFirmwares ;
4139
42- public class TSS extends Task <List < String > > {
40+ public class TSS extends Task <String > {
4341
4442 // note: Matcher is NOT thread safe
4543 private static final Matcher ipswURLMatcher = Pattern .compile ("https?://.*apple.*\\ .ipsw" ).matcher ("" );
@@ -70,39 +68,44 @@ private TSS(String deviceIdentifier, String ecid, String savePath, String boardC
7068 }
7169
7270 /**
73- * @return a list of versions that blobs have been saved for
74- * (an empty list if a build manifest was manually supplied)
71+ * @return a printable multiline string describing the blobs saved
7572 * @throws TSSException if blobs were not saved successfully
7673 */
7774 @ Override
78- protected List < String > call () throws TSSException {
79- checkValues ();
75+ protected String call () throws TSSException {
76+ checkInputs ();
8077
81- ArrayList < String > ipswURLs = new ArrayList <> ();
82- ArrayList < String > versionStrings = new ArrayList <>( );
83- getIpswURLS ( ipswURLs , versionStrings );
78+ List < Utils . IOSVersion > iosVersions = getIOSVersions ();
79+ System . out . println ( "iosVersions = " + iosVersions );
80+ ArrayList < String > args = constructArgs ( );
8481
85- String [] args = constructArgs ();
82+ StringBuilder sb = new StringBuilder ("Successfully saved blobs in\n " ).append (savePath );
83+ if (manualIpswURL == null ) {
84+ sb .append (iosVersions .size () == 1 ? "\n \n For version " : "\n \n For versions " );
85+ }
8686
8787 // can't use forEach() because exception won't be caught
88- for (String ipswURL : ipswURLs ) {
88+ for (Utils . IOSVersion iosVersion : iosVersions ) {
8989 try {
90- args [ args .length - 1 ] = extractBuildManifest (ipswURL ).getAbsolutePath ();
90+ args . set ( args .size () - 1 , extractBuildManifest (iosVersion . ipswURL ).getAbsolutePath () );
9191 } catch (IOException e ) {
9292 throw new TSSException ("Unable to extract BuildManifest." , true , e );
9393 }
9494 try {
95- System .out .println ("Running: " + Arrays . toString ( args ) );
95+ System .out .println ("Running: " + args );
9696 String tssLog = executeProgram (args );
9797 parseTSSLog (tssLog );
9898 } catch (IOException e ) {
9999 throw new TSSException ("There was an error starting tsschecker." , true , e );
100100 }
101+
102+ if (iosVersion .versionString != null ) sb .append (iosVersion .versionString ).append (", " );
101103 }
102- return versionStrings ;
104+
105+ return sb .substring (0 , sb .length () - 2 );
103106 }
104107
105- private void checkValues () throws TSSException {
108+ private void checkInputs () throws TSSException {
106109 boolean hasCorrectIdentifierPrefix = deviceIdentifier .startsWith ("iPad" ) || deviceIdentifier .startsWith ("iPod" )
107110 || deviceIdentifier .startsWith ("iPhone" ) || deviceIdentifier .startsWith ("AppleTV" );
108111 if (!deviceIdentifier .contains ("," ) || !hasCorrectIdentifierPrefix ) {
@@ -126,24 +129,19 @@ private void checkValues() throws TSSException {
126129 * Adds to the arraylists, depending on the fields {@link #manualIpswURL} and {@link #manualVersion}.
127130 * <p>
128131 * If both of those fields are null, it adds all signed versions.
129- * If {@link #manualIpswURL} is specified, the parameter {@code versionStrings} will not be modified.
130132 *
131- * @param ipswURLS an empty list that will be filled with URLs to IPSW(s)
132- * @param versionStrings an empty list that will be filled with strings of iOS versions to be displayed to the user
133+ * @return a list of {@link Utils.IOSVersion} to save blobs for
133134 */
134- private void getIpswURLS ( ArrayList < String > ipswURLS , ArrayList < String > versionStrings ) throws TSSException {
135+ private List < Utils . IOSVersion > getIOSVersions ( ) throws TSSException {
135136 try {
136137 if (manualVersion != null ) {
137- ipswURLS . add (getFirmwareList (deviceIdentifier ).stream ().filter (stringObjectMap ->
138- manualVersion .equals (stringObjectMap . get ( "version" )) )
139- .collect ( Collectors . toList ()). get ( 0 ). get ( "url" ). toString ( ));
138+ return Collections . singletonList (getFirmwareList (deviceIdentifier ).stream ().filter (iosVersion ->
139+ manualVersion .equals (iosVersion . versionString )). findFirst ( )
140+ .orElseThrow (() -> new TSSException ( "No versions found." , false ) ));
140141 } else if (manualIpswURL != null ) {
141- ipswURLS . add ( manualIpswURL );
142+ return Collections . singletonList ( new Utils . IOSVersion ( null , manualIpswURL , null ) );
142143 } else { // all signed firmwares
143- getSignedFirmwares (deviceIdentifier ).forEach (firmware -> {
144- ipswURLS .add (firmware .get ("url" ).toString ());
145- versionStrings .add (firmware .get ("version" ).toString ());
146- });
144+ return getSignedFirmwares (deviceIdentifier );
147145 }
148146 } catch (FileNotFoundException e ) {
149147 throw new TSSException ("The device \" " + deviceIdentifier + "\" could not be found." , false , e );
@@ -152,23 +150,23 @@ private void getIpswURLS(ArrayList<String> ipswURLS, ArrayList<String> versionSt
152150 }
153151 }
154152
155- private String [] constructArgs () {
156- ArrayList <String > argsList = new ArrayList <>(13 );
153+ private ArrayList < String > constructArgs () {
154+ ArrayList <String > args = new ArrayList <>(15 );
157155 String tsscheckerPath = Utils .getTsschecker ().getAbsolutePath ();
158156 //noinspection ResultOfMethodCallIgnored
159157 new File (savePath ).mkdirs ();
160- Collections .addAll (argsList , tsscheckerPath , "--nocache" , "--save" , "--device" , deviceIdentifier , "--ecid" , ecid , "--save-path" , savePath );
158+ Collections .addAll (args , tsscheckerPath , "--nocache" , "--save" , "--device" , deviceIdentifier , "--ecid" , ecid , "--save-path" , savePath );
161159 if (boardConfig != null ) {
162- Collections .addAll (argsList , "--boardconfig" , boardConfig );
160+ Collections .addAll (args , "--boardconfig" , boardConfig );
163161 }
164162 if (apnonce != null ) {
165- Collections .addAll (argsList , "--apnonce" , apnonce );
163+ Collections .addAll (args , "--apnonce" , apnonce );
166164 } else {
167- Collections .addAll (argsList , "--generator" , "0x1111111111111111" );
165+ Collections .addAll (args , "--generator" , "0x1111111111111111" );
168166 }
169- Collections .addAll (argsList , "--build-manifest" , "" );
167+ Collections .addAll (args , "--build-manifest" , "" );
170168
171- return argsList . toArray ( new String [ 0 ]) ;
169+ return args ;
172170 }
173171
174172 private void parseTSSLog (String tsscheckerLog ) throws TSSException {
0 commit comments