Skip to content

Commit

Permalink
feat: adding fdroid flavor to build without GMS and Firebase (WPB-279…
Browse files Browse the repository at this point in the history
…9) (#2727)

Co-authored-by: Yamil Medina <yamilmedina@users.noreply.github.com>
Co-authored-by: Mohamad Jaara <mohamad.jaara@wire.com>
  • Loading branch information
3 people committed Feb 22, 2024
1 parent ff529ed commit 0e0430d
Show file tree
Hide file tree
Showing 24 changed files with 355 additions and 56 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,7 @@ lint/tmp/
# Autogenerated file with git hash information.
app/src/main/assets/version.txt
/intellij.gdsl

# Editor temporary files
*~
\#*#
21 changes: 21 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,29 @@ android {
jniLibs.pickFirsts.add("**/libsodium.so")
}
android.buildFeatures.buildConfig = true

var fdroidBuild = gradle.startParameter.taskRequests.toString().lowercase().contains("fdroid")
sourceSets {
// Add the "foss" sourceSets for the fdroid flavor
if(fdroidBuild) {
getByName("main") {
java.srcDirs("src/foss/kotlin", "src/prod/kotlin")
resources.srcDirs("src/prod/res")
println("Building with FOSS sourceSets")
}
// For all other flavors use the "nonfree" sourceSets
} else {
getByName("main") {
java.srcDirs("src/nonfree/kotlin")
println("Building with non-free sourceSets")
}
}
}
}




dependencies {
implementation("com.wire.kalium:kalium-logic")
implementation("com.wire.kalium:kalium-util")
Expand Down
39 changes: 39 additions & 0 deletions app/src/fdroid/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--
Wire
Copyright (C) 2018 Wire Swiss GmbH
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 <http://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.wire.android"
android:sharedUserId="${sharedUserId}">
<application>
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
tools:node="remove" />
<meta-data
android:name="com.google.android.gms.version"
tools:node="remove" />
<service
android:name=".services.WireFirebaseMessagingService"
tools:node="remove" />
<meta-data
android:name="com.wire.android.initializer.FirebaseInitializer"
tools:node="remove" />

</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* 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 http://www.gnu.org/licenses/.
*/
package com.wire.android.ui.home.messagecomposer.location

import android.content.Context
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class LocationPickerHelperFlavor @Inject constructor(context: Context) : LocationPickerHelper(context) {
suspend fun getLocation(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
getLocationWithoutGms(
onSuccess = onSuccess,
onError = onError
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* 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 http://www.gnu.org/licenses/.
*
*
*/

package com.wire.android.util.extension

import android.content.Context

fun Context.isGoogleServicesAvailable(): Boolean {
val returnValue: Boolean = false
return returnValue
}

fun Context.initGoogleFirebase() { /* Stub for compatibility */ }
Original file line number Diff line number Diff line change
Expand Up @@ -24,51 +24,13 @@ import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import androidx.core.location.LocationManagerCompat
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.tasks.CancellationTokenSource
import com.wire.android.util.extension.isGoogleServicesAvailable
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.tasks.await
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class LocationPickerHelper @Inject constructor(@ApplicationContext val context: Context) {

suspend fun getLocation(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
if (context.isGoogleServicesAvailable()) {
getLocationWithGms(
onSuccess = onSuccess,
onError = onError
)
} else {
getLocationWithoutGms(
onSuccess = onSuccess,
onError = onError
)
}
}

/**
* Choosing the best location estimate by docs.
* https://developer.android.com/develop/sensors-and-location/location/retrieve-current#BestEstimate
*/
@SuppressLint("MissingPermission")
private suspend fun getLocationWithGms(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
if (isLocationServicesEnabled()) {
val locationProvider = LocationServices.getFusedLocationProviderClient(context)
val currentLocation =
locationProvider.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, CancellationTokenSource().token).await()
val address = Geocoder(context).getFromLocation(currentLocation.latitude, currentLocation.longitude, 1).orEmpty()
onSuccess(GeoLocatedAddress(address.firstOrNull(), currentLocation))
} else {
onError()
}
}
open class LocationPickerHelper @Inject constructor(@ApplicationContext val context: Context) {

@SuppressLint("MissingPermission")
private fun getLocationWithoutGms(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
protected fun getLocationWithoutGms(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
if (isLocationServicesEnabled()) {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val networkLocationListener: LocationListener = object : LocationListener {
Expand All @@ -84,7 +46,7 @@ class LocationPickerHelper @Inject constructor(@ApplicationContext val context:
}
}

private fun isLocationServicesEnabled(): Boolean {
protected fun isLocationServicesEnabled(): Boolean {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
return LocationManagerCompat.isLocationEnabled(locationManager)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class LocationPickerViewModel @Inject constructor(private val locationPickerHelper: LocationPickerHelper) : ViewModel() {
class LocationPickerViewModel @Inject constructor(private val locationPickerHelper: LocationPickerHelperFlavor) : ViewModel() {

var state: LocationPickerState by mutableStateOf(LocationPickerState())
private set
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package com.wire.android.ui.home.messagecomposer.state

import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
Expand All @@ -32,7 +33,6 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.max
import com.google.android.gms.common.util.VisibleForTesting
import com.wire.android.R
import com.wire.android.ui.common.colorsScheme
import com.wire.android.ui.common.textfield.WireTextFieldColors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

package com.wire.android.ui.home.settings.account

import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.google.android.gms.common.util.VisibleForTesting
import com.wire.android.BuildConfig
import com.wire.android.appLogger
import com.wire.android.navigation.SavedStateViewModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
*/
package com.wire.android.ui.home.settings.account.email.updateEmail

import androidx.annotation.VisibleForTesting
import android.util.Patterns
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.gms.common.util.VisibleForTesting
import com.wire.kalium.logic.feature.user.GetSelfUserUseCase
import com.wire.kalium.logic.feature.user.UpdateEmailUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
*/
package com.wire.android.ui.home.settings.account.handle

import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.gms.common.util.VisibleForTesting
import com.wire.android.ui.authentication.create.common.handle.HandleUpdateErrorState
import com.wire.kalium.logic.feature.auth.ValidateUserHandleResult
import com.wire.kalium.logic.feature.auth.ValidateUserHandleUseCase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,12 @@ import android.content.ContextWrapper
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability

fun Context.checkPermission(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) ==
PackageManager.PERMISSION_GRANTED
}

fun Context.isGoogleServicesAvailable(): Boolean {
val status = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this)
return status == ConnectionResult.SUCCESS
}

fun Context.getActivity(): AppCompatActivity? = when (this) {
is AppCompatActivity -> this
is ContextWrapper -> baseContext.getActivity()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* 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 http://www.gnu.org/licenses/.
*/
package com.wire.android.ui.home.messagecomposer.location

import android.annotation.SuppressLint
import android.content.Context
import android.location.Geocoder
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.tasks.CancellationTokenSource
import com.wire.android.util.extension.isGoogleServicesAvailable
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.tasks.await

@Singleton
class LocationPickerHelperFlavor @Inject constructor(context: Context) : LocationPickerHelper(context) {

suspend fun getLocation(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
if (context.isGoogleServicesAvailable()) {
getLocationWithGms(
onSuccess = onSuccess,
onError = onError
)
} else {
getLocationWithoutGms(
onSuccess = onSuccess,
onError = onError
)
}
}

/**
* Choosing the best location estimate by docs.
* https://developer.android.com/develop/sensors-and-location/location/retrieve-current#BestEstimate
*/
@SuppressLint("MissingPermission")
private suspend fun getLocationWithGms(onSuccess: (GeoLocatedAddress) -> Unit, onError: () -> Unit) {
if (isLocationServicesEnabled()) {
val locationProvider = LocationServices.getFusedLocationProviderClient(context)
val currentLocation =
locationProvider.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, CancellationTokenSource().token).await()
val address = Geocoder(context).getFromLocation(currentLocation.latitude, currentLocation.longitude, 1).orEmpty()
onSuccess(GeoLocatedAddress(address.firstOrNull(), currentLocation))
} else {
onError()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* 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 http://www.gnu.org/licenses/.
*
*
*/

package com.wire.android.util.extension

import android.content.Context

import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability

fun Context.isGoogleServicesAvailable(): Boolean {
val status = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this)
return status == ConnectionResult.SUCCESS
}

0 comments on commit 0e0430d

Please sign in to comment.