Skip to content

Commit

Permalink
Merge pull request #8 from geeksville/master
Browse files Browse the repository at this point in the history
0.2.1 merge
  • Loading branch information
geeksville authored Mar 31, 2020
2 parents 0ebb959 + d9fe9c6 commit 63f991d
Show file tree
Hide file tree
Showing 35 changed files with 823 additions and 269 deletions.
2 changes: 2 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ for verbose logging:
adb shell setprop log.tag.FA VERBOSE
```

Copyright 2018, S. Kevin Hester-Chow, [email protected]. GPL V3 license
Copyright 2019, Geeksville Industries, LLC. GPL V3 license


59 changes: 7 additions & 52 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# High priority
Work items for soon alpha builds

* update play store listing for public beta
* let channel be editited
* make link sharing work
* finish map view
* run services in sim mode on emulator
* show offline nodes as greyed out
* show time since last contact on the node info card
Expand All @@ -28,7 +30,6 @@ the channel is encrypted, you can share the the channel key with others by qr co
* when a text arrives, move that node info card to the bottom on the window - put the text to the left of the card. with a small arrow/distance/shortname
* let the user type texts somewhere
* use this for preferences? https://developer.android.com/guide/topics/ui/settings/
* at connect we might receive messages before finished downloading the nodeinfo. In that case, process those messages later
* test with oldest compatible android in emulator (see below for testing with hardware)
* add play store link with https://developers.google.com/analytics/devguides/collection/android/v4/campaigns#google-play-url-builder and the play icon

Expand Down Expand Up @@ -71,7 +72,6 @@ rules at the BluetoothDevice level. Either make SafeBluetooth lock at the devic
* test with an oldish android release using real hardware
* stop using a foreground service
* use platform theme (dark or light)
* remove mixpanel analytics
* 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 things with device
* if the rxpacket queue on the device overflows (because android hasn't connected in a while) send a special packet to android which means 'X packets have been dropped because you were offline' -drop oldest packets first
Expand Down Expand Up @@ -161,53 +161,8 @@ Don't leave device discoverable. Don't let unpaired users do things with device
* generate real channel QR codes
* Have play store entry ask users to report if their android version is too old to allow install
* use git submodule for androidlib


Rare bug reproduced:

D/com.geeksville.mesh.service.SafeBluetooth: work readC 8ba2bcc2-ee02-4a55-a531-c525c5e454d5 is completed, resuming status=0, res=android.bluetooth.BluetoothGattCharacteristic@f6eb84e
D/com.geeksville.mesh.service.RadioInterfaceService: Received 9 bytes from radio
D/com.geeksville.mesh.service.SafeBluetooth: Enqueuing work: readC 8ba2bcc2-ee02-4a55-a531-c525c5e454d5
D/com.geeksville.mesh.service.SafeBluetooth$BluetoothContinuation: Starting work: readC 8ba2bcc2-ee02-4a55-a531-c525c5e454d5
D/com.geeksville.mesh.service.MeshService: Received broadcast com.geeksville.mesh.RECEIVE_FROMRADIO
E/com.geeksville.util.Exceptions: exceptionReporter Uncaught Exception
com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at com.google.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1566)
at com.google.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:1655)
at com.geeksville.mesh.MeshProtos$FromRadio.parseFrom(MeshProtos.java:9097)
at com.geeksville.mesh.service.MeshService$radioInterfaceReceiver$1$onReceive$1.invoke(MeshService.kt:742)
at com.geeksville.mesh.service.MeshService$radioInterfaceReceiver$1$onReceive$1.invoke(Unknown Source:0)
at com.geeksville.util.ExceptionsKt.exceptionReporter(Exceptions.kt:31)
at com.geeksville.mesh.service.MeshService$radioInterfaceReceiver$1.onReceive(MeshService.kt:722)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1550)
at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
D/com.geeksville.mesh.service.SafeBluetooth: work readC 8ba2bcc2-ee02-4a55-a531-c525c5e454d5 is completed, resuming status=0, res=android.bluetooth.BluetoothGattCharacteristic@f6eb84e
D/com.geeksville.mesh.service.RadioInterfaceService: Received 9 bytes from radio
D/com.geeksville.mesh.service.SafeBluetooth: Enqueuing work: readC 8ba2bcc2-ee02-4a55-a531-c525c5e454d5
D/com.geeksville.mesh.service.SafeBluetooth$BluetoothContinuation: Starting work: readC 8ba2bcc2-ee02-4a55-a531-c525c5e454d5
D/com.geeksville.mesh.service.MeshService: Received broadcast com.geeksville.mesh.RECEIVE_FROMRADIO


Transition powerFSM transition=Press, from=DARK to=ON
pressing
sending owner !246f28b5367c/Bob use/Bu
Update DB node 0x7c for variant 4, rx_time=0
old user !246f28b5367c/Bob use/Bu
updating changed=0 user !246f28b5367c/Bob use/Bu
immedate send on mesh (txGood=32,rxGood=0,rxBad=0)
Trigger powerFSM 1
Transition powerFSM transition=Press, from=ON to=ON
Setting fast framerate
Setting idle framerate
Transition powerFSM transition=Screen-on timeout, from=ON to=DARK

NOTE: no debug messages on device, though we see in radio interface service we are repeatedly reading FromRadio and getting
the same seven bytes. It sure seems like the old service is still sort of alive...
* update play store listing for public beta
* track radio brands/regions as a user property (include no-radio as an option)
* remove mixpanel analytics
* at connect we might receive messages before finished downloading the nodeinfo. In that case, process those messages later

9 changes: 6 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 104
versionName "0.1.4"
versionCode 121
versionName "0.2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down Expand Up @@ -45,7 +45,7 @@ android {

composeOptions {
kotlinCompilerVersion "1.3.61-dev-withExperimentalGoogleExtensions-20200129"
kotlinCompilerExtensionVersion "0.1.0-dev06"
kotlinCompilerExtensionVersion "0.1.0-dev07"
}
}

Expand Down Expand Up @@ -88,6 +88,9 @@ dependencies {
//implementation 'com.google.protobuf:protobuf-java-util:3.11.1'
implementation 'com.google.protobuf:protobuf-javalite:3.11.1'

// mapbox
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.0.0'

// You also need to include the following Compose toolkit dependencies.
implementation("androidx.compose:compose-runtime:$compose_version")
implementation("androidx.ui:ui-graphics:$compose_version")
Expand Down
22 changes: 22 additions & 0 deletions app/src/androidTest/java/com/geeksville/mesh/ChannelTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.geeksville.mesh


import androidx.compose.frames.open
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.geeksville.mesh.model.Channel
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class ChannelTest {
@Test
fun channelUrlGood() {
open() // Needed to make Compose think we are inside a Frame
val ch = Channel.emulated

Assert.assertTrue(ch.getChannelUrl().toString().startsWith(Channel.prefix))
Assert.assertEquals(Channel(ch.getChannelUrl()), ch)
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.geeksville.mesh

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand All @@ -19,6 +17,6 @@ class ExampleInstrumentedTest {
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.geeksville.com.geeksville.mesh", appContext.packageName)
assertEquals("com.geeksville.mesh", appContext.packageName)
}
}
104 changes: 104 additions & 0 deletions app/src/main/java/androidx/ui/fakeandroidview/ComposedView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.ui.fakeandroidview

import android.content.Context
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import androidx.annotation.LayoutRes
import androidx.compose.Composable

/**
* Composes an Android [View] given a layout resource [resId]. The method handles the inflation
* of the [View] and will call the [postInflationCallback] after this happens. Note that the
* callback will always be invoked on the main thread.
*
* @param resId The id of the layout resource to be inflated.
* @param postInflationCallback The callback to be invoked after the layout is inflated.
*/
@Composable
// TODO(popam): support modifiers here
fun AndroidView(@LayoutRes resId: Int, postInflationCallback: (View) -> Unit = { _ -> }) {
AndroidViewHolder(postInflationCallback = postInflationCallback, resId = resId)
}


private class AndroidViewHolder(context: Context) : ViewGroup(context) {
var view: View? = null
set(value) {
if (value != field) {
field = value
removeAllViews()
addView(view)
}
}

var postInflationCallback: (View) -> Unit = {}

var resId: Int? = null
set(value) {
if (value != field) {
field = value
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(resId!!, this, false)
this.view = view
postInflationCallback(view)
}
}

init {
isClickable = true
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
view?.measure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(view?.measuredWidth ?: 0, view?.measuredHeight ?: 0)
}

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
view?.layout(l, t, r, b)
}

override fun getLayoutParams(): LayoutParams? {
return view?.layoutParams ?: LayoutParams(MATCH_PARENT, MATCH_PARENT)
}

/**
* Implement this method to handle touch screen motion events.
*
*
* If this method is used to detect click actions, it is recommended that
* the actions be performed by implementing and calling
* [.performClick]. This will ensure consistent system behavior,
* including:
*
* * obeying click sound preferences
* * dispatching OnClickListener calls
* * handling [ACTION_CLICK][AccessibilityNodeInfo.ACTION_CLICK] when
* accessibility features are enabled
*
*
* @param event The motion event.
* @return True if the event was handled, false otherwise.
*/
override fun onTouchEvent(event: MotionEvent?): Boolean {
return super.onTouchEvent(event)
}
}
13 changes: 9 additions & 4 deletions app/src/main/java/com/geeksville/mesh/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class MainActivity : AppCompatActivity(), Logging,
val prefs = UIState.getPreferences(this)
UIState.ownerName = prefs.getString("owner", "")!!
UIState.meshService = null
UIState.savedInstanceState = savedInstanceState

// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
Expand All @@ -200,9 +201,6 @@ class MainActivity : AppCompatActivity(), Logging,

requestPermission()

setContent {
MeshApp()
}

/* not yet working
// Configure sign-in to request the user's ID, email address, and basic
Expand All @@ -221,6 +219,10 @@ class MainActivity : AppCompatActivity(), Logging,

// Handle any intent
handleIntent(intent)

setContent {
MeshApp()
}
}

override fun onNewIntent(intent: Intent) {
Expand All @@ -233,9 +235,12 @@ class MainActivity : AppCompatActivity(), Logging,
val appLinkAction = intent.action
val appLinkData: Uri? = intent.data

UIState.requestedChannelUrl = null // assume none

// Were we asked to open one our channel URLs?
if (Intent.ACTION_VIEW == appLinkAction && appLinkData != null) {
if (Intent.ACTION_VIEW == appLinkAction) {
debug("Asked to open a channel URL - FIXME, ask user if they want to switch to that channel. If so send the config to the radio")
UIState.requestedChannelUrl = appLinkData
}
}

Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/com/geeksville/mesh/MeshUtilApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import com.geeksville.android.GeeksvilleApplication
import com.geeksville.android.Logging
import com.geeksville.util.Exceptions
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.mapbox.mapboxsdk.Mapbox


class MeshUtilApplication : GeeksvilleApplication(null, "58e72ccc361883ea502510baa46580e3") {
class MeshUtilApplication : GeeksvilleApplication() {

override fun onCreate() {
super.onCreate()
Expand All @@ -26,5 +27,8 @@ class MeshUtilApplication : GeeksvilleApplication(null, "58e72ccc361883ea502510b
crashlytics.recordException(exception)
}
}

// Mapbox Access token
Mapbox.getInstance(this, getString(R.string.mapbox_access_token))
}
}
Loading

0 comments on commit 63f991d

Please sign in to comment.