From 67794f0433482e0c7d9d4b6cd9ac24cc00466b30 Mon Sep 17 00:00:00 2001 From: andrekir Date: Fri, 11 Mar 2022 00:03:46 -0300 Subject: [PATCH 1/3] improve firmware update --- .../geeksville/mesh/service/MeshService.kt | 11 ++++---- .../mesh/service/SoftwareUpdateService.kt | 27 ++++++++++++------- .../geeksville/mesh/ui/SettingsFragment.kt | 13 +++++++++ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index fe3672049..a28c52a9b 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -1309,13 +1309,14 @@ class MeshService : Service(), Logging { if (asStr != null) hwModelStr = asStr } + setFirmwareUpdateFilename(hwModelStr) val mi = with(myInfo) { MyNodeInfo( myNodeNum, hasGps, hwModelStr, firmwareVersion, - firmwareUpdateFilename != null, + firmwareUpdateFilename?.appLoad != null && firmwareUpdateFilename?.spiffs != null, isBluetoothInterface && SoftwareUpdateService.shouldUpdate( this@MeshService, DeviceVersion(firmwareVersion) @@ -1328,9 +1329,7 @@ class MeshService : Service(), Logging { airUtilTx ) } - newMyNodeInfo = mi - setFirmwareUpdateFilename(mi) } } @@ -1670,12 +1669,12 @@ class MeshService : Service(), Logging { /*** * Return the filename we will install on the device */ - private fun setFirmwareUpdateFilename(info: MyNodeInfo) { + private fun setFirmwareUpdateFilename(model: String?) { firmwareUpdateFilename = try { - if (info.firmwareVersion != null && info.model != null) + if (model != null) SoftwareUpdateService.getUpdateFilename( this, - info.model + model ) else null diff --git a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt index 8326a5168..7fe354101 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt @@ -243,7 +243,7 @@ class SoftwareUpdateService : JobIntentService(), Logging { false // If we fail parsing our update info } - /** Return a Pair of apploadfilename, spiffs filename this device needs to use as an update (or null if no update needed) + /** Return a Pair of appload filename, spiffs filename this device needs to use as an update (or null if no update needed) */ fun getUpdateFilename( context: Context, @@ -290,9 +290,15 @@ class SoftwareUpdateService : JobIntentService(), Logging { * you can use it for the software update. */ fun doUpdate(context: Context, sync: SafeBluetooth, assets: UpdateFilenames) { + // calculate total firmware size (spiffs + appLoad) + var totalFirmwareSize = 0 + if (assets.appLoad != null && assets.spiffs != null) { + totalFirmwareSize += context.assets.open(assets.appLoad).available() + totalFirmwareSize += context.assets.open(assets.spiffs).available() + } // we must attempt spiffs first, because if we update the appload the device will reboot afterwards try { - assets.spiffs?.let { doUpdate(context, sync, it, FLASH_REGION_SPIFFS) } + assets.spiffs?.let { doUpdate(context, sync, it, FLASH_REGION_SPIFFS, totalFirmwareSize) } } catch (_: BLECharacteristicNotFoundException) { // If we can't update spiffs (because not supported by target), do not fail errormsg("Ignoring failure to update spiffs on old appload") @@ -301,7 +307,7 @@ class SoftwareUpdateService : JobIntentService(), Logging { errormsg("Device rejected invalid spiffs partition") } - assets.appLoad?.let { doUpdate(context, sync, it, FLASH_REGION_APPLOAD) } + assets.appLoad?.let { doUpdate(context, sync, it, FLASH_REGION_APPLOAD, totalFirmwareSize) } sendProgress(context, ProgressSuccess, true) } @@ -317,7 +323,8 @@ class SoftwareUpdateService : JobIntentService(), Logging { context: Context, sync: SafeBluetooth, assetName: String, - flashRegion: Int = FLASH_REGION_APPLOAD + flashRegion: Int = FLASH_REGION_APPLOAD, + totalFirmwareSize: Int = 0 ) { val isAppload = flashRegion == FLASH_REGION_APPLOAD @@ -378,13 +385,15 @@ class SoftwareUpdateService : JobIntentService(), Logging { // Send all the blocks var oldProgress = -1 // used to limit # of log spam while (firmwareNumSent < firmwareSize) { - // If we are doing the spiffs partition, we limit progress to a max of 50%, so that the user doesn't think we are done - // yet - val maxProgress = if (flashRegion != FLASH_REGION_APPLOAD) - 50 else 100 + // If we are doing the spiffs partition, we limit progress to a max of maxProgress + // when updating the appload partition, progress from (100 - maxProgress) to 100% + // maxProgress = spiffs% = 100% - appLoad%; (int * 10 + 5) / 10 used for rounding + val maxProgress = ((firmwareSize * 1000 / totalFirmwareSize) + 5) / 10 + val minProgress = if (flashRegion != FLASH_REGION_APPLOAD) + 0 else (100 - maxProgress) sendProgress( context, - firmwareNumSent * maxProgress / firmwareSize, + minProgress + firmwareNumSent * maxProgress / firmwareSize, isAppload ) if (progress != oldProgress) { diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 89717f296..83fd0561f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -24,6 +24,7 @@ import android.widget.* import androidx.fragment.app.activityViewModels import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData +import com.geeksville.analytics.DataPair import com.geeksville.android.GeeksvilleApplication import com.geeksville.android.Logging import com.geeksville.android.hideKeyboard @@ -474,6 +475,10 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { model.meshService?.let { service -> debug("User started firmware update") + GeeksvilleApplication.analytics.track( + "firmware_update", + DataPair("content_type", "start") + ) binding.updateFirmwareButton.isEnabled = false // Disable until things complete binding.updateProgressBar.visibility = View.VISIBLE binding.updateProgressBar.progress = 0 // start from scratch @@ -515,6 +520,10 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { } else when (progress) { ProgressSuccess -> { + GeeksvilleApplication.analytics.track( + "firmware_update", + DataPair("content_type", "success") + ) binding.scanStatusText.setText(R.string.update_successful) binding.updateProgressBar.visibility = View.GONE } @@ -523,6 +532,10 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { binding.updateProgressBar.visibility = View.GONE } else -> { + GeeksvilleApplication.analytics.track( + "firmware_update", + DataPair("content_type", "failure") + ) binding.scanStatusText.setText(R.string.update_failed) binding.updateProgressBar.visibility = View.VISIBLE } From 6258780106b17430b369c54457cafacd8ca3e8fa Mon Sep 17 00:00:00 2001 From: andrekir Date: Tue, 15 Mar 2022 01:33:30 -0300 Subject: [PATCH 2/3] update mapbox tokens --- .github/workflows/android.yml | 7 ++++--- .github/workflows/release.yml | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 1638c5a2f..1991620cc 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -19,11 +19,12 @@ jobs: - name: Load secrets run: | rm ./app/src/main/res/values/mapbox-token.xml - echo -e "\n $MAPBOXTOKEN\n" > ./app/src/main/res/values/mapbox-token.xml + echo -e "\n $MAPBOX_ACCESS_TOKEN\n" > ./app/src/main/res/values/mapbox-token.xml mkdir -p ~/.gradle - echo "MAPBOX_DOWNLOADS_TOKEN=$MAPBOXTOKEN" >>~/.gradle/gradle.properties + echo "MAPBOX_DOWNLOADS_TOKEN=$MAPBOX_DOWNLOADS_TOKEN" >>~/.gradle/gradle.properties env: - MAPBOXTOKEN: ${{ secrets.MAPBOXTOKEN }} + MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }} + MAPBOX_DOWNLOADS_TOKEN: ${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - name: Mock files for CI run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6019b76f1..b8734afd9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,14 +22,15 @@ jobs: rm ./app/google-services.json echo $GSERVICES > ./app/google-services.json rm ./app/src/main/res/values/mapbox-token.xml - echo -e "\n $MAPBOXTOKEN\n" > ./app/src/main/res/values/mapbox-token.xml + echo -e "\n $MAPBOX_ACCESS_TOKEN\n" > ./app/src/main/res/values/mapbox-token.xml mkdir -p ~/.gradle - echo "MAPBOX_DOWNLOADS_TOKEN=$MAPBOXTOKEN" >> ~/.gradle/gradle.properties + echo "MAPBOX_DOWNLOADS_TOKEN=$MAPBOX_DOWNLOADS_TOKEN" >> ~/.gradle/gradle.properties echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME echo "$KEYSTORE_PROPERTIES" > ./keystore.properties env: GSERVICES: ${{ secrets.GSERVICES }} - MAPBOXTOKEN: ${{ secrets.MAPBOXTOKEN }} + MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }} + MAPBOX_DOWNLOADS_TOKEN: ${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} KEYSTORE: ${{ secrets.KEYSTORE }} KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }} KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }} From bf8f4f16604c60679f9d3d4f16a01851b37edddb Mon Sep 17 00:00:00 2001 From: andrekir Date: Sat, 19 Mar 2022 17:12:24 -0300 Subject: [PATCH 3/3] 1.2.60 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e038e8315..90ca7c514 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,8 +43,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 30 // 30 can't work until an explicit location permissions dialog is added - versionCode 20259 // format is Mmmss (where M is 1+the numeric major number - versionName "1.2.59" + versionCode 20260 // format is Mmmss (where M is 1+the numeric major number + versionName "1.2.60" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // per https://developer.android.com/studio/write/vector-asset-studio