Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add sideload build flavor #1544

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,20 @@ jobs:
- name: Run local tests
run: ./gradlew testFdroidDebug testGoogleDebug

- name: Upload debug artifact
- name: Upload fdroid debug artifact
uses: actions/upload-artifact@v4
with:
name: fdroidDebug
path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
retention-days: 30

- name: Upload sideload debug artifact
uses: actions/upload-artifact@v4
with:
name: sideloadDebug
path: app/build/outputs/apk/sideload/debug/app-sideload-debug.apk
retention-days: 30

- name: Upload build reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
Expand Down
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ android {
}
flavorDimensions = ['default']
productFlavors {
sideload {
dimension = 'default'
applicationIdSuffix ".sideload"
versionNameSuffix "-sideload"
}
fdroid {
dimension = 'default'
dependenciesInfo {
Expand Down
33 changes: 33 additions & 0 deletions app/src/sideload/java/com/geeksville/mesh/MeshUtilApplication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.geeksville.mesh

import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class MeshUtilApplication : GeeksvilleApplication() {

override fun onCreate() {
super.onCreate()

Logging.showLogs = BuildConfig.DEBUG

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.geeksville.mesh.analytics

import android.content.Context
import com.geeksville.mesh.android.Logging

class DataPair(val name: String, valueIn: Any?) {
val value = valueIn ?: "null"

/// An accumulating firebase event - only one allowed per event
constructor(d: Double) : this("BOGUS", d)
constructor(d: Int) : this("BOGUS", d)
}

/**
* Implement our analytics API using Firebase Analytics
*/
@Suppress("UNUSED_PARAMETER")
class NopAnalytics(context: Context) : AnalyticsProvider, Logging {

init {
}

override fun setEnabled(on: Boolean) {
}

override fun endSession() {
}

override fun trackLowValue(event: String, vararg properties: DataPair) {
}

override fun track(event: String, vararg properties: DataPair) {
}

override fun startSession() {
}

override fun setUserInfo(vararg p: DataPair) {
}

override fun increment(name: String, amount: Double) {
}

/**
* Send a google analytics screen view event
*/
override fun sendScreenView(name: String) {
}

override fun endScreenView() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.geeksville.mesh.android

import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import com.geeksville.mesh.analytics.AnalyticsProvider

open class GeeksvilleApplication : Application(), Logging {

companion object {
lateinit var analytics: AnalyticsProvider
}

/// Are we running inside the testlab?
val isInTestLab: Boolean
get() {
val testLabSetting =
Settings.System.getString(contentResolver, "firebase.test.lab") ?: null
if(testLabSetting != null)
info("Testlab is $testLabSetting")
return "true" == testLabSetting
}

private val analyticsPrefs: SharedPreferences by lazy {
getSharedPreferences("analytics-prefs", Context.MODE_PRIVATE)
}

var isAnalyticsAllowed: Boolean
get() = analyticsPrefs.getBoolean("allowed", true)
set(value) {
analyticsPrefs.edit {
putBoolean("allowed", value)
}

// Change the flag with the providers
analytics.setEnabled(value && !isInTestLab) // Never do analytics in the test lab
}

@Suppress("UNUSED_PARAMETER")
fun askToRate(activity: AppCompatActivity) {
// do nothing
}

override fun onCreate() {
super.onCreate()

val nopAnalytics = com.geeksville.mesh.analytics.NopAnalytics(this)
analytics = nopAnalytics
isAnalyticsAllowed = false
}
}

fun Context.isGooglePlayAvailable(): Boolean = false
13 changes: 13 additions & 0 deletions app/src/sideload/res/drawable/ic_launcher2_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="3.7795277"
android:scaleY="3.7795277">
<path
android:pathData="M0.1623,0.1772l28.2505,0l0,28.2205l-28.2505,0z"
android:strokeWidth="0.529167"
android:fillColor="#2c2d3c"/>
</group>
</vector>
21 changes: 21 additions & 0 deletions app/src/sideload/res/drawable/ic_launcher2_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="2.4944882"
android:scaleY="2.4944882"
android:translateX="18.36"
android:translateY="18.36">
<path
android:pathData="m17.5564,11.8482 l-5.208,7.6376 -1.5217,-1.0377 5.9674,-8.7512c0.1714,-0.2513 0.4558,-0.4019 0.76,-0.4022 0.3042,-0.0003 0.5889,0.1497 0.7608,0.4008l5.9811,8.7374 -1.5199,1.0404z"
android:strokeLineJoin="round"
android:fillColor="#67ea94"
android:fillType="evenOdd"/>
<path
android:pathData="m5.854,19.4956 l6.3707,-9.3423 -1.5749,-1.0739 -6.3707,9.3423z"
android:strokeLineJoin="round"
android:fillColor="#67ea94"
android:fillType="evenOdd"/>
</group>
</vector>
4 changes: 4 additions & 0 deletions app/src/sideload/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Meshtastic-sideload</string>"
</resources>
Loading