150 lines
6.4 KiB
Kotlin
150 lines
6.4 KiB
Kotlin
package org.microg.nlp.ui
|
|
|
|
import android.content.ComponentName
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.content.Intent.ACTION_VIEW
|
|
import android.content.pm.PackageManager.GET_META_DATA
|
|
import android.content.res.ColorStateList
|
|
import android.graphics.Color
|
|
import android.os.Bundle
|
|
import android.util.TypedValue
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import androidx.annotation.AttrRes
|
|
import androidx.annotation.ColorInt
|
|
import androidx.core.content.ContextCompat
|
|
import androidx.databinding.Observable
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.lifecycle.lifecycleScope
|
|
import kotlinx.coroutines.launch
|
|
import org.microg.nlp.client.UnifiedLocationClient
|
|
import org.microg.nlp.ui.BackendType.GEOCODER
|
|
import org.microg.nlp.ui.BackendType.LOCATION
|
|
import org.microg.nlp.ui.databinding.BackendDetailsBinding
|
|
import java.util.*
|
|
|
|
class BackendDetailsFragment : Fragment(R.layout.backend_details) {
|
|
|
|
fun Double.toStringWithDigits(digits: Int): String {
|
|
val s = this.toString()
|
|
val i = s.indexOf('.')
|
|
if (i <= 0 || s.length - i - 1 < digits) return s
|
|
if (digits == 0) return s.substring(0, i)
|
|
return s.substring(0, s.indexOf('.') + digits + 1)
|
|
}
|
|
|
|
fun Float.toStringWithDigits(digits: Int): String {
|
|
val s = this.toString()
|
|
val i = s.indexOf('.')
|
|
if (i <= 0 || s.length - i - 1 < digits) return s
|
|
if (digits == 0) return s.substring(0, i)
|
|
return s.substring(0, s.indexOf('.') + digits + 1)
|
|
}
|
|
|
|
@ColorInt
|
|
fun Context.resolveColor(@AttrRes resid: Int): Int? {
|
|
val typedValue = TypedValue()
|
|
if (!theme.resolveAttribute(resid, typedValue, true)) return null
|
|
val colorRes = if (typedValue.resourceId != 0) typedValue.resourceId else typedValue.data
|
|
return ContextCompat.getColor(this, colorRes)
|
|
}
|
|
|
|
val switchBarEnabledColor: Int
|
|
get() = context?.resolveColor(androidx.appcompat.R.attr.colorControlActivated) ?: Color.RED
|
|
|
|
val switchBarDisabledColor: Int
|
|
get() {
|
|
val color = context?.resolveColor(android.R.attr.textColorSecondary) ?: Color.RED
|
|
return Color.argb(100, Color.red(color), Color.green(color), Color.blue(color))
|
|
}
|
|
|
|
val switchBarTrackTintColor: ColorStateList
|
|
get() {
|
|
val color = context?.resolveColor(android.R.attr.textColorPrimaryInverse)
|
|
?: Color.RED
|
|
val withAlpha = Color.argb(50, Color.red(color), Color.green(color), Color.blue(color))
|
|
return ColorStateList(arrayOf(emptyArray<Int>().toIntArray()), arrayOf(withAlpha).toIntArray())
|
|
}
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
|
val binding = BackendDetailsBinding.inflate(inflater, container, false)
|
|
binding.fragment = this
|
|
binding.switchWidget.trackTintList = switchBarTrackTintColor
|
|
lifecycleScope.launchWhenStarted {
|
|
val entry = createBackendInfo()
|
|
binding.entry = entry
|
|
binding.executePendingBindings()
|
|
if (entry?.type == LOCATION) {
|
|
val client = UnifiedLocationClient[entry.context]
|
|
|
|
val location = client.getLastLocationForBackend(entry.serviceInfo.packageName, entry.serviceInfo.name, entry.firstSignatureDigest)
|
|
?: return@launchWhenStarted
|
|
var locationString = "${location.latitude.toStringWithDigits(6)}, ${location.longitude.toStringWithDigits(6)}"
|
|
|
|
val address = client.getFromLocation(location.latitude, location.longitude, 1, Locale.getDefault().toString()).singleOrNull()
|
|
if (address != null) {
|
|
val addressLine = StringBuilder()
|
|
var i = 0
|
|
addressLine.append(address.getAddressLine(i))
|
|
while (addressLine.length < 10 && address.maxAddressLineIndex > i) {
|
|
i++
|
|
addressLine.append(", ")
|
|
addressLine.append(address.getAddressLine(i))
|
|
}
|
|
locationString = addressLine.toString()
|
|
}
|
|
binding.lastLocationString = locationString
|
|
binding.executePendingBindings()
|
|
}
|
|
}
|
|
return binding.root
|
|
}
|
|
|
|
fun onBackendEnabledChanged(entry: BackendInfo) {
|
|
entry.enabled = !entry.enabled
|
|
}
|
|
|
|
private fun createExternalIntent(packageName: String, activityName: String): Intent {
|
|
val intent = Intent(ACTION_VIEW);
|
|
intent.setPackage(packageName);
|
|
intent.setClassName(packageName, activityName);
|
|
return intent;
|
|
}
|
|
|
|
private fun startExternalActivity(packageName: String, activityName: String) {
|
|
requireContext().startActivity(createExternalIntent(packageName, activityName))
|
|
}
|
|
|
|
fun onAboutClicked(entry: BackendInfo) {
|
|
entry.aboutActivity?.let { activityName -> startExternalActivity(entry.serviceInfo.packageName, activityName) }
|
|
}
|
|
|
|
fun onConfigureClicked(entry: BackendInfo) {
|
|
entry.settingsActivity?.let { activityName -> startExternalActivity(entry.serviceInfo.packageName, activityName) }
|
|
}
|
|
|
|
private suspend fun createBackendInfo(): BackendInfo? {
|
|
val activity = activity ?: return null
|
|
val intent = activity.intent ?: return null
|
|
val type = BackendType.values().find { it.name == intent.getStringExtra(EXTRA_TYPE) }
|
|
?: return null
|
|
val packageName = intent.getStringExtra(EXTRA_PACKAGE) ?: return null
|
|
val name = intent.getStringExtra(EXTRA_NAME) ?: return null
|
|
val serviceInfo = activity.packageManager.getServiceInfo(ComponentName(packageName, name), GET_META_DATA)
|
|
?: return null
|
|
val enabledBackends = when (type) {
|
|
GEOCODER -> UnifiedLocationClient[activity].getGeocoderBackends()
|
|
LOCATION -> UnifiedLocationClient[activity].getLocationBackends()
|
|
}
|
|
return BackendInfo(activity, serviceInfo, type, lifecycleScope, enabledBackends)
|
|
}
|
|
|
|
companion object {
|
|
val ACTION = "org.microg.nlp.ui.BACKEND_DETAILS"
|
|
val EXTRA_TYPE = "org.microg.nlp.ui.BackendDetailsFragment.type"
|
|
val EXTRA_PACKAGE = "org.microg.nlp.ui.BackendDetailsFragment.package"
|
|
val EXTRA_NAME = "org.microg.nlp.ui.BackendDetailsFragment.name"
|
|
}
|
|
} |