Skip to content

Commit

Permalink
Location: Move network location provider to independent module
Browse files Browse the repository at this point in the history
  • Loading branch information
mar-v-in committed Jul 4, 2023
1 parent 155d9f7 commit ba8e052
Show file tree
Hide file tree
Showing 69 changed files with 417 additions and 281 deletions.
1 change: 1 addition & 0 deletions play-services-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dependencies {
implementation project(':play-services-fido-core')
implementation project(':play-services-gmscompliance-core')
implementation project(':play-services-location-core')
implementation project(':play-services-location-core-provider')
withNearbyImplementation project(':play-services-nearby-core')
implementation project(':play-services-oss-licenses-core')
implementation project(':play-services-pay-core')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ class SafetyNetFragment : PreferenceFragmentCompat() {

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.preferences_safetynet)
}

@SuppressLint("RestrictedApi")
override fun onBindPreferences() {
switchBarPreference = preferenceScreen.findPreference("pref_safetynet_enabled") ?: switchBarPreference
runAttest = preferenceScreen.findPreference("pref_safetynet_run_attest") ?: runAttest
runReCaptcha = preferenceScreen.findPreference("pref_recaptcha_run_test") ?: runReCaptcha
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class SettingsFragment : ResourceSettingsFragment() {
true
}
findPreference<Preference>(PREF_ABOUT)!!.summary = getString(R.string.about_version_str, AboutFragment.getSelfVersion(context))

findPreference<Preference>(PREF_EXPOSURE)?.isVisible = NearbyPreferencesIntegration.isAvailable
findPreference<Preference>(PREF_EXPOSURE)?.icon = NearbyPreferencesIntegration.getIcon(requireContext())
findPreference<Preference>(PREF_EXPOSURE)?.summary = NearbyPreferencesIntegration.getExposurePreferenceSummary(requireContext())
}

override fun onResume() {
Expand All @@ -63,10 +67,6 @@ class SettingsFragment : ResourceSettingsFragment() {

findPreference<Preference>(PREF_CHECKIN)!!.setSummary(if (CheckinPreferences.isEnabled(requireContext())) R.string.service_status_enabled_short else R.string.service_status_disabled_short)
findPreference<Preference>(PREF_SNET)!!.setSummary(if (SafetyNetPreferences.isEnabled(requireContext())) R.string.service_status_enabled_short else R.string.service_status_disabled_short)

findPreference<Preference>(PREF_EXPOSURE)?.isVisible = NearbyPreferencesIntegration.isAvailable
findPreference<Preference>(PREF_EXPOSURE)?.icon = NearbyPreferencesIntegration.getIcon(requireContext())
findPreference<Preference>(PREF_EXPOSURE)?.summary = NearbyPreferencesIntegration.getExposurePreferenceSummary(context)
}

companion object {
Expand Down
32 changes: 32 additions & 0 deletions play-services-location/core/base/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

dependencies {
api project(':play-services-location')
implementation project(':play-services-base-core')
}

android {
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"

defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
6 changes: 6 additions & 0 deletions play-services-location/core/base/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2023 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest package="org.microg.gms.location.base" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package org.microg.gms.location

import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.os.SystemClock
import android.text.format.DateUtils
import android.util.Log
import androidx.core.location.LocationCompat

const val ACTION_NETWORK_LOCATION_SERVICE = "org.microg.gms.location.network.ACTION_NETWORK_LOCATION_SERVICE"
const val EXTRA_LOCATION = "location"
const val EXTRA_PENDING_INTENT = "pending_intent"
const val EXTRA_ENABLE = "enable"
const val EXTRA_INTERVAL_MILLIS = "interval"
const val EXTRA_FORCE_NOW = "force_now"
const val EXTRA_LOW_POWER = "low_power"
const val EXTRA_WORK_SOURCE = "work_source"
const val EXTRA_BYPASS = "bypass"

val Location.elapsedMillis: Long
get() = LocationCompat.getElapsedRealtimeMillis(this)

fun Long.formatRealtime(): CharSequence = if (this <= 0) "n/a" else DateUtils.getRelativeTimeSpanString((this - SystemClock.elapsedRealtime()) + System.currentTimeMillis(), System.currentTimeMillis(), 0)
fun Long.formatDuration(): CharSequence {
if (this == 0L) return "0ms"
if (this > 315360000000L /* ten years */) return "\u221e"
val interval = listOf(1000, 60, 60, 24, Long.MAX_VALUE)
val intervalName = listOf("ms", "s", "m", "h", "d")
var ret = ""
var rem = this
for (i in 0 until interval.size) {
val mod = rem % interval[i]
if (mod != 0L) {
ret = "$mod${intervalName[i]}$ret"
}
rem /= interval[i]
if (mod == 0L && rem == 1L) {
ret = "${interval[i]}${intervalName[i]}$ret"
break
} else if (rem == 0L) {
break
}
}
return ret
}

private var hasMozillaLocationServiceSupportFlag: Boolean? = null
fun Context.hasMozillaLocationServiceSupport(): Boolean {
if (!hasNetworkLocationServiceBuiltIn()) return false
var flag = hasMozillaLocationServiceSupportFlag
if (flag == null) {
return try {
val clazz = Class.forName("org.microg.gms.location.network.mozilla.MozillaLocationServiceClient")
val apiKey = clazz.getDeclaredField("API_KEY").get(null) as? String?
flag = apiKey != null
hasMozillaLocationServiceSupportFlag = flag
flag
} catch (e: Exception) {
Log.w("Location", e)
hasMozillaLocationServiceSupportFlag = false
false
}
} else {
return flag
}
}

private var hasNetworkLocationServiceBuiltInFlag: Boolean? = null
fun Context.hasNetworkLocationServiceBuiltIn(): Boolean {
var flag = hasNetworkLocationServiceBuiltInFlag
if (flag == null) {
try {
val serviceIntent = Intent().apply {
action = ACTION_NETWORK_LOCATION_SERVICE
setPackage(packageName)
}
val services = packageManager?.queryIntentServices(serviceIntent, PackageManager.MATCH_DEFAULT_ONLY)
flag = services?.isNotEmpty() ?: false
hasNetworkLocationServiceBuiltInFlag = flag
return flag
} catch (e: Exception) {
hasNetworkLocationServiceBuiltInFlag = false
return false
}
} else {
return flag
}
}
3 changes: 1 addition & 2 deletions play-services-location/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ apply plugin: 'kotlin-android'

dependencies {
api project(':play-services-location')
compileOnly project(':play-services-location-system-api')
implementation project(':play-services-base-core')
implementation project(':play-services-location-core-base')

implementation "androidx.lifecycle:lifecycle-service:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
Expand All @@ -23,7 +23,6 @@ dependencies {

implementation "com.android.volley:volley:$volleyVersion"

implementation 'org.microg:address-formatter:0.3.1'
compileOnly project(':play-services-maps')
}

Expand Down
46 changes: 46 additions & 0 deletions play-services-location/core/provider/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

dependencies {
api project(':play-services-location')
compileOnly project(':play-services-location-core-system-api')
implementation project(':play-services-base-core')
implementation project(':play-services-location-core-base')

implementation "androidx.lifecycle:lifecycle-service:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion"

implementation "com.android.volley:volley:$volleyVersion"

implementation 'org.microg:address-formatter:0.3.1'
}

android {
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"

defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
buildConfigField "String", "ICHNAEA_KEY", "\"${localProperties.get("ichnaea.key", "")}\""
}

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
65 changes: 65 additions & 0 deletions play-services-location/core/provider/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ SPDX-FileCopyrightText: 2023 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:tools="http://schemas.android.com/tools"
package="org.microg.gms.location.provider"
xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BODY_SENSORS" />

<uses-permission
android:name="android.permission.LOCATION_HARDWARE"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.INSTALL_LOCATION_PROVIDER"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.NETWORK_SCAN"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />

<application>
<uses-library android:name="com.android.location.provider" />

<service
android:name="org.microg.gms.location.network.NetworkLocationService"
android:exported="false">
<intent-filter>
<action android:name="org.microg.gms.location.network.ACTION_NETWORK_LOCATION_SERVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
<service
android:name="org.microg.gms.location.provider.NetworkLocationProviderService"
android:exported="true"
android:permission="android.permission.WRITE_SECURE_SETTINGS">
<intent-filter>
<action android:name="com.android.location.service.v2.NetworkLocationProvider" />
<action android:name="com.android.location.service.v3.NetworkLocationProvider" />
</intent-filter>
<meta-data
android:name="serviceVersion"
android:value="2" />
</service>
<service
android:name="org.microg.gms.location.provider.GeocodeProviderService"
android:exported="true"
android:permission="android.permission.WRITE_SECURE_SETTINGS">
<intent-filter>
<action android:name="com.android.location.service.GeocodeProvider" />
<action android:name="com.google.android.location.GeocodeProvider" />
</intent-filter>
<meta-data
android:name="serviceVersion"
android:value="2" />
</service>
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import android.database.DatabaseUtils
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.location.Location
import android.util.Log
import androidx.core.content.contentValuesOf
import androidx.core.os.bundleOf
import org.microg.gms.location.network.cell.CellDetails
Expand Down Expand Up @@ -133,22 +132,25 @@ internal class LocationCacheDatabase(context: Context?) : SQLiteOpenHelper(conte
).use { cursor ->
if (cursor.moveToNext()) {
val midLocation = cursor.getMidLocation(Long.MAX_VALUE, 0f)
(midLocation != null) to (midLocation?.let { it.distanceTo(location) > LEARN_BAD_SIZE_CELL} == true)
(midLocation != null) to (midLocation?.let { it.distanceTo(location) > LEARN_BAD_SIZE_CELL } == true)
} else {
false to false
}
}
if (exists && isBad) {
writableDatabase.update(TABLE_CELLS_LEARN, contentValuesOf(
writableDatabase.update(
TABLE_CELLS_LEARN, contentValuesOf(
FIELD_LATITUDE_HIGH to location.latitude,
FIELD_LATITUDE_LOW to location.latitude,
FIELD_LONGITUDE_HIGH to location.longitude,
FIELD_LONGITUDE_LOW to location.longitude,
FIELD_TIME to location.time,
FIELD_BAD_TIME to location.time
), CELLS_SELECTION, getCellSelectionArgs(cell))
), CELLS_SELECTION, getCellSelectionArgs(cell)
)
} else if (!exists) {
writableDatabase.insertWithOnConflict(TABLE_CELLS_LEARN, null, contentValuesOf(
writableDatabase.insertWithOnConflict(
TABLE_CELLS_LEARN, null, contentValuesOf(
FIELD_MCC to cell.mcc,
FIELD_MNC to cell.mnc,
FIELD_LAC_TAC to (cell.lac ?: cell.tac ?: 0),
Expand Down Expand Up @@ -180,13 +182,14 @@ internal class LocationCacheDatabase(context: Context?) : SQLiteOpenHelper(conte
).use { cursor ->
if (cursor.moveToNext()) {
val midLocation = cursor.getMidLocation(Long.MAX_VALUE, 0f)
(midLocation != null) to (midLocation?.let { it.distanceTo(location) > LEARN_BAD_SIZE_WIFI} == true)
(midLocation != null) to (midLocation?.let { it.distanceTo(location) > LEARN_BAD_SIZE_WIFI } == true)
} else {
false to false
}
}
if (exists && isBad) {
writableDatabase.update(TABLE_WIFI_LEARN, contentValuesOf(
writableDatabase.update(
TABLE_WIFI_LEARN, contentValuesOf(
FIELD_LATITUDE_HIGH to location.latitude,
FIELD_LATITUDE_LOW to location.latitude,
FIELD_LONGITUDE_HIGH to location.longitude,
Expand All @@ -195,7 +198,8 @@ internal class LocationCacheDatabase(context: Context?) : SQLiteOpenHelper(conte
FIELD_BAD_TIME to location.time
), getWifiSelection(wifi), null)
} else if (!exists) {
writableDatabase.insertWithOnConflict(TABLE_WIFI_LEARN, null, contentValuesOf(
writableDatabase.insertWithOnConflict(
TABLE_WIFI_LEARN, null, contentValuesOf(
FIELD_MAC to wifi.macBytes,
FIELD_LATITUDE_HIGH to location.latitude,
FIELD_LATITUDE_LOW to location.latitude,
Expand Down Expand Up @@ -225,7 +229,7 @@ internal class LocationCacheDatabase(context: Context?) : SQLiteOpenHelper(conte
db.execSQL("CREATE INDEX IF NOT EXISTS ${TABLE_WIFIS}_time_index ON $TABLE_WIFIS($FIELD_TIME);")
db.execSQL("CREATE INDEX IF NOT EXISTS ${TABLE_CELLS_LEARN}_time_index ON $TABLE_CELLS_LEARN($FIELD_TIME);")
db.execSQL("CREATE INDEX IF NOT EXISTS ${TABLE_WIFI_LEARN}_time_index ON $TABLE_WIFI_LEARN($FIELD_TIME);")
db.execSQL("DROP TABLE IF EXISTS ${TABLE_WIFI_SCANS};")
db.execSQL("DROP TABLE IF EXISTS $TABLE_WIFI_SCANS;")
}

fun cleanup(db: SQLiteDatabase) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.content.Intent
import android.location.Location
import android.os.SystemClock
import android.os.WorkSource
import org.microg.gms.location.EXTRA_LOCATION

class NetworkLocationRequest(
var pendingIntent: PendingIntent,
Expand All @@ -23,6 +24,6 @@ class NetworkLocationRequest(

fun send(context: Context, location: Location) {
lastRealtime = SystemClock.elapsedRealtime()
pendingIntent.send(context, 0, Intent().apply { putExtra(NetworkLocationService.EXTRA_LOCATION, location) })
pendingIntent.send(context, 0, Intent().apply { putExtra(EXTRA_LOCATION, location) })
}
}
Loading

0 comments on commit ba8e052

Please sign in to comment.