44 Contributors: IIAB Project
55 Copyright (c) 2026 IIAB Project
66 Description : Java wrapper for the native libaria2c.so binary.
7- Handles native aria2c download tasks.
87 ============================================================================
98 */
109
1716
1817import java .io .BufferedReader ;
1918import java .io .File ;
19+ import java .io .FileOutputStream ;
20+ import java .io .IOException ;
21+ import java .io .InputStream ;
2022import java .io .InputStreamReader ;
2123import java .util .regex .Matcher ;
2224import java .util .regex .Pattern ;
@@ -29,9 +31,7 @@ public class Aria2Manager {
2931
3032 public interface DownloadListener {
3133 void onProgress (int percentage , String speed , String eta );
32-
3334 void onComplete (String downloadPath );
34-
3535 void onError (String error );
3636 }
3737
@@ -55,30 +55,62 @@ public void startDownload(Context context, String url, DownloadListener listener
5555
5656 // Secure DHT file within our app (avoids the com.termux crash)
5757 File dhtFile = new File (context .getFilesDir (), "dht.dat" );
58+ if (!dhtFile .exists ()) {
59+ try { dhtFile .createNewFile (); } catch (Exception e ) { Log .w (TAG , "Could not create dht.dat" ); }
60+ }
61+
62+ // --- Extract SSL Certificate from assets ---
63+ File caCertFile = new File (context .getFilesDir (), "cacert.pem" );
64+ if (!caCertFile .exists ()) {
65+ extractAsset (context , "cacert.pem" , caCertFile );
66+ }
5867
5968 Log .d (TAG , "Executing Native Aria2c..." );
6069 Log .d (TAG , "Target URL: " + url );
6170
62- // 3. Build the command with the magic of Bash translated to Java
63- ProcessBuilder pb = new ProcessBuilder (
64- aria2Bin .getAbsolutePath (),
65- "--dir=" + downloadDir .getAbsolutePath (),
66- "--continue=true" ,
67- "--allow-overwrite=true" ,
68- "--auto-file-renaming=false" ,
69- "--max-connection-per-server=4" ,
70- "--split=4" ,
71- "--follow-metalink=mem" ,
72- "--enable-dht=true" ,
73- "--dht-file-path=" + dhtFile .getAbsolutePath (),
74- "--bt-enable-lpd=true" ,
75- "--seed-time=0" ,
76- "--check-certificate=false" , // <--- Ignore missing SSL certificates in native Android
77- "--console-log-level=warn" ,
78- "--summary-interval=1" ,
79- "--download-result=hide" ,
80- url
81- );
71+ // --- RUN NETWORK PROFILER (Time-boxed speed test) ---
72+ // UI updates are now handled inside the profiler
73+ boolean forceIpv4 = Aria2NetworkProfiler .shouldForceIpv4 (aria2Bin , downloadDir , dhtFile , url , mainHandler , listener );
74+ // ----------------------------------------------------
75+
76+ // 3. Build the command dynamically
77+ java .util .List <String > command = new java .util .ArrayList <>();
78+ command .add (aria2Bin .getAbsolutePath ());
79+ command .add ("--dir=" + downloadDir .getAbsolutePath ());
80+ command .add ("--continue=true" );
81+ command .add ("--allow-overwrite=true" );
82+ command .add ("--auto-file-renaming=false" );
83+ command .add ("--max-connection-per-server=4" );
84+ command .add ("--split=4" );
85+ command .add ("--follow-metalink=mem" );
86+ command .add ("--enable-dht=true" );
87+ command .add ("--dht-file-path=" + dhtFile .getAbsolutePath ());
88+ command .add ("--bt-enable-lpd=true" );
89+ command .add ("--seed-time=0" );
90+
91+ // --- Apply SSL Certificate Validation ---
92+ if (caCertFile .exists ()) {
93+ Log .d (TAG , "SSL certificates found. Enforcing strict validation." );
94+ command .add ("--check-certificate=true" );
95+ command .add ("--ca-certificate=" + caCertFile .getAbsolutePath ());
96+ } else {
97+ Log .w (TAG , "cacert.pem not found! Falling back to insecure connection." );
98+ command .add ("--check-certificate=false" );
99+ }
100+
101+ command .add ("--console-log-level=warn" );
102+ command .add ("--summary-interval=1" );
103+ command .add ("--download-result=hide" );
104+
105+ // Apply network decision
106+ if (forceIpv4 ) {
107+ Log .w (TAG , "Network profiler decided to FORCE IPv4." );
108+ command .add ("--disable-ipv6=true" );
109+ }
110+
111+ command .add (url );
112+
113+ ProcessBuilder pb = new ProcessBuilder (command );
82114
83115 // Redirect errors to the same input stream
84116 pb .redirectErrorStream (true );
@@ -98,7 +130,7 @@ public void startDownload(Context context, String url, DownloadListener listener
98130 break ;
99131 }
100132
101- Log .d (TAG , "[Aria2] " + line ); // Ver todo en el Logcat para debuggear
133+ Log .d (TAG , "[Aria2] " + line );
102134
103135 Matcher matcher = pattern .matcher (line );
104136 if (matcher .find ()) {
@@ -137,4 +169,20 @@ public void stopDownload() {
137169 aria2Process .destroy ();
138170 }
139171 }
172+
173+ /**
174+ * Helper method to copy files from the APK assets folder to internal storage.
175+ */
176+ private void extractAsset (Context context , String assetName , File destination ) {
177+ try (InputStream is = context .getAssets ().open (assetName );
178+ FileOutputStream fos = new FileOutputStream (destination )) {
179+ byte [] buffer = new byte [8192 ];
180+ int read ;
181+ while ((read = is .read (buffer )) != -1 ) {
182+ fos .write (buffer , 0 , read );
183+ }
184+ } catch (IOException e ) {
185+ Log .e (TAG , "Failed to extract " + assetName + " from assets" , e );
186+ }
187+ }
140188}
0 commit comments