2828package se .bitcraze .crazyfliecontrol .bootloader ;
2929
3030import java .io .File ;
31+ import java .io .FileOutputStream ;
3132import java .io .IOException ;
33+ import java .io .InputStream ;
34+ import java .io .OutputStream ;
35+ import java .net .URL ;
36+ import java .security .KeyManagementException ;
37+ import java .security .NoSuchAlgorithmException ;
3238import java .util .ArrayList ;
3339import java .util .Collections ;
3440import java .util .List ;
3844import se .bitcraze .crazyflie .lib .bootloader .Bootloader .BootloaderListener ;
3945import se .bitcraze .crazyflie .lib .bootloader .FirmwareRelease ;
4046import se .bitcraze .crazyflie .lib .crazyradio .RadioDriver ;
41- import se .bitcraze .crazyfliecontrol .bootloader .FirmwareDownloader .FirmwareDownloadListener ;
4247import se .bitcraze .crazyfliecontrol2 .MainActivity ;
4348import se .bitcraze .crazyfliecontrol2 .R ;
4449import se .bitcraze .crazyfliecontrol2 .UsbLinkAndroid ;
4550import android .app .Activity ;
4651import android .app .AlertDialog ;
47- import android .app .DownloadManager ;
4852import android .app .ProgressDialog ;
4953import android .content .Context ;
5054import android .content .DialogInterface ;
51- import android .content .IntentFilter ;
5255import android .content .pm .ActivityInfo ;
5356import android .graphics .Color ;
5457import android .os .AsyncTask ;
5558import android .os .AsyncTask .Status ;
56- import android .os .Build ;
5759import android .os .Bundle ;
5860import android .os .Handler ;
61+ import android .os .PowerManager ;
5962import android .text .Spannable ;
6063import android .text .style .ForegroundColorSpan ;
6164import android .util .Log ;
7174import android .widget .TextView ;
7275import android .widget .Toast ;
7376
77+ import javax .net .ssl .HttpsURLConnection ;
78+
7479public class BootloaderActivity extends Activity {
7580
7681 private static final String LOG_TAG = "BootloaderActivity" ;
@@ -106,15 +111,11 @@ protected void onCreate(Bundle savedInstanceState) {
106111 initializeFirmwareSpinner ();
107112
108113 mFirmwareDownloader = new FirmwareDownloader (this );
109-
110- this .registerReceiver (mFirmwareDownloader .onComplete , new IntentFilter (DownloadManager .ACTION_DOWNLOAD_COMPLETE ));
111114 }
112115
113-
114116 @ Override
115117 protected void onDestroy () {
116118 super .onDestroy ();
117- this .unregisterReceiver (mFirmwareDownloader .onComplete );
118119 getWindow ().clearFlags (WindowManager .LayoutParams .FLAG_KEEP_SCREEN_ON );
119120 }
120121
@@ -235,20 +236,6 @@ public void run() {
235236 });
236237 }
237238
238- private FirmwareDownloadListener mDownloadListener = new FirmwareDownloadListener () {
239- public void downloadFinished () {
240- //flash firmware once firmware is downloaded
241- appendConsole ("Firmware downloaded." );
242- startBootloader ();
243- }
244-
245- public void downloadProblem (String msg ) {
246- //flash firmware once firmware is downloaded
247- appendConsole ("Firmware download failed: " + msg );
248- stopFlashProcess (false );
249- }
250- };
251-
252239 public void startFlashProcess (final View view ) {
253240 // disable button and spinner
254241 mFlashFirmwareButton .setEnabled (false );
@@ -261,8 +248,139 @@ public void startFlashProcess(final View view) {
261248 // download firmware file
262249 appendConsole ("Downloading firmware..." );
263250
264- mFirmwareDownloader .addDownloadListener (mDownloadListener );
265- mFirmwareDownloader .downloadFirmware (this .mSelectedFirmwareRelease );
251+ DownloadTask mDownloadTask = new DownloadTask ();
252+ mDownloadTask .execute (this .mSelectedFirmwareRelease );
253+ }
254+
255+ private class DownloadTask extends AsyncTask <FirmwareRelease , Integer , String > {
256+
257+ private PowerManager .WakeLock mWakeLock ;
258+ private boolean mAlreadyDownloaded = false ;
259+
260+ private String downloadFile (String urlString , String fileName , String tagName ) {
261+ InputStream input = null ;
262+ OutputStream output = null ;
263+ HttpsURLConnection connection = null ;
264+
265+ // Retrofitting support for TLSv1.2, because GitHub only supports TLSv1.2
266+ try {
267+ HttpsURLConnection .setDefaultSSLSocketFactory (new TLSSocketFactory ());
268+ } catch (KeyManagementException | NoSuchAlgorithmException e ) {
269+ e .printStackTrace ();
270+ }
271+
272+ try {
273+ URL url = new URL (urlString );
274+ connection = (HttpsURLConnection ) url .openConnection ();
275+ connection .connect ();
276+
277+ // expect HTTP 200 OK, so we don't mistakenly save error report instead of the file
278+ if (connection .getResponseCode () != HttpsURLConnection .HTTP_OK ) {
279+ return "Server returned HTTP " + connection .getResponseCode () + " " + connection .getResponseMessage ();
280+ }
281+
282+ // this will be useful to display download percentage. it might be -1: server did not report the length
283+ int fileLength = connection .getContentLength ();
284+
285+ // download the file
286+ File outputFile = new File (BootloaderActivity .this .getExternalFilesDir (null ) + "/" + BootloaderActivity .BOOTLOADER_DIR + "/" + tagName + "/" , fileName );
287+ outputFile .getParentFile ().mkdirs ();
288+ input = connection .getInputStream ();
289+ output = new FileOutputStream (outputFile );
290+
291+ byte data [] = new byte [4096 ];
292+ long total = 0 ;
293+ int count ;
294+ while ((count = input .read (data )) != -1 ) {
295+ // allow canceling
296+ if (isCancelled ()) {
297+ input .close ();
298+ return null ;
299+ }
300+ total += count ;
301+ // publishing the progress....
302+ if (fileLength > 0 ) { // only if total length is known
303+ publishProgress ((int ) (total * 100 / fileLength ));
304+ }
305+ output .write (data , 0 , count );
306+ }
307+ } catch (Exception e ) {
308+ return e .toString ();
309+ } finally {
310+ try {
311+ if (output != null ) {
312+ output .close ();
313+ }
314+ if (input != null ) {
315+ input .close ();
316+ }
317+ } catch (IOException ignored ) {
318+
319+ }
320+ if (connection != null ) {
321+ connection .disconnect ();
322+ }
323+ }
324+ return null ;
325+ }
326+
327+ @ Override
328+ protected String doInBackground (FirmwareRelease ... sFirmwareRelease ) {
329+ mSelectedFirmwareRelease = sFirmwareRelease [0 ];
330+
331+ if (mSelectedFirmwareRelease != null ) {
332+ if (mFirmwareDownloader .isFileAlreadyDownloaded (mSelectedFirmwareRelease .getTagName () + "/" + mSelectedFirmwareRelease .getAssetName ())) {
333+ mAlreadyDownloaded = true ;
334+ return null ;
335+ }
336+ String browserDownloadUrl = mSelectedFirmwareRelease .getBrowserDownloadUrl ();
337+ if (mFirmwareDownloader .isNetworkAvailable ()) {
338+ return downloadFile (browserDownloadUrl , mSelectedFirmwareRelease .getAssetName (), mSelectedFirmwareRelease .getTagName ());
339+ } else {
340+ Log .d (LOG_TAG , "Network connection not available." );
341+ return "No network connection available.\n Please check your connectivity." ;
342+ }
343+ } else {
344+ return "Selected firmware does not have assets." ;
345+ }
346+ }
347+
348+ @ Override
349+ protected void onPreExecute () {
350+ super .onPreExecute ();
351+ // take CPU lock to prevent CPU from going off if the user presses the power button during download
352+ PowerManager pm = (PowerManager ) BootloaderActivity .this .getSystemService (Context .POWER_SERVICE );
353+ mWakeLock = pm .newWakeLock (PowerManager .PARTIAL_WAKE_LOCK , getClass ().getName ());
354+ mWakeLock .acquire ();
355+ mProgressBar .setProgress (0 );
356+ }
357+
358+ @ Override
359+ protected void onProgressUpdate (Integer ... progress ) {
360+ super .onProgressUpdate (progress );
361+ // if we get here, length is known, now set indeterminate to false
362+ mProgressBar .setIndeterminate (false );
363+ mProgressBar .setMax (100 );
364+ mProgressBar .setProgress (progress [0 ]);
365+ }
366+
367+ @ Override
368+ protected void onPostExecute (String result ) {
369+ mWakeLock .release ();
370+ if (result != null ) {
371+ //flash firmware once firmware is downloaded
372+ appendConsole ("Firmware download failed: " + result );
373+ stopFlashProcess (false );
374+ } else {
375+ //flash firmware once firmware is downloaded
376+ if (mAlreadyDownloaded ) {
377+ appendConsole ("Firmware file already downloaded." );
378+ } else {
379+ appendConsole ("Firmware downloaded." );
380+ }
381+ startBootloader ();
382+ }
383+ }
266384 }
267385
268386 private void startBootloader () {
@@ -436,7 +554,6 @@ private void stopFlashProcess(boolean reset) {
436554 if (mBootloader != null ) {
437555 mBootloader .close ();
438556 }
439- mFirmwareDownloader .removeDownloadListener (mDownloadListener );
440557 //re-enable widgets
441558 mFlashFirmwareButton .setEnabled (true );
442559 mReleaseNotesButton .setEnabled (true );
@@ -446,11 +563,4 @@ private void stopFlashProcess(boolean reset) {
446563 getWindow ().clearFlags (WindowManager .LayoutParams .FLAG_KEEP_SCREEN_ON );
447564 }
448565
449- /**
450- * @param context used to check the device version and DownloadManager information
451- * @return true if the download manager is available
452- */
453- public static boolean isDownloadManagerAvailable (Context context ) {
454- return Build .VERSION .SDK_INT >= Build .VERSION_CODES .GINGERBREAD ;
455- }
456566}
0 commit comments