diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 551d479b0..0f4a1a9c8 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,12 +1,10 @@
-
+
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 54874b2cf..dba811c87 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -16,6 +16,7 @@
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 404ddafec..e8f81507d 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -4,5 +4,6 @@
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 21fee36ad..742228ae3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,8 @@ android {
applicationId "com.geeksville.mesh"
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
targetSdkVersion 29
- versionCode 20105 // format is Mmmss (where M is 1+the numeric major number
- versionName "1.1.5"
+ versionCode 20106 // format is Mmmss (where M is 1+the numeric major number
+ versionName "1.1.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -114,11 +114,11 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'androidx.core:core-ktx:1.3.1'
+ implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
@@ -166,7 +166,7 @@ dependencies {
implementation 'com.google.android.gms:play-services-auth:18.1.0'
// Add the Firebase SDK for Crashlytics.
- implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
+ implementation 'com.google.firebase:firebase-crashlytics:17.2.2'
// alas implementation bug deep in the bowels when I tried it for my SyncBluetoothDevice class
// implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
diff --git a/app/src/debug/assets/firmware b/app/src/debug/assets/firmware
deleted file mode 120000
index e4a11c5bf..000000000
--- a/app/src/debug/assets/firmware
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../meshtastic-esp32/release/latest/bins
\ No newline at end of file
diff --git a/app/src/main/assets/firmware b/app/src/main/assets/firmware
new file mode 120000
index 000000000..e52f5091a
--- /dev/null
+++ b/app/src/main/assets/firmware
@@ -0,0 +1 @@
+../../../../../meshtastic-esp32/release/latest/forandroid
\ No newline at end of file
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 72969025c..62c105a4a 100644
--- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
+++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
@@ -1,7 +1,7 @@
package com.geeksville.mesh.service
import android.annotation.SuppressLint
-import android.app.*
+import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -20,14 +20,16 @@ import com.geeksville.concurrent.handledLaunch
import com.geeksville.mesh.*
import com.geeksville.mesh.MeshProtos.MeshPacket
import com.geeksville.mesh.MeshProtos.ToRadio
-import com.geeksville.mesh.R
import com.geeksville.mesh.database.MeshtasticDatabase
import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.database.entity.Packet
import com.geeksville.util.*
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.ResolvableApiException
-import com.google.android.gms.location.*
+import com.google.android.gms.location.FusedLocationProviderClient
+import com.google.android.gms.location.LocationRequest
+import com.google.android.gms.location.LocationServices
+import com.google.android.gms.location.LocationSettingsRequest
import com.google.protobuf.ByteString
import com.google.protobuf.InvalidProtocolBufferException
import kotlinx.coroutines.*
@@ -234,7 +236,11 @@ class MeshService : Service(), Logging {
})
}
- private fun updateNotification() = serviceNotifications.updateNotification(recentReceivedTextPacket, notificationSummary, getSenderName())
+ private fun updateNotification() = serviceNotifications.updateNotification(
+ recentReceivedTextPacket,
+ notificationSummary,
+ getSenderName()
+ )
/**
* tell android not to kill us
@@ -247,7 +253,11 @@ class MeshService : Service(), Logging {
// We always start foreground because that's how our service is always started (if we didn't then android would kill us)
// but if we don't really need foreground we immediately stop it.
- val notification = serviceNotifications.createNotification(recentReceivedTextPacket, notificationSummary, getSenderName())
+ val notification = serviceNotifications.createNotification(
+ recentReceivedTextPacket,
+ notificationSummary,
+ getSenderName()
+ )
startForeground(serviceNotifications.notifyId, notification)
if (!wantForeground) {
stopForeground(true)
@@ -1272,8 +1282,6 @@ class MeshService : Service(), Logging {
if (info.region != null && info.firmwareVersion != null && info.hwModel != null)
SoftwareUpdateService.getUpdateFilename(
this,
- info.region,
- info.firmwareVersion,
info.hwModel
)
else
@@ -1286,6 +1294,9 @@ class MeshService : Service(), Logging {
debug("setFirmwareUpdateFilename $firmwareUpdateFilename")
}
+ /// We only allow one update to be running at a time
+ private var updateJob: Job? = null
+
private fun doFirmwareUpdate() {
// Run in the IO thread
val filename = firmwareUpdateFilename ?: throw Exception("No update filename")
@@ -1293,9 +1304,13 @@ class MeshService : Service(), Logging {
BluetoothInterface.safe
?: throw Exception("Can't update - no bluetooth connected")
- serviceScope.handledLaunch {
- SoftwareUpdateService.doUpdate(this@MeshService, safe, filename)
- }
+ if (updateJob?.isActive == true)
+ throw Exception("Firmware update already running")
+ else
+ updateJob = serviceScope.handledLaunch {
+ info("Starting firmware update coroutine")
+ SoftwareUpdateService.doUpdate(this@MeshService, safe, filename)
+ }
}
/**
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 1efbec740..1c955064f 100644
--- a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt
+++ b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt
@@ -214,21 +214,11 @@ class SoftwareUpdateService : JobIntentService(), Logging {
*/
fun getUpdateFilename(
context: Context,
- hwVerIn: String,
- swVer: String,
mfg: String
): String? {
val curver = context.getString(R.string.cur_firmware_version)
- val regionRegex = Regex(".+-(.+)")
-
- val hwVer = if (hwVerIn.isEmpty() || hwVerIn == "unset")
- "1.0-US" else hwVerIn // lie and claim US, because that's what the device load will be doing without hwVer set
-
- val (region) = regionRegex.find(hwVer)?.destructured
- ?: throw Exception("Malformed hw version")
-
- val base = "firmware-$mfg-$region-$curver.bin"
+ val base = "firmware-$mfg-$curver.bin"
// Check to see if the file exists (some builds might not include update files for size reasons)
val firmwareFiles = context.assets.list("firmware") ?: arrayOf()
@@ -239,24 +229,19 @@ class SoftwareUpdateService : JobIntentService(), Logging {
}
/** Return the filename this device needs to use as an update (or null if no update needed)
+ * No longer used, because we get update info inband from our radio API
*/
fun getUpdateFilename(context: Context, sync: SafeBluetooth): String? {
val service = sync.gatt!!.services.find { it.uuid == SW_UPDATE_UUID }!!
- val hwVerDesc = service.getCharacteristic(HW_VERSION_CHARACTER)
+ //val hwVerDesc = service.getCharacteristic(HW_VERSION_CHARACTER)
val mfgDesc = service.getCharacteristic(MANUFACTURE_CHARACTER)
- val swVerDesc = service.getCharacteristic(SW_VERSION_CHARACTER)
-
- // looks like 1.0-US
- var hwVer = sync.readCharacteristic(hwVerDesc).getStringValue(0)
+ //val swVerDesc = service.getCharacteristic(SW_VERSION_CHARACTER)
// looks like HELTEC
val mfg = sync.readCharacteristic(mfgDesc).getStringValue(0)
- // looks like 0.0.12
- val swVer = sync.readCharacteristic(swVerDesc).getStringValue(0)
-
- return getUpdateFilename(context, hwVer, swVer, mfg)
+ return getUpdateFilename(context, mfg)
}
/**
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 611053f98..a18c4d085 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt
@@ -483,17 +483,19 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
updateProgressBar.progress = 0 // start from scratch
scanStatusText.text = "Updating firmware, wait up to eight minutes..."
- service.startFirmwareUpdate()
- while (service.updateStatus >= 0) {
- updateProgressBar.progress = service.updateStatus
- delay(2000) // Only check occasionally
+ try {
+ service.startFirmwareUpdate()
+ while (service.updateStatus >= 0) {
+ updateProgressBar.progress = service.updateStatus
+ delay(2000) // Only check occasionally
+ }
+ } finally {
+ val isSuccess = (service.updateStatus == -1)
+ scanStatusText.text =
+ if (isSuccess) "Update successful" else "Update failed"
+ updateProgressBar.isEnabled = false
+ updateFirmwareButton.isEnabled = !isSuccess
}
-
- val isSuccess = (service.updateStatus == -1)
- scanStatusText.text =
- if (isSuccess) "Update successful" else "Update failed"
- updateProgressBar.isEnabled = false
- updateFirmwareButton.isEnabled = !isSuccess
}
}
}
@@ -512,6 +514,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
val info = model.myNodeInfo.value
if (connected == MeshService.ConnectionState.CONNECTED && info != null && info.shouldUpdate && info.couldUpdate) {
updateFirmwareButton.visibility = View.VISIBLE
+ updateFirmwareButton.isEnabled = true
updateFirmwareButton.text =
getString(R.string.update_to).format(getString(R.string.cur_firmware_version))
} else {
diff --git a/app/src/main/proto b/app/src/main/proto
index 5cdd7bff5..a0b8d8889 160000
--- a/app/src/main/proto
+++ b/app/src/main/proto
@@ -1 +1 @@
-Subproject commit 5cdd7bff56b0ea54351e5ea0e358e864b061078f
+Subproject commit a0b8d888961720d70ab7467c94d8fa0687e58020
diff --git a/app/src/release/assets/firmware b/app/src/release/assets/firmware
deleted file mode 120000
index e4a11c5bf..000000000
--- a/app/src/release/assets/firmware
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../meshtastic-esp32/release/latest/bins
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 20fef1900..473a5bc44 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,7 +10,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.1'
+ classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 81725c2c8..fe37d07f9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat May 30 13:30:38 PDT 2020
+#Wed Oct 21 17:39:27 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip