diff --git a/app/src/main/java/eu/darken/capod/common/AppForegroundState.kt b/app/src/main/java/eu/darken/capod/common/AppForegroundState.kt new file mode 100644 index 00000000..cb56b13a --- /dev/null +++ b/app/src/main/java/eu/darken/capod/common/AppForegroundState.kt @@ -0,0 +1,85 @@ +package eu.darken.capod.common + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.ProcessLifecycleOwner +import eu.darken.capod.common.coroutine.AppScope +import eu.darken.capod.common.coroutine.DispatcherProvider +import eu.darken.capod.common.debug.logging.Logging.Priority.WARN +import eu.darken.capod.common.debug.logging.asLog +import eu.darken.capod.common.debug.logging.log +import eu.darken.capod.common.debug.logging.logTag +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AppForegroundState @Inject constructor( + @AppScope appScope: CoroutineScope, + dispatcherProvider: DispatcherProvider, +) { + + val isForeground: StateFlow = callbackFlow { + val lifecycle = runCatching { ProcessLifecycleOwner.get().lifecycle } + .getOrElse { + log(TAG, WARN) { "Failed to access process lifecycle, assuming background: ${it.asLog()}" } + trySend(false) + close() + return@callbackFlow + } + + trySend(safeCurrentForegroundState()) + + val observer = LifecycleEventObserver { _, event -> + when (event) { + Lifecycle.Event.ON_START -> trySend(true) + Lifecycle.Event.ON_STOP -> trySend(false) + else -> Unit + } + } + + runCatching { lifecycle.addObserver(observer) } + .onFailure { + log(TAG, WARN) { "Failed to observe process lifecycle, assuming background: ${it.asLog()}" } + trySend(false) + close() + } + + awaitClose { + runCatching { lifecycle.removeObserver(observer) } + .onFailure { log(TAG, WARN) { "Failed to remove process lifecycle observer: ${it.asLog()}" } } + } + } + .flowOn(dispatcherProvider.MainImmediate) + .catch { + log(TAG, WARN) { "Foreground state flow failed, assuming background: ${it.asLog()}" } + emit(false) + } + .distinctUntilChanged() + .onEach { log(TAG) { "isForeground=$it" } } + .stateIn( + scope = appScope, + started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5_000L), + initialValue = safeCurrentForegroundState(), + ) + + private fun safeCurrentForegroundState(): Boolean = runCatching { + ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) + }.getOrElse { + log(TAG, WARN) { "Failed to read process lifecycle state, assuming background: ${it.asLog()}" } + false + } + + companion object { + private val TAG = logTag("App", "ForegroundState") + } +} diff --git a/app/src/main/java/eu/darken/capod/common/bluetooth/BluetoothManager2.kt b/app/src/main/java/eu/darken/capod/common/bluetooth/BluetoothManager2.kt index 0bb4226b..4828aed6 100644 --- a/app/src/main/java/eu/darken/capod/common/bluetooth/BluetoothManager2.kt +++ b/app/src/main/java/eu/darken/capod/common/bluetooth/BluetoothManager2.kt @@ -318,6 +318,74 @@ class BluetoothManager2 @Inject constructor( emit(wrappedDevices) } + @android.annotation.SuppressLint("MissingPermission") + private fun queryBondedAddresses(): Set = + adapter?.bondedDevices?.map { it.address }?.toSet() ?: emptySet() + + val bondedDeviceAddresses: Flow> = callbackFlow { + fun sendBondedAddresses(): Boolean = try { + trySend(queryBondedAddresses()) + true + } catch (e: Exception) { + log(TAG, WARN) { "Error querying bonded device addresses: $e" } + trySend(emptySet()) + close(e) + false + } + + if (!sendBondedAddresses()) return@callbackFlow + + val receiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action != BluetoothDevice.ACTION_BOND_STATE_CHANGED) return + sendBondedAddresses() + } + } + try { + context.registerReceiver(receiver, IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) + } catch (e: Exception) { + log(TAG, ERROR) { "Failed to register bond-state receiver: $e" } + close(e) + return@callbackFlow + } + + awaitClose { + try { + context.unregisterReceiver(receiver) + } catch (e: Exception) { + log(TAG, WARN) { "Error unregistering bond-state receiver: $e" } + } + } + } + .retryWhen { cause, attempt -> + log(TAG, WARN) { "bondedDeviceAddresses Flow failed (attempt ${attempt + 1}): $cause" } + when { + cause is SecurityException -> { + delay(3_000L) + true + } + attempt < 3 -> { + delay(1000 * (attempt + 1)) + true + } + else -> false + } + } + .catch { e -> + log(TAG, ERROR) { "bondedDeviceAddresses Flow failed after retries: $e" } + emit(emptySet()) + } + .distinctUntilChanged() + .setupCommonEventHandlers(TAG) { "bondedDeviceAddresses" } + .stateIn( + scope = appScope + dispatcherProvider.IO, + started = SharingStarted.WhileSubscribed( + stopTimeoutMillis = 5_000L, + replayExpirationMillis = 0L, + ), + initialValue = emptySet(), + ) + private var _isNudgeAvailable: Boolean = true val isNudgeAvailable: Boolean get() = _isNudgeAvailable diff --git a/app/src/main/java/eu/darken/capod/common/bluetooth/ScannerMode.kt b/app/src/main/java/eu/darken/capod/common/bluetooth/ScannerMode.kt index 816e9b67..4856a4fb 100644 --- a/app/src/main/java/eu/darken/capod/common/bluetooth/ScannerMode.kt +++ b/app/src/main/java/eu/darken/capod/common/bluetooth/ScannerMode.kt @@ -1,25 +1,11 @@ package eu.darken.capod.common.bluetooth -import androidx.annotation.StringRes -import eu.darken.capod.R import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -enum class ScannerMode( - val identifier: String, - @StringRes val labelRes: Int -) { - @SerialName("scanner.mode.lowpower") LOW_POWER( - "scanner.mode.lowpower", - R.string.settings_scanner_mode_lowpower_label - ), - @SerialName("scanner.mode.balanced") BALANCED( - "scanner.mode.balanced", - R.string.settings_scanner_mode_balanced_label - ), - @SerialName("scanner.mode.lowlatency") LOW_LATENCY( - "scanner.mode.lowlatency", - R.string.settings_scanner_mode_lowlatency_label - ), -} \ No newline at end of file +enum class ScannerMode { + @SerialName("scanner.mode.lowpower") LOW_POWER, + @SerialName("scanner.mode.balanced") BALANCED, + @SerialName("scanner.mode.lowlatency") LOW_LATENCY, +} diff --git a/app/src/main/java/eu/darken/capod/main/core/GeneralSettings.kt b/app/src/main/java/eu/darken/capod/main/core/GeneralSettings.kt index 6325930b..e5227c27 100644 --- a/app/src/main/java/eu/darken/capod/main/core/GeneralSettings.kt +++ b/app/src/main/java/eu/darken/capod/main/core/GeneralSettings.kt @@ -9,7 +9,6 @@ import androidx.datastore.preferences.preferencesDataStore import dagger.hilt.android.qualifiers.ApplicationContext import eu.darken.capod.common.BuildConfigWrap import eu.darken.capod.common.bluetooth.BluetoothAddress -import eu.darken.capod.common.bluetooth.ScannerMode import eu.darken.capod.common.datastore.createValue import eu.darken.capod.common.serialization.ByteArrayBase64Serializer import eu.darken.capod.common.serialization.SerializationCapod @@ -44,8 +43,6 @@ class GeneralSettings @Inject constructor( val keepConnectedNotificationAfterDisconnect = dataStore.createValue("core.monitor.notification.connected.keepafterdisconnected", false) - val scannerMode = dataStore.createValue("core.scanner.mode", ScannerMode.BALANCED, json, onErrorFallbackToDefault = true) - val oldMinimumSignalQuality = dataStore.createValue("core.signal.minimum", 0.20f) val oldMainDeviceAddress = dataStore.createValue( diff --git a/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt b/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt index 8d0dc0c0..4b806c9c 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt @@ -19,7 +19,6 @@ import androidx.compose.material.icons.twotone.FilterList import androidx.compose.material.icons.automirrored.twotone.Message import androidx.compose.material.icons.twotone.Notifications import androidx.compose.material.icons.twotone.Palette -import androidx.compose.material.icons.twotone.SettingsBluetooth import androidx.compose.material.icons.automirrored.twotone.ViewList import androidx.compose.material3.AlertDialog import androidx.compose.material3.Icon @@ -45,7 +44,6 @@ import androidx.hilt.navigation.compose.hiltViewModel import eu.darken.capod.R import eu.darken.capod.common.compose.Preview2 import eu.darken.capod.common.compose.PreviewWrapper -import eu.darken.capod.common.bluetooth.ScannerMode import androidx.lifecycle.compose.collectAsStateWithLifecycle import eu.darken.capod.common.error.ErrorEventHandler import eu.darken.capod.common.navigation.NavigationEventHandler @@ -70,7 +68,6 @@ fun GeneralSettingsScreenHost(vm: GeneralSettingsViewModel = hiltViewModel()) { state = it, onNavigateUp = { vm.navUp() }, onMonitorModeSelected = { mode -> vm.setMonitorMode(mode) }, - onScannerModeSelected = { mode -> vm.setScannerMode(mode) }, onShowConnectedNotificationChanged = { enabled -> vm.setShowConnectedNotification(enabled) }, onKeepNotificationAfterDisconnectChanged = { enabled -> vm.setKeepNotificationAfterDisconnect(enabled) }, onDebugSettings = { vm.goToDebugSettings() }, @@ -90,7 +87,6 @@ fun GeneralSettingsScreen( state: GeneralSettingsViewModel.State, onNavigateUp: () -> Unit, onMonitorModeSelected: (MonitorMode) -> Unit, - onScannerModeSelected: (ScannerMode) -> Unit, onShowConnectedNotificationChanged: (Boolean) -> Unit, onKeepNotificationAfterDisconnectChanged: (Boolean) -> Unit, onDebugSettings: () -> Unit, @@ -104,7 +100,6 @@ fun GeneralSettingsScreen( modifier: Modifier = Modifier, ) { var showMonitorModeDialog by remember { mutableStateOf(false) } - var showScannerModeDialog by remember { mutableStateOf(false) } var showColorDialog by remember { mutableStateOf(false) } val isMaterialYouActive = state.themeState.style == ThemeStyle.MATERIAL_YOU && @@ -138,14 +133,6 @@ fun GeneralSettingsScreen( onClick = { showMonitorModeDialog = true }, ) } - item { - SettingsBaseItem( - title = stringResource(R.string.settings_scanner_mode_label), - subtitle = stringResource(state.scannerMode.labelRes), - icon = Icons.TwoTone.SettingsBluetooth, - onClick = { showScannerModeDialog = true }, - ) - } item { SettingsCategoryHeader(text = stringResource(R.string.settings_category_appearance_label)) } @@ -313,20 +300,6 @@ fun GeneralSettingsScreen( ) } - if (showScannerModeDialog) { - ListPreferenceDialog( - title = stringResource(R.string.settings_scanner_mode_label), - entries = ScannerMode.entries, - selectedEntry = state.scannerMode, - onEntrySelected = { - onScannerModeSelected(it) - showScannerModeDialog = false - }, - entryLabel = { stringResource(it.labelRes) }, - onDismiss = { showScannerModeDialog = false }, - ) - } - if (showColorDialog) { ThemeColorSelectorDialog( selectedColor = state.themeState.color, @@ -342,7 +315,6 @@ fun GeneralSettingsScreen( private fun previewGeneralState(isPro: Boolean) = GeneralSettingsViewModel.State( isPro = isPro, monitorMode = MonitorMode.AUTOMATIC, - scannerMode = ScannerMode.BALANCED, showConnectedNotification = true, keepNotificationAfterDisconnect = false, isOffloadedFilteringDisabled = false, @@ -358,7 +330,6 @@ private fun GeneralSettingsScreenProPreview() = PreviewWrapper { state = previewGeneralState(isPro = true), onNavigateUp = {}, onMonitorModeSelected = {}, - onScannerModeSelected = {}, onShowConnectedNotificationChanged = {}, onKeepNotificationAfterDisconnectChanged = {}, onDebugSettings = {}, @@ -375,7 +346,6 @@ private fun GeneralSettingsScreenNonProPreview() = PreviewWrapper { state = previewGeneralState(isPro = false), onNavigateUp = {}, onMonitorModeSelected = {}, - onScannerModeSelected = {}, onShowConnectedNotificationChanged = {}, onKeepNotificationAfterDisconnectChanged = {}, onDebugSettings = {}, diff --git a/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsViewModel.kt b/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsViewModel.kt index 43ce8443..1d2560ea 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsViewModel.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsViewModel.kt @@ -1,7 +1,6 @@ package eu.darken.capod.main.ui.settings.general import dagger.hilt.android.lifecycle.HiltViewModel -import eu.darken.capod.common.bluetooth.ScannerMode import eu.darken.capod.common.coroutine.DispatcherProvider import eu.darken.capod.common.debug.logging.Logging.Priority.INFO import eu.darken.capod.common.debug.logging.log @@ -32,7 +31,6 @@ class GeneralSettingsViewModel @Inject constructor( data class State( val isPro: Boolean, val monitorMode: MonitorMode, - val scannerMode: ScannerMode, val showConnectedNotification: Boolean, val keepNotificationAfterDisconnect: Boolean, val isOffloadedFilteringDisabled: Boolean, @@ -46,12 +44,11 @@ class GeneralSettingsViewModel @Inject constructor( val state = combine( combine( generalSettings.monitorMode.flow, - generalSettings.scannerMode.flow, generalSettings.useExtraMonitorNotification.flow, generalSettings.keepConnectedNotificationAfterDisconnect.flow, - ) { monitorMode, scannerMode, showNotif, keepNotif -> + ) { monitorMode, showNotif, keepNotif -> @Suppress("USELESS_CAST") - arrayOf(monitorMode as Any, scannerMode as Any, showNotif as Any, keepNotif as Any) + arrayOf(monitorMode as Any, showNotif as Any, keepNotif as Any) }, combine( generalSettings.isOffloadedFilteringDisabled.flow, @@ -67,9 +64,8 @@ class GeneralSettingsViewModel @Inject constructor( State( isPro = isPro, monitorMode = general[0] as MonitorMode, - scannerMode = general[1] as ScannerMode, - showConnectedNotification = general[2] as Boolean, - keepNotificationAfterDisconnect = general[3] as Boolean, + showConnectedNotification = general[1] as Boolean, + keepNotificationAfterDisconnect = general[2] as Boolean, isOffloadedFilteringDisabled = compat[0] as Boolean, isOffloadedBatchingDisabled = compat[1] as Boolean, useIndirectScanResultCallback = compat[2] as Boolean, @@ -82,11 +78,6 @@ class GeneralSettingsViewModel @Inject constructor( generalSettings.monitorMode.valueBlocking = mode } - fun setScannerMode(mode: ScannerMode) { - log(TAG, INFO) { "setScannerMode($mode)" } - generalSettings.scannerMode.valueBlocking = mode - } - fun setShowConnectedNotification(enabled: Boolean) { log(TAG, INFO) { "setShowConnectedNotification($enabled)" } generalSettings.useExtraMonitorNotification.valueBlocking = enabled diff --git a/app/src/main/java/eu/darken/capod/monitor/core/ble/BlePodMonitor.kt b/app/src/main/java/eu/darken/capod/monitor/core/ble/BlePodMonitor.kt index 88f16e4d..285a5e5a 100644 --- a/app/src/main/java/eu/darken/capod/monitor/core/ble/BlePodMonitor.kt +++ b/app/src/main/java/eu/darken/capod/monitor/core/ble/BlePodMonitor.kt @@ -45,6 +45,7 @@ import javax.inject.Singleton class BlePodMonitor @Inject constructor( @AppScope private val appScope: CoroutineScope, private val bleScanner: BleScanner, + private val bleScanModeController: BleScanModeController, private val podFactory: PodFactory, private val timeSource: TimeSource, private val generalSettings: GeneralSettings, @@ -128,7 +129,7 @@ class BlePodMonitor @Inject constructor( ) private fun createBleScanner() = combine( - generalSettings.scannerMode.flow, + bleScanModeController.scannerMode, debugSettings.showUnfiltered.flow, generalSettings.isOffloadedBatchingDisabled.flow, generalSettings.isOffloadedFilteringDisabled.flow, diff --git a/app/src/main/java/eu/darken/capod/monitor/core/ble/BleScanModeController.kt b/app/src/main/java/eu/darken/capod/monitor/core/ble/BleScanModeController.kt new file mode 100644 index 00000000..4083d832 --- /dev/null +++ b/app/src/main/java/eu/darken/capod/monitor/core/ble/BleScanModeController.kt @@ -0,0 +1,114 @@ +package eu.darken.capod.monitor.core.ble + +import eu.darken.capod.common.AppForegroundState +import eu.darken.capod.common.bluetooth.BluetoothAddress +import eu.darken.capod.common.bluetooth.BluetoothManager2 +import eu.darken.capod.common.bluetooth.ScannerMode +import eu.darken.capod.common.coroutine.AppScope +import eu.darken.capod.common.debug.logging.Logging +import eu.darken.capod.common.debug.logging.log +import eu.darken.capod.common.debug.logging.logTag +import eu.darken.capod.common.flow.replayingShare +import eu.darken.capod.common.flow.setupCommonEventHandlers +import eu.darken.capod.profiles.core.DeviceProfilesRepo +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.update +import java.util.Locale +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class BleScanModeController @Inject constructor( + @AppScope appScope: CoroutineScope, + appForegroundState: AppForegroundState, + profilesRepo: DeviceProfilesRepo, + bluetoothManager: BluetoothManager2, +) { + + private val overrideCounts = MutableStateFlow>(emptyMap()) + private val activeOverride: Flow = overrideCounts.map { it.topPriority() } + + val scannerMode: Flow = combine( + activeOverride, + appForegroundState.isForeground, + profilesRepo.profiles, + bluetoothManager.connectedDevices + .onStart { emit(emptyList()) } + .catch { + log(TAG, Logging.Priority.WARN) { "connectedDevices failed, treating as empty: $it" } + emit(emptyList()) + }, + bluetoothManager.bondedDeviceAddresses, + ) { override, isForeground, profiles, connectedDevices, bondedAddresses -> + resolveScannerMode( + overrideMode = override, + isForeground = isForeground, + profileAddresses = profiles.mapNotNull { it.address }.toSet(), + bondedAddresses = bondedAddresses, + connectedAddresses = connectedDevices.map { it.address }.toSet(), + ) + } + .distinctUntilChanged() + .onEach { log(TAG) { "Effective scanner mode: $it" } } + .setupCommonEventHandlers(TAG) { "scannerMode" } + .replayingShare(appScope) + + suspend fun withTemporaryOverride(mode: ScannerMode, block: suspend () -> T): T { + log(TAG) { "withTemporaryOverride($mode) acquire" } + overrideCounts.update { it.adjust(mode, +1) } + try { + return block() + } finally { + overrideCounts.update { it.adjust(mode, -1) } + log(TAG) { "withTemporaryOverride($mode) release" } + } + } + + private fun Map.adjust(mode: ScannerMode, delta: Int): Map { + val current = this[mode] ?: 0 + val next = current + delta + return when { + next <= 0 -> this - mode + else -> this + (mode to next) + } + } + + private fun Map.topPriority(): ScannerMode? = OVERRIDE_PRIORITY.firstOrNull { containsKey(it) } + + companion object { + private val TAG = logTag("Bluetooth", "ScannerMode") + private val OVERRIDE_PRIORITY = listOf(ScannerMode.LOW_LATENCY, ScannerMode.BALANCED, ScannerMode.LOW_POWER) + } +} + +internal fun resolveScannerMode( + overrideMode: ScannerMode?, + isForeground: Boolean, + profileAddresses: Set, + bondedAddresses: Set, + connectedAddresses: Set, +): ScannerMode { + if (overrideMode != null) return overrideMode + + val connectedProfileAddresses = profileAddresses.normalized() + .intersect(bondedAddresses.normalized()) + .intersect(connectedAddresses.normalized()) + + return when { + connectedProfileAddresses.isNotEmpty() -> ScannerMode.LOW_LATENCY + isForeground -> ScannerMode.BALANCED + else -> ScannerMode.LOW_POWER + } +} + +private fun Iterable.normalized(): Set = this + .map { it.uppercase(Locale.US) } + .toSet() diff --git a/app/src/main/java/eu/darken/capod/troubleshooter/ui/TroubleShooterViewModel.kt b/app/src/main/java/eu/darken/capod/troubleshooter/ui/TroubleShooterViewModel.kt index 82e58ad0..527e60b2 100644 --- a/app/src/main/java/eu/darken/capod/troubleshooter/ui/TroubleShooterViewModel.kt +++ b/app/src/main/java/eu/darken/capod/troubleshooter/ui/TroubleShooterViewModel.kt @@ -16,6 +16,7 @@ import eu.darken.capod.common.uix.ViewModel4 import eu.darken.capod.main.core.GeneralSettings import eu.darken.capod.monitor.core.DeviceMonitor import eu.darken.capod.monitor.core.ble.BlePodMonitor +import eu.darken.capod.monitor.core.ble.BleScanModeController import eu.darken.capod.monitor.core.primaryDevice import eu.darken.capod.pods.core.apple.ble.BlePodSnapshot import eu.darken.capod.pods.core.unknown.UnknownSnapshotBle @@ -40,6 +41,7 @@ class TroubleShooterViewModel @Inject constructor( private val generalSettings: GeneralSettings, private val profilesRepo: DeviceProfilesRepo, private val blePodMonitor: BlePodMonitor, + private val bleScanModeController: BleScanModeController, private val deviceMonitor: DeviceMonitor, private val debugSettings: DebugSettings, private val timeSource: TimeSource, @@ -84,39 +86,119 @@ class TroubleShooterViewModel @Inject constructor( fun troubleShootBle() = launch(context = dispatcherProvider.IO) { log(TAG, INFO) { "troubleShootBle()" } - generalSettings.scannerMode.valueBlocking = ScannerMode.LOW_LATENCY - - run { - progress("Checking for headphones...") - val mainDevice = withTimeoutOrNull(STEP_TIME) { - deviceMonitor.primaryDevice().filterNotNull().firstOrNull() + bleScanModeController.withTemporaryOverride(ScannerMode.LOW_LATENCY) override@{ + run { + progress("Checking for headphones...") + val mainDevice = withTimeoutOrNull(STEP_TIME) { + deviceMonitor.primaryDevice().filterNotNull().firstOrNull() + } + if (mainDevice != null) { + success("Headphones found, nothing to troubleshoot.") + return@override + } else { + progress("Headphones not detected.\n") + } } - if (mainDevice != null) { - success("Headphones found, nothing to troubleshoot.") - return@launch - } else { - progress("Headphones not detected.\n") + + val doScan: suspend (Boolean, Boolean, Boolean, Boolean) -> Collection = + { hardwareFilteringDisabled, + hardwareBatchingDisabled, + indirectCallback, + unfiltered -> + val sb = StringBuilder("SCAN - Settings: ") + sb.append("hardwareFilteringDisabled=$hardwareFilteringDisabled, ") + sb.append("hardwareBatchingDisabled=$hardwareBatchingDisabled, ") + sb.append("indirectCallback=$indirectCallback, ") + sb.append("unfiltered=$unfiltered") + progress(sb.toString()) + generalSettings.isOffloadedFilteringDisabled.valueBlocking = hardwareFilteringDisabled + generalSettings.isOffloadedBatchingDisabled.valueBlocking = hardwareBatchingDisabled + generalSettings.useIndirectScanResultCallback.valueBlocking = indirectCallback + debugSettings.showUnfiltered.valueBlocking = unfiltered + + val start = timeSource.elapsedRealtime() + val devices = withTimeoutOrNull(STEP_TIME) { + blePodMonitor.devices + .take(10) + .takeWhile { timeSource.elapsedRealtime() - start < STEP_TIME - 1000 } + .toList() + .flatten() + .distinctBy { it.address } + } ?: emptyList() + log(TAG) { "SCAN: BLE Devices: $devices" } + if (devices.isNotEmpty()) { + progress("SCAN: Received data from ${devices.size} BLE devices") + devices + } else { + progress("SCAN: No data received") + devices + } + } + + run { + progress("Checking if we can receive BLE data at all.") + if (doScan(false, false, false, true).isNotEmpty()) return@run + if (doScan(false, false, true, true).isNotEmpty()) return@run + if (doScan(true, true, true, true).isNotEmpty()) return@run + if (doScan(true, true, false, true).isNotEmpty()) return@run + if (doScan(true, false, true, true).isNotEmpty()) return@run + if (doScan(true, false, false, true).isNotEmpty()) return@run + if (doScan(false, true, true, true).isNotEmpty()) return@run + if (doScan(false, true, false, true).isNotEmpty()) return@run + + failure("Phone is not receiving BLE data.", BleState.Result.Failure.Type.PHONE) + + generalSettings.isOffloadedFilteringDisabled.valueBlocking = false + generalSettings.isOffloadedBatchingDisabled.valueBlocking = false + generalSettings.useIndirectScanResultCallback.valueBlocking = false + debugSettings.showUnfiltered.valueBlocking = false + + return@override } - } - val doScan: suspend (Boolean, Boolean, Boolean, Boolean) -> Collection = - { hardwareFilteringDisabled, - hardwareBatchingDisabled, - indirectCallback, - unfiltered -> - val sb = StringBuilder("SCAN - Settings: ") - sb.append("hardwareFilteringDisabled=$hardwareFilteringDisabled, ") - sb.append("hardwareBatchingDisabled=$hardwareBatchingDisabled, ") - sb.append("indirectCallback=$indirectCallback, ") - sb.append("unfiltered=$unfiltered") - progress(sb.toString()) - generalSettings.isOffloadedFilteringDisabled.valueBlocking = hardwareFilteringDisabled - generalSettings.isOffloadedBatchingDisabled.valueBlocking = hardwareBatchingDisabled - generalSettings.useIndirectScanResultCallback.valueBlocking = indirectCallback - debugSettings.showUnfiltered.valueBlocking = unfiltered + progress("We received at least some BLE data.\n") - val start = timeSource.elapsedRealtime() - val devices = withTimeoutOrNull(STEP_TIME) { + run { + progress("Checking for supported headphones.") + + if (doScan(false, false, false, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(false, false, true, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(true, true, true, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(true, true, false, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(true, false, true, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(true, false, false, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(false, true, true, false).any { it !is UnknownSnapshotBle }) return@run + if (doScan(false, true, false, false).any { it !is UnknownSnapshotBle }) return@run + + failure("No compatible headphones found", BleState.Result.Failure.Type.HEADPHONES) + + generalSettings.isOffloadedFilteringDisabled.valueBlocking = false + generalSettings.isOffloadedBatchingDisabled.valueBlocking = false + generalSettings.useIndirectScanResultCallback.valueBlocking = false + + return@override + } + + progress("Found some headphones that are supported by CAPod.\n") + + run { + progress("Checking for your headphones with new BLE settings...") + val mainDevice = withTimeoutOrNull(STEP_TIME) { + deviceMonitor.primaryDevice().filterNotNull().firstOrNull() + } + if (mainDevice != null) { + success("Found your headphones, new BLE settings worked :)!") + return@override + } + } + + progress("Still no headphones detected that count as yours.\n") + + run { + progress("Checking all closeby headphones.") + + val otherDevices = withTimeoutOrNull(STEP_TIME) { + val start = timeSource.elapsedRealtime() blePodMonitor.devices .take(10) .takeWhile { timeSource.elapsedRealtime() - start < STEP_TIME - 1000 } @@ -124,122 +206,40 @@ class TroubleShooterViewModel @Inject constructor( .flatten() .distinctBy { it.address } } ?: emptyList() - log(TAG) { "SCAN: BLE Devices: $devices" } - if (devices.isNotEmpty()) { - progress("SCAN: Received data from ${devices.size} BLE devices") - devices - } else { - progress("SCAN: No data received") - devices + + otherDevices.forEachIndexed { index, dev -> log(TAG) { "Device #$index: $dev" } } + + if (otherDevices.isEmpty()) { + failure("No supported headphones found near your device.", BleState.Result.Failure.Type.HEADPHONES) + return@override } - } - run { - progress("Checking if we can receive BLE data at all.") - if (doScan(false, false, false, true).isNotEmpty()) return@run - if (doScan(false, false, true, true).isNotEmpty()) return@run - if (doScan(true, true, true, true).isNotEmpty()) return@run - if (doScan(true, true, false, true).isNotEmpty()) return@run - if (doScan(true, false, true, true).isNotEmpty()) return@run - if (doScan(true, false, false, true).isNotEmpty()) return@run - if (doScan(false, true, true, true).isNotEmpty()) return@run - if (doScan(false, true, false, true).isNotEmpty()) return@run + progress("Headphones found nearby, but not detected as yours.\n") + progress("Creating profile for closest headphones.") - failure("Phone is not receiving BLE data.", BleState.Result.Failure.Type.PHONE) + val candidate = otherDevices + .filter { it !is UnknownSnapshotBle } + .maxBy { it.signalQuality } - generalSettings.isOffloadedFilteringDisabled.valueBlocking = false - generalSettings.isOffloadedBatchingDisabled.valueBlocking = false - generalSettings.useIndirectScanResultCallback.valueBlocking = false - debugSettings.showUnfiltered.valueBlocking = false + log(TAG, INFO) { "Candidate is $candidate" } - return@launch - } + profilesRepo.addProfile( + profile = AppleDeviceProfile( + label = context.getString(R.string.troubleshooter_title), + model = candidate.model, + ), + addFirst = true, + ) - progress("We received at least some BLE data.\n") + val mainDevice = withTimeoutOrNull(STEP_TIME) { + deviceMonitor.primaryDevice().filterNotNull().firstOrNull() + } - run { - progress("Checking for supported headphones.") - - if (doScan(false, false, false, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(false, false, true, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(true, true, true, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(true, true, false, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(true, false, true, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(true, false, false, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(false, true, true, false).any { it !is UnknownSnapshotBle }) return@run - if (doScan(false, true, false, false).any { it !is UnknownSnapshotBle }) return@run - - failure("No compatible headphones found", BleState.Result.Failure.Type.HEADPHONES) - - generalSettings.isOffloadedFilteringDisabled.valueBlocking = false - generalSettings.isOffloadedBatchingDisabled.valueBlocking = false - generalSettings.useIndirectScanResultCallback.valueBlocking = false - - return@launch - } - - progress("Found some headphones that are supported by CAPod.\n") - - run { - progress("Checking for your headphones with new BLE settings...") - val mainDevice = withTimeoutOrNull(STEP_TIME) { - deviceMonitor.primaryDevice().filterNotNull().firstOrNull() - } - if (mainDevice != null) { - success("Found your headphones, new BLE settings worked :)!") - return@launch - } - } - - progress("Still no headphones detected that count as yours.\n") - - run { - progress("Checking all closeby headphones.") - - val otherDevices = withTimeoutOrNull(STEP_TIME) { - val start = timeSource.elapsedRealtime() - blePodMonitor.devices - .take(10) - .takeWhile { timeSource.elapsedRealtime() - start < STEP_TIME - 1000 } - .toList() - .flatten() - .distinctBy { it.address } - } ?: emptyList() - - otherDevices.forEachIndexed { index, dev -> log(TAG) { "Device #$index: $dev" } } - - if (otherDevices.isEmpty()) { - failure("No supported headphones found near your device.", BleState.Result.Failure.Type.HEADPHONES) - return@launch - } - - progress("Headphones found nearby, but not detected as yours.\n") - progress("Creating profile for closest headphones.") - - val candidate = otherDevices - .filter { it !is UnknownSnapshotBle } - .maxBy { it.signalQuality } - - log(TAG, INFO) { "Candidate is $candidate" } - - profilesRepo.addProfile( - profile = AppleDeviceProfile( - label = context.getString(R.string.troubleshooter_title), - model = candidate.model, - ), - addFirst = true, - ) - - val mainDevice = withTimeoutOrNull(STEP_TIME) { - deviceMonitor.primaryDevice().filterNotNull().firstOrNull() - } - - generalSettings.scannerMode.valueBlocking = ScannerMode.BALANCED - - if (mainDevice != null) { - success("Success! Detected your headphones.") - } else { - failure("No headphones detected near your device.", BleState.Result.Failure.Type.HEADPHONES) + if (mainDevice != null) { + success("Success! Detected your headphones.") + } else { + failure("No headphones detected near your device.", BleState.Result.Failure.Type.HEADPHONES) + } } } } diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index a4fbb0ec..667630c6 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -46,8 +46,6 @@ Wys \'n ekstra kennisgewing wanneer \'n toestel gekoppel is. Dit laat jou toe om die permanente \"Geen toestelle\" kennisgewing te versteek deur die \"Toestelstatus\" kanaal te deaktiveer. Hou kennisgewing ná ontkoppeling Hou aan om die laaste bekende batteryvlakke te wys selfs nadat jou AirPods ontkoppel. - Skandeerdermodus - Moet die Bluetooth Lae Energie-dataskandeerder werkverrigting prioritiseer of energie bespaar? Outo-pouse Pouseer oudio wanneer die toestel uit jou oor verwyder word. Outo-speel @@ -222,9 +220,6 @@ Die volgende toestemming is vereis: Stelselwaarskuwingsvenster Laat CAPod toe om oor ander toepassings te teken om die kenmerk Wys opspringer moontlik te maak. - Lae krag - Gebalanseer - Lae latensie Wanneer toepassing oop is Wanneer toestel gekoppel is Altyd diff --git a/app/src/main/res/values-am/strings.xml b/app/src/main/res/values-am/strings.xml index 6465a15b..5ce59517 100644 --- a/app/src/main/res/values-am/strings.xml +++ b/app/src/main/res/values-am/strings.xml @@ -46,8 +46,6 @@ አንድ መሣሪያ ሲገናኝ ተጨማሪ ማሳወቂያ ያሳያል። ይህ የ \"የመሣሪያ ሁኔታ\" ቻናልን በማሰናከል ቋሚውን \"ምንም መሣሪያዎች የሉም\" የሚለውን ማሳወቂያ እንዲደብቁ ያስችልዎታል። ከተነተቀ በኋላ ማሳወቂያውን ይያዙ AirPods ከተነተቁ በኋላም የመጨረሻውን የታወቀ የባትሪ ደረጃ ማሳየቱን ይቀጥሉ - የቃኚ ሁነታ - የብሉቱዝ ዝቅተኛ ኃይል ዳታ ቃኚው አፈጻጸምን ቅድሚያ መስጠት አለበት ወይስ ኃይል መቆጠብ አለበት? ራስ-ሰር ለአፍታ ማቆም መሳሪያውን ከጆሮዎ ሲያወጡ ድምጽን ለአፍታ ያቁሙ። ራስ-ሰር አጫውት @@ -222,9 +220,6 @@ የሚከተለው ፈቃድ ያስፈልጋል: የስርዓት ማስጠንቀቂያ መስኮት \"ብቅ-ባይ አሳይ\" ባህሪውን ለማስቻል CAPod በሌሎች መተግበሪያዎች ላይ እንዲሳል ፍቀድ። - ዝቅተኛ ኃይል - ሚዛናዊ - ዝቅተኛ መዘግየት መተግበሪያው ሲከፈት መሣሪያ ሲገናኝ ሁልጊዜ diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 22f7ec28..5b733bca 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -46,8 +46,6 @@ يعرض إشعارًا إضافيًا عند توصيل جهاز. يتيح لك هذا إخفاء الإشعار الدائم \"لا توجد أجهزة\" عن طريق تعطيل قناة \"حالة الجهاز\". الاحتفاظ بالإشعار بعد قطع الاتصال الاستمرار في عرض مستويات البطارية المعروفة الأخيرة حتى بعد قطع اتصال AirPods - وضع الماسح الضوئي - هل يجب أن يعطي ماسح بيانات البلوتوث منخفض الطاقة الأولوية للأداء أم يحافظ على الطاقة؟ إيقاف مؤقت تلقائي إيقاف الصوت مؤقتًا عند إزالة الجهاز من أذنك. تشغيل تلقائي @@ -230,9 +228,6 @@ الإذن التالي مطلوب: نافذة تنبيه النظام السماح لـ CAPod بالرسم فوق التطبيقات الأخرى لتمكين ميزة \"إظهار النافذة المنبثقة\". - طاقة منخفضة - متوازن - تأخير منخفض عند فتح التطبيق عند اتصال الجهاز دائمًا diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 6247a3ac..c3759ef0 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -46,8 +46,6 @@ Cihaz qoşulduqda əlavə bildiriş göstərir. Bu, \"Cihaz statusu\" kanalını deaktiv etməklə daimi \"Cihaz yoxdur\" bildirişini gizlətməyə imkan verir. Ayrıldıqdan sonra bildirişi saxla AirPods ayrıldıqdan sonra belə sonuncu bilinən batareya səviyyələrini göstərməyə davam et - Skaner rejimi - Bluetooth Aşağı Enerji məlumat skaneri performansa üstünlük verməli, yoxsa enerjiyə qənaət etməlidir? Avtomatik fasilə Cihazı qulağınızdan çıxardıqda səsi dayandırın. Avtomatik oxutma @@ -222,9 +220,6 @@ Aşağıdakı icazə tələb olunur: Sistem xəbərdarlıq pəncərəsi \"Pop-up göstər\" xüsusiyyətini mümkün etmək üçün CAPod-a digər tətbiqlərin üzərində çəkməyə icazə verin. - Aşağı güc - Balanslaşdırılmış - Aşağı gecikmə Tətbiq açıq olduqda Cihaz qoşulduqda Həmişə diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 4613dea0..d1418f2f 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -46,8 +46,6 @@ Паказвае дадатковае апавяшчэнне пры падключэнні прылады. Гэта дазваляе схаваць пастаяннае апавяшчэнне \"Няма прылад\" шляхам адключэння канала \"Стан прылады\". Захаваць апавяшчэнне пасля адключэння Працягваць паказваць апошнія вядомыя ўзроўні зарадкі нават пасля адключэння вашых AirPods - Рэжым сканера - Ці павінен сканер даных Bluetooth Low Energy аддаваць перавагу прадукцыйнасці або эканоміць энергію? Аўтаматычная паўза Прыпыняць аўдыя пры выманні прылады з вуха. Аўтаматычнае прайграванне @@ -226,9 +224,6 @@ Патрабуецца наступны дазвол: Сістэмнае акно папярэджання Дазвольце CAPod маляваць паверх іншых праграм, каб зрабіць магчымай функцыю \"Паказаць усплывальнае акно\". - Нізкае энергаспажыванне - Збалансавана - Нізкая затрымка Калі праграма адкрыта Калі прылада падключана Заўсёды diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 72006861..e98d6d27 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -46,8 +46,6 @@ Показва допълнително известие, когато устройство е свързано. Това ви позволява да скриете постоянното известие \"Няма устройства\" чрез деактивиране на канала \"Състояние на устройството\". Запази известието след прекъсване Продължавай да показваш последните известни нива на батерията дори след прекъсване на връзката с AirPods - Режим на скенер - Трябва ли скенерът за данни с ниска енергия на Bluetooth да даде приоритет на производителността или да пести енергия? Автоматична пауза Поставяне на аудио на пауза при премахване на устройството от ухото ви. Автоматично възпроизвеждане @@ -222,9 +220,6 @@ Необходимо е следното разрешение: Системен изскачащ прозорец Позволете на CAPod да рисува върху други приложения, за да направи функцията \"Покажи изскачащ прозорец\" възможна. - Ниска мощност - Балансиран - Ниска латентност Когато приложението е отворено Когато устройството е свързано Винаги diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index baa09f01..34a857e1 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -46,8 +46,6 @@ একটি ডিভাইস সংযুক্ত হলে একটি অতিরিক্ত বিজ্ঞপ্তি দেখায়। এটি আপনাকে \"ডিভাইস স্ট্যাটাস\" চ্যানেল নিষ্ক্রিয় করে স্থায়ী \"কোনো ডিভাইস নেই\" বিজ্ঞপ্তি লুকাতে দেয়। সংযোগ বিচ্ছিন্নের পরে বিজ্ঞপ্তি রাখুন আপনার AirPods সংযোগ বিচ্ছিন্ন হওয়ার পরেও সর্বশেষ জানা ব্যাটারি স্তর দেখাতে থাকুন - স্ক্যানার মোড - ব্লুটুথ লো এনার্জি ডেটা স্ক্যানার কি কর্মক্ষমতাকে অগ্রাধিকার দেবে নাকি শক্তি সংরক্ষণ করবে? স্বয়ংক্রিয় বিরতি আপনার কান থেকে ডিভাইসটি সরানোর সময় অডিওতে বিরতি দিন। স্বয়ংক্রিয় প্লে @@ -222,9 +220,6 @@ নিম্নলিখিত অনুমতি প্রয়োজন: সিস্টেম অ্যালার্ট উইন্ডো \"পপআপ দেখান\" বৈশিষ্ট্যটি সম্ভব করতে CAPod-কে অন্যান্য অ্যাপের উপরে আঁকতে অনুমতি দিন। - কম শক্তি - ভারসাম্যপূর্ণ - কম বিলম্ব অ্যাপ খোলা থাকলে ডিভাইস সংযুক্ত থাকলে সর্বদা diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index d5746828..1872e2d2 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -46,8 +46,6 @@ Mostra una notificació addicional quan hi ha un dispositiu connectat. Això permet ocultar la notificació permanent «Sense dispositius» desactivant el canal «Estat del dispositiu». Mantén les notificacions després de la desconnexió Continua mostrant els últims nivells de bateria coneguts fins i tot després que els AirPods es desconnectin - Mode escàner - L\'escàner de dades Bluetooth de baix consum hauria de prioritzar el rendiment o estalviar energia? Pausa automàtica Pausa l\'àudio quan ús tragueu el dispositiu de l\'orella. Reproducció automàtica @@ -222,9 +220,6 @@ Cal el permís següent: Finestra d\'alerta del sistema Permet que el CAPod dibuixi sobre altres aplicacions per fer possible la característica «Mostra emergent». - Baixa potència - Equilibrat - Baixa latència Quan l\'aplicació està oberta Quan el dispositiu està connectat Sempre diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index dda0cff4..d9d00e1e 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -46,8 +46,6 @@ Zobrazí dodatečné oznámení, když je zařízení připojeno. To umožňuje skrýt trvalé oznámení \"Žádné zařízení\" vypnutím kanálu \"Stav zařízení\". Uchovat oznámení po odpojení Pokračovat v zobrazování poslední známé úrovně nabití baterie i po odpojení AirPods - Režim skenování - Má skenování Bluetooth Low Energy upřednostnit výkon, nebo úsporu energie? Autom. pozastavení Pozastavení zvuku při vyjmutí zařízení z ucha. Autom. přehrávání @@ -226,9 +224,6 @@ Je vyžadováno následující oprávnění: Okno systémových upozornění Aby bylo možné použít unkci \"Zobrazit vyskakovací okno\", je nutné umožnit aplikaci CAPod vykreslení přes jiné aplikace. - Nízký výkon - Vyvážený - Nízká latence Při otevření aplikace Při připojení zařízení Vždy diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 46521404..01abc3b7 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -46,8 +46,6 @@ Viser en ekstra notifikation, når en enhed er tilsluttet. Dette lader dig skjule den permanente \"Ingen enheder\"-notifikation ved at deaktivere \"Enhedsstatus\"-kanalen. Behold notifikation efter afbrydelse Fortsæt med at vise de sidst kendte batteriniveauer, selv efter dine AirPods afbrydes - Scannertilstand - Skal Bluetooth Low Energy-datascanneren prioritere ydeevne eller spare på energien? Auto-pause Sæt lyd på pause, når du fjerner enheden fra dit øre. Auto-afspilning @@ -222,9 +220,6 @@ Følgende tilladelse er påkrævet: Systemalarmvindue Tillad CAPod at tegne over andre apps for at gøre funktionen \"Vis pop op\" mulig. - Lavt strømforbrug - Balanceret - Lav latens Når appen er åben Når enheden er tilsluttet Altid diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5dffdff7..d6fe58d6 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -46,8 +46,6 @@ Zeigt eine zusätzliche Benachrichtigung an, wenn ein Gerät verbunden ist. Dadurch kannst du die permanente Benachrichtigung „Keine Geräte“ ausblenden, indem du den Kanal „Gerätestatus“ deaktivierst. Benachrichtigung nach Trennung beibehalten Zeigt weiterhin den letzten bekannten Akkustand an, auch wenn die Verbindung zu deinen AirPods getrennt wurde - Scan-Modus - Soll die Bluetooth Low Energy Überwachung Leistung priorisieren oder Energie sparen? Automatische Pause Musik pausieren, wenn der Kopfhörer vom Ohr entfernt wird. Automatisches abspielen @@ -222,9 +220,6 @@ Die folgende Genehmigung ist erforderlich: Systemwarnungsfenster Erlaube CAPod, PopUp Benachrichtigungen über anderen Apps anzuzeigen. - Geringer Strom - Ausgewogen - Geringe Latenz Wenn die App geöffnet ist Wenn das Gerät verbunden ist Immer diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 0d461410..b0400fff 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -46,8 +46,6 @@ Εμφανίζει μια επιπλέον ειδοποίηση όταν μια συσκευή είναι συνδεδεμένη. Αυτό σας επιτρέπει να αποκρύψετε τη μόνιμη ειδοποίηση \"Δεν υπάρχουν συσκευές\" απενεργοποιώντας το κανάλι \"Κατάσταση συσκευής\". Διατήρηση ειδοποίησης μετά την αποσύνδεση Συνεχίστε να εμφανίζετε τα τελευταία γνωστά επίπεδα μπαταρίας ακόμα και μετά την αποσύνδεση των AirPods σας - Λειτουργία σαρωτή - Ο σαρωτής δεδομένων Bluetooth Low Energy θα πρέπει να δώσει προτεραιότητα στην απόδοση ή στην εξοικονόμηση ενέργειας; Αυτόματη παύση Παύση ήχου κατά την αφαίρεση της συσκευής από το αυτί σας. Αυτόματη αναπαραγωγή @@ -222,9 +220,6 @@ Απαιτείται η ακόλουθη άδεια: Παράθυρο ειδοποίησης συστήματος Επιτρέψτε στο CAPod να σχεδιάζει πάνω από άλλες εφαρμογές για να καταστεί δυνατή η λειτουργία \"Εμφάνιση αναδυόμενου\". - Χαμηλή ισχύς - Ισορροπημένο - Χαμηλή καθυστέρηση Όταν η εφαρμογή είναι ανοιχτή Όταν η συσκευή είναι συνδεδεμένη Πάντα diff --git a/app/src/main/res/values-es-rAR/strings.xml b/app/src/main/res/values-es-rAR/strings.xml index c4716fc4..4deb9163 100644 --- a/app/src/main/res/values-es-rAR/strings.xml +++ b/app/src/main/res/values-es-rAR/strings.xml @@ -46,8 +46,6 @@ Muestra una notificación extra cuando un dispositivo está conectado. Esto te permite ocultar la notificación permanente \"Sin dispositivos\" desactivando el canal \"Estado del dispositivo\". Mantener la notificación después de la desconexión Seguir mostrando los últimos niveles de batería conocidos incluso después de que tus AirPods se desconecten - Modo escáner - ¿Debería el escáner de datos de Bluetooth de baja energía priorizar el rendimiento o conservar energía? Pausa automática Pausar el audio al quitar el dispositivo de tu oreja. Reproducción automática @@ -222,9 +220,6 @@ Se requiere el siguiente permiso: Ventana emergente Permite que CAPod se superponga a otras aplicaciones para que la función «Mostrar ventana emergente». - Baja energía - Equilibrado - Baja latencia Cuando la aplicación está abierta Cuando el dispositivo está conectado Siempre diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 601c9460..9ddf9fd5 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -46,8 +46,6 @@ Muestra una notificación adicional cuando un dispositivo está conectado. Esto te permite ocultar la notificación permanente \"Sin dispositivos\" desactivando el canal \"Estado del dispositivo\". Mantener la notificación después de la desconexión Seguir mostrando los últimos niveles de batería conocidos incluso después de que tus AirPods se desconecten - Modo escáner - ¿Debería el escáner de datos de Bluetooth de baja energía priorizar el rendimiento o conservar energía? Pausa automática Pausar el audio al quitar el dispositivo de tu oreja. Reproducción automática @@ -222,9 +220,6 @@ Se requiere el siguiente permiso: Ventana emergente Permite que CAPod se superponga a otras aplicaciones para que la función «Mostrar ventana emergente». - Baja energía - Equilibrado - Baja latencia Cuando la aplicación está abierta Cuando el dispositivo está conectado Siempre diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 4b8f61f8..32e3f119 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -46,8 +46,6 @@ Muestra una notificación adicional cuando un dispositivo está conectado. Esto le permite ocultar la notificación permanente \"Sin dispositivos\" deshabilitando el canal \"Estado del dispositivo\". Mantener la notificación después de la desconexión Seguir mostrando los últimos niveles de batería conocidos incluso después de que tus AirPods se desconecten - Modo escáner - ¿Debería el escáner de datos de Bluetooth de baja energía priorizar el rendimiento o conservar energía? Pausa automática Pausar el audio al quitar el dispositivo de tu oído. Reproducción automática @@ -222,9 +220,6 @@ Se requiere el siguiente permiso: Ventana emergente Permite que CAPod se superponga a otras aplicaciones para que la función «Mostrar ventana emergente». - Baja energía - Equilibrado - Baja latencia Cuando la aplicación está abierta Cuando el dispositivo está conectado Siempre diff --git a/app/src/main/res/values-et-rEE/strings.xml b/app/src/main/res/values-et-rEE/strings.xml index f7b1c9bb..3a1fc4cc 100644 --- a/app/src/main/res/values-et-rEE/strings.xml +++ b/app/src/main/res/values-et-rEE/strings.xml @@ -46,8 +46,6 @@ Kuvab seadme ühendumisel lisateavituse. See peidab pidevalt nähtava „Seadmed puuduvad“ teate, selleks keelates „Seadme olek“ kanali. Kuva teadet ka pärast eemaldamist Jätkake viimase teadaoleva akutaseme kuvamist isegi pärast AirPodside eemaldamist - Skannimisrežiim - Kas Bluetooth madalama energiatarbimisega andmete skanner eelistab jõudlust või mõõdukat energiahaldust? Automaatne peatamine Seadme kõrvast eemaldamisel peata esitamine. Automaatne esitamine @@ -222,9 +220,6 @@ Vaja on järgmist luba: Süsteemi teate aken Luba CAPodil toimetada teiste rakenduste kohal, et näha hüpikaknaid. - Madal võimsus - Tasakaalustatud - Madal latents Kui rakendus on avatud Kui seade on ühendatud Alati diff --git a/app/src/main/res/values-eu-rES/strings.xml b/app/src/main/res/values-eu-rES/strings.xml index 215e8852..56295ee9 100644 --- a/app/src/main/res/values-eu-rES/strings.xml +++ b/app/src/main/res/values-eu-rES/strings.xml @@ -46,8 +46,6 @@ Gailu bat konektatuta dagoenean jakinarazpen gehigarri bat erakusten du. Honek \"Gailurik ez\" jakinarazpen iraunkorra ezkutatzeko aukera ematen dizu \"Gailuaren egoera\" kanala desgaituz. Mantendu jakinarazpena deskonektatu ondoren Jarraitu azken bateria-maila ezagunak erakusten zure AirPods-ak deskonektatu ondoren ere - Eskaner modua - Bluetooth Energia Baxuko datuen eskanerrak errendimendua lehenetsi behar al du ala energia aurreztu? Pausatze automatikoa Pausatu audioa gailua belarritik kentzean. Erreprodukzio automatikoa @@ -222,9 +220,6 @@ Hurrengo baimena beharrezkoa da: Sistemaren alerta-leihoa Baimendu CAPod-i beste aplikazioen gainean marraztea \"Erakutsi pop-up-a\" ezaugarria posible egiteko. - Potentzia baxua - Orekatua - Latentzia baxua Aplikazioa irekita dagoenean Gailua konektatuta dagoenean Beti diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 2fe3df31..9865c6f5 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -46,8 +46,6 @@ هنگامی که یک دستگاه متصل است، یک اعلان اضافی نشان می‌دهد. این به شما امکان می‌دهد اعلان دائمی \"بدون دستگاه\" را با غیرفعال کردن کانال \"وضعیت دستگاه\" پنهان کنید. حفظ اعلان پس از قطع اتصال نمایش آخرین سطوح شارژ شناخته‌شده حتی پس از قطع اتصال AirPods شما - حالت اسکنر - آیا اسکنر داده بلوتوث کم‌مصرف باید عملکرد را در اولویت قرار دهد یا انرژی را ذخیره کند؟ مکث خودکار هنگام برداشتن دستگاه از گوش، صدا را متوقف کنید. پخش خودکار @@ -222,9 +220,6 @@ مجوز زیر مورد نیاز است: پنجره هشدار سیستم به CAPod اجازه دهید روی سایر برنامه‌ها نمایش دهد تا ویژگی \"نمایش پاپ‌آپ\" ممکن شود. - کم‌مصرف - متعادل - تأخیر کم وقتی برنامه باز است وقتی دستگاه متصل است همیشه diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 0db1a386..bbe9beb8 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -46,8 +46,6 @@ Näyttää lisäilmoituksen, kun laite on yhdistetty. Tämä antaa sinun piilottaa pysyvän \"Ei laitteita\" -ilmoituksen poistamalla \"Laitteen tila\" -kanavan käytöstä. Säilytä ilmoitus yhteyden katkaisun jälkeen Jatka viimeisten tunnettujen akkutasojen näyttämistä senkin jälkeen, kun AirPodit katkaisevat yhteyden - Skanneritila - Pitäisikö Bluetooth Low Energy -dataskannerin priorisoida suorituskykyä vai säästää energiaa? Automaattinen tauko Keskeytä ääni, kun poistat laitteen korvastasi. Automaattinen toisto @@ -222,9 +220,6 @@ Seuraava lupa vaaditaan: Järjestelmän hälytysikkuna Salli CAPod-sovelluksen piirtää muiden sovellusten päälle mahdollistaakseen \"Näytä ponnahdusikkuna\" -ominaisuuden. - Virransäästö - Tasapainoinen - Matala viive Kun sovellus on auki Kun laite on yhdistetty Aina diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 41890b61..aa548f6b 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -46,8 +46,6 @@ Nagpapakita ng karagdagang notipikasyon kapag konektado ang isang device. Pinapayagan ka nitong itago ang permanenteng \"Walang mga device\" na notipikasyon sa pamamagitan ng pag-disable sa \"Katayuan ng device\" na channel. Panatilihin ang notipikasyon pagkatapos mag-disconnect Ipagpatuloy ang pagpapakita ng huling kilalang mga antas ng baterya kahit pagkatapos mag-disconnect ang iyong AirPods - Mode ng scanner - Dapat bang unahin ng Bluetooth Low Energy data scanner ang performance o magtipid ng enerhiya? Auto pause I-pause ang audio kapag inaalis ang device sa iyong tainga. Auto play @@ -222,9 +220,6 @@ Kailangan ang sumusunod na pahintulot: System Alert Window Payagan ang CAPod na mag-draw sa ibabaw ng ibang mga app para maging posible ang feature na \"Ipakita ang PopUp\". - Mababang enerhiya - Balanse - Mababang latency Kapag bukas ang app Kapag konektado ang device Palagi diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 88324b72..08810204 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -46,8 +46,6 @@ Affiche une notification supplémentaire si un appareil est connecté. Cela vous permet de masquer la notification permanente « Aucun appareil » en désactivant le canal « État de l’appareil ». Garder la notification après déconnexion Afficher les derniers niveaux de batterie connus même après déconnexion de vos AirPods - Mode analyse - L’analyseur des données « basse énergie » de Bluetooth devrait-il prioriser les performances ou préserver l’énergie ? Pause automatique Mettre le son en pause si vous ôtez l’appareil de votre oreille. Lecture automatique @@ -222,9 +220,6 @@ L’autorisation suivante est nécessaire : Fenêtre d’alerte système Permettre à CAPod d’apparaître par-dessus les autres applis pour rendre la fonction « Afficher une fenêtre contextuelle » possible. - Puissance faible - Équilibré - Latence faible Si l’appli est ouverte Si l’appareil est connecté Toujours diff --git a/app/src/main/res/values-gl-rES/strings.xml b/app/src/main/res/values-gl-rES/strings.xml index c5d8eae2..89d2683b 100644 --- a/app/src/main/res/values-gl-rES/strings.xml +++ b/app/src/main/res/values-gl-rES/strings.xml @@ -46,8 +46,6 @@ Mostra unha notificación adicional cando un dispositivo está conectado. Isto permíteche ocultar a notificación permanente de \"Sen dispositivos\" desactivando a canle \"Estado do dispositivo\". Manter notificación tras desconexión Seguir mostrando os últimos niveis de batería coñecidos mesmo despois de que os teus AirPods se desconecten - Modo de escáner - O escáner de datos Bluetooth de baixa enerxía debería priorizar o rendemento ou conservar enerxía? Pausa automática Pausar o son ao quitar o dispositivo da orella. Reprodución automática @@ -222,9 +220,6 @@ É necesario o seguinte permiso: Xanela de alerta do sistema Permitir que CAPod debuxe sobre outras aplicacións para facer posible a función \"Mostrar PopUp\". - Baixo consumo - Equilibrado - Baixa latencia Cando a aplicación está aberta Cando o dispositivo está conectado Sempre diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index 0f03a4be..29221f0e 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -46,8 +46,6 @@ जब कोई डिवाइस कनेक्ट होता है तो एक अतिरिक्त सूचना दिखाता है। यह आपको \"डिवाइस स्थिति\" चैनल को अक्षम करके स्थायी \"कोई डिवाइस नहीं\" सूचना को छिपाने की अनुमति देता है। डिस्कनेक्ट होने के बाद सूचना बनाए रखें आपके AirPods डिस्कनेक्ट होने के बाद भी अंतिम ज्ञात बैटरी स्तर दिखाना जारी रखें - स्कैनर मोड - क्या ब्लूटूथ लो एनर्जी डेटा स्कैनर को प्रदर्शन को प्राथमिकता देनी चाहिए या ऊर्जा बचानी चाहिए? ऑटो-पॉज़ डिवाइस को अपने कान से हटाने पर ऑडियो रोकें। ऑटो-प्ले @@ -222,9 +220,6 @@ निम्नलिखित अनुमति आवश्यक है: सिस्टम अलर्ट विंडो CAPod को अन्य ऐप्स के ऊपर ड्रॉ करने की अनुमति दें ताकि \"पॉपअप दिखाएं\" सुविधा संभव हो सके। - कम बिजली - संतुलित - कम विलंब जब ऐप खुला हो जब डिवाइस कनेक्ट हो हमेशा diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index a71a50f3..57eb5eda 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -46,8 +46,6 @@ Prikazuje dodatnu obavijest kada je uređaj povezan. To vam omogućuje da sakrijete trajnu obavijest \"Nema uređaja\" onemogućavanjem kanala \"Status uređaja\". Zadrži obavijest nakon prekida veze Nastavi prikazivati zadnje poznate razine baterije i nakon što se vaši AirPods odspoje - Način skeniranja - Treba li Bluetooth Low Energy skener podataka dati prednost performansama ili štedjeti energiju? Automatska pauza Pauzirajte zvuk kada uklonite uređaj iz uha. Automatska reprodukcija @@ -224,9 +222,6 @@ Sljedeća dozvola je potrebna: Prozor sistemskog upozorenja Dopustite CAPod-u crtanje preko drugih aplikacija kako bi omogućili značajku \"Prikaži skočni prozor\". - Niska potrošnja - Uravnoteženo - Niska latencija Kada je aplikacija otvorena Kada je uređaj povezan Uvijek diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 518e541d..341f02b0 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -46,8 +46,6 @@ Extra értesítést jelenít meg, amikor egy eszköz csatlakozik. Ez lehetővé teszi az állandó \"Nincs eszköz\" értesítés elrejtését az \"Eszköz állapota\" csatorna letiltásával. Értesítés megőrzése lecsatlakozás után Az utolsó ismert akkumulátorszintek megjelenítésének folytatása az AirPods lecsatlakozása után is - Szkenner mód - A Bluetooth Low Energy szkenner a teljesítményt vagy az energiatakarékosságot részesítse előnyben? Automatikus szünet Zene leállítása, amikor kiveszi a füléből az eszközt. Automatikus lejátszás @@ -222,9 +220,6 @@ A következő engedély szükséges: Rendszer figyelmeztető ablak Engedélyezze a CAPod-nak, hogy más alkalmazások fölé rajzoljon az \"Előugró ablak megjelenítése\" funkció lehetővé tételéhez. - Alacsony fogyasztás - Kiegyensúlyozott - Alacsony késleltetés Amikor az alkalmazás nyitva van Amikor az eszköz csatlakozik Mindig diff --git a/app/src/main/res/values-hy-rAM/strings.xml b/app/src/main/res/values-hy-rAM/strings.xml index ef95709e..706f5df4 100644 --- a/app/src/main/res/values-hy-rAM/strings.xml +++ b/app/src/main/res/values-hy-rAM/strings.xml @@ -46,8 +46,6 @@ Ցուցադրում է լրացուցիչ ծանուցում, երբ սարքը միացված է։ Սա թույլ է տալիս թաքցնել մշտական \"Սարքեր չկան\" ծանուցումը՝ անջատելով \"Սարքի կարգավիճակը\" ալիքը։ Պահել ծանուցումը անջատումից հետո Շարունակել ցուցադրել վերջին հայտնի մարտկոցի մակարդակները նույնիսկ ձեր AirPods-ների անջատումից հետո - Սկաների ռեժիմ - Bluetooth Low Energy տվյալների սկաները պետք է առաջնահերթություն տա արդյունավետությանը, թե՞ խնայի էներգիան։ Ինքնադադար Դադարեցրեք ձայնը, երբ սարքը հանում եք ականջից։ Ինքնանվագարկում @@ -222,9 +220,6 @@ Հետևյալ թույլտվությունն անհրաժեշտ է՝ Համակարգային զգուշացման պատուհան Թույլ տվեք CAPod-ին նկարել այլ հավելվածների վերևում՝ \"Ցուցադրել բացվող պատուհան\" գործառույթը հնարավոր դարձնելու համար։ - Ցածր էներգիա - Հավասարակշռված - Ցածր ուշացում Երբ հավելվածը բաց է Երբ սարքը միացված է Միշտ diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 71f211a5..8016608e 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -46,8 +46,6 @@ Menampilkan notifikasi tambahan ketika perangkat terhubung. Ini memungkinkan Anda menyembunyikan notifikasi permanen \"Tidak ada perangkat\" dengan menonaktifkan saluran \"Status perangkat\". Pertahankan notifikasi setelah terputus Terus menampilkan level baterai terakhir yang diketahui bahkan setelah AirPods terputus - Mode pemindai - Haruskah pemindai data Bluetooth Hemat Energi memprioritaskan kinerja atau menghemat energi? Jeda otomatis Jeda audio saat melepas perangkat dari telinga Anda. Putar otomatis @@ -220,9 +218,6 @@ Izin berikut diperlukan: Jendela Peringatan Sistem Izinkan CAPod menggambar di atas aplikasi lain untuk memungkinkan fitur \"Tampilkan PopUp\". - Hemat daya - Seimbang - Latensi rendah Saat aplikasi terbuka Saat perangkat terhubung Selalu diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 1f4c5ccf..e9767842 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -46,8 +46,6 @@ Sýnir auka tilkynningu þegar tæki er tengt. Þetta gerir þér kleift að fela varanlega \"Engin tæki\" tilkynninguna með því að slökkva á \"Staða tækis\" rásinni. Halda tilkynningu eftir aftengi Halda áfram að sýna síðustu þekktu rafhlöðustöðu jafnvel eftir að AirPods tengjast af - Skannastilling - Ætti Bluetooth Low Energy gagnaskanninn að forgangsraða afköstum eða spara orku? Sjálfvirk hlé Gera hlé á hljóði þegar tækið er tekið úr eyranu. Sjálfvirk spilun @@ -222,9 +220,6 @@ Eftirfarandi heimild er nauðsynleg: Kerfisviðvörunargluggi Leyfðu CAPod að teikna yfir önnur forrit til að gera eiginleikann \"Sýna upplýsingaglugga\" mögulegan. - Lágt afl - Jafnvægi - Lítil töf Þegar forrit er opið Þegar tæki er tengt Alltaf diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 04266ef3..8e5d6e7c 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -46,8 +46,6 @@ Mostra una notifica aggiuntiva quando un dispositivo è connesso. Ciò consente di nascondere la notifica permanente \"Nessun dispositivo\" disabilitando il canale \"Stato del dispositivo\". Mantieni notifica dopo la disconnessione Continua a mostrare gli ultimi livelli di batteria noti anche dopo la disconnessione dei tuoi AirPods - Modalità scanner - Lo scanner di dati Bluetooth Low Energy deve dare priorità alle prestazioni o risparmiare energia? Pausa automatica Metti in pausa l\'audio quando rimuovi il dispositivo dall\'orecchio. Riproduzione automatica @@ -222,9 +220,6 @@ È richiesto il seguente permesso: Finestra di avviso di sistema Consenti a CAPod di disegnare sopra altre app per rendere possibile la funzionalità \"Mostra pop-up\". - Basso consumo - Bilanciato - Bassa latenza Quando l\'app è aperta Quando il dispositivo è connesso Sempre diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 55ef7776..91581719 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -46,8 +46,6 @@ מציג התראה נוספת כאשר מכשיר מחובר. זה מאפשר לך להסתיר את ההתראה הקבועה \"אין מכשירים\" על ידי השבתת הערוץ \"סטטוס מכשיר\". שמור התראה לאחר ניתוק המשך להציג את רמות הסוללה האחרונות הידועות גם לאחר ניתוק ה-AirPods - מצב סורק - האם סורק ה-Bluetooth Low Energy צריך לתת עדיפות לביצועים או לחסוך באנרגיה? השהייה אוטומטית עצירת אודיו בהסרת המכשיר מהאוזן. הפעלה אוטומטית @@ -226,9 +224,6 @@ ההרשאה הבאה נדרשת: חלון התראת מערכת אפשר ל-CAPod לצייר מעל אפליקציות אחרות כדי לאפשר את תכונת \"הצג חלון קופץ\". - חיסכון באנרגיה - מאוזן - השהייה נמוכה כשהאפליקציה פתוחה כשמכשיר מחובר תמיד diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index f9557e00..7fdd1079 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -46,8 +46,6 @@ デバイスが接続されると追加の通知を表示します。これにより、「デバイスステータス」チャネルを無効にすることで、永続的な「デバイスなし」通知を非表示にできます。 切断後も通知を維持 AirPodsが切断された後も、最後に確認されたバッテリー残量を表示し続けます - スキャナーモード - Bluetooth Low Energyデータスキャナーはパフォーマンスを優先すべきか、エネルギーを節約すべきか? 自動一時停止 デバイスを耳から外すとオーディオを一時停止します。 自動再生 @@ -220,9 +218,6 @@ 次の権限が必要です: システムアラートウィンドウ 「ポップアップを表示」機能を有効にするため、CAPodが他のアプリの上に表示できるようにします。 - 低消費電力 - バランス - 低遅延 アプリを開いているとき デバイス接続時 常に diff --git a/app/src/main/res/values-ka-rGE/strings.xml b/app/src/main/res/values-ka-rGE/strings.xml index aa45aaf4..55ca09c2 100644 --- a/app/src/main/res/values-ka-rGE/strings.xml +++ b/app/src/main/res/values-ka-rGE/strings.xml @@ -46,8 +46,6 @@ აჩვენებს დამატებით შეტყობინებას, როდესაც მოწყობილობა დაკავშირებულია. ეს საშუალებას გაძლევთ დამალოთ მუდმივი \"მოწყობილობები არ არის\" შეტყობინება \"მოწყობილობის სტატუსის\" არხის გამორთვით. შეტყობინების შენარჩუნება გათიშვის შემდეგ განაგრძეთ ბოლო ცნობილი ბატარეის დონეების ჩვენება მაშინაც კი, როცა თქვენი AirPods გაითიშება - სკანერის რეჟიმი - Bluetooth Low Energy მონაცემთა სკანერმა პრიორიტეტი უნდა მიანიჭოს შესრულებას თუ ენერგიის დაზოგვას? ავტომატური პაუზა აუდიოს დაპაუზება მოწყობილობის ყურიდან ამოღებისას. ავტომატური დაკვრა @@ -222,9 +220,6 @@ საჭიროა შემდეგი ნებართვა: სისტემური გამაფრთხილებელი ფანჯარა დაუშვით, რომ CAPod სხვა აპებზე ზემოდან გამოჩნდეს, რათა \"Show PopUp\" ფუნქცია შესაძლებელი გახდეს. - დაბალი ენერგომოხმარება - ბალანსირებული - დაბალი დაყოვნება როცა აპი ღიაა როცა მოწყობილობა დაკავშირებულია ყოველთვის diff --git a/app/src/main/res/values-km-rKH/strings.xml b/app/src/main/res/values-km-rKH/strings.xml index f74e5136..91fc2ee7 100644 --- a/app/src/main/res/values-km-rKH/strings.xml +++ b/app/src/main/res/values-km-rKH/strings.xml @@ -46,8 +46,6 @@ បង្ហាញការជូនដំណឹងបន្ថែមនៅពេលឧបករណ៍ត្រូវបានភ្ជាប់។ វាអនុញ្ញាតឱ្យអ្នកលាក់ការជូនដំណឹងអចិន្ត្រៃយ៍ \"គ្មានឧបករណ៍\" ដោយបិទឆានែល \"ស្ថានភាពឧបករណ៍\"។ រក្សាការជូនដំណឹងបន្ទាប់ពីផ្តាច់ បន្តបង្ហាញកម្រិតថ្មចុងក្រោយដែលស្គាល់ សូម្បីបន្ទាប់ពី AirPods របស់អ្នកផ្តាច់ក៏ដោយ - របៀបវិភាគ - តើម៉ាស៊ីនវិភាគទិន្នន័យ Bluetooth Low Energy គួរតែផ្តល់អាទិភាពដល់ដំណើរការ ឬសន្សំសំចៃថាមពល? ផ្អាកដោយស្វ័យប្រវត្តិ ផ្អាកសំឡេងនៅពេលដកឧបករណ៍ចេញពីត្រចៀករបស់អ្នក។ ចាក់ដោយស្វ័យប្រវត្តិ @@ -220,9 +218,6 @@ ការអនុញ្ញាតខាងក្រោមត្រូវបានទាមទារ: បង្អួចជូនដំណឹងប្រព័ន្ធ អនុញ្ញាតឱ្យ CAPod គូរពីលើកម្មវិធីផ្សេងទៀតដើម្បីធ្វើឱ្យមុខងារ \"បង្ហាញផ្ទាំងលោត\" អាចធ្វើទៅបាន។ - ថាមពលទាប - មានតុល្យភាព - ភាពយឺតយ៉ាវទាប នៅពេលកម្មវិធីបើក នៅពេលឧបករណ៍បានភ្ជាប់ ជានិច្ច diff --git a/app/src/main/res/values-kmr-rTR/strings.xml b/app/src/main/res/values-kmr-rTR/strings.xml index 955c5df3..3cabe3e5 100644 --- a/app/src/main/res/values-kmr-rTR/strings.xml +++ b/app/src/main/res/values-kmr-rTR/strings.xml @@ -46,8 +46,6 @@ Dema ku amûrek girêdayî ye agahdariyek zêde nîşan dide. Ev dihêle hûn agahdariya daîmî ya \"Amûr tune\" bi neçalakkirina kanala \"Rewşa amûrê\" veşêrin. Piştî qutbûnê agahdariyê biparêze Piştî ku AirPods-ên te qut dibin jî asta dawîn a naskirî ya bataryayê nîşan bide - Moda skanerê - Gelo divê skanera daneyên Bluetooth Kêm Enerjiyê pêşî li performansê bigire an enerjiyê biparêze? Rawestandina otomatîk Dema ku amûrê ji guhê xwe derdixin, deng rawestînin. Lîstina otomatîk @@ -222,9 +220,6 @@ Destûra jêrîn hewce ye: Pencereya Hişyariya Pergalê Destûrê bidin CAPod ku li ser sepanên din xêz bike da ku taybetmendiya \"Pop-Up Nîşan Bide\" gengaz bike. - Hêza kêm - Hevseng - Derengiya kêm Dema sepan vekirî ye Dema amûr girêdayî ye Herdem diff --git a/app/src/main/res/values-kn-rIN/strings.xml b/app/src/main/res/values-kn-rIN/strings.xml index 8b9cd037..49b5dc56 100644 --- a/app/src/main/res/values-kn-rIN/strings.xml +++ b/app/src/main/res/values-kn-rIN/strings.xml @@ -46,8 +46,6 @@ ಸಾಧನ ಸಂಪರ್ಕಗೊಂಡಾಗ ಹೆಚ್ಚುವರಿ ಅಧಿಸೂಚನೆಯನ್ನು ತೋರಿಸುತ್ತದೆ. ಇದು \"ಸಾಧನ ಸ್ಥಿತಿ\" ಚಾನಲ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುವ ಮೂಲಕ ಶಾಶ್ವತ \"ಯಾವುದೇ ಸಾಧನಗಳಿಲ್ಲ\" ಅಧಿಸೂಚನೆಯನ್ನು ಮರೆಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಂಪರ್ಕ ಕಡಿತದ ನಂತರ ಅಧಿಸೂಚನೆ ಇರಿಸಿ ನಿಮ್ಮ AirPods ಸಂಪರ್ಕ ಕಡಿತವಾದ ನಂತರವೂ ಕೊನೆಯ ತಿಳಿದಿರುವ ಬ್ಯಾಟರಿ ಮಟ್ಟವನ್ನು ತೋರಿಸುವುದನ್ನು ಮುಂದುವರಿಸಿ - ಸ್ಕ್ಯಾನರ್ ಮೋಡ್ - ಬ್ಲೂಟೂತ್ ಕಡಿಮೆ ಶಕ್ತಿಯ ಡೇಟಾ ಸ್ಕ್ಯಾನರ್ ಕಾರ್ಯಕ್ಷಮತೆಗೆ ಆದ್ಯತೆ ನೀಡಬೇಕೇ ಅಥವಾ ಶಕ್ತಿಯನ್ನು ಉಳಿಸಬೇಕೇ? ಸ್ವಯಂ-ವಿರಾಮ ನಿಮ್ಮ ಕಿವಿಯಿಂದ ಸಾಧನವನ್ನು ತೆಗೆದುಹಾಕಿದಾಗ ಆಡಿಯೊವನ್ನು ವಿರಾಮಗೊಳಿಸಿ. ಸ್ವಯಂ-ಪ್ಲೇ @@ -222,9 +220,6 @@ ಕೆಳಗಿನ ಅನುಮತಿ ಅಗತ್ಯವಿದೆ: ಸಿಸ್ಟಮ್ ಅಲರ್ಟ್ ವಿಂಡೋ \"ಪಾಪ್‌ಅಪ್ ತೋರಿಸಿ\" ವೈಶಿಷ್ಟ್ಯವನ್ನು ಸಾಧ್ಯವಾಗಿಸಲು CAPod ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೇಲೆ ಚಿತ್ರಿಸಲು ಅನುಮತಿಸಿ. - ಕಡಿಮೆ ಶಕ್ತಿ - ಸಮತೋಲಿತ - ಕಡಿಮೆ ವಿಳಂಬ ಅಪ್ಲಿಕೇಶನ್ ತೆರೆದಿರುವಾಗ ಸಾಧನ ಸಂಪರ್ಕಗೊಂಡಾಗ ಯಾವಾಗಲೂ diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 82b8cc11..0db21074 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -46,8 +46,6 @@ 기기가 연결되면 추가 알림을 표시합니다. 이렇게 하면 \"기기 상태\" 채널을 비활성화하여 영구적인 \"기기 없음\" 알림을 숨길 수 있습니다. 연결 해제 후에도 알림 유지하기 AirPods이 연결 해제된 후에도 마지막으로 알려진 배터리 잔량 계속 표시하기 - 스캐너 모드 - Bluetooth Low Energy 데이터 스캐너가 성능을 우선시해야 할까요, 아니면 에너지를 절약해야 할까요? 자동 일시 중지 기기를 귀에서 빼면 오디오를 일시 중지합니다. 자동 재생 @@ -220,9 +218,6 @@ 다음과 같은 권한이 필요합니다: 시스템 알림창 \"팝업 표시\" 기능을 사용하려면 다른 앱 위에 그리기를 허용해야 합니다. - 저전력 - 균형잡힌 - 저지연 앱이 열려있을때 장치가 연결되었을때 항상 diff --git a/app/src/main/res/values-ky-rKG/strings.xml b/app/src/main/res/values-ky-rKG/strings.xml index 1b319573..93afb83d 100644 --- a/app/src/main/res/values-ky-rKG/strings.xml +++ b/app/src/main/res/values-ky-rKG/strings.xml @@ -46,8 +46,6 @@ Түзмөк туташканда кошумча билдирүү көрсөтүлөт. Бул \"Түзмөктүн абалы\" каналын өчүрүү менен туруктуу \"Түзмөктөр жок\" билдирүүсүн жашырууга мүмкүндүк берет. Ажыратылгандан кийин билдирүүнү сактоо AirPods ажыратылгандан кийин да акыркы белгилүү батарея деңгээлдерин көрсөтүүнү улантуу - Сканер режими - Bluetooth Low Energy маалымат сканери өндүрүмдүүлүктү биринчи орунга коюшу керекпи же энергияны үнөмдөшү керекпи? Авто тыным Түзмөктү кулагыңыздан чыгарганда аудиону тындырыңыз. Авто ойнотуу @@ -222,9 +220,6 @@ Төмөнкү уруксат талап кылынат: Тутум эскертүү терезеси \"Калкыма терезе көрсөтүү\" функциясын мүмкүн кылуу үчүн CAPod\'го башка колдонмолордун үстүнөн тартууга уруксат бериңиз. - Аз кубаттуулук - Тең салмактуу - Аз кечигүү Колдонмо ачык болгондо Түзмөк туташканда Ар дайым diff --git a/app/src/main/res/values-lo-rLA/strings.xml b/app/src/main/res/values-lo-rLA/strings.xml index 4b140ee0..1d254c55 100644 --- a/app/src/main/res/values-lo-rLA/strings.xml +++ b/app/src/main/res/values-lo-rLA/strings.xml @@ -46,8 +46,6 @@ ສະແດງການແຈ້ງເຕືອນເພີ່ມເຕີມເມື່ອອຸປະກອນເຊື່ອມຕໍ່ແລ້ວ. ນີ້ຊ່ວຍໃຫ້ທ່ານສາມາດເຊື່ອງການແຈ້ງເຕືອນຖາວອນ \"ບໍ່ມີອຸປະກອນ\" ໂດຍການປິດຊ່ອງ \"ສະຖານະອຸປະກອນ\" . ຮັກສາການແຈ້ງເຕືອນຫຼັງຈາກຕັດການເຊື່ອມຕໍ່ ສືບຕໍ່ສະແດງລະດັບແບັດເຕີລີ້ທີ່ຮູ້ຈັກຫຼ້າສຸດແມ້ຫຼັງຈາກ AirPods ຕັດການເຊື່ອມຕໍ່ - ໂໝດສະແກນ - ເຄື່ອງສະແກນຂໍ້ມູນ Bluetooth Low Energy ຄວນໃຫ້ຄວາມສຳຄັນກັບປະສິດທິພາບ ຫຼື ປະຢັດພະລັງງານ? ຢຸດອັດຕະໂນມັດ ຢຸດສຽງຊົ່ວຄາວເມື່ອຖອດອຸປະກອນອອກຈາກຫູຂອງທ່ານ. ຫຼິ້ນອັດຕະໂນມັດ @@ -220,9 +218,6 @@ ຕ້ອງການການອະນຸຍາດຕໍ່ໄປນີ້: ໜ້າຕ່າງການແຈ້ງເຕືອນລະບົບ ອະນຸຍາດໃຫ້ CAPod ແຕ້ມທັບແອັບອື່ນເພື່ອໃຫ້ຄຸນສົມບັດ \"ສະແດງປັອບອັບ\" ເປັນໄປໄດ້. - ພະລັງງານຕໍ່າ - ສົມດູນ - ຄວາມຊັກຊ້າຕໍ່າ ເມື່ອແອັບເປີດ ເມື່ອອຸປະກອນເຊື່ອມຕໍ່ ສະເໝີ diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 85ded3d3..4c335de0 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -46,8 +46,6 @@ Rodo papildomą pranešimą, kai prijungiamas įrenginys. Tai leidžia paslėpti nuolatinį pranešimą \"Nėra įrenginių\" išjungiant kanalą \"Įrenginio būsena\". Palikti pranešimą atjungus Toliau rodyti paskutinį žinomą baterijos lygį net ir atjungus „AirPods\" - Skenavimo režimas - Ar „Bluetooth Low Energy\" duomenų skaitytuvas turėtų teikti pirmenybę našumui ar taupyti energiją? Automatinė pauzė Pristabdyti garsą išėmus įrenginį iš ausies. Automatinis grojimas @@ -226,9 +224,6 @@ Reikalingas šis leidimas: Sistemos perspėjimo langas Leiskite CAPod piešti virš kitų programų, kad būtų galima naudoti funkciją „Rodyti iškylantįjį langą\". - Mažos galios - Subalansuotas - Mažas delsimas Kai programa atidaryta Kai įrenginys prijungtas Visada diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 8f087794..49e6faf1 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -46,8 +46,6 @@ Rāda papildu paziņojumu, kad ierīce ir pievienota. Tas ļauj paslēpt pastāvīgo paziņojumu \"Nav ierīču\", atspējojot kanālu \"Ierīces statuss\". Saglabāt paziņojumu pēc atvienošanas Turpināt rādīt pēdējos zināmos baterijas līmeņus arī pēc AirPods atvienošanas - Skenēšanas režīms - Vai Bluetooth Low Energy datu skenerim vajadzētu prioritizēt veiktspēju vai taupīt enerģiju? Automātiska pauze Pauzēt audio, noņemot ierīci no auss. Automātiska atskaņošana @@ -224,9 +222,6 @@ Nepieciešama šāda atļauja: Sistēmas brīdinājuma logs Atļaujiet CAPod zīmēt virs citām lietotnēm, lai iespējotu funkciju \"Rādīt uznirstošo logu\". - Zema jauda - Līdzsvarots - Zema latence Kad lietotne ir atvērta Kad ierīce ir savienota Vienmēr diff --git a/app/src/main/res/values-mk-rMK/strings.xml b/app/src/main/res/values-mk-rMK/strings.xml index 9220c2f1..b47f8e97 100644 --- a/app/src/main/res/values-mk-rMK/strings.xml +++ b/app/src/main/res/values-mk-rMK/strings.xml @@ -46,8 +46,6 @@ Прикажува дополнително известување кога уредот е поврзан. Ова ви овозможува да го скриете трајното известување \"Нема уреди\" со оневозможување на каналот \"Статус на уредот\". Задржи го известувањето по прекинување Продолжи да ги прикажуваш последните познати нивоа на батеријата дури и откако вашите AirPods ќе се исклучат - Режим на скенер - Дали скенерот за податоци со ниска енергија на Bluetooth треба да даде приоритет на перформансите или да заштеди енергија? Автоматска пауза Паузирајте го аудиото кога го отстранувате уредот од увото. Автоматско репродуцирање @@ -222,9 +220,6 @@ Потребна е следната дозвола: Системски прозорец за предупредување Дозволете CAPod да црта преку други апликации за да ја овозможи функцијата \"Прикажи попап\". - Ниска моќност - Балансирано - Ниска латенција Кога апликацијата е отворена Кога уредот е поврзан Секогаш diff --git a/app/src/main/res/values-ml-rIN/strings.xml b/app/src/main/res/values-ml-rIN/strings.xml index e68b692c..60b2001b 100644 --- a/app/src/main/res/values-ml-rIN/strings.xml +++ b/app/src/main/res/values-ml-rIN/strings.xml @@ -46,8 +46,6 @@ ഒരു ഉപകരണം കണക്റ്റുചെയ്യുമ്പോൾ ഒരു അധിക അറിയിപ്പ് കാണിക്കുന്നു. \"ഉപകരണ നില\" ചാനൽ പ്രവർത്തനരഹിതമാക്കി സ്ഥിരമായ \"ഉപകരണങ്ങളൊന്നുമില്ല\" അറിയിപ്പ് മറയ്ക്കാൻ ഇത് നിങ്ങളെ അനുവദിക്കുന്നു. വിച്ഛേദിച്ച ശേഷം അറിയിപ്പ് നിലനിർത്തുക നിങ്ങളുടെ AirPods വിച്ഛേദിച്ചാലും അവസാനമായി അറിയപ്പെടുന്ന ബാറ്ററി ലെവലുകൾ കാണിക്കുന്നത് തുടരുക - സ്കാനർ മോഡ് - ബ്ലൂടൂത്ത് ലോ എനർജി ഡാറ്റ സ്കാനർ പ്രകടനത്തിന് മുൻഗണന നൽകണോ അതോ ഊർജ്ജം ലാഭിക്കണോ? യാന്ത്രികമായി താൽക്കാലികമായി നിർത്തുക നിങ്ങളുടെ ചെവിയിൽ നിന്ന് ഉപകരണം നീക്കം ചെയ്യുമ്പോൾ ഓഡിയോ താൽക്കാലികമായി നിർത്തുക. യാന്ത്രികമായി പ്ലേ ചെയ്യുക @@ -222,9 +220,6 @@ ഇനിപ്പറയുന്ന അനുമതി ആവശ്യമാണ്: സിസ്റ്റം അലേർട്ട് വിൻഡോ \"പോപ്പ്അപ്പ് കാണിക്കുക\" സവിശേഷത സാധ്യമാക്കാൻ മറ്റ് ആപ്പുകളുടെ മുകളിൽ വരയ്ക്കാൻ CAPod-നെ അനുവദിക്കുക. - കുറഞ്ഞ പവർ - സന്തുലിതം - കുറഞ്ഞ ലേറ്റൻസി ആപ്പ് തുറന്നിരിക്കുമ്പോൾ ഉപകരണം കണക്റ്റുചെയ്യുമ്പോൾ എപ്പോഴും diff --git a/app/src/main/res/values-mn-rMN/strings.xml b/app/src/main/res/values-mn-rMN/strings.xml index 5f7f03d0..6119e914 100644 --- a/app/src/main/res/values-mn-rMN/strings.xml +++ b/app/src/main/res/values-mn-rMN/strings.xml @@ -46,8 +46,6 @@ Төхөөрөмж холбогдсон үед нэмэлт мэдэгдэл харуулна. Энэ нь \"Төхөөрөмжийн төлөв\" сувгийг идэвхгүй болгосноор \"Төхөөрөмж алга\" гэсэн байнгын мэдэгдлийг нуух боломжийг олгоно. Салсны дараа мэдэгдлийг хадгалах Таны AirPods салсан ч хамгийн сүүлд мэдэгдэж буй батарейн түвшинг үргэлжлүүлэн харуулна - Сканнерын горим - Bluetooth Low Energy өгөгдлийн сканнер нь гүйцэтгэлийг эсвэл эрчим хүчийг хэмнэхийг урьтал болгох ёстой юу? Автомат түр зогсоох Төхөөрөмжийг чихнээсээ салгахад дууг түр зогсооно. Автомат тоглуулах @@ -222,9 +220,6 @@ Дараах зөвшөөрөл шаардлагатай: Системийн анхааруулгын цонх CAPod-д \"Попап харуулах\" боломжийг ажиллуулахын тулд бусад апп-уудын дээр зурах зөвшөөрөл олгоно уу. - Бага эрчим хүч - Тэнцвэртэй - Бага хоцрогдол Апп нээлттэй үед Төхөөрөмж холбогдсон үед Үргэлж diff --git a/app/src/main/res/values-mr-rIN/strings.xml b/app/src/main/res/values-mr-rIN/strings.xml index 966a970c..8e432c73 100644 --- a/app/src/main/res/values-mr-rIN/strings.xml +++ b/app/src/main/res/values-mr-rIN/strings.xml @@ -46,8 +46,6 @@ जेव्हा एखादे डिव्हाइस कनेक्ट केलेले असते तेव्हा अतिरिक्त सूचना दर्शविते. हे आपल्याला \"डिव्हाइस स्थिती\" चॅनेल अक्षम करून कायमस्वरूपी \"कोणतेही डिव्हाइस नाही\" सूचना लपविण्यास अनुमती देते. डिस्कनेक्ट झाल्यानंतर सूचना ठेवा तुमचे AirPods डिस्कनेक्ट झाल्यानंतरही शेवटचे ज्ञात बॅटरी स्तर दर्शवणे सुरू ठेवा - स्कॅनर मोड - ब्लूटूथ लो एनर्जी डेटा स्कॅनरने कार्यक्षमतेला प्राधान्य द्यावे की ऊर्जा वाचवावी? ऑटो-पॉज आपल्या कानातून डिव्हाइस काढताना ऑडिओ थांबवा. ऑटो-प्ले @@ -222,9 +220,6 @@ खालील परवानगी आवश्यक आहे: सिस्टम अलर्ट विंडो \"पॉपअप दर्शवा\" वैशिष्ट्य शक्य करण्यासाठी CAPod ला इतर अॅप्सवर चित्रे काढण्याची अनुमती द्या. - कमी ऊर्जा - संतुलित - कमी विलंब अॅप उघडे असताना डिव्हाइस कनेक्ट असताना नेहमी diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index d141c6c6..4ac34294 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -46,8 +46,6 @@ Memaparkan pemberitahuan tambahan apabila peranti disambungkan. Ini membolehkan anda menyembunyikan pemberitahuan kekal \"Tiada peranti\" dengan melumpuhkan saluran \"Status peranti\". Kekalkan pemberitahuan selepas nyahsambung Terus menunjukkan tahap bateri terakhir yang diketahui walaupun selepas AirPods anda nyahsambung - Mod pengimbas - Patutkah pengimbas data Bluetooth Tenaga Rendah mengutamakan prestasi atau menjimatkan tenaga? Jeda automatik Jeda audio apabila peranti dikeluarkan dari telinga anda. Main automatik @@ -220,9 +218,6 @@ Kebenaran berikut diperlukan: Tetingkap Amaran Sistem Benarkan CAPod melukis di atas apl lain untuk membolehkan ciri \"Tunjukkan pop timbul\". - Kuasa rendah - Seimbang - Kependaman rendah Apabila apl dibuka Apabila peranti disambungkan Sentiasa diff --git a/app/src/main/res/values-my-rMM/strings.xml b/app/src/main/res/values-my-rMM/strings.xml index 960de5ae..fb0d1819 100644 --- a/app/src/main/res/values-my-rMM/strings.xml +++ b/app/src/main/res/values-my-rMM/strings.xml @@ -46,8 +46,6 @@ စက်ပစ္စည်းတစ်ခုချိတ်ဆက်သောအခါ အပိုအသိပေးချက်တစ်ခုပြသသည်။ ၎င်းသည် \"စက်ပစ္စည်းအခြေအနေ\" ချန်နယ်ကို ပိတ်ခြင်းဖြင့် အမြဲတမ်း \"စက်ပစ္စည်းမရှိပါ\" အသိပေးချက်ကို ဝှက်ထားနိုင်စေသည်။ ချိတ်ဆက်မှုပြတ်ပြီးနောက် အသိပေးချက်ကိုထားရှိပါ သင့် AirPods ချိတ်ဆက်မှုပြတ်ပြီးနောက်ပင် နောက်ဆုံးသိရှိထားသော ဘက်ထရီအဆင့်များကို ဆက်လက်ပြသပါ - စကင်နာမုဒ် - Bluetooth Low Energy ဒေတာစကင်နာသည် စွမ်းဆောင်ရည်ကို ဦးစားပေးသင့်သလား သို့မဟုတ် စွမ်းအင်ချွေတာသင့်သလား။ အလိုအလြှောက်ရပ်တန့်ခြင်း သင့်နားကြပ်ကို နားမှဖယ်ရှားသည့်အခါ အသံကိုခေတ္တရပ်ပါ။ အလိုအလြှောက်ဖွင့်ခြင်း @@ -220,9 +218,6 @@ အောက်ပါခွင့်ပြုချက်လိုအပ်သည်: စနစ်သတိပေးချက်ပြတင်းပေါက် \"ပြတင်းပေါက်ပြသခြင်း\" အင်္ဂါရပ်ကိုဖြစ်နိုင်စေရန် CAPod အား အခြားအက်ပ်များပေါ်တွင် ပုံဆွဲခွင့်ပြုပါ။ - စွမ်းအင်နည်း - ချိန်ညှိထားသော - နှောင့်နှေးမှုနည်း အက်ပ်ဖွင့်ထားသောအခါ စက်ပစ္စည်းချိတ်ဆက်ထားသောအခါ အမြဲတမ်း diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index bf8ccf01..28ac2065 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -46,8 +46,6 @@ Viser en ekstra varsling når en enhet er tilkoblet. Dette lar deg skjule det permanente varselet \"Ingen enheter\" ved å deaktivere kanalen \"Enhetsstatus\". Behold varsling etter frakobling Fortsett å vise de sist kjente batterinivåene selv etter at AirPods kobler fra - Skannermodus - Skal Bluetooth Low Energy data-skanneren prioritere ytelse eller å spare energi? Sett på pause automatisk Sett lyden på pause når du fjerner enheten fra øret. Spill av automatisk @@ -222,9 +220,6 @@ Følgende tillatelse er påkrevd: Systemvarslingsvindu Tillat CAPod å tegne over andre apper for å gjøre funksjonen \"Vis popup\" mulig. - Lavt strømforbruk - Balansert - Lav forsinkelse Når appen er åpen Når enheten er tilkoblet Alltid diff --git a/app/src/main/res/values-ne-rNP/strings.xml b/app/src/main/res/values-ne-rNP/strings.xml index 4d5a7f44..3594fe0e 100644 --- a/app/src/main/res/values-ne-rNP/strings.xml +++ b/app/src/main/res/values-ne-rNP/strings.xml @@ -46,8 +46,6 @@ उपकरण जडान हुँदा अतिरिक्त सूचना देखाउँछ। यसले तपाईंलाई \"उपकरण स्थिति\" च्यानल असक्षम गरेर स्थायी \"कुनै उपकरण छैन\" सूचना लुकाउन अनुमति दिन्छ। विच्छेद पछि सूचना राख्नुहोस् तपाईंको AirPods विच्छेद भएपछि पनि अन्तिम ज्ञात ब्याट्री स्तर देखाउन जारी राख्नुहोस् - स्क्यानर मोड - ब्लुटुथ कम ऊर्जा डाटा स्क्यानरले प्रदर्शनलाई प्राथमिकता दिनुपर्छ वा ऊर्जा बचत गर्नुपर्छ? स्वत: पज आफ्नो कानबाट उपकरण हटाउँदा अडियो पज गर्नुहोस्। स्वत: प्ले @@ -222,9 +220,6 @@ निम्न अनुमति आवश्यक छ: प्रणाली अलर्ट विन्डो \"पपअप देखाउनुहोस्\" सुविधा सम्भव बनाउन CAPod लाई अन्य एपहरूमाथि कोर्न अनुमति दिनुहोस्। - कम ऊर्जा - सन्तुलित - कम विलम्बता एप खुला हुँदा उपकरण जडान हुँदा सधैं diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 70cd76f4..d99992a8 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -46,8 +46,6 @@ Toont een extra melding wanneer een apparaat is verbonden. Hiermee kun je de permanente melding \"Geen apparaten\" verbergen door het kanaal \"Apparaatstatus\" uit te schakelen. Melding behouden na verbreken verbinding Blijf de laatst bekende batterijniveaus weergeven, zelfs nadat je AirPods zijn losgekoppeld - Scannermodus - Moet de \'Bluetooth Low Energy\'-datascanner prioriteit geven aan prestaties of aan energiebesparing? Auto pauze Pauzeer de audio wanneer je het apparaat van je oor haalt. Automatisch afspelen @@ -222,9 +220,6 @@ De volgende toestemming is vereist: Systeemwaarschuwingsvenster Geef CAPod de mogelijkheid om over andere apps heen te tekenen, zodat de functie \"Pop-up weergeven\" mogelijk is. - Laag vermogen - Evenwichtig - Lage latentie Wanneer de app geopend is Wanneer het apparaat is aangesloten Altijd diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 0629d7c4..b74159e7 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -46,8 +46,6 @@ Wyświetl dodatkowe powiadomienie, gdy urządzenie jest podłączone. Pozwala to ukryć stałe powiadomienie \"Brak urządzeń\", wyłączając kanał \"Status urządzenia\". Zachowaj powiadomienie po rozłączeniu Kontynuuj wyświetlanie ostatniego znanego poziomu baterii nawet po rozłączeniu AirPods - Tryb skanera - Czy skaner danych Bluetooth Low Energy ma priorytetowo działać w ramach wydajności, czy oszczędzania energii? Automatyczne wstrzymywanie Wstrzymaj odtwarzanie, gdy urządzenia jest wyciągane z ucha. Automatyczne odtwarzanie @@ -228,9 +226,6 @@ K4r0lSz; Następujące uprawnienie jest wymagane: Okna alertów systemowych Zezwól na wyświetlanie CAPod nad innymi aplikacjami, aby aktywować funkcję \"Wyświetlanie informacji\". - Oszczędzanie energii - Zrównoważone - Małe opóźnienia Gdy aplikacja jest uruchomiona Gdy urządzenie jest podłączone Zawsze diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index eb0e1b44..b7882730 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -46,8 +46,6 @@ Mostra uma notificação extra quando um dispositivo está conectado. Isso permite que você oculte a notificação permanente \"Nenhum dispositivo\" desativando o canal \"Status do dispositivo\". Manter notificação após desconectar Continuar mostrando os últimos níveis de bateria registrados mesmo após a desconexão do AirPods - Modo de scanner - O scanner de dados Bluetooth de Baixo Consumo de Energia deve priorizar o desempenho ou economizar energia? Pausa automática Pause o áudio ao remover o dispositivo do ouvido. Reprodução automática @@ -222,9 +220,6 @@ A seguinte permissão é necessária: Janela de Alerta do Sistema Permitir que o CAPod desenhe sobre outros aplicativos para tornar possível o recurso \"Mostrar PopUp\". - Baixa potência - Balanceado - Baixa latência Quando o aplicativo está aberto Quando o dispositivo está conectado Sempre diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index be6933ba..e88026fa 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -46,8 +46,6 @@ Mostra uma notificação extra quando um dispositivo está ligado. Isto permite-lhe ocultar a notificação permanente \"Sem dispositivos\" desativando o canal \"Estado do dispositivo\". Manter notificação após desligar Continuar a mostrar os últimos níveis de bateria conhecidos mesmo após os AirPods desligarem - Modo de scanner - O scanner de dados Bluetooth de Baixo Consumo de Energia deve dar prioridade ao desempenho ou poupar energia? Pausa automática Colocar o áudio em pausa ao remover o dispositivo do ouvido. Reprodução automática @@ -222,9 +220,6 @@ A seguinte permissão é necessária: Janela de alerta do sistema Permitir que o CAPod desenhe sobre outras aplicações para tornar possível a funcionalidade \"Mostrar PopUp\". - Baixo consumo - Equilibrado - Baixa latência Quando a aplicação está aberta Quando o dispositivo está ligado Sempre diff --git a/app/src/main/res/values-rm/strings.xml b/app/src/main/res/values-rm/strings.xml index 13d81902..e23a9df6 100644 --- a/app/src/main/res/values-rm/strings.xml +++ b/app/src/main/res/values-rm/strings.xml @@ -46,8 +46,6 @@ Mussa ina notificaziun supplementara cura ch\'in apparat è connectà. Quai permetta da zoppar la notificaziun permanenta \"Nagins apparats\" cun deactivar il chanal \"Stadi da l\'apparat\". Mantegnair la notificaziun suenter la deconnexiun Cuntinuar da mussar ils davos nivels da battaria enconuschents er suenter che Voss AirPods sa deconnectan - Modus da scanner - Duai il scanner da datas da Bluetooth Low Energy priorisar la prestaziun u spargnar energia? Pausa automata Interrumper l\'audio cura che l\'apparat vegn allontanà da l\'ureglia. Play automatic @@ -222,9 +220,6 @@ La suandanta permissiun è necessaria: Fanestra d\'avis dal sistem Permetter a CAPod da dessegnar sur autras apps per render pussaivla la funcziun \"Mussar PopUp\". - Bassa energia - Equilibrà - Bassa latenza Cura che l\'app è averta Cura che l\'apparat è connectà Adina diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 2b050e60..fd85b4d0 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -46,8 +46,6 @@ Afișează o notificare suplimentară atunci când un dispozitiv este conectat. Acest lucru vă permite să ascundeți notificarea permanentă \"Niciun dispozitiv\" prin dezactivarea canalului \"Stare dispozitiv\". Păstrează notificarea după deconectare Continuă să afișeze ultimele niveluri cunoscute ale bateriei chiar și după deconectarea AirPods - Modul scanare - Scanerul de date Bluetooth Energie Scăzută (BLE) ar trebui să acorde prioritate performanței sau economiei de energie? Pauză automată Întrerupeți sunetul când scoateți dispozitivul din ureche. Redare automată @@ -224,9 +222,6 @@ Următoarea permisiune este necesară: Fereastră alertă sistem Permiteți CAPod să deseneze peste alte aplicații pentru a face posibilă funcția \"Afișare PopUp\". - Consum redus - Echilibrat - Latență redusă Când aplicația este deschisă Când dispozitivul este conectat Întotdeauna diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3ab4437a..91371f34 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -46,8 +46,6 @@ Показывать дополнительное уведомление, когда устройство подключено. Это позволяет скрыть постоянное уведомление «Нет устройств», отключая канал «Статус устройства». Оставить уведомление после отключения Продолжать показывать последний известный заряд батареи даже после отключения AirPods - Режим сканера - Какой режим должен по умолчанию использовать сканер данных Bluetooth Low Energy - производительность или экономию энергии? Автопауза Приостановка аудио при удалении устройства из уха. Автовоспроизведение @@ -227,9 +225,6 @@ AL_Cool_T Требуется следующее разрешение: Окно системных предупреждений Позволить CAPod наложение поверх других приложений для работы функции \"Всплывающие сообщения\". - Низкая мощность - Сбалансированно - Низкая задержка Когда приложение открыто Когда устройство подключено Всегда diff --git a/app/src/main/res/values-sc-rIT/strings.xml b/app/src/main/res/values-sc-rIT/strings.xml index 6c0aec7e..b8c7e828 100644 --- a/app/src/main/res/values-sc-rIT/strings.xml +++ b/app/src/main/res/values-sc-rIT/strings.xml @@ -46,8 +46,6 @@ Mustrat una notìfica extra cando unu dispositivu est cullegadu. Custu ti permitit de cuare sa notìfica permanente \"Perunu dispositivu\" disativende su canale \"Istadu de su dispositivu\". Mantene sa notìfica a pustis de sa disconnexione Sighi a mustrare is ùrtimos livelos de bateria connotos fintzas a pustis chi is AirPods si disconnetint - Modalidade scanner - S\'iscaner de datos Bluetooth Low Energy depet dare prioridade a is prestatziones o aforrare energia? Pàusa automàtica Pone in pàusa s\'àudio cando bogas su dispositivu dae s\'origra. Riprodutzione automàtica @@ -222,9 +220,6 @@ Su permissu in fata est netzessàriu: Ventana de alerta de su sistema Permiti a CAPod de disegnare subra àteras apps pro rèndere possìbile sa funtzione \"Mustra PopUp\". - Consumu bàsciu - Ecuilibradu - Latèntzia bàscia Cando s\'app est aberta Cando su dispositivu est cullegadu Sèmper diff --git a/app/src/main/res/values-si-rLK/strings.xml b/app/src/main/res/values-si-rLK/strings.xml index a74d91e7..6c9cbb21 100644 --- a/app/src/main/res/values-si-rLK/strings.xml +++ b/app/src/main/res/values-si-rLK/strings.xml @@ -46,8 +46,6 @@ උපාංගයක් සම්බන්ධ වූ විට අමතර දැනුම්දීමක් පෙන්වයි. \"උපාංග තත්ත්වය\" නාලිකාව අක්‍රීය කිරීමෙන් \"උපාංග නොමැත\" ස්ථිර දැනුම්දීම සැඟවීමට මෙය ඔබට ඉඩ සලසයි. විසන්ධි වූ පසු දැනුම්දීම තබන්න ඔබගේ AirPods විසන්ධි වූ පසුවද අවසාන වරට දන්නා බැටරි මට්ටම් පෙන්වීම දිගටම කරන්න - ස්කෑනර් ප්‍රකාරය - බ්ලූටූත් අඩු ශක්ති දත්ත ස්කෑනරය කාර්ය සාධනයට ප්‍රමුඛත්වය දිය යුතුද නැතහොත් ශක්තිය සංරක්ෂණය කළ යුතුද? ස්වයංක්‍රීයව විරාම කරන්න ඔබේ කනෙන් උපාංගය ඉවත් කරන විට ශ්‍රව්‍ය විරාම කරන්න. ස්වයංක්‍රීයව වාදනය කරන්න @@ -222,9 +220,6 @@ පහත අවසරය අවශ්‍ය වේ: පද්ධති ඇඟවුම් කවුළුව \"පොප්-අප් පෙන්වන්න\" විශේෂාංගය හැකි කිරීමට CAPod හට වෙනත් යෙදුම් මත අඳින්නට ඉඩ දෙන්න. - අඩු ශක්තිය - සමතුලිත - අඩු ප්‍රමාදය යෙදුම විවෘතව ඇති විට උපාංගය සම්බන්ධ වූ විට සෑමවිටම diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 18033869..7d17ba9e 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -46,8 +46,6 @@ Zobrazí dodatočné oznámenie keď je zariadenie pripojené. To umožňuje skryť trvalé oznámenie \"Žiadne zariadenia\" vypnutím kanálu \"Stav zariadenia\". Ponechať oznámenie po odpojení Pokračovať v zobrazovaní posledných známych úrovní batérie aj po odpojení vašich AirPods - Režim skenera - Mal by skener Bluetooth Low Energy uprednostňovať výkon alebo šetriť energiu? Automatické pozastavenie Pozastavte zvuk, keď si vyberiete zariadenie z ucha. Automatické prehrávanie @@ -226,9 +224,6 @@ Je vyžadované nasledujúce povolenie: Systémové výstražné okno Povoľte CAPodu kresliť cez iné aplikácie, aby bola možná funkcia \"Zobraziť vyskakovacie okno\". - Nízka spotreba - Vyvážený - Nízka latencia Keď je aplikácia otvorená Keď je zariadenie pripojené Vždy diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 38535a65..ceb536ef 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -46,8 +46,6 @@ Prikaže dodatno obvestilo, ko je naprava povezana. To vam omogoča, da skrijete trajno obvestilo \"Ni naprav\" tako, da onemogočite kanal \"Stanje naprave\". Ohrani obvestilo po prekinitvi povezave Nadaljuj s prikazovanjem zadnjih znanih ravni baterije tudi po prekinitvi povezave z vašimi AirPods - Način optičnega bralnika - Ali naj optični bralnik podatkov Bluetooth Low Energy daje prednost zmogljivosti ali varčuje z energijo? Samodejna prekinitev Začasno ustavi zvok, ko napravo odstranite iz ušesa. Samodejno predvajanje @@ -226,9 +224,6 @@ Zahtevano je naslednje dovoljenje: Sistemsko opozorilno okno Dovolite CAPod risanje čez druge aplikacije, da omogočite funkcijo \"Pokaži pojavno okno\". - Nizka poraba - Uravnoteženo - Nizka zakasnitev Ko je aplikacija odprta Ko je naprava povezana Vedno diff --git a/app/src/main/res/values-sq-rAL/strings.xml b/app/src/main/res/values-sq-rAL/strings.xml index 00aabd65..bc911575 100644 --- a/app/src/main/res/values-sq-rAL/strings.xml +++ b/app/src/main/res/values-sq-rAL/strings.xml @@ -46,8 +46,6 @@ Shfaq një njoftim shtesë kur një pajisje lidhet. Kjo ju lejon të fshihni njoftimin e përhershëm \"Asnjë pajisje\" duke çaktivizuar kanalin \"Statusi i pajisjes\". Mbaj njoftimin pas shkëputjes Vazhdo të shfaqësh nivelet e fundit të njohura të baterisë edhe pasi AirPods tuaja shkëputen - Modaliteti i skanerit - A duhet skaneri i të dhënave Bluetooth Low Energy të prioritizojë performancën apo të kursejë energji? Pauzë automatike Vendos në pauzë audion kur hiqni pajisjen nga veshi. Luaj automatikisht @@ -222,9 +220,6 @@ Leja e mëposhtme kërkohet: Dritare Alarmi Sistemi Lejoni CAPod të vizatojë mbi aplikacionet e tjera për të mundësuar veçorinë \"Shfaq PopUp\". - Energji e ulët - I balancuar - Vonesë e ulët Kur aplikacioni është i hapur Kur pajisja është e lidhur Gjithmonë diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 000a7f2e..80b2338a 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -46,8 +46,6 @@ Приказује додатно обавештење када је уређај повезан. Ово вам омогућава да сакријете трајно обавештење „Нема уређаја” онемогућавањем канала „Статус уређаја”. Задржи обавештење након прекида везе Настави да приказује последње познате нивое батерије чак и након што се AirPods искључе - Режим скенера - Да ли би скенер података Bluetooth Low Energy требало да да приоритет перформансама или да штеди енергију? Аутоматска пауза Паузирајте звук када уклоните уређај из ува. Аутоматска репродукција @@ -224,9 +222,6 @@ Потребна је следећа дозвола: Приказ преко других апликација Дозволите CAPod-у да се приказује преко других апликација да би функција \"Прикажи искачући прозор\" била могућа. - Ниска потрошња - Уравнотежено - Ниска латенција Када је апликација отворена Када је уређај повезан Увек diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 235128f1..41c419e7 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -46,8 +46,6 @@ Visar en extra avisering när en enhet är ansluten. Detta låter dig dölja den permanenta aviseringen \"Inga enheter\" genom att inaktivera kanalen \"Enhetsstatus\". Behåll avisering efter frånkoppling Fortsätt visa de senast kända batterinivåerna även efter att dina AirPods kopplas från - Skannerläge - Ska Bluetooth Low Energy-dataskannern prioritera prestanda eller spara energi? Automatisk paus Pausa ljudet när du tar bort enheten från örat. Automatisk uppspelning @@ -222,9 +220,6 @@ Följande behörighet krävs: Visa över andra appar Tillåt CAPod att rita över andra appar för att möjliggöra funktionen \"Visa popup\". - Låg effekt - Balanserad - Låg latens När appen är öppen När enheten är ansluten Alltid diff --git a/app/src/main/res/values-sw/strings.xml b/app/src/main/res/values-sw/strings.xml index 46fcd13b..922a2296 100644 --- a/app/src/main/res/values-sw/strings.xml +++ b/app/src/main/res/values-sw/strings.xml @@ -46,8 +46,6 @@ Inaonyesha arifa ya ziada wakati kifaa kimeunganishwa. Hii inakuwezesha kuficha arifa ya kudumu ya \"Hakuna vifaa\" kwa kuzima kituo cha \"Hali ya kifaa\". Weka arifa baada ya kukata muunganisho Endelea kuonyesha viwango vya mwisho vya betri hata baada ya AirPods yako kukatika muunganisho - Hali ya skana - Je, skana ya data ya Bluetooth Low Energy itangulize utendakazi au ihifadhi nishati? Sitisha kiotomatiki Sitisha sauti unapotoa kifaa sikioni. Cheza kiotomatiki @@ -222,9 +220,6 @@ Ruhusa ifuatayo inahitajika: Dirisha la Arifa ya Mfumo Ruhusu CAPod kuchora juu ya programu nyingine ili kuwezesha kipengele cha \"Onyesha Kidirisha\". - Nishati ya chini - Uwiano - Ucheleweshaji mdogo Programu inapofunguliwa Kifaa kinapounganishwa Kila mara diff --git a/app/src/main/res/values-ta-rIN/strings.xml b/app/src/main/res/values-ta-rIN/strings.xml index 3401a816..0e3ede14 100644 --- a/app/src/main/res/values-ta-rIN/strings.xml +++ b/app/src/main/res/values-ta-rIN/strings.xml @@ -46,8 +46,6 @@ ஒரு சாதனம் இணைக்கப்படும்போது கூடுதல் அறிவிப்பைக் காட்டுகிறது. \"சாதன நிலை\" சேனலை முடக்குவதன் மூலம் நிரந்தர \"சாதனங்கள் இல்லை\" அறிவிப்பை மறைக்க இது உங்களை அனுமதிக்கிறது. துண்டிக்கப்பட்ட பிறகு அறிவிப்பை வைத்திரு உங்கள் AirPods துண்டிக்கப்பட்ட பிறகும் கடைசியாக அறியப்பட்ட பேட்டரி நிலைகளைக் காட்டவும் - ஸ்கேனர் முறை - புளூடூத் குறைந்த ஆற்றல் தரவு ஸ்கேனர் செயல்திறனுக்கு முன்னுரிமை அளிக்க வேண்டுமா அல்லது ஆற்றலைச் சேமிக்க வேண்டுமா? தானியங்கு இடைநிறுத்தம் உங்கள் காதில் இருந்து சாதனத்தை அகற்றும்போது ஆடியோவை இடைநிறுத்தவும். தானியங்கு இயக்கம் @@ -222,9 +220,6 @@ பின்வரும் அனுமதி தேவை: கணினி எச்சரிக்கை சாளரம் \"பாப்அப் காட்டு\" அம்சத்தை சாத்தியமாக்க CAPod-ஐ பிற ஆப்ஸ்களின் மேல் வரைய அனுமதிக்கவும். - குறைந்த ஆற்றல் - சமநிலை - குறைந்த தாமதம் ஆப்ஸ் திறந்திருக்கும்போது சாதனம் இணைக்கப்பட்டிருக்கும்போது எப்போதும் diff --git a/app/src/main/res/values-te-rIN/strings.xml b/app/src/main/res/values-te-rIN/strings.xml index ca368d83..0d7627f3 100644 --- a/app/src/main/res/values-te-rIN/strings.xml +++ b/app/src/main/res/values-te-rIN/strings.xml @@ -46,8 +46,6 @@ పరికరం కనెక్ట్ అయినప్పుడు అదనపు నోటిఫికేషన్‌ను చూపుతుంది. ఇది \"పరికర స్థితి\" ఛానెల్‌ను నిలిపివేయడం ద్వారా శాశ్వత \"పరికరం లేదు\" నోటిఫికేషన్‌ను దాచడానికి మిమ్మల్ని అనుమతిస్తుంది. డిస్‌కనెక్ట్ తర్వాత నోటిఫికేషన్ ఉంచు మీ AirPods డిస్‌కనెక్ట్ అయిన తర్వాత కూడా చివరిగా తెలిసిన బ్యాటరీ స్థాయిలను చూపించడం కొనసాగించు - స్కానర్ మోడ్ - బ్లూటూత్ తక్కువ శక్తి డేటా స్కానర్ పనితీరుకు ప్రాధాన్యత ఇవ్వాలా లేదా శక్తిని ఆదా చేయాలా? ఆటో పాజ్ మీ చెవి నుండి పరికరాన్ని తీసివేసినప్పుడు ఆడియోను పాజ్ చేయండి. ఆటో ప్లే @@ -222,9 +220,6 @@ కింది అనుమతి అవసరం: సిస్టమ్ అలర్ట్ విండో \"పాపప్ చూపించు\" ఫీచర్‌ను సాధ్యం చేయడానికి ఇతర యాప్‌ల మీద గీయడానికి CAPodను అనుమతించండి. - తక్కువ శక్తి - సమతుల్యం - తక్కువ జాప్యం యాప్ తెరిచి ఉన్నప్పుడు పరికరం కనెక్ట్ అయినప్పుడు ఎల్లప్పుడూ diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 704c538f..69e650a1 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -46,8 +46,6 @@ แสดงการแจ้งเตือนเพิ่มเติมเมื่ออุปกรณ์เชื่อมต่อ ซึ่งช่วยให้คุณสามารถซ่อนการแจ้งเตือนถาวร \"ไม่มีอุปกรณ์\" โดยการปิดใช้งานช่อง \"สถานะอุปกรณ์\" คงการแจ้งเตือนหลังตัดการเชื่อมต่อ แสดงระดับแบตเตอรี่ล่าสุดที่ทราบต่อไปแม้ว่า AirPods ของคุณจะตัดการเชื่อมต่อแล้ว - โหมดสแกนเนอร์ - เครื่องสแกนข้อมูล Bluetooth Low Energy ควรให้ความสำคัญกับประสิทธิภาพหรือประหยัดพลังงาน? หยุดชั่วคราวอัตโนมัติ หยุดเสียงชั่วคราวเมื่อถอดอุปกรณ์ออกจากหู เล่นอัตโนมัติ @@ -220,9 +218,6 @@ ต้องการสิทธิ์ต่อไปนี้: หน้าต่างแจ้งเตือนระบบ อนุญาตให้ CAPod วาดทับแอปอื่นเพื่อให้คุณสมบัติ \"แสดงป๊อปอัป\" ทำงานได้ - ประหยัดพลังงาน - สมดุล - ความหน่วงต่ำ เมื่อเปิดแอป เมื่ออุปกรณ์เชื่อมต่อ เสมอ diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index c1d3438e..dcfaabd3 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -46,8 +46,6 @@ Bir cihaz bağlandığında ek bir bildirim gösterir. Bu, \"Cihaz durumu\" kanalını devre dışı bırakarak kalıcı \"Cihaz yok\" bildirimini gizlemenizi sağlar. Bağlantı kesildikten sonra bildirimi koru AirPods bağlantısı kesildikten sonra bile bilinen son pil seviyelerini göstermeye devam et - Tarama modu - Bluetooth Düşük Enerji veri tarayıcısının performansa mı yoksa enerji tasarrufuna mı öncelik versin? Otomatik duraklat Aygıtı kulağınızdan çıkarınca sesi duraklatır. Otomatik oynat @@ -222,9 +220,6 @@ Aşağıdaki izin gereklidir: Sistem Uyarı Penceresi \"Açılır Pencere Göster\" özelliğini mümkün kılmak için CAPod\'un diğer uygulamaların üzerine çizmesine izin verin. - Düşük güç - Dengeli - Düşük gecikme Uygulama açıkken Cihaz bağlıyken Her zaman diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 16cf286b..f632faf8 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -46,8 +46,6 @@ Показує додаткове сповіщення, коли пристрій підключено. Це дозволяє приховати постійне сповіщення \"Немає пристроїв\", вимкнувши канал \"Стан пристрою\". Залишати сповіщення після відключення Продовжувати показувати останні відомі рівні заряду навіть після відключення AirPods - Режим сканера - Сканер даних Bluetooth Low Energy має зосередитися на продуктивності чи збереженні заряду батареї? Автопауза Зупинка відтворення аудіо, коли навушник прибрано з Вашого вуха. Автовідтворення @@ -226,9 +224,6 @@ Потрібен наступний дозвіл: Відображення поверх інших програм Дозвольте CAPod відображатися поверх інших програм, щоб уможливити функцію \"Показувати спливаюче вікно\". - Енергозбереження - Збалансований - Низька затримка Коли програму відкрито Коли пристрій підключено Завжди diff --git a/app/src/main/res/values-ur-rIN/strings.xml b/app/src/main/res/values-ur-rIN/strings.xml index 90d511a8..f239ec9a 100644 --- a/app/src/main/res/values-ur-rIN/strings.xml +++ b/app/src/main/res/values-ur-rIN/strings.xml @@ -46,8 +46,6 @@ جب کوئی آلہ منسلک ہوتا ہے تو ایک اضافی اطلاع دکھاتا ہے۔ اس سے آپ \"آلہ کی حیثیت\" چینل کو غیر فعال کر کے مستقل \"کوئی آلہ نہیں\" اطلاع کو چھپا سکتے ہیں۔ منقطع ہونے کے بعد اطلاع رکھیں آپ کے AirPods منقطع ہونے کے بعد بھی آخری معلوم بیٹری کی سطح دکھاتے رہیں - اسکینر موڈ - کیا بلوٹوتھ لو انرجی ڈیٹا اسکینر کو کارکردگی کو ترجیح دینی چاہئے یا توانائی بچانی چاہئے؟ خودکار توقف آلہ کو کان سے ہٹاتے وقت آڈیو کو روکیں۔ خودکار پلے @@ -222,9 +220,6 @@ درج ذیل اجازت درکار ہے: سسٹم الرٹ ونڈو \"پاپ اپ دکھائیں\" خصوصیت ممکن بنانے کے لئے CAPod کو دوسری ایپس کے اوپر ڈرا کرنے کی اجازت دیں۔ - کم توانائی - متوازن - کم تاخیر جب ایپ کھلی ہو جب آلہ منسلک ہو ہمیشہ diff --git a/app/src/main/res/values-uz/strings.xml b/app/src/main/res/values-uz/strings.xml index 318900b1..9aaed5c9 100644 --- a/app/src/main/res/values-uz/strings.xml +++ b/app/src/main/res/values-uz/strings.xml @@ -46,8 +46,6 @@ Qurilma ulanganda qo\'shimcha bildirishnoma ko\'rsatadi. Bu sizga \"Qurilma holati\" kanalini o\'chirib qo\'yish orqali doimiy \"Qurilmalar yo\'q\" bildirishnomasini yashirishga imkon beradi. Uzilgandan keyin bildirishnomani saqlash AirPods uzilgandan keyin ham oxirgi ma\'lum batareya darajalarini ko\'rsatishni davom ettiring - Skaner rejimi - Bluetooth Low Energy ma\'lumotlar skaneri samaradorlikni birinchi o\'ringa qo\'yishi kerakmi yoki energiyani tejashi kerakmi? Avtomatik pauza Qurilmani qulog\'ingizdan olib tashlaganingizda audioni pauza qiling. Avtomatik ijro etish @@ -222,9 +220,6 @@ Quyidagi ruxsat talab qilinadi: Tizim ogohlantirish oynasi \"Qalqib chiquvchi oynani ko\'rsatish\" funksiyasini mumkin qilish uchun CAPod\'ga boshqa ilovalar ustida chizish ruxsatini bering. - Kam quvvat - Muvozanatli - Kam kechikish Ilova ochiq bo\'lganda Qurilma ulanganda Har doim diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 6120adbf..22e75e47 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -46,8 +46,6 @@ Hiển thị thông báo bổ sung khi một thiết bị được kết nối. Điều này cho phép bạn ẩn thông báo cố định \"Không có thiết bị\" bằng cách tắt kênh \"Trạng thái thiết bị\". Giữ thông báo sau khi ngắt kết nối Tiếp tục hiển thị mức pin đã biết gần nhất ngay cả sau khi AirPods của bạn ngắt kết nối - Chế độ quét - Máy quét dữ liệu Bluetooth Low Energy nên ưu tiên hiệu suất hay tiết kiệm năng lượng? Tự động tạm dừng Tạm dừng âm thanh khi tháo thiết bị khỏi tai bạn. Tự động phát @@ -220,9 +218,6 @@ Cần quyền sau: Cửa sổ cảnh báo hệ thống Cho phép CAPod hiển thị đè lên các ứng dụng khác để tính năng Show PopUp hoạt động. - Tiết kiệm pin - Cân bằng - Độ trễ thấp Khi ứng dụng đang mở Khi thiết bị được kết nối Luôn luôn diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 72043ad8..05ab92be 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -46,8 +46,6 @@ 在设备连接时显示一条额外通知。这使您可以禁用“设备状态”通道来隐藏永久性的“无设备”通知。 断开连接后保持通知 即使您的 AirPods 断开连接,继续显示上次已知的电池电量水平 - 扫描模式 - 低功耗蓝牙数据扫描器应着重性能还是省电? 自动暂停 从耳中取出时自动暂停音频播放 自动播放 @@ -220,9 +218,6 @@ 需要以下权限: 系统警告窗口 允许 CAPod 在其他应用的界面上方显示,以允许如“显示弹窗”功能。 - 低耗电 - 平衡 - 低延迟 当应用程序打开时 设备连接时 总是 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index e707e8bb..a34e953f 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -46,8 +46,6 @@ 裝置連接時顯示額外通知。這讓您可以停用「裝置狀態」頻道來隱藏永久的「沒有裝置」通知。 斷線後保留通知 即使 AirPods 斷線後仍顯示上次的電量 - 掃描模式 - 低功耗藍牙掃描器應該優先考慮效能還是節能? 自動暫停 從耳中摘下時自動暫停。 自動播放 @@ -220,9 +218,6 @@ 需要以下權限: 系統警示視窗 允許 CAPod 在其他應用程式上方顯示內容,以啟用「顯示彈出式視窗」功能。 - 低功耗 - 平衡 - 低延遲 應用程式開啟時 裝置已連線時 一律 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 89603fd3..956948b8 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -46,8 +46,6 @@ 裝置連接時顯示額外通知。這讓您可以停用「裝置狀態」頻道來隱藏永久的「沒有裝置」通知。 斷線後保留通知 即使 AirPods 斷線後仍顯示上次的電量 - 掃描模式 - 低功耗藍牙掃描器應該優先考慮效能還是節能? 自動暫停 從耳中摘下時自動暫停。 自動播放 @@ -220,9 +218,6 @@ 可能要求下列權限: 系統警報視窗 允許 CAPod 在其他應用程式上繪圖,使「顯示彈出式視窗」功能成為可能。 - 低功耗 - 平衡 - 低延遲 應用程式開啟時 裝置連線時 一律 diff --git a/app/src/main/res/values-zu/strings.xml b/app/src/main/res/values-zu/strings.xml index 6b9a3c07..64ea334e 100644 --- a/app/src/main/res/values-zu/strings.xml +++ b/app/src/main/res/values-zu/strings.xml @@ -46,8 +46,6 @@ Ibonisa isaziso esengeziwe lapho idivayisi ixhunyiwe. Lokhu kukuvumela ukuthi ufihle isaziso esihlala njalo esithi \"Awekho amadivayisi\" ngokukhubaza isiteshi \"Isimo sedivayisi\". Gcina isaziso ngemva kokunqamuka Qhubeka ubonise amazinga ebhethri okugcina aziwayo nangemva kokuthi ama-AirPods akho anqamuke - Imodi yesithwebuli - Ingabe isithwebuli sedatha ye-Bluetooth Low Energy kufanele sibeke phambili ukusebenza noma ukonga amandla? Misa kancane ngokuzenzakalela Misa kancane umsindo lapho ukhipha idivayisi endlebeni yakho. Dlala ngokuzenzakalela @@ -222,9 +220,6 @@ Imvume elandelayo iyadingeka: Iwindi Lesexwayiso Sohlelo Vumela i-CAPod ukuthi idwebe phezu kwezinye izinhlelo zokusebenza ukwenza isici \"Bonisa isigelekeqe\" sikwazi ukusebenza. - Amandla aphansi - Okulinganiswe - Ukulibaziseka okuncane Uma uhlelo lokusebenza luvuliwe Uma idivayisi ixhunyiwe Njalo diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f924e1fc..d7977639 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,8 +50,6 @@ Shows an extra notification when a device is connected. This lets you hide the permanent \"No devices\" notification by disabling the \"Device status\" channel. Keep notification after disconnect Continue showing the last known battery levels even after your AirPods disconnect - Scanner mode - Should the Bluetooth Low Energy data scanner prioritize performance or conserve energy? Auto pause Pause audio when removing the device from your ear. Auto play @@ -251,10 +249,6 @@ System Alert Window Allow CAPod to draw over other apps to make the feature \"Show PopUp\" possible. - Low power - Balanced - Low latency - When app is open When device is connected Always diff --git a/app/src/test/java/eu/darken/capod/monitor/core/ble/BleScanModeControllerTest.kt b/app/src/test/java/eu/darken/capod/monitor/core/ble/BleScanModeControllerTest.kt new file mode 100644 index 00000000..d395e262 --- /dev/null +++ b/app/src/test/java/eu/darken/capod/monitor/core/ble/BleScanModeControllerTest.kt @@ -0,0 +1,328 @@ +package eu.darken.capod.monitor.core.ble + +import eu.darken.capod.common.AppForegroundState +import eu.darken.capod.common.bluetooth.BluetoothAddress +import eu.darken.capod.common.bluetooth.BluetoothDevice2 +import eu.darken.capod.common.bluetooth.BluetoothManager2 +import eu.darken.capod.common.bluetooth.ScannerMode +import eu.darken.capod.profiles.core.AppleDeviceProfile +import eu.darken.capod.profiles.core.DeviceProfile +import eu.darken.capod.profiles.core.DeviceProfilesRepo +import eu.darken.capod.pods.core.apple.PodModel +import io.kotest.matchers.shouldBe +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Test +import testhelpers.BaseTest + +class BleScanModeControllerTest : BaseTest() { + + @Test + fun `temporary override wins`() { + resolveScannerMode( + overrideMode = ScannerMode.LOW_POWER, + isForeground = true, + profileAddresses = setOf(ADDRESS), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = setOf(ADDRESS), + ) shouldBe ScannerMode.LOW_POWER + } + + @Test + fun `connected paired profile uses low latency in foreground`() { + resolveScannerMode( + overrideMode = null, + isForeground = true, + profileAddresses = setOf(ADDRESS), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = setOf(ADDRESS), + ) shouldBe ScannerMode.LOW_LATENCY + } + + @Test + fun `connected paired profile uses low latency in background`() { + resolveScannerMode( + overrideMode = null, + isForeground = false, + profileAddresses = setOf(ADDRESS), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = setOf(ADDRESS), + ) shouldBe ScannerMode.LOW_LATENCY + } + + @Test + fun `foreground without connected paired profile uses balanced`() { + resolveScannerMode( + overrideMode = null, + isForeground = true, + profileAddresses = setOf(ADDRESS), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = emptySet(), + ) shouldBe ScannerMode.BALANCED + } + + @Test + fun `background without connected paired profile uses low power`() { + resolveScannerMode( + overrideMode = null, + isForeground = false, + profileAddresses = setOf(ADDRESS), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = emptySet(), + ) shouldBe ScannerMode.LOW_POWER + } + + @Test + fun `connected unprofiled device does not use low latency`() { + resolveScannerMode( + overrideMode = null, + isForeground = true, + profileAddresses = setOf(ADDRESS), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = setOf(OTHER_ADDRESS), + ) shouldBe ScannerMode.BALANCED + } + + @Test + fun `connected unpaired profile does not use low latency`() { + resolveScannerMode( + overrideMode = null, + isForeground = false, + profileAddresses = setOf(ADDRESS), + bondedAddresses = emptySet(), + connectedAddresses = setOf(ADDRESS), + ) shouldBe ScannerMode.LOW_POWER + } + + @Test + fun `low latency requires the same address to be profiled bonded and connected`() { + resolveScannerMode( + overrideMode = null, + isForeground = false, + profileAddresses = setOf(ADDRESS, OTHER_ADDRESS), + bondedAddresses = setOf(ADDRESS, THIRD_ADDRESS), + connectedAddresses = setOf(OTHER_ADDRESS, THIRD_ADDRESS), + ) shouldBe ScannerMode.LOW_POWER + } + + @Test + fun `address matching is case insensitive`() { + resolveScannerMode( + overrideMode = null, + isForeground = false, + profileAddresses = setOf(ADDRESS.lowercase()), + bondedAddresses = setOf(ADDRESS), + connectedAddresses = setOf(ADDRESS.lowercase()), + ) shouldBe ScannerMode.LOW_LATENCY + } + + @Test + fun `scannerMode emits even when connectedDevices never emits - regression guard`() = runTest { + val controller = createController( + isForeground = MutableStateFlow(true), + profiles = MutableStateFlow(listOf(profileWithAddress(ADDRESS))), + connectedDevices = MutableStateFlow(emptyList()), + bondedAddresses = MutableStateFlow(emptySet()), + ) + + controller.scannerMode.first() shouldBe ScannerMode.BALANCED + } + + @Test + fun `scannerMode upgrades to LOW_LATENCY when bonded profile connects`() = + runTest(UnconfinedTestDispatcher()) { + val connected = MutableStateFlow>(emptyList()) + val controller = createController( + isForeground = MutableStateFlow(true), + profiles = MutableStateFlow(listOf(profileWithAddress(ADDRESS))), + connectedDevices = connected, + bondedAddresses = MutableStateFlow(setOf(ADDRESS)), + ) + + val emissions = mutableListOf() + val job = backgroundScope.launch { controller.scannerMode.collect { emissions += it } } + runCurrent() + + emissions.last() shouldBe ScannerMode.BALANCED + + connected.value = listOf(deviceWithAddress(ADDRESS)) + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_LATENCY + job.cancel() + } + + @Test + fun `withTemporaryOverride raises mode while active and releases on completion`() = + runTest(UnconfinedTestDispatcher()) { + val controller = createController( + isForeground = MutableStateFlow(false), + profiles = MutableStateFlow(emptyList()), + connectedDevices = MutableStateFlow(emptyList()), + bondedAddresses = MutableStateFlow(emptySet()), + ) + + val emissions = mutableListOf() + val collector = backgroundScope.launch { controller.scannerMode.collect { emissions += it } } + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_POWER + + val gate = CompletableDeferred() + val running = launch { + controller.withTemporaryOverride(ScannerMode.LOW_LATENCY) { gate.await() } + } + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_LATENCY + + gate.complete(Unit) + running.join() + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_POWER + collector.cancel() + } + + @Test + fun `overlapping withTemporaryOverride blocks both honored`() = runTest(UnconfinedTestDispatcher()) { + val controller = createController( + isForeground = MutableStateFlow(false), + profiles = MutableStateFlow(emptyList()), + connectedDevices = MutableStateFlow(emptyList()), + bondedAddresses = MutableStateFlow(emptySet()), + ) + + val emissions = mutableListOf() + val collector = backgroundScope.launch { controller.scannerMode.collect { emissions += it } } + runCurrent() + + val gateA = CompletableDeferred() + val gateB = CompletableDeferred() + + val a = launch { controller.withTemporaryOverride(ScannerMode.LOW_LATENCY) { gateA.await() } } + val b = launch { controller.withTemporaryOverride(ScannerMode.LOW_LATENCY) { gateB.await() } } + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_LATENCY + + gateA.complete(Unit) + a.join() + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_LATENCY + + gateB.complete(Unit) + b.join() + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_POWER + collector.cancel() + } + + @Test + fun `withTemporaryOverride releases on exception`() = runTest(UnconfinedTestDispatcher()) { + val controller = createController( + isForeground = MutableStateFlow(false), + profiles = MutableStateFlow(emptyList()), + connectedDevices = MutableStateFlow(emptyList()), + bondedAddresses = MutableStateFlow(emptySet()), + ) + + val emissions = mutableListOf() + val collector = backgroundScope.launch { controller.scannerMode.collect { emissions += it } } + runCurrent() + + runCatching { + controller.withTemporaryOverride(ScannerMode.LOW_LATENCY) { + throw IllegalStateException("boom") + } + } + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_POWER + collector.cancel() + } + + @Test + fun `withTemporaryOverride releases on cancellation`() = runTest(UnconfinedTestDispatcher()) { + val controller = createController( + isForeground = MutableStateFlow(false), + profiles = MutableStateFlow(emptyList()), + connectedDevices = MutableStateFlow(emptyList()), + bondedAddresses = MutableStateFlow(emptySet()), + ) + + val emissions = mutableListOf() + val collector = backgroundScope.launch { controller.scannerMode.collect { emissions += it } } + runCurrent() + + val gate = CompletableDeferred() + val running = launch { + try { + controller.withTemporaryOverride(ScannerMode.LOW_LATENCY) { gate.await() } + } catch (_: CancellationException) { + // expected + } + } + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_LATENCY + + running.cancel() + running.join() + runCurrent() + + emissions.last() shouldBe ScannerMode.LOW_POWER + collector.cancel() + } + + private fun profileWithAddress(address: BluetoothAddress): DeviceProfile = AppleDeviceProfile( + label = "test", + model = PodModel.AIRPODS_PRO2_USBC, + address = address, + ) + + private fun deviceWithAddress(address: BluetoothAddress): BluetoothDevice2 = mockk { + every { this@mockk.address } returns address + } + + private fun TestScope.createController( + isForeground: MutableStateFlow, + profiles: MutableStateFlow>, + connectedDevices: MutableStateFlow>, + bondedAddresses: MutableStateFlow>, + ): BleScanModeController { + val foregroundState: AppForegroundState = mockk { + every { this@mockk.isForeground } returns isForeground + } + val profilesRepo: DeviceProfilesRepo = mockk { + every { this@mockk.profiles } returns profiles + } + val bluetoothManager: BluetoothManager2 = mockk { + every { this@mockk.connectedDevices } returns connectedDevices + every { this@mockk.bondedDeviceAddresses } returns bondedAddresses + } + return BleScanModeController( + appScope = backgroundScope, + appForegroundState = foregroundState, + profilesRepo = profilesRepo, + bluetoothManager = bluetoothManager, + ) + } + + private companion object { + const val ADDRESS = "AA:BB:CC:DD:EE:FF" + const val OTHER_ADDRESS = "11:22:33:44:55:66" + const val THIRD_ADDRESS = "22:33:44:55:66:77" + } +}