kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
misc
rodzic
ee54f9fa36
commit
bb39bab1c1
16
TODO.md
16
TODO.md
|
@ -1,17 +1,25 @@
|
||||||
|
|
||||||
* assert() is apparently a noop - change to use my version of assert
|
|
||||||
* make frontend using https://developer.android.com/jetpack/compose/tutorial
|
* make frontend using https://developer.android.com/jetpack/compose/tutorial
|
||||||
|
*fix bluetooth
|
||||||
|
|
||||||
# Medium priority
|
# Medium priority
|
||||||
|
|
||||||
* remove secret google settings json before open sourcing
|
* remove secret google settings json before open sourcing
|
||||||
* require user auth to pair with the device (i.e. press button on device to allow a new phone to pair with it).
|
* require user auth to pair with the device (i.e. press button on device to allow a new phone to pair with it).
|
||||||
Don't leave device discoverable. Don't let unpaired users do thing with device
|
Don't leave device discoverable. Don't let unpaired users do thing with device
|
||||||
* add crash reporting
|
|
||||||
* remove example code boilerplate from the service
|
* remove example code boilerplate from the service
|
||||||
* add analytics (make them optional)
|
|
||||||
|
|
||||||
# Low priority
|
# Low priority
|
||||||
|
|
||||||
|
* make analytics optional
|
||||||
* possibly use finotes for analytics https://finotes.com/
|
* possibly use finotes for analytics https://finotes.com/
|
||||||
* also add a receiver that fires after a new update was installed from the play stoe
|
* also add a receiver that fires after a new update was installed from the play stoe
|
||||||
|
|
||||||
|
# Done
|
||||||
|
|
||||||
|
* assert() is apparently a noop - change to use my version of assert
|
||||||
|
* DONE add crash reporting
|
||||||
|
* DONE add analytics (make them optional)
|
||||||
|
|
|
@ -15,12 +15,13 @@ import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.geeksville.android.Logging
|
||||||
|
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity(), Logging {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val REQUEST_ENABLE_BT = 10
|
const val REQUEST_ENABLE_BT = 10
|
||||||
|
@ -33,6 +34,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestPermission() {
|
fun requestPermission() {
|
||||||
|
debug("Checking permissions")
|
||||||
|
|
||||||
val perms = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
|
val perms = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
|
||||||
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
|
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
|
||||||
Manifest.permission.BLUETOOTH,
|
Manifest.permission.BLUETOOTH,
|
||||||
|
@ -72,7 +75,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
/* Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
/* Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
||||||
.setAction("Action", null).show() */
|
.setAction("Action", null).show() */
|
||||||
|
|
||||||
|
// test crash reporting
|
||||||
|
// logAssert(false)
|
||||||
// throw NotImplementedError("I like crap")
|
// throw NotImplementedError("I like crap")
|
||||||
|
|
||||||
if(bluetoothAdapter != null) {
|
if(bluetoothAdapter != null) {
|
||||||
SoftwareUpdateService.enqueueWork(this, SoftwareUpdateService.scanDevicesIntent)
|
SoftwareUpdateService.enqueueWork(this, SoftwareUpdateService.scanDevicesIntent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@ import android.content.Intent
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.ParcelUuid
|
import android.os.ParcelUuid
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.util.Log
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.JobIntentService
|
import androidx.core.app.JobIntentService
|
||||||
|
import com.geeksville.android.Logging
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ import java.util.*
|
||||||
* FIXME - broadcast when we found devices, made progress sending blocks or when the update is complete
|
* FIXME - broadcast when we found devices, made progress sending blocks or when the update is complete
|
||||||
* FIXME - make the user decide to start an update on a particular device
|
* FIXME - make the user decide to start an update on a particular device
|
||||||
*/
|
*/
|
||||||
class SoftwareUpdateService : JobIntentService() {
|
class SoftwareUpdateService : JobIntentService(), Logging {
|
||||||
|
|
||||||
private val bluetoothAdapter: BluetoothAdapter by lazy(LazyThreadSafetyMode.NONE) {
|
private val bluetoothAdapter: BluetoothAdapter by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
|
@ -49,9 +49,9 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
|
|
||||||
// Start the update by writing the # of bytes in the image
|
// Start the update by writing the # of bytes in the image
|
||||||
val numBytes = firmwareStream.available()
|
val numBytes = firmwareStream.available()
|
||||||
assert(totalSizeDesc.setValue(numBytes, BluetoothGattCharacteristic.FORMAT_UINT32, 0))
|
logAssert(totalSizeDesc.setValue(numBytes, BluetoothGattCharacteristic.FORMAT_UINT32, 0))
|
||||||
assert(updateGatt.writeCharacteristic(totalSizeDesc))
|
logAssert(updateGatt.writeCharacteristic(totalSizeDesc))
|
||||||
assert(updateGatt.readCharacteristic(totalSizeDesc))
|
logAssert(updateGatt.readCharacteristic(totalSizeDesc))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the next block of our file to the device
|
// Send the next block of our file to the device
|
||||||
|
@ -64,15 +64,15 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
val buffer = ByteArray(blockSize)
|
val buffer = ByteArray(blockSize)
|
||||||
|
|
||||||
// slightly expensive to keep reallocing this buffer, but whatever
|
// slightly expensive to keep reallocing this buffer, but whatever
|
||||||
assert(firmwareStream.read(buffer) == blockSize)
|
logAssert(firmwareStream.read(buffer) == blockSize)
|
||||||
|
|
||||||
dataDesc = updateService.getCharacteristic(SW_UPDATE_DATA_CHARACTER)!!
|
dataDesc = updateService.getCharacteristic(SW_UPDATE_DATA_CHARACTER)!!
|
||||||
// updateGatt.beginReliableWrite()
|
// updateGatt.beginReliableWrite()
|
||||||
dataDesc.value = buffer
|
dataDesc.value = buffer
|
||||||
assert(updateGatt.writeCharacteristic(dataDesc))
|
logAssert(updateGatt.writeCharacteristic(dataDesc))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(false) // fixme
|
logAssert(false) // fixme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
//intentAction = ACTION_GATT_CONNECTED
|
//intentAction = ACTION_GATT_CONNECTED
|
||||||
//connectionState = STATE_CONNECTED
|
//connectionState = STATE_CONNECTED
|
||||||
// broadcastUpdate(intentAction)
|
// broadcastUpdate(intentAction)
|
||||||
assert(bluetoothGatt.discoverServices())
|
logAssert(bluetoothGatt.discoverServices())
|
||||||
}
|
}
|
||||||
BluetoothProfile.STATE_DISCONNECTED -> {
|
BluetoothProfile.STATE_DISCONNECTED -> {
|
||||||
//intentAction = ACTION_GATT_DISCONNECTED
|
//intentAction = ACTION_GATT_DISCONNECTED
|
||||||
|
@ -122,7 +122,7 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
|
|
||||||
// New services discovered
|
// New services discovered
|
||||||
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
||||||
assert(status == BluetoothGatt.GATT_SUCCESS)
|
logAssert(status == BluetoothGatt.GATT_SUCCESS)
|
||||||
|
|
||||||
// broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED)
|
// broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED)
|
||||||
|
|
||||||
|
@ -142,13 +142,13 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
characteristic: BluetoothGattCharacteristic,
|
characteristic: BluetoothGattCharacteristic,
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
assert(status == BluetoothGatt.GATT_SUCCESS)
|
logAssert(status == BluetoothGatt.GATT_SUCCESS)
|
||||||
|
|
||||||
if (characteristic == totalSizeDesc) {
|
if (characteristic == totalSizeDesc) {
|
||||||
// Our read of this has completed, either fail or continue updating
|
// Our read of this has completed, either fail or continue updating
|
||||||
val readvalue =
|
val readvalue =
|
||||||
characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)
|
characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)
|
||||||
assert(readvalue != 0) // FIXME - handle this case
|
logAssert(readvalue != 0) // FIXME - handle this case
|
||||||
enqueueWork(this@SoftwareUpdateService, sendNextBlockIntent)
|
enqueueWork(this@SoftwareUpdateService, sendNextBlockIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
characteristic: BluetoothGattCharacteristic?,
|
characteristic: BluetoothGattCharacteristic?,
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
assert(status == BluetoothGatt.GATT_SUCCESS)
|
logAssert(status == BluetoothGatt.GATT_SUCCESS)
|
||||||
|
|
||||||
if (characteristic == dataDesc) {
|
if (characteristic == dataDesc) {
|
||||||
enqueueWork(this@SoftwareUpdateService, sendNextBlockIntent)
|
enqueueWork(this@SoftwareUpdateService, sendNextBlockIntent)
|
||||||
|
@ -169,7 +169,7 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
}
|
}
|
||||||
bluetoothGatt = result.device.connectGatt(this@SoftwareUpdateService, false, gattCallback)!!
|
bluetoothGatt = result.device.connectGatt(this@SoftwareUpdateService, false, gattCallback)!!
|
||||||
toast("FISH " + bluetoothGatt)
|
toast("FISH " + bluetoothGatt)
|
||||||
assert(bluetoothGatt.discoverServices())
|
logAssert(bluetoothGatt.discoverServices())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
|
|
||||||
override fun onHandleWork(intent: Intent) { // We have received work to do. The system or framework is already
|
override fun onHandleWork(intent: Intent) { // We have received work to do. The system or framework is already
|
||||||
// holding a wake lock for us at this point, so we can just go.
|
// holding a wake lock for us at this point, so we can just go.
|
||||||
Log.i("SimpleJobIntentService", "Executing work: $intent")
|
info("Executing work: $intent")
|
||||||
var label = intent.getStringExtra("label")
|
var label = intent.getStringExtra("label")
|
||||||
if (label == null) {
|
if (label == null) {
|
||||||
label = intent.toString()
|
label = intent.toString()
|
||||||
|
@ -220,12 +220,10 @@ class SoftwareUpdateService : JobIntentService() {
|
||||||
scanDevicesIntent.action -> scanLeDevice(true)
|
scanDevicesIntent.action -> scanLeDevice(true)
|
||||||
startUpdateIntent.action -> startUpdate()
|
startUpdateIntent.action -> startUpdate()
|
||||||
sendNextBlockIntent.action -> sendNextBlock()
|
sendNextBlockIntent.action -> sendNextBlock()
|
||||||
else -> assert(false)
|
else -> logAssert(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(
|
info("Completed service @ " + SystemClock.elapsedRealtime()
|
||||||
"SimpleJobIntentService",
|
|
||||||
"Completed service @ " + SystemClock.elapsedRealtime()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue