Apply various IDE code quality suggestions (#3734)

This commit is contained in:
Joris Pelgröm 2023-07-31 21:17:42 +02:00 committed by GitHub
parent 0800e9b402
commit 670b17e76c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 124 additions and 161 deletions

View file

@ -64,7 +64,7 @@ class HighAccuracyLocationService : Service() {
fun updateNotificationAddress(context: Context, location: Location, geocodedAddress: String = "") {
var locationReadable = geocodedAddress
if (locationReadable.isNullOrEmpty()) {
if (locationReadable.isEmpty()) {
locationReadable = getFormattedLocationInDegree(location.latitude, location.longitude)
}
locationReadable = "$locationReadable (~${location.accuracy}m)"

View file

@ -109,7 +109,7 @@ class ActivitySensorManager : BroadcastReceiver(), SensorManager {
activity,
probActivity,
getSensorIcon(probActivity),
result.probableActivities.map { typeToString(it) to it.confidence }.toMap()
result.probableActivities.associate { typeToString(it) to it.confidence }
)
}
}

View file

@ -401,13 +401,13 @@ class LocationSensorManager : LocationSensorManagerBase() {
private fun getHighAccuracyModeUpdateInterval(): Int {
val updateIntervalHighAccuracySeconds = getSetting(
latestContext,
LocationSensorManager.backgroundLocation,
backgroundLocation,
SETTING_HIGH_ACCURACY_MODE_UPDATE_INTERVAL,
SensorSettingType.NUMBER,
DEFAULT_UPDATE_INTERVAL_HA_SECONDS.toString()
)
var updateIntervalHighAccuracySecondsInt = if (updateIntervalHighAccuracySeconds.isNullOrEmpty()) DEFAULT_UPDATE_INTERVAL_HA_SECONDS else updateIntervalHighAccuracySeconds.toInt()
var updateIntervalHighAccuracySecondsInt = if (updateIntervalHighAccuracySeconds.isEmpty()) DEFAULT_UPDATE_INTERVAL_HA_SECONDS else updateIntervalHighAccuracySeconds.toInt()
if (updateIntervalHighAccuracySecondsInt < 5) {
updateIntervalHighAccuracySecondsInt = DEFAULT_UPDATE_INTERVAL_HA_SECONDS
@ -417,7 +417,7 @@ class LocationSensorManager : LocationSensorManagerBase() {
}
private fun getHighAccuracyModeState(): Boolean {
var highAccuracyMode = getHighAccuracyModeSetting()
val highAccuracyMode = getHighAccuracyModeSetting()
if (!highAccuracyMode) return false

View file

@ -42,7 +42,7 @@ import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
import androidx.core.text.HtmlCompat.fromHtml
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.util.IntervalToString
import io.homeassistant.companion.android.util.intervalToString
import io.homeassistant.companion.android.common.R as commonR
@Composable
@ -81,7 +81,7 @@ fun SettingsWearTemplateTile(
OutlinedButton(
onClick = { dropdownExpanded = true }
) {
Text(IntervalToString(LocalContext.current, refreshInterval))
Text(intervalToString(LocalContext.current, refreshInterval))
}
DropdownMenu(
expanded = dropdownExpanded,
@ -93,7 +93,7 @@ fun SettingsWearTemplateTile(
onRefreshIntervalChanged(option)
dropdownExpanded = false
}) {
Text(IntervalToString(LocalContext.current, option))
Text(intervalToString(LocalContext.current, option))
}
}
}

View file

@ -28,7 +28,7 @@ open class BaseActivity : AppCompatActivity() {
car = Car.createCar(this)
carRestrictionManager =
car?.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) as CarUxRestrictionsManager
var listener =
val listener =
CarUxRestrictionsManager.OnUxRestrictionsChangedListener { restrictions ->
if (restrictions.isRequiresDistractionOptimization) {
startCarAppActivity()

View file

@ -148,14 +148,15 @@ object ClimateControl : HaControl {
}
}
private fun entityShouldBePresentedAsThermostat(entity: Entity<Map<String, Any>>): Boolean {
return temperatureControlModes.containsKey(entity.state) &&
((entity.attributes["hvac_modes"] as? List<String>)?.isNotEmpty() == true) &&
((entity.attributes["hvac_modes"] as? List<String>)?.any { it == entity.state } == true) &&
((entity.attributes["hvac_modes"] as? List<String>)?.all { temperatureControlModes.containsKey(it) } == true) &&
(
((entity.attributes["supported_features"] as Int) and SUPPORT_TARGET_TEMPERATURE == SUPPORT_TARGET_TEMPERATURE) ||
((entity.attributes["supported_features"] as Int) and SUPPORT_TARGET_TEMPERATURE_RANGE == SUPPORT_TARGET_TEMPERATURE_RANGE)
)
}
private fun entityShouldBePresentedAsThermostat(entity: Entity<Map<String, Any>>): Boolean =
(entity.attributes["hvac_modes"] as? List<String>).let { modes ->
temperatureControlModes.containsKey(entity.state) &&
modes?.isNotEmpty() == true &&
modes.any { it == entity.state } &&
modes.all { temperatureControlModes.containsKey(it) } &&
(
((entity.attributes["supported_features"] as Int) and SUPPORT_TARGET_TEMPERATURE == SUPPORT_TARGET_TEMPERATURE) ||
((entity.attributes["supported_features"] as Int) and SUPPORT_TARGET_TEMPERATURE_RANGE == SUPPORT_TARGET_TEMPERATURE_RANGE)
)
}
}

View file

@ -20,7 +20,7 @@ import io.homeassistant.companion.android.common.R as commonR
@RequiresApi(Build.VERSION_CODES.R)
object CoverControl : HaControl {
const val SUPPORT_SET_POSITION = 4
private const val SUPPORT_SET_POSITION = 4
override fun provideControlFeatures(
context: Context,
control: Control.StatefulBuilder,

View file

@ -9,7 +9,6 @@ import android.service.controls.actions.ControlAction
import android.service.controls.templates.ControlButton
import android.service.controls.templates.ToggleTemplate
import androidx.annotation.RequiresApi
import androidx.compose.ui.text.capitalize
import io.homeassistant.companion.android.common.data.integration.Entity
import io.homeassistant.companion.android.common.data.integration.IntegrationRepository
import io.homeassistant.companion.android.common.data.integration.domain

View file

@ -16,7 +16,7 @@ import io.homeassistant.companion.android.webview.WebViewActivity
class MyActivity : BaseActivity() {
companion object {
val EXTRA_URI = "EXTRA_URI"
private const val EXTRA_URI = "EXTRA_URI"
fun newInstance(context: Context, uri: Uri): Intent {
return Intent(context, MyActivity::class.java).apply {

View file

@ -76,7 +76,6 @@ import io.homeassistant.companion.android.sensors.NotificationSensorManager
import io.homeassistant.companion.android.sensors.SensorReceiver
import io.homeassistant.companion.android.settings.SettingsActivity
import io.homeassistant.companion.android.util.UrlUtil
import io.homeassistant.companion.android.util.cancelGroupIfNeeded
import io.homeassistant.companion.android.vehicle.HaCarAppService
import io.homeassistant.companion.android.websocket.WebsocketManager
import io.homeassistant.companion.android.webview.WebViewActivity
@ -1132,9 +1131,8 @@ class MessagingManager @Inject constructor(
data: Map<String, String>
) {
// Use importance property for legacy priority support
val priority = data[NotificationData.IMPORTANCE]
when (priority) {
when (data[NotificationData.IMPORTANCE]) {
"high" -> {
builder.priority = NotificationCompat.PRIORITY_HIGH
}
@ -1367,7 +1365,7 @@ class MessagingManager @Inject constructor(
private fun Bitmap.getCompressedFrame(): Bitmap? {
var newWidth = 480
var newHeight = 0
val newHeight: Int
// If already smaller than 480p do not scale else scale
if (width < newWidth) {
newWidth = width

View file

@ -46,8 +46,6 @@ class OnboardingViewModel @Inject constructor(
var discoveryOptions: OnboardApp.DiscoveryOptions? = null
var manualContinueEnabled by mutableStateOf(false)
private set
var authCode by mutableStateOf("")
private set
var deviceIsWatch by mutableStateOf(false)
val deviceName = mutableStateOf("")
val locationTrackingPossible = mutableStateOf(false)
@ -55,6 +53,8 @@ class OnboardingViewModel @Inject constructor(
val notificationsPossible = mutableStateOf(true)
var notificationsEnabled by mutableStateOf(false)
private var authCode = ""
fun onManualUrlUpdated(url: String) {
manualUrl.value = url
manualContinueEnabled = URLUtil.isValidUrl(url)

View file

@ -153,7 +153,7 @@ class SettingsActivity : BaseActivity() {
Log.d(TAG, "settingsActivityAuthenticationResult(): authenticating: $authenticating, externalAuth: $isExtAuth")
externalAuthCallback?.let {
if (it(result) == true) {
if (it(result)) {
externalAuthCallback = null
}
}

View file

@ -59,8 +59,8 @@ import java.time.format.FormatStyle
import io.homeassistant.companion.android.common.R as commonR
class SettingsFragment(
val presenter: SettingsPresenter,
val langProvider: LanguagesProvider
private val presenter: SettingsPresenter,
private val langProvider: LanguagesProvider
) : SettingsView, PreferenceFragmentCompat() {
companion object {
@ -274,10 +274,6 @@ class SettingsFragment(
}
findPreference<SwitchPreference>("crash_reporting")?.let {
it.isVisible = BuildConfig.FLAVOR == "full"
it.setOnPreferenceChangeListener { _, newValue ->
val checked = newValue as Boolean
true
}
}
lifecycleScope.launch {
@ -358,9 +354,9 @@ class SettingsFragment(
if (pref != null) {
val systemIndex = pref.findIndexOfValue("system")
if (systemIndex > 0) {
var entries = pref.entries?.toMutableList()
val entries = pref.entries?.toMutableList()
entries?.removeAt(systemIndex)
var entryValues = pref.entryValues?.toMutableList()
val entryValues = pref.entryValues?.toMutableList()
entryValues?.removeAt(systemIndex)
if (entries != null && entryValues != null) {
pref.entries = entries.toTypedArray()

View file

@ -238,14 +238,14 @@ class SettingsPresenterImpl @Inject constructor(
// Assist
var assistantSuggestion = serverManager.defaultServers.any { it.version?.isAtLeast(2023, 5) == true }
if (assistantSuggestion && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
assistantSuggestion = if (assistantSuggestion && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val roleManager = context.getSystemService<RoleManager>()
assistantSuggestion = roleManager?.isRoleAvailable(RoleManager.ROLE_ASSISTANT) == true && !roleManager.isRoleHeld(RoleManager.ROLE_ASSISTANT)
roleManager?.isRoleAvailable(RoleManager.ROLE_ASSISTANT) == true && !roleManager.isRoleHeld(RoleManager.ROLE_ASSISTANT)
} else if (assistantSuggestion && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val defaultApp: String? = Settings.Secure.getString(context.contentResolver, "assistant")
assistantSuggestion = defaultApp?.contains(BuildConfig.APPLICATION_ID) == false
defaultApp?.contains(BuildConfig.APPLICATION_ID) == false
} else {
assistantSuggestion = false
false
}
if (assistantSuggestion) {
suggestions += SettingsHomeSuggestion(

View file

@ -180,7 +180,7 @@ class LogFragment : Fragment() {
// Lets exclude github app, because github doesn't support sharing text files (only images)
// Also no issue template will be used
val excludedComponents = getExcludedComponentsForPackageName(sendIntent, arrayOf("com.github.android"))
if (excludedComponents.size > 0) {
if (excludedComponents.size > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponents.toTypedArray())
}
}

View file

@ -26,7 +26,7 @@ import io.homeassistant.companion.android.common.R as commonR
class NotificationDetailFragment : Fragment() {
companion object {
val ARG_NOTIF = "notification"
const val ARG_NOTIF = "notification"
}
@Inject

View file

@ -8,6 +8,7 @@ import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.widget.SearchView
import androidx.core.text.HtmlCompat
import androidx.fragment.app.commit
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
@ -170,15 +171,10 @@ class NotificationHistoryFragment : PreferenceFragmentCompat() {
pref.setOnPreferenceClickListener {
val args = Bundle()
args.putSerializable(NotificationDetailFragment.ARG_NOTIF, item)
parentFragmentManager
.beginTransaction()
.replace(
R.id.content,
NotificationDetailFragment::class.java,
args
)
.addToBackStack("Notification Detail")
.commit()
parentFragmentManager.commit {
replace(R.id.content, NotificationDetailFragment::class.java, args)
addToBackStack("Notification Detail")
}
return@setOnPreferenceClickListener true
}

View file

@ -1,6 +1,7 @@
package io.homeassistant.companion.android.settings.sensor
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@ -111,6 +112,7 @@ class SensorDetailFragment : Fragment() {
}
}
@SuppressLint("InlinedApi")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View file

@ -48,8 +48,11 @@ class ManageShortcutsViewModel @Inject constructor(
application: Application
) : AndroidViewModel(application) {
companion object {
private const val TAG = "ShortcutViewModel"
}
val app = application
private val TAG = "ShortcutViewModel"
private var shortcutManager = application.applicationContext.getSystemService<ShortcutManager>()!!
val canPinShortcuts = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && shortcutManager.isRequestPinShortcutSupported
var pinnedShortcuts = shortcutManager.pinnedShortcuts

View file

@ -238,7 +238,7 @@ fun SsidView(
}
if (prioritizeDropdown) {
DropdownMenu(
expanded = prioritizeDropdown,
expanded = true,
onDismissRequest = { prioritizeDropdown = false },
modifier = Modifier.fillMaxWidth()
) {

View file

@ -33,7 +33,9 @@ class ForegroundServiceLauncher(private val serviceClass: Class<out Service>) {
} else {
if (restartInProcess) {
Log.w(TAG, "Cannot start service ${serviceClass.simpleName}. Service currently restarting...")
} else if (isRunning) Log.w(TAG, "Cannot start service ${serviceClass.simpleName}. Service is not running...")
} else {
Log.w(TAG, "Cannot start service ${serviceClass.simpleName}. Service is not running...")
}
}
}
@ -43,7 +45,9 @@ class ForegroundServiceLauncher(private val serviceClass: Class<out Service>) {
shouldStop = true
if (restartInProcess) {
Log.d(TAG, "Stop service ${serviceClass.simpleName}. Service currently restarting. Stopping service after it is restarted.")
} else if (isStarting) Log.d(TAG, "Stop service ${serviceClass.simpleName}. Service is currently starting. Stopping service after it is started.")
} else {
Log.d(TAG, "Stop service ${serviceClass.simpleName}. Service is currently starting. Stopping service after it is started.")
}
} else if (isRunning) {
context.stopService(Intent(context, serviceClass))
Log.d(TAG, "Stop service ${serviceClass.simpleName}")
@ -76,7 +80,9 @@ class ForegroundServiceLauncher(private val serviceClass: Class<out Service>) {
} else {
if (restartInProcess) {
Log.w(TAG, "Cannot restart service ${serviceClass.simpleName}. Service currently restarting...")
} else if (isStarting) Log.w(TAG, "Cannot restart service ${serviceClass.simpleName}. Service is currently starting...")
} else {
Log.w(TAG, "Cannot restart service ${serviceClass.simpleName}. Service is currently starting...")
}
}
}

View file

@ -18,7 +18,7 @@ object LogcatReader {
val process = pb.start()
val reader = BufferedReader(InputStreamReader(process.inputStream))
var line: String? = ""
var line: String?
while (reader.readLine().also { line = it } != null) {
log.append(line + "\n")
}

View file

@ -1,13 +0,0 @@
package io.homeassistant.companion.android.util
import android.app.NotificationManager
import androidx.car.app.notification.CarNotificationManager
import io.homeassistant.companion.android.common.util.cancelNotificationGroupIfNeeded
fun CarNotificationManager.cancelGroupIfNeeded(manager: NotificationManager, tag: String?, id: Int): Boolean =
cancelNotificationGroupIfNeeded(
manager,
tag,
id,
this::cancel
)

View file

@ -13,11 +13,11 @@ import kotlin.math.abs
// We need to keep track of (pointer) down, move, (pointer) up and cancel events to be able to detect flings
// (or swipes) and send the direction + number of pointers for that fling to the app
abstract class OnSwipeListener(context: Context?) : View.OnTouchListener {
var handler = Handler(Looper.getMainLooper())
private var handler = Handler(Looper.getMainLooper())
var velocityTracker: VelocityTracker? = null
var downEvent: MotionEvent? = null
var numberOfPointers = 0
private var velocityTracker: VelocityTracker? = null
private var downEvent: MotionEvent? = null
private var numberOfPointers = 0
private var minimumFlingVelocity = 0
private var maximumFlingVelocity = 0

View file

@ -47,7 +47,7 @@ class DefaultIconFilter(
override fun queryIcons(pack: ITypeface, query: String?): List<IIcon> {
val icons = pack.icons
if (query == null || query.isBlank()) {
if (query.isNullOrBlank()) {
// No search query, return all icons.
return icons.map { key -> pack.getIcon(key) }
}

View file

@ -1,12 +0,0 @@
package io.homeassistant.companion.android.util.recyclerview
import android.annotation.SuppressLint
import androidx.recyclerview.widget.DiffUtil
class GenericMapperDiffCallback<T>(private val mapper: (T) -> Any?) : DiffUtil.ItemCallback<T>() {
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean = mapper(oldItem) == mapper(newItem)
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean = oldItem == newItem
}

View file

@ -22,7 +22,7 @@ abstract class BaseVehicleScreen(
get() = car?.let {
(
it.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) as CarUxRestrictionsManager
).getCurrentCarUxRestrictions().isRequiresDistractionOptimization()
).currentCarUxRestrictions.isRequiresDistractionOptimization
} ?: false
init {
@ -50,7 +50,7 @@ abstract class BaseVehicleScreen(
car?.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) as CarUxRestrictionsManager
val listener =
CarUxRestrictionsManager.OnUxRestrictionsChangedListener { restrictions ->
onDrivingOptimizedChanged(restrictions.isRequiresDistractionOptimization())
onDrivingOptimizedChanged(restrictions.isRequiresDistractionOptimization)
}
carRestrictionManager?.registerListener(listener)
}

View file

@ -1,6 +1,5 @@
package io.homeassistant.companion.android.vehicle
import android.util.Log
import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.model.Action
@ -12,7 +11,6 @@ import io.homeassistant.companion.android.common.R
class SwitchToDrivingOptimizedScreen(carContext: CarContext) : Screen(carContext) {
override fun onGetTemplate(): Template {
Log.i(TAG, "onGetTemplate")
return MessageTemplate.Builder(carContext.getString(R.string.aa_driving_optimized_change))
.setIcon(CarIcon.APP_ICON)
.addAction(

View file

@ -143,7 +143,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private val ioScope: CoroutineScope = CoroutineScope(Dispatchers.Main + Job())
private val requestPermissions =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
if (it.any { it.value }) {
if (it.any { result -> result.value }) {
webView.reload()
}
}
@ -385,7 +385,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
) {
Log.e(TAG, "onReceivedSslError: $error")
showError(
io.homeassistant.companion.android.webview.WebView.ErrorType.SSL,
ErrorType.SSL,
error,
null
)
@ -819,7 +819,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private suspend fun checkAndWarnForDisabledLocation() {
var showLocationDisabledWarning = false
var settingsWithLocationPermissions = mutableListOf<String>()
val settingsWithLocationPermissions = mutableListOf<String>()
if (!DisabledLocationHandler.isLocationEnabled(this) && presenter.isSsidUsed()) {
showLocationDisabledWarning = true
settingsWithLocationPermissions.add(getString(commonR.string.pref_connection_wifi))
@ -827,7 +827,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
for (manager in SensorReceiver.MANAGERS) {
for (basicSensor in manager.getAvailableSensors(this)) {
if (manager.isEnabled(this, basicSensor)) {
var permissions = manager.requiredPermissions(basicSensor.id)
val permissions = manager.requiredPermissions(basicSensor.id)
val fineLocation = DisabledLocationHandler.containsLocationPermission(permissions, true)
val coarseLocation = DisabledLocationHandler.containsLocationPermission(permissions, false)
@ -882,7 +882,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoPlayer?.prepare()
exoMute = !exoMute
exoToggleMute()
exoPlayerView.setPlayer(exoPlayer)
exoPlayerView.player = exoPlayer
exoPlayerView.visibility = View.VISIBLE
findViewById<ImageView>(R.id.exo_fullscreen_icon).setOnClickListener {
@ -916,11 +916,11 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoLeft = (rect.getInt("left") * displayMetrics.density).toInt()
exoTop = (rect.getInt("top") * displayMetrics.density).toInt()
exoRight = (rect.getInt("right") * displayMetrics.density).toInt()
if ((exoPlayer == null) || (exoPlayer!!.videoFormat == null)) {
exoBottom = if ((exoPlayer == null) || (exoPlayer!!.videoFormat == null)) {
// only set exoBottom if we can't calculate it from the video
exoBottom = (rect.getInt("bottom") * displayMetrics.density).toInt()
(rect.getInt("bottom") * displayMetrics.density).toInt()
} else {
exoBottom = exoTop + (exoRight - exoLeft) * exoPlayer!!.videoFormat!!.height /
exoTop + (exoRight - exoLeft) * exoPlayer!!.videoFormat!!.height /
exoPlayer!!.videoFormat!!.width
}
runOnUiThread {
@ -928,7 +928,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
}
}
fun exoToggleMute() {
private fun exoToggleMute() {
exoMute = !exoMute
if (exoMute) {
exoPlayer?.volume = 0f
@ -1152,12 +1152,12 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
if (statusBarColor != 0) {
window.statusBarColor = statusBarColor
} else {
Log.e(TAG, "Cannot set status bar color $statusBarColor. Skipping coloring...")
Log.e(TAG, "Cannot set status bar color. Skipping coloring...")
}
if (navigationBarColor != 0) {
window.navigationBarColor = navigationBarColor
} else {
Log.e(TAG, "Cannot set navigation bar color $navigationBarColor. Skipping coloring...")
Log.e(TAG, "Cannot set navigation bar color. Skipping coloring...")
}
// Set foreground colors
@ -1281,7 +1281,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
alert.setMessage(commonR.string.security_vulnerably_message)
alert.setPositiveButton(commonR.string.security_vulnerably_view) { _, _ ->
val intent = Intent(Intent.ACTION_VIEW)
intent.setData(Uri.parse("https://www.home-assistant.io/latest-security-alert/"))
intent.data = Uri.parse("https://www.home-assistant.io/latest-security-alert/")
startActivity(intent)
}
alert.setNegativeButton(commonR.string.security_vulnerably_understand) { _, _ ->
@ -1505,7 +1505,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private fun enablePinchToZoom() {
// Enable pinch to zoom
webView.getSettings().setBuiltInZoomControls(presenter.isPinchToZoomEnabled())
webView.settings.builtInZoomControls = presenter.isPinchToZoomEnabled()
// Use idea from https://github.com/home-assistant/iOS/pull/1472 to filter viewport
val pinchToZoom = if (presenter.isPinchToZoomEnabled()) "true" else "false"
webView.evaluateJavascript(

View file

@ -317,9 +317,9 @@ class WebViewPresenterImpl @Inject constructor(
val m: Matcher = c.matcher(colorString)
return if (m.matches()) {
Color.rgb(
m.group(1).toInt(),
m.group(2).toInt(),
m.group(3).toInt()
m.group(1)!!.toInt(),
m.group(2)!!.toInt(),
m.group(3)!!.toInt()
)
} else {
Color.parseColor(colorString)

View file

@ -48,7 +48,7 @@ import io.homeassistant.companion.android.common.R as commonR
class ButtonWidget : AppWidgetProvider() {
companion object {
private const val TAG = "ButtonWidget"
public const val CALL_SERVICE =
const val CALL_SERVICE =
"io.homeassistant.companion.android.widgets.button.ButtonWidget.CALL_SERVICE"
private const val CALL_SERVICE_AUTH =
"io.homeassistant.companion.android.widgets.button.ButtonWidget.CALL_SERVICE_AUTH"

View file

@ -13,7 +13,6 @@ import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
@ -24,6 +23,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.core.graphics.toColorInt
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
@ -215,7 +215,6 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {
}
val buttonWidget = buttonWidgetDao.get(appWidgetId)
var serviceText = ""
val backgroundTypeValues = mutableListOf(
getString(commonR.string.widget_background_type_daynight),
@ -227,7 +226,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {
binding.backgroundType.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, backgroundTypeValues)
if (buttonWidget != null) {
serviceText = "${buttonWidget.domain}.${buttonWidget.service}"
val serviceText = "${buttonWidget.domain}.${buttonWidget.service}"
binding.widgetTextConfigService.setText(serviceText)
binding.label.setText(buttonWidget.label)
@ -241,7 +240,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {
backgroundTypeValues.indexOf(getString(commonR.string.widget_background_type_daynight))
}
)
binding.textColor.visibility = if (buttonWidget.backgroundType == WidgetBackgroundType.TRANSPARENT) View.VISIBLE else View.GONE
binding.textColor.isVisible = buttonWidget.backgroundType == WidgetBackgroundType.TRANSPARENT
binding.textColorWhite.isChecked =
buttonWidget.textColor?.let { it.toColorInt() == ContextCompat.getColor(this, android.R.color.white) } ?: true
binding.textColorBlack.isChecked =
@ -256,7 +255,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {
setupServerSelect(buttonWidget?.serverId)
serviceAdapter = SingleItemArrayAdapter<Service>(this) {
serviceAdapter = SingleItemArrayAdapter(this) {
if (it != null) getServiceString(it) else ""
}
binding.widgetTextConfigService.setAdapter(serviceAdapter)
@ -274,7 +273,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {
// Custom components can cause services to not load
// Display error text
Log.e(TAG, "Unable to load services from Home Assistant", e)
if (server.id == selectedServerId) binding.widgetConfigServiceError.visibility = VISIBLE
if (server.id == selectedServerId) binding.widgetConfigServiceError.visibility = View.VISIBLE
}
}
lifecycleScope.launch {
@ -295,16 +294,11 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {
binding.backgroundType.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
binding.textColor.visibility =
if (parent?.adapter?.getItem(position) == getString(commonR.string.widget_background_type_transparent)) {
View.VISIBLE
} else {
View.GONE
}
binding.textColor.isVisible = parent?.adapter?.getItem(position) == getString(commonR.string.widget_background_type_transparent)
}
override fun onNothingSelected(parent: AdapterView<*>?) {
binding.textColor.visibility = View.GONE
binding.textColor.isVisible = false
}
}

View file

@ -21,11 +21,14 @@ class WidgetDynamicFieldAdapter(
private val serviceFieldList: ArrayList<ServiceFieldBinder>
) : RecyclerView.Adapter<WidgetDynamicFieldAdapter.ViewHolder>() {
companion object {
private const val TAG = "WidgetField"
}
class ViewHolder(
val binding: WidgetButtonConfigureDynamicFieldBinding
) : RecyclerView.ViewHolder(binding.root)
private val TAG = "WidgetField"
private val dropDownOnFocus = View.OnFocusChangeListener { view, hasFocus ->
if (hasFocus && view is AutoCompleteTextView) {
view.showDropDown()
@ -179,7 +182,7 @@ class WidgetDynamicFieldAdapter(
this.split(",").forEach { subString ->
// Ignore whitespace
if (!subString.isBlank()) {
if (subString.isNotBlank()) {
subString.trim().toJsonType()?.let { jsonArray.add(it) }
}
}

View file

@ -255,7 +255,7 @@ class EntityWidgetConfigureActivity : BaseWidgetConfigureActivity() {
}
private val entityDropDownOnItemClick =
AdapterView.OnItemClickListener { parent, view, position, id ->
AdapterView.OnItemClickListener { parent, _, position, _ ->
selectedEntity = parent.getItemAtPosition(position) as Entity<Any>?
setupAttributes()
}
@ -326,7 +326,7 @@ class EntityWidgetConfigureActivity : BaseWidgetConfigureActivity() {
)
if (appendAttributes) {
val attributes = if (selectedAttributeIds.isNullOrEmpty()) {
val attributes = if (selectedAttributeIds.isEmpty()) {
binding.widgetTextConfigAttribute.text.toString()
} else {
selectedAttributeIds

View file

@ -469,10 +469,10 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
val serverId = if (extras.containsKey(EXTRA_SERVER_ID)) extras.getInt(EXTRA_SERVER_ID) else null
val entitySelection: String? = extras.getString(EXTRA_ENTITY_ID)
val labelSelection: String? = extras.getString(EXTRA_LABEL)
val showSkip: Boolean? = extras.getBoolean(EXTRA_SHOW_SKIP)
val showSeek: Boolean? = extras.getBoolean(EXTRA_SHOW_SEEK)
val showVolume: Boolean? = extras.getBoolean(EXTRA_SHOW_VOLUME)
val showSource: Boolean? = extras.getBoolean(EXTRA_SHOW_SOURCE)
val showSkip: Boolean = extras.getBoolean(EXTRA_SHOW_SKIP)
val showSeek: Boolean = extras.getBoolean(EXTRA_SHOW_SEEK)
val showVolume: Boolean = extras.getBoolean(EXTRA_SHOW_VOLUME)
val showSource: Boolean = extras.getBoolean(EXTRA_SHOW_SOURCE)
val backgroundType: WidgetBackgroundType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
extras.getSerializable(EXTRA_BACKGROUND_TYPE, WidgetBackgroundType::class.java)
} else {
@ -480,7 +480,7 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
extras.getSerializable(EXTRA_BACKGROUND_TYPE) as? WidgetBackgroundType
} ?: WidgetBackgroundType.DAYNIGHT
if (serverId == null || entitySelection == null || showSkip == null || showSeek == null || showVolume == null || showSource == null) {
if (serverId == null || entitySelection == null) {
Log.e(TAG, "Did not receive complete configuration data")
return
}

View file

@ -127,9 +127,7 @@ class TemplateWidgetConfigureActivity : BaseWidgetConfigureActivity() {
binding.backgroundType.setSelection(0)
}
binding.templateText.doAfterTextChanged { editableText ->
renderTemplateText()
}
binding.templateText.doAfterTextChanged { renderTemplateText() }
binding.backgroundType.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {

View file

@ -24,9 +24,9 @@ class CookieJarCookieManagerShim : CookieJar {
override fun loadForRequest(url: HttpUrl): List<Cookie> {
val cookies: String = CookieManager.getInstance()
?.getCookie(url.toString()) ?: return emptyList()
return cookies.split("; ").map {
return cookies.split("; ").mapNotNull {
Cookie.parse(url, it)
}.filterNotNull()
}
}
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {

View file

@ -22,8 +22,8 @@ class HomeAssistantApis @Inject constructor(
const val USER_AGENT = "User-Agent"
val USER_AGENT_STRING = "Home Assistant/${BuildConfig.VERSION_NAME} (Android ${Build.VERSION.RELEASE}; ${Build.MODEL})"
private val CALL_TIMEOUT = 30L
private val READ_TIMEOUT = 30L
private const val CALL_TIMEOUT = 30L
private const val READ_TIMEOUT = 30L
}
private fun configureOkHttpClient(builder: OkHttpClient.Builder): OkHttpClient.Builder {
if (BuildConfig.DEBUG) {

View file

@ -29,9 +29,6 @@ import io.homeassistant.companion.android.common.data.websocket.impl.entities.As
import io.homeassistant.companion.android.common.data.websocket.impl.entities.AssistPipelineEventType
import io.homeassistant.companion.android.common.data.websocket.impl.entities.AssistPipelineIntentEnd
import io.homeassistant.companion.android.common.data.websocket.impl.entities.GetConfigResponse
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flow
@ -72,8 +69,6 @@ class IntegrationRepositoryImpl @AssistedInject constructor(
private const val APPLOCK_TIMEOUT_GRACE_MS = 1000
}
private val ioScope = CoroutineScope(Dispatchers.IO + Job())
private val server get() = serverManager.getServer(serverId)!!
private val webSocketRepository get() = serverManager.webSocketRepository(serverId)

View file

@ -96,8 +96,8 @@ class PrefsRepositoryImpl @Inject constructor(
return localStorage.getString(PREF_LOCALES)
}
override suspend fun saveLocales(locales: String) {
localStorage.putString(PREF_LOCALES, locales)
override suspend fun saveLocales(lang: String) {
localStorage.putString(PREF_LOCALES, lang)
}
override suspend fun getScreenOrientation(): String? {

View file

@ -60,10 +60,11 @@ object DisabledLocationHandler {
}
fun showLocationDisabledWarnDialog(context: Context, settings: Array<String>, showAsNotification: Boolean = false, withDisableOption: Boolean = false, callback: (() -> Unit)? = null) {
var positionTextId = commonR.string.confirm_positive
var negativeTextId = commonR.string.confirm_negative
if (withDisableOption && callback != null) {
negativeTextId = commonR.string.location_disabled_option_disable
val positionTextId = commonR.string.confirm_positive
val negativeTextId = if (withDisableOption && callback != null) {
commonR.string.location_disabled_option_disable
} else {
commonR.string.confirm_negative
}
val intent = Intent(

View file

@ -102,12 +102,12 @@ fun cancelNotificationGroupIfNeeded(
false
}
} else {
if (isGroupSummary && groupNotifications.size != 1) {
if (isGroupSummary) {
Log.d(
TAG,
"Notification is the group summary, but the group has more than or no notifications inside (" + groupNotifications.size + "). Cancel notification"
)
} else if (!isGroupSummary && groupNotifications.size != 2) {
} else {
Log.d(
TAG,
"Notification is in a group, but the group has more/less than 2 notifications inside (" + groupNotifications.size + "). Cancel notification"

View file

@ -397,7 +397,6 @@ abstract class AppDatabase : RoomDatabase() {
override fun migrate(database: SupportSQLiteDatabase) {
val cursor = database.query("SELECT * FROM sensor_settings")
val sensorSettings = mutableListOf<ContentValues>()
var migrationSuccessful = false
var migrationFailed = false
try {
if (cursor.moveToFirst()) {
@ -406,7 +405,7 @@ abstract class AppDatabase : RoomDatabase() {
ContentValues().also {
val currentSensorId = cursor.getString(cursor.getColumnIndex("sensor_id"))
val currentSensorSettingName = cursor.getString(cursor.getColumnIndex("name"))
var entries: String = ""
var entries = ""
var newSensorSettingName = currentSensorSettingName
// Alarm
if (currentSensorId == "next_alarm" && currentSensorSettingName == "Allow List") {
@ -482,12 +481,11 @@ abstract class AppDatabase : RoomDatabase() {
} catch (e: Exception) {
migrationFailed = true
Log.e(TAG, "Unable to migrate, proceeding with recreating the table", e)
null
}
database.execSQL("DROP TABLE IF EXISTS `sensor_settings`")
database.execSQL("CREATE TABLE IF NOT EXISTS `sensor_settings` (`sensor_id` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, `value_type` TEXT NOT NULL DEFAULT 'string', `entries` TEXT NOT NULL, `enabled` INTEGER NOT NULL DEFAULT '1', PRIMARY KEY(`sensor_id`, `name`))")
sensorSettings?.forEach {
sensorSettings.forEach {
database.insert("sensor_settings", OnConflictStrategy.REPLACE, it)
}
if (migrationFailed) {

View file

@ -3,7 +3,7 @@ package io.homeassistant.companion.android.util
import android.content.Context
import io.homeassistant.companion.android.common.R
fun IntervalToString(context: Context, interval: Int): String {
fun intervalToString(context: Context, interval: Int): String {
return when {
interval == 0 -> context.getString(R.string.interval_manual)
interval >= 60 * 60 -> context.resources.getQuantityString(R.plurals.interval_hours, interval / 60 / 60, interval / 60 / 60)

View file

@ -28,7 +28,7 @@ import androidx.wear.compose.material.rememberPickerState
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.theme.wearColorPalette
import io.homeassistant.companion.android.util.IntervalToString
import io.homeassistant.companion.android.util.intervalToString
import io.homeassistant.companion.android.views.ListHeader
import kotlinx.coroutines.launch
import kotlin.math.sign
@ -72,7 +72,7 @@ fun RefreshIntervalPickerView(
.focusable()
) {
Text(
IntervalToString(LocalContext.current, options[it]),
intervalToString(LocalContext.current, options[it]),
fontSize = 24.sp,
color = if (it != this.selectedOption) wearColorPalette.onBackground else wearColorPalette.primary
)

View file

@ -21,7 +21,7 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria
import io.homeassistant.companion.android.common.R
import io.homeassistant.companion.android.theme.WearAppTheme
import io.homeassistant.companion.android.theme.wearColorPalette
import io.homeassistant.companion.android.util.IntervalToString
import io.homeassistant.companion.android.util.intervalToString
import io.homeassistant.companion.android.views.ListHeader
import io.homeassistant.companion.android.views.ThemeLazyColumn
@ -61,7 +61,7 @@ fun TemplateTileSettingsView(
text = stringResource(id = R.string.refresh_interval)
)
},
secondaryLabel = { Text(IntervalToString(LocalContext.current, refreshInterval)) },
secondaryLabel = { Text(intervalToString(LocalContext.current, refreshInterval)) },
onClick = onClickRefreshInterval
)
}

View file

@ -17,7 +17,7 @@ import io.homeassistant.companion.android.common.R as commonR
class MobileAppIntegrationActivity : AppCompatActivity(), MobileAppIntegrationView {
companion object {
private const val TAG = "MobileAppIntegrationActivity"
val EXTRA_SERVER = "server"
const val EXTRA_SERVER = "server"
fun newInstance(context: Context, serverId: Int): Intent {
return Intent(context, MobileAppIntegrationActivity::class.java).apply {