From 76d023d764d04d98d732e1bbd2cb2ac5045dea08 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 3 Mar 2020 20:07:19 -0800 Subject: [PATCH 01/25] onCommit() is more selective than onActive(), so it turns off our btscan sideeffect faster --- .idea/vcs.xml | 1 + .../com/geeksville/mesh/ui/BTScanScreen.kt | 23 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index ed2599e8..404ddafe 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -3,5 +3,6 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt index 22baa576..dacda93d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt @@ -4,10 +4,12 @@ import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothManager import android.bluetooth.le.* import android.os.ParcelUuid -import androidx.compose.* +import androidx.compose.Composable +import androidx.compose.Context +import androidx.compose.Model import androidx.compose.frames.modelMapOf +import androidx.compose.onCommit import androidx.ui.core.ContextAmbient -import androidx.ui.core.LayoutModifier import androidx.ui.core.Text import androidx.ui.layout.Column import androidx.ui.layout.LayoutGravity @@ -63,7 +65,8 @@ fun BTScanScreen() { val bluetoothAdapter = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter - onActive { + onCommit(AppStatus.currentScreen) { + ScanState.debug("BTScan component active") ScanUIState.selectedMacAddr = RadioInterfaceService.getBondedDeviceAddress(context) val scanCallback = object : ScanCallback() { @@ -113,10 +116,10 @@ fun BTScanScreen() { /// The following call might return null if the user doesn't have bluetooth access permissions val s: BluetoothLeScanner? = bluetoothAdapter.bluetoothLeScanner - if(s == null) { - ScanUIState.errorText = "This application requires bluetooth access. Please grant access in android settings." - } - else { + if (s == null) { + ScanUIState.errorText = + "This application requires bluetooth access. Please grant access in android settings." + } else { ScanState.debug("starting scan") // filter and only accept devices that have a sw update service @@ -134,6 +137,7 @@ fun BTScanScreen() { } onDispose { + ScanState.debug("BTScan component deactivated") ScanState.stopScan() } } @@ -143,7 +147,10 @@ fun BTScanScreen() { Text("An unexpected error was encountered. Please file a bug on our github: ${ScanUIState.errorText}") } else { if (ScanUIState.devices.isEmpty()) { - Text(text = "Looking for Meshtastic devices... (zero found)", modifier = LayoutGravity.Center) + Text( + text = "Looking for Meshtastic devices... (zero found)", + modifier = LayoutGravity.Center + ) CircularProgressIndicator() // Show that we are searching still } else { From b1238156cf1b2f2a91618f0f0ef79df817da30ec Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 3 Mar 2020 20:07:40 -0800 Subject: [PATCH 02/25] more analytics to track clicks in the app --- app/src/main/java/com/geeksville/mesh/ui/Channel.kt | 6 +++++- app/src/main/java/com/geeksville/mesh/ui/Messages.kt | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt index 81eac742..88a32584 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt @@ -17,6 +17,7 @@ import androidx.ui.material.OutlinedButton import androidx.ui.material.ripple.Ripple import androidx.ui.tooling.preview.Preview import androidx.ui.unit.dp +import com.geeksville.analytics.DataPair import com.geeksville.android.GeeksvilleApplication import com.geeksville.android.Logging import com.geeksville.mesh.R @@ -94,7 +95,10 @@ fun ChannelContent(channel: Channel = Channel("Default", 7)) { Ripple(bounded = false) { OutlinedButton(modifier = LayoutGravity.Center + LayoutPadding(left = 24.dp), onClick = { - GeeksvilleApplication.analytics.track("channel_share") // track how many times users share channels + GeeksvilleApplication.analytics.track( + "share", + DataPair("content_type", "channel") + ) // track how many times users share channels val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND diff --git a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt index 37504595..cb07b731 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt @@ -17,6 +17,7 @@ import androidx.ui.material.ProvideEmphasis import androidx.ui.text.TextStyle import androidx.ui.tooling.preview.Preview import androidx.ui.unit.dp +import com.geeksville.android.GeeksvilleApplication import com.geeksville.mesh.model.MessagesState import com.geeksville.mesh.model.MessagesState.messages import com.geeksville.mesh.model.NodeDB @@ -105,6 +106,7 @@ fun MessagesContent() { val str = message.value MessagesState.sendMessage(str) message.value = "" // blow away the string the user just entered + GeeksvilleApplication.analytics.track("send_text") // track how many times users share channels }, hintText = "Type your message here..." ) From 29d87bffb3f7cbe77906d291e7780a70be2bce96 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 11:16:43 -0800 Subject: [PATCH 03/25] analytics tweaks --- .../main/java/com/geeksville/mesh/service/MeshService.kt | 4 ++++ app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt | 6 ------ app/src/main/java/com/geeksville/mesh/ui/Messages.kt | 2 -- 3 files changed, 4 insertions(+), 8 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 74efe56c..72e021a1 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -524,6 +524,8 @@ class MeshService : Service(), Logging { else -> TODO() } + + GeeksvilleApplication.analytics.track("data_receive") } /// Update our DB of users based on someone sending out a User subpacket @@ -820,6 +822,8 @@ class MeshService : Service(), Logging { sendToRadio(ToRadio.newBuilder().apply { this.packet = packet }) + + GeeksvilleApplication.analytics.track("data_send") } override fun getRadioConfig(): ByteArray = toRemoteExceptions { diff --git a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt index 1d033f00..fdd0f905 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt @@ -139,11 +139,6 @@ private fun AppContent(openDrawer: () -> Unit) { } ) - // VerticalScroller breaks flexible layouts - because verticalscrollers have 'infinite' height - // VerticalScroller(modifier = LayoutFlexible(1f)) { - //if (screen != Screen.settings) - // ScanState.stopScan() // Nasty hack to teardown the bt scanner - when (screen) { Screen.messages -> MessagesContent() Screen.settings -> SettingsContent() @@ -151,7 +146,6 @@ private fun AppContent(openDrawer: () -> Unit) { Screen.channel -> ChannelContent() else -> TODO() } - //} } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt index cb07b731..37504595 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt @@ -17,7 +17,6 @@ import androidx.ui.material.ProvideEmphasis import androidx.ui.text.TextStyle import androidx.ui.tooling.preview.Preview import androidx.ui.unit.dp -import com.geeksville.android.GeeksvilleApplication import com.geeksville.mesh.model.MessagesState import com.geeksville.mesh.model.MessagesState.messages import com.geeksville.mesh.model.NodeDB @@ -106,7 +105,6 @@ fun MessagesContent() { val str = message.value MessagesState.sendMessage(str) message.value = "" // blow away the string the user just entered - GeeksvilleApplication.analytics.track("send_text") // track how many times users share channels }, hintText = "Type your message here..." ) From fd17dcefe10d7999309fb4ee72bc6b9764188027 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 11:44:17 -0800 Subject: [PATCH 04/25] update to Compose dev06 --- app/build.gradle | 2 +- app/src/main/java/com/geeksville/mesh/ui/AppDrawer.kt | 5 ++--- .../main/java/com/geeksville/mesh/ui/BTScanScreen.kt | 2 +- app/src/main/java/com/geeksville/mesh/ui/Channel.kt | 10 +++++----- app/src/main/java/com/geeksville/mesh/ui/Messages.kt | 8 ++++---- .../main/java/com/geeksville/mesh/ui/NodeInfoCard.kt | 2 +- app/src/main/java/com/geeksville/mesh/ui/Settings.kt | 1 - build.gradle | 2 +- 8 files changed, 15 insertions(+), 17 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 56012448..b71b8647 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,7 +45,7 @@ android { composeOptions { kotlinCompilerVersion "1.3.61-dev-withExperimentalGoogleExtensions-20200129" - kotlinCompilerExtensionVersion "0.1.0-dev05" + kotlinCompilerExtensionVersion "0.1.0-dev06" } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/AppDrawer.kt b/app/src/main/java/com/geeksville/mesh/ui/AppDrawer.kt index 032ada63..ae9f471a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/AppDrawer.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/AppDrawer.kt @@ -7,7 +7,6 @@ import androidx.ui.core.Text import androidx.ui.foundation.shape.corner.RoundedCornerShape import androidx.ui.graphics.Color import androidx.ui.layout.* -import androidx.ui.material.Button import androidx.ui.material.Divider import androidx.ui.material.MaterialTheme import androidx.ui.material.TextButton @@ -75,9 +74,9 @@ private fun DrawerButton( Surface( modifier = modifier + LayoutPadding( - left = 8.dp, + start = 8.dp, top = 8.dp, - right = 8.dp, + end = 8.dp, bottom = 0.dp ), color = backgroundColor, diff --git a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt index dacda93d..4f1f3714 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt @@ -3,9 +3,9 @@ package com.geeksville.mesh.ui import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothManager import android.bluetooth.le.* +import android.content.Context import android.os.ParcelUuid import androidx.compose.Composable -import androidx.compose.Context import androidx.compose.Model import androidx.compose.frames.modelMapOf import androidx.compose.onCommit diff --git a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt index 88a32584..6219c047 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt @@ -5,7 +5,7 @@ import android.graphics.Bitmap import androidx.compose.Composable import androidx.ui.core.ContextAmbient import androidx.ui.core.Text -import androidx.ui.foundation.DrawImage +import androidx.ui.foundation.SimpleImage import androidx.ui.graphics.Image import androidx.ui.graphics.ImageConfig import androidx.ui.graphics.NativeImage @@ -88,12 +88,12 @@ fun ChannelContent(channel: Channel = Channel("Default", 7)) { // val image = imageResource(id = R.drawable.qrcode) val image = AndroidImage(UIState.getChannelQR(context)) - Container(modifier = LayoutGravity.Center + LayoutSize.Min(200.dp, 200.dp)) { - DrawImage(image = image) - } + //Container(modifier = LayoutGravity.Center + LayoutSize.Min(200.dp, 200.dp)) { + SimpleImage(image = image) + //} Ripple(bounded = false) { - OutlinedButton(modifier = LayoutGravity.Center + LayoutPadding(left = 24.dp), + OutlinedButton(modifier = LayoutGravity.Center + LayoutPadding(start = 24.dp), onClick = { GeeksvilleApplication.analytics.track( "share", diff --git a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt index 37504595..f45a4137 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt @@ -39,7 +39,7 @@ fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) { Row(modifier = modifier) { UserIcon(NodeDB.nodes[msg.from]) - Column(modifier = LayoutPadding(left = 12.dp)) { + Column(modifier = LayoutPadding(start = 12.dp)) { Row { val nodes = NodeDB.nodes @@ -51,7 +51,7 @@ fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) { ProvideEmphasis(emphasis = TimestampEmphasis) { Text( text = dateFormat.format(msg.date), - modifier = LayoutPadding(left = 8.dp), + modifier = LayoutPadding(start = 8.dp), style = MaterialTheme.typography().caption ) } @@ -79,8 +79,8 @@ fun MessagesContent() { messages.forEach { msg -> MessageCard( msg, modifier = LayoutPadding( - left = sidePad, - right = sidePad, + start = sidePad, + end = sidePad, top = topPad, bottom = topPad ) diff --git a/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt b/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt index 6edba21d..cc17f427 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/NodeInfoCard.kt @@ -69,7 +69,7 @@ fun NodeInfoCard(node: NodeInfo) { // Text("Node: ${it.user?.longName}") Row(modifier = LayoutPadding(16.dp)) { UserIcon( - modifier = LayoutPadding(left = 0.dp, top = 0.dp, right = 0.dp, bottom = 0.dp), + modifier = LayoutPadding(start = 0.dp, top = 0.dp, end = 0.dp, bottom = 0.dp), user = node ) diff --git a/app/src/main/java/com/geeksville/mesh/ui/Settings.kt b/app/src/main/java/com/geeksville/mesh/ui/Settings.kt index 2e065951..dbdb88de 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Settings.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Settings.kt @@ -1,7 +1,6 @@ package com.geeksville.mesh.ui import androidx.compose.Composable -import androidx.compose.ambient import androidx.compose.state import androidx.ui.core.ContextAmbient import androidx.ui.core.Text diff --git a/build.gradle b/build.gradle index 13557f96..021d6811 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext.kotlin_version = '1.3.61' - ext.compose_version = '0.1.0-dev05' + ext.compose_version = '0.1.0-dev06' repositories { google() jcenter() From 80597bf48a1d1b860057f04e15194846397730c4 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 12:12:56 -0800 Subject: [PATCH 05/25] don't use Crossfade because it kinda breaks onCommit --- .../java/com/geeksville/mesh/ui/MeshApp.kt | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt index fdd0f905..3ab6a3ea 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt @@ -2,7 +2,6 @@ package com.geeksville.mesh.ui import androidx.compose.Composable import androidx.compose.state -import androidx.ui.animation.Crossfade import androidx.ui.core.ContextAmbient import androidx.ui.core.Text import androidx.ui.layout.Column @@ -124,29 +123,30 @@ fun previewView() { @Composable private fun AppContent(openDrawer: () -> Unit) { - Crossfade(AppStatus.currentScreen) { screen -> - Surface(color = (MaterialTheme.colors()).background) { + // crossfade breaks onCommit behavior because it keeps old views around + //Crossfade(AppStatus.currentScreen) { screen -> + Surface(color = (MaterialTheme.colors()).background) { - Column { - TopAppBar( - title = { Text(text = "Meshtastic") }, - navigationIcon = { - Container(LayoutSize(40.dp, 40.dp)) { - VectorImageButton(R.drawable.ic_launcher_new_foreground) { - openDrawer() - } + Column { + TopAppBar( + title = { Text(text = "Meshtastic") }, + navigationIcon = { + Container(LayoutSize(40.dp, 40.dp)) { + VectorImageButton(R.drawable.ic_launcher_new_foreground) { + openDrawer() } } - ) - - when (screen) { - Screen.messages -> MessagesContent() - Screen.settings -> SettingsContent() - Screen.users -> HomeContent() - Screen.channel -> ChannelContent() - else -> TODO() } + ) + + when (AppStatus.currentScreen) { + Screen.messages -> MessagesContent() + Screen.settings -> SettingsContent() + Screen.users -> HomeContent() + Screen.channel -> ChannelContent() + else -> TODO() } } } + //} } From bedcdb9cd107ce520437275de9c20b25b051be20 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 12:13:21 -0800 Subject: [PATCH 06/25] remove old compose goo no longer needed with newer versions --- .../java/com/geeksville/mesh/ui/Analytics.kt | 19 ++++++++++++ .../com/geeksville/mesh/ui/BTScanScreen.kt | 1 + .../java/com/geeksville/mesh/ui/Channel.kt | 2 ++ .../java/com/geeksville/mesh/ui/MeshApp.kt | 2 ++ .../java/com/geeksville/mesh/ui/Messages.kt | 2 ++ .../java/com/geeksville/mesh/ui/Vectors.kt | 30 +++++++++---------- geeksville-androidlib | 2 +- 7 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/com/geeksville/mesh/ui/Analytics.kt diff --git a/app/src/main/java/com/geeksville/mesh/ui/Analytics.kt b/app/src/main/java/com/geeksville/mesh/ui/Analytics.kt new file mode 100644 index 00000000..57fedcb3 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/Analytics.kt @@ -0,0 +1,19 @@ +package com.geeksville.mesh.ui + +import androidx.compose.Composable +import androidx.compose.onCommit +import com.geeksville.android.GeeksvilleApplication + +/** + * Track compose screen visibility + */ +@Composable +fun analyticsScreen(name: String) { + onCommit(AppStatus.currentScreen) { + GeeksvilleApplication.analytics.sendScreenView(name) + + onDispose { + GeeksvilleApplication.analytics.endScreenView() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt index 4f1f3714..b4b67d22 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt @@ -65,6 +65,7 @@ fun BTScanScreen() { val bluetoothAdapter = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter + analyticsScreen(name = "settings") onCommit(AppStatus.currentScreen) { ScanState.debug("BTScan component active") ScanUIState.selectedMacAddr = RadioInterfaceService.getBondedDeviceAddress(context) diff --git a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt index 6219c047..ab4979ec 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt @@ -73,6 +73,8 @@ class AndroidImage(val bitmap: Bitmap) : Image { @Composable fun ChannelContent(channel: Channel = Channel("Default", 7)) { + analyticsScreen(name = "channel") + val typography = MaterialTheme.typography() val context = ContextAmbient.current diff --git a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt index 3ab6a3ea..71690ddc 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt @@ -33,6 +33,8 @@ fun getInitials(name: String): String { @Composable fun HomeContent() { + analyticsScreen(name = "settings") + Column { Row { VectorImage( diff --git a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt index f45a4137..1e4b5685 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt @@ -67,6 +67,8 @@ fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) { @Composable fun MessagesContent() { + analyticsScreen(name = "messages") + Column(modifier = LayoutSize.Fill) { val sidePad = 8.dp diff --git a/app/src/main/java/com/geeksville/mesh/ui/Vectors.kt b/app/src/main/java/com/geeksville/mesh/ui/Vectors.kt index 0ad6c10c..22fb0f5d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Vectors.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Vectors.kt @@ -2,25 +2,23 @@ package com.geeksville.mesh.ui import androidx.annotation.DrawableRes import androidx.compose.Composable -import androidx.ui.core.DensityAmbient import androidx.ui.core.Modifier -import androidx.ui.foundation.Clickable +import androidx.ui.foundation.Icon import androidx.ui.graphics.Color import androidx.ui.graphics.vector.DrawVector import androidx.ui.layout.Container import androidx.ui.layout.LayoutSize -import androidx.ui.material.ripple.Ripple +import androidx.ui.material.IconButton import androidx.ui.res.vectorResource -import androidx.ui.unit.dp @Composable fun VectorImageButton(@DrawableRes id: Int, onClick: () -> Unit) { - Ripple(bounded = false) { - Clickable(onClick = onClick) { - VectorImage(id = id /* , modifier = LayoutSize(40.dp, 40.dp) */) - } + //Ripple(bounded = false) { + IconButton(onClick = onClick) { + Icon(vectorResource(id) /* , modifier = LayoutSize(40.dp, 40.dp) */) } + //} } /* fun AppBarIcon(icon: Image, onClick: () -> Unit) { @@ -40,13 +38,13 @@ fun VectorImage( ) { val vector = vectorResource(id) // WithDensity { - Container( - modifier = modifier + LayoutSize( - vector.defaultWidth, - vector.defaultHeight - ) - ) { - DrawVector(vector, tint) - } + Container( + modifier = modifier + LayoutSize( + vector.defaultWidth, + vector.defaultHeight + ) + ) { + DrawVector(vector, tint) + } // } } diff --git a/geeksville-androidlib b/geeksville-androidlib index b9616763..7ac97ad1 160000 --- a/geeksville-androidlib +++ b/geeksville-androidlib @@ -1 +1 @@ -Subproject commit b9616763f34cf5c09d8e0abe49fb79a5844ce27c +Subproject commit 7ac97ad19f4e32007707c390ff4a858ae05afcd1 From 094f8b6a438a9b6a60105d39a38804a4743816cb Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 13:40:09 -0800 Subject: [PATCH 07/25] fix channel image scaling with new compose --- .../java/com/geeksville/mesh/ui/Channel.kt | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt index ab4979ec..3f289c7a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Channel.kt @@ -3,20 +3,21 @@ package com.geeksville.mesh.ui import android.content.Intent import android.graphics.Bitmap import androidx.compose.Composable -import androidx.ui.core.ContextAmbient -import androidx.ui.core.Text -import androidx.ui.foundation.SimpleImage -import androidx.ui.graphics.Image -import androidx.ui.graphics.ImageConfig -import androidx.ui.graphics.NativeImage +import androidx.ui.core.* +import androidx.ui.foundation.Box +import androidx.ui.graphics.* import androidx.ui.graphics.colorspace.ColorSpace import androidx.ui.graphics.colorspace.ColorSpaces +import androidx.ui.graphics.painter.ImagePainter import androidx.ui.layout.* import androidx.ui.material.MaterialTheme import androidx.ui.material.OutlinedButton import androidx.ui.material.ripple.Ripple import androidx.ui.tooling.preview.Preview +import androidx.ui.unit.Density +import androidx.ui.unit.PxSize import androidx.ui.unit.dp +import androidx.ui.unit.toRect import com.geeksville.analytics.DataPair import com.geeksville.android.GeeksvilleApplication import com.geeksville.android.Logging @@ -71,6 +72,35 @@ class AndroidImage(val bitmap: Bitmap) : Image { } } + +/// Stolen from the Compose SimpleImage, replace with their real Image component someday +// TODO(mount, malkov) : remove when RepaintBoundary is a modifier: b/149982905 +// This is class and not val because if b/149985596 +private object ClipModifier : DrawModifier { + override fun draw(density: Density, drawContent: () -> Unit, canvas: Canvas, size: PxSize) { + canvas.save() + canvas.clipRect(size.toRect()) + drawContent() + canvas.restore() + } +} + +/// Stolen from the Compose SimpleImage, replace with their real Image component someday +@Composable +fun ScaledImage( + image: Image, + modifier: Modifier = Modifier.None, + tint: Color? = null +) { + with(DensityAmbient.current) { + val imageModifier = ImagePainter(image).toModifier( + scaleFit = ScaleFit.FillMaxDimension, + colorFilter = tint?.let { ColorFilter(it, BlendMode.srcIn) } + ) + Box(modifier + ClipModifier + imageModifier) + } +} + @Composable fun ChannelContent(channel: Channel = Channel("Default", 7)) { analyticsScreen(name = "channel") @@ -90,9 +120,10 @@ fun ChannelContent(channel: Channel = Channel("Default", 7)) { // val image = imageResource(id = R.drawable.qrcode) val image = AndroidImage(UIState.getChannelQR(context)) - //Container(modifier = LayoutGravity.Center + LayoutSize.Min(200.dp, 200.dp)) { - SimpleImage(image = image) - //} + ScaledImage( + image = image, + modifier = LayoutGravity.Center + LayoutSize.Min(200.dp, 200.dp) + ) Ripple(bounded = false) { OutlinedButton(modifier = LayoutGravity.Center + LayoutPadding(start = 24.dp), From a506904ed9eabe42c27bfe652a7891491e8f9846 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 13:59:22 -0800 Subject: [PATCH 08/25] set isConnected earlier, so quick calls from clients still work --- .../com/geeksville/mesh/service/RadioInterfaceService.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt index 1281b2d0..6b0e485a 100644 --- a/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt @@ -221,7 +221,7 @@ class RadioInterfaceService : Service(), Logging { // Handle an incoming packet from the radio, broadcasts it as an android intent private fun handleFromRadio(p: ByteArray) { - if(logReceives) { + if (logReceives) { receivedPacketsLog.write(p) receivedPacketsLog.flush() } @@ -279,6 +279,9 @@ class RadioInterfaceService : Service(), Logging { fromNum = service.getCharacteristic(BTM_FROMNUM_CHARACTER) + // We must set this to true before broadcasting connectionChanged + isConnected = true + safe!!.setNotify(fromNum, true) { debug("fromNum changed, so we are reading new messages") doReadFromRadio() @@ -286,7 +289,6 @@ class RadioInterfaceService : Service(), Logging { // Now tell clients they can (finally use the api) broadcastConnectionChanged(true) - isConnected = true // Immediately broadcast any queued packets sitting on the device doReadFromRadio() @@ -349,7 +351,7 @@ class RadioInterfaceService : Service(), Logging { info("Closing radio interface service") if (logSends) sentPacketsLog.close() - if(logReceives) + if (logReceives) receivedPacketsLog.close() safe?.close() safe = null From dd6b78892770e0220a367745736bf364888ef21f Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 13:59:53 -0800 Subject: [PATCH 09/25] release 0.1.0 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b71b8647..d9519901 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 22 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 9 - versionName "0.0.9" + versionCode 100 + versionName "0.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { From e57ff6e88183407fa8469b8d979464f9d2a44f1b Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 19:26:04 -0800 Subject: [PATCH 10/25] Add CI --- .github/workflows/android.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/android.yml diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 00000000..2dc92001 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,23 @@ +name: Android CI +# from https://medium.com/@wkrzywiec/github-actions-for-android-first-approach-f616c24aa0f9 + +on: + push: + branches: + - '*' + # - '!master' + # - '!release*' + +jobs: + test: + name: Run Unit Tests + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v1 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Unit tests + run: bash ./gradlew test --stacktrace From 656a301c74cb66fa72501f562597772d4aeaf8aa Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 19:30:25 -0800 Subject: [PATCH 11/25] fix CI? --- .github/workflows/android.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 2dc92001..a9823e8e 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -1,22 +1,16 @@ name: Android CI # from https://medium.com/@wkrzywiec/github-actions-for-android-first-approach-f616c24aa0f9 -on: - push: - branches: - - '*' - # - '!master' - # - '!release*' +on: push jobs: test: - name: Run Unit Tests + name: Test runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@master - name: set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@master with: java-version: 1.8 - name: Unit tests From 93d48fcddfde491deba83821f0f674ec00b3f3e7 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 4 Mar 2020 21:06:30 -0800 Subject: [PATCH 12/25] todo updates --- TODO.md | 1 + geeksville-androidlib | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index f0d8c3d5..d9a38eb1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,7 @@ # High priority Work items for soon alpha builds +* update play store listing for public beta * run services in sim mode on emulator * show offline nodes as greyed out * show time since last contact on the node info card diff --git a/geeksville-androidlib b/geeksville-androidlib index 7ac97ad1..bcd63acb 160000 --- a/geeksville-androidlib +++ b/geeksville-androidlib @@ -1 +1 @@ -Subproject commit 7ac97ad19f4e32007707c390ff4a858ae05afcd1 +Subproject commit bcd63acb84078a18788d94f9351e46d8e63ceb47 From 2e7aff84ea8942a163b50c98699226959dc640d3 Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 5 Mar 2020 09:50:33 -0800 Subject: [PATCH 13/25] hide an autobug in compose --- .../main/java/com/geeksville/mesh/MainActivity.kt | 14 ++++++++++++++ geeksville-androidlib | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index afbe6189..c880099b 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -13,6 +13,7 @@ import android.os.Build import android.os.Bundle import android.view.Menu import android.view.MenuItem +import android.view.MotionEvent import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat @@ -29,6 +30,7 @@ import com.geeksville.mesh.ui.AppStatus import com.geeksville.mesh.ui.MeshApp import com.geeksville.mesh.ui.ScanState import com.geeksville.mesh.ui.Screen +import com.geeksville.util.Exceptions import com.geeksville.util.exceptionReporter import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInAccount @@ -328,6 +330,18 @@ class MainActivity : AppCompatActivity(), Logging, } } + override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { + return try { + super.dispatchTouchEvent(ev) + } catch (ex: IllegalStateException) { + Exceptions.report( + ex, + "dispatchTouchEvent" + ) // hide this Compose error from the user but report to the mothership + false + } + } + private val meshServiceReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) = exceptionReporter { diff --git a/geeksville-androidlib b/geeksville-androidlib index bcd63acb..45c5deee 160000 --- a/geeksville-androidlib +++ b/geeksville-androidlib @@ -1 +1 @@ -Subproject commit bcd63acb84078a18788d94f9351e46d8e63ceb47 +Subproject commit 45c5deeee23b1e104265a553eeb497caa120bd47 From 39a9bf20353d2f911f655cde1a94175c39b35f78 Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 5 Mar 2020 12:41:23 -0800 Subject: [PATCH 14/25] release 0.1.1 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d9519901..8341424a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 22 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 100 - versionName "0.1.0" + versionCode 101 + versionName "0.1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { From 5d86eec710e85fe60e3285dd97707e03ff285857 Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 5 Mar 2020 13:36:57 -0800 Subject: [PATCH 15/25] typo in screen name --- app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt index 71690ddc..a9c2e2ba 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt @@ -33,7 +33,7 @@ fun getInitials(name: String): String { @Composable fun HomeContent() { - analyticsScreen(name = "settings") + analyticsScreen(name = "users") Column { Row { From 94dbb237e8710bcc67f053a35077e223e020388e Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 5 Mar 2020 13:37:06 -0800 Subject: [PATCH 16/25] update build tool --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 021d6811..c4072156 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ buildscript { // Check that you have the Google Services Gradle plugin v4.3.2 or later // (if not, add it). classpath 'com.google.gms:google-services:4.3.3' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta01' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta02' // protobuf plugin - docs here https://github.com/google/protobuf-gradle-plugin classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.11' From f7f201adbcc673bcd18662e416a980d639d8aab3 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 6 Mar 2020 20:47:45 -0800 Subject: [PATCH 17/25] don't leak a reference to the service --- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index c880099b..4b416391 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -241,6 +241,8 @@ class MainActivity : AppCompatActivity(), Logging, override fun onDestroy() { unregisterMeshReceiver() + UIState.meshService = + null // When our activity goes away make sure we don't keep a ptr around to the service super.onDestroy() } From bb3acc1d0bf6fa85eeccbf5bc207fda1db3f1867 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 6 Mar 2020 20:49:39 -0800 Subject: [PATCH 18/25] update to latest protos --- app/src/main/proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/proto b/app/src/main/proto index c4ee1448..f309ee8f 160000 --- a/app/src/main/proto +++ b/app/src/main/proto @@ -1 +1 @@ -Subproject commit c4ee1448ea99058fe45c6738e547197e4a4c1887 +Subproject commit f309ee8f9e9db37daabd7c76da683e052ef62f7a From 9f7ab46bbe99becfba07ab8bc9796c6cea24085e Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 6 Mar 2020 20:55:47 -0800 Subject: [PATCH 19/25] fix crashlytics report: if user turns off bluetooth, disabling scan might fail --- app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt index b4b67d22..a39423cf 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/BTScanScreen.kt @@ -45,7 +45,11 @@ object ScanState : Logging { fun stopScan() { if (callback != null) { debug("stopping scan") - scanner!!.stopScan(callback) + try { + scanner!!.stopScan(callback) + } catch (ex: IllegalStateException) { + warn("Ignoring error stopping scan, user probably disabled bluetooth: $ex") + } callback = null } } From b09b6ebc89cb39c8dd31ee0611541c362d423633 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 6 Mar 2020 20:55:55 -0800 Subject: [PATCH 20/25] release 0.1.2 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8341424a..3ca6dbe4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 22 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 101 - versionName "0.1.1" + versionCode 102 + versionName "0.1.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { From 692f5994a03de1e453e1751f908231ca8881598d Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 7 Mar 2020 17:19:36 -0800 Subject: [PATCH 21/25] add instructions on how to capture logcat logs --- debugging-android.md | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 debugging-android.md diff --git a/debugging-android.md b/debugging-android.md new file mode 100644 index 00000000..bcb789b6 --- /dev/null +++ b/debugging-android.md @@ -0,0 +1,61 @@ +# Found a problem with our android app? + +Oops sorry about that ;-). Android sends us automated crash reports for some types of failures but not all failures. + +It would be super useful if you could help us by capturing a "logcat" file of the app while it was doing the bad thing and you attach that file to a github [issue](https://github.com/meshtastic/Meshtastic-Android/issues). + +Here's how to do that... + +Setup your phone & PC to allow debugging: + +* Install "adb" (android debug bridge). [Here's](https://lifehacker.com/the-easiest-way-to-install-androids-adb-and-fastboot-to-1586992378) +a tutorial I found on the web. Please let me know if it works for you. +* [Enable](https://www.howtogeek.com/129728/how-to-access-the-developer-options-menu-and-enable-usb-debugging-on-android-4.2/) +developer mode on your phone. The procedure might be slightly different for some phones, if necessary google for "enable developer mode YOURPHONENAME" +* Connect your phone to your PC USB port. A dialog on the phone will say "do you want to allow this PC to access debug mode on your phone?" +Say yes and also click the checkbox to always allow your PC access. +* type "adb devices" at your computer shell prompt, you should see your phone listed. If you see that ADB is working fine. + +* Long press on the meshtastic app and choose "force stop", to ensure that we are starting from scratch for this log (it will make it easier to understand it) +* If you have a Mac or Linux type: +``` +adb shell 'logcat --pid=$(pidof -s com.geeksville.mesh)' | tee newlogfile.txt +``` + +* If you have a PC type: +``` +adb shell "logcat --pid=$(pidof -s com.geeksville.mesh)" >newlogfile.txt (I don't know the equivalent of TEE for windows?) +``` + +This will capture a bunch of logging information as you use the app. Please go through the app to the part that was giving you troubles (No device listed on the settings screen etc). And then press +ctrl-c in the adb window to stop logging. Please open a github [issue](https://github.com/meshtastic/Meshtastic-Android/issues) describing the problem and attach the log file. We'll get back to you with what we find (possibly with some extra questions). + +``` +kevinh@kevin-server:~/development$ adb shell 'logcat --pid=$(pidof -s com.geeksville.mesh)' | +--------- beginning of main +03-07 17:10:05.669 13452 13452 W ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@fbf5fa0 +03-07 17:10:05.927 13452 13452 D com.geeksville.mesh.MainActivity: Checking permissions +03-07 17:10:06.033 13452 13452 W geeksville.mes: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed) +03-07 17:10:06.034 13452 13452 W geeksville.mes: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed) +03-07 17:10:06.179 13452 13452 D com.geeksville.mesh.MainActivity: Binding to mesh service! +03-07 17:10:06.267 13452 13484 I geeksville.mes: Background concurrent copying GC freed 18374(1149KB) AllocSpace objects, 5(164KB) LOS objects, 49% free, 2384KB/4769KB, paused 329us total 124.902ms +03-07 17:10:06.267 13452 13484 W geeksville.mes: Reducing the number of considered missed Gc histogram windows from 1692 to 100 +03-07 17:10:06.288 13452 24599 I FA : Tag Manager is not found and thus will not be used +03-07 17:10:06.500 13452 24593 I Adreno : QUALCOMM build : 4a00b69, I4e7e888065 +03-07 17:10:06.500 13452 24593 I Adreno : Build Date : 04/09/19 +03-07 17:10:06.500 13452 24593 I Adreno : OpenGL ES Shader Compiler Version: EV031.26.06.00 +03-07 17:10:06.500 13452 24593 I Adreno : Local Branch : mybranche95a5ea3-cf05-f19a-a0e7-5cb90179c3d8 +03-07 17:10:06.500 13452 24593 I Adreno : Remote Branch : quic/gfx-adreno.lnx.1.0 +03-07 17:10:06.500 13452 24593 I Adreno : Remote Branch : NONE +03-07 17:10:06.500 13452 24593 I Adreno : Reconstruct Branch : NOTHING +03-07 17:10:06.500 13452 24593 I Adreno : Build Config : S P 8.0.6 AArch64 +03-07 17:10:06.508 13452 24593 I Adreno : PFP: 0x016ee183, ME: 0x00000000 +03-07 17:10:06.546 13452 24593 W Gralloc3: mapper 3.x is not supported +03-07 17:10:06.548 13452 24593 E libc : Access denied finding property "vendor.gralloc.disable_ahardware_buffer" +03-07 17:10:06.544 13452 13452 W RenderThread: type=1400 audit(0.0:7134): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=24620 scontext=u:r:untrusted_app:s0:c157,c257,c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0 +03-07 17:10:06.607 13452 13452 I com.geeksville.mesh.service.MeshService: in isConnected=false +03-07 17:10:06.608 13452 13452 D com.geeksville.mesh.MainActivity: connchange false +03-07 17:10:06.608 13452 13452 D com.geeksville.mesh.MainActivity$mesh$1: connected to mesh service, isConnected=false +03-07 17:10:06.609 13452 13452 D com.geeksville.mesh.ui.AnalyticsLog: logging screen view messages + +``` \ No newline at end of file From db3c9266e874f038c1d07596be12d1eb8ac46c05 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 8 Mar 2020 14:47:00 -0700 Subject: [PATCH 22/25] 0.1.3 fix autobug related to meshService unexpectedly being !null --- app/build.gradle | 4 ++-- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 3 ++- geeksville-androidlib | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3ca6dbe4..11f6cc6a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 22 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 102 - versionName "0.1.2" + versionCode 103 + versionName "0.1.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 4b416391..d4850409 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -411,7 +411,8 @@ class MainActivity : AppCompatActivity(), Logging, private fun bindMeshService() { debug("Binding to mesh service!") // we bind using the well known name, to make sure 3rd party apps could also - logAssert(UIState.meshService == null) + if (UIState.meshService != null) + Exceptions.reportError("meshService was supposed to be null, ignoring (but reporting a bug)") MeshService.startService(this)?.let { intent -> // ALSO bind so we can use the api diff --git a/geeksville-androidlib b/geeksville-androidlib index 45c5deee..ee0863c3 160000 --- a/geeksville-androidlib +++ b/geeksville-androidlib @@ -1 +1 @@ -Subproject commit 45c5deeee23b1e104265a553eeb497caa120bd47 +Subproject commit ee0863c3c94856f9859d17219761903f4dea00fd From fb2304ba82520c8da46b34f3ff388e26691729b8 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 8 Mar 2020 15:22:31 -0700 Subject: [PATCH 23/25] track the # of nodes associated with each anonymous user, to know which users are actually using the hardware vs tire kickers with the app. --- .../com/geeksville/mesh/service/MeshService.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 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 72e021a1..591d410e 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -525,7 +525,11 @@ class MeshService : Service(), Logging { else -> TODO() } - GeeksvilleApplication.analytics.track("data_receive") + GeeksvilleApplication.analytics.track( + "data_receive", + DataPair("num_bytes", bytes.size), + DataPair("type", data.typValue) + ) } /// Update our DB of users based on someone sending out a User subpacket @@ -675,6 +679,11 @@ class MeshService : Service(), Logging { DataPair("num_nodes", numNodes), DataPair("num_online", numOnlineNodes) ) + + // Once someone connects to hardware start tracking the approximate number of nodes in their mesh + // this allows us to collect stats on what typical mesh size is and to tell difference between users who just + // downloaded the app, vs has connected it to some hardware. + GeeksvilleApplication.analytics.setUserInfo(DataPair("num_nodes", numNodes)) } catch (ex: RemoteException) { // It seems that when the ESP32 goes offline it can briefly come back for a 100ms ish which // causes the phone to try and reconnect. If we fail downloading our initial radio state we don't want to @@ -823,7 +832,11 @@ class MeshService : Service(), Logging { this.packet = packet }) - GeeksvilleApplication.analytics.track("data_send") + GeeksvilleApplication.analytics.track( + "data_send", + DataPair("num_bytes", payloadIn.size), + DataPair("type", typ) + ) } override fun getRadioConfig(): ByteArray = toRemoteExceptions { From 309cc464e953c852fe481862ef6946b4480d6e47 Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 9 Mar 2020 12:51:54 -0700 Subject: [PATCH 24/25] track hw model so we know how many heltec vs ttgo etc --- .../java/com/geeksville/mesh/service/MeshService.kt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 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 591d410e..3930e3d5 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -386,7 +386,7 @@ class MeshService : Service(), Logging { val NODENUM_BROADCAST = 255 // MyNodeInfo sent via special protobuf from radio - data class MyNodeInfo(val myNodeNum: Int, val hasGPS: Boolean) + data class MyNodeInfo(val myNodeNum: Int, val hasGPS: Boolean, val hwModel: String) var myNodeInfo: MyNodeInfo? = null @@ -604,7 +604,7 @@ class MeshService : Service(), Logging { connectedRadio.readMyNode() ) - val mynodeinfo = MyNodeInfo(myInfo.myNodeNum, myInfo.hasGps) + val mynodeinfo = MyNodeInfo(myInfo.myNodeNum, myInfo.hasGps, myInfo.hwModel) myNodeInfo = mynodeinfo // Ask for the current node DB @@ -674,16 +674,21 @@ class MeshService : Service(), Logging { try { reinitFromRadio() + val radioModel = DataPair("radio_model", myNodeInfo?.hwModel ?: "unknown") GeeksvilleApplication.analytics.track( "mesh_connect", DataPair("num_nodes", numNodes), - DataPair("num_online", numOnlineNodes) + DataPair("num_online", numOnlineNodes), + radioModel ) // Once someone connects to hardware start tracking the approximate number of nodes in their mesh // this allows us to collect stats on what typical mesh size is and to tell difference between users who just // downloaded the app, vs has connected it to some hardware. - GeeksvilleApplication.analytics.setUserInfo(DataPair("num_nodes", numNodes)) + GeeksvilleApplication.analytics.setUserInfo( + DataPair("num_nodes", numNodes), + radioModel + ) } catch (ex: RemoteException) { // It seems that when the ESP32 goes offline it can briefly come back for a 100ms ish which // causes the phone to try and reconnect. If we fail downloading our initial radio state we don't want to From 389dbf4476452ca8047c6b0fa98fced0448c4e8a Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 9 Mar 2020 18:54:33 -0700 Subject: [PATCH 25/25] 0.1.4 catch and report a rare? Compose exception kotlin.NullPointerException androidx.ui.core.selection.SelectionManager$handleDragObserver$1.onStart (SelectionManager.kt:184) --- app/build.gradle | 4 ++-- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 11f6cc6a..1ea64284 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 22 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 103 - versionName "0.1.3" + versionCode 104 + versionName "0.1.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index d4850409..dd816aca 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -335,7 +335,7 @@ class MainActivity : AppCompatActivity(), Logging, override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { return try { super.dispatchTouchEvent(ev) - } catch (ex: IllegalStateException) { + } catch (ex: Throwable) { Exceptions.report( ex, "dispatchTouchEvent"