255 lines
8.9 KiB
Kotlin
255 lines
8.9 KiB
Kotlin
/*
|
|
* Nextcloud Android client application
|
|
*
|
|
* @author Chris Narkiewicz
|
|
*
|
|
* Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package com.nextcloud.client.device
|
|
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.os.BatteryManager
|
|
import android.os.Build
|
|
import android.os.PowerManager
|
|
import com.nextcloud.client.preferences.AppPreferences
|
|
import com.nhaarman.mockitokotlin2.any
|
|
import com.nhaarman.mockitokotlin2.anyOrNull
|
|
import com.nhaarman.mockitokotlin2.eq
|
|
import com.nhaarman.mockitokotlin2.mock
|
|
import com.nhaarman.mockitokotlin2.never
|
|
import com.nhaarman.mockitokotlin2.verify
|
|
import com.nhaarman.mockitokotlin2.whenever
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertFalse
|
|
import org.junit.Assert.assertTrue
|
|
import org.junit.Before
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
import org.junit.runners.Suite
|
|
import org.mockito.Mock
|
|
import org.mockito.MockitoAnnotations
|
|
|
|
@RunWith(Suite::class)
|
|
@Suite.SuiteClasses(
|
|
TestPowerManagementService.PowerSaveMode::class,
|
|
TestPowerManagementService.Battery::class
|
|
)
|
|
class TestPowerManagementService {
|
|
|
|
abstract class Base {
|
|
@Mock
|
|
lateinit var context: Context
|
|
|
|
@Mock
|
|
lateinit var platformPowerManager: PowerManager
|
|
|
|
@Mock
|
|
lateinit var deviceInfo: DeviceInfo
|
|
|
|
internal lateinit var powerManagementService: PowerManagementServiceImpl
|
|
|
|
@Mock
|
|
lateinit var preferences: AppPreferences
|
|
|
|
@Before
|
|
fun setUpBase() {
|
|
MockitoAnnotations.initMocks(this)
|
|
powerManagementService = PowerManagementServiceImpl(
|
|
context,
|
|
platformPowerManager,
|
|
preferences,
|
|
deviceInfo
|
|
)
|
|
}
|
|
}
|
|
|
|
class PowerSaveMode : Base() {
|
|
|
|
@Test
|
|
fun `power saving queries power manager on API 21+`() {
|
|
// GIVEN
|
|
// API level >= 22 (since 22+ is supported)
|
|
// power save mode is on
|
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.LOLLIPOP_MR1)
|
|
whenever(platformPowerManager.isPowerSaveMode).thenReturn(true)
|
|
|
|
// WHEN
|
|
// power save mode is checked
|
|
// THEN
|
|
// power save mode is enabled
|
|
// state is obtained from platform power manager
|
|
assertTrue(powerManagementService.isPowerSavingEnabled)
|
|
verify(platformPowerManager).isPowerSaveMode
|
|
}
|
|
|
|
@Test
|
|
fun `power saving exclusion is available for flagged vendors`() {
|
|
for (vendor in PowerManagementServiceImpl.OVERLY_AGGRESSIVE_POWER_SAVING_VENDORS) {
|
|
whenever(deviceInfo.vendor).thenReturn(vendor)
|
|
assertTrue("Vendor $vendor check failed", powerManagementService.isPowerSavingExclusionAvailable)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `power saving exclusion is not available for other vendors`() {
|
|
whenever(deviceInfo.vendor).thenReturn("some_other_nice_vendor")
|
|
assertFalse(powerManagementService.isPowerSavingExclusionAvailable)
|
|
}
|
|
|
|
@Test
|
|
fun `power saving check is disabled`() {
|
|
// GIVEN
|
|
// a device which falsely returns power save mode enabled
|
|
// power check is overridden by user
|
|
whenever(preferences.isPowerCheckDisabled).thenReturn(true)
|
|
whenever(platformPowerManager.isPowerSaveMode).thenReturn(true)
|
|
|
|
// WHEN
|
|
// power save mode is checked
|
|
// THEN
|
|
// power saving is disabled
|
|
assertFalse(powerManagementService.isPowerSavingEnabled)
|
|
}
|
|
}
|
|
|
|
class Battery : Base() {
|
|
|
|
companion object {
|
|
const val FULL_RAGE = 32
|
|
const val HALF_RANGE = 16
|
|
}
|
|
|
|
val intent: Intent = mock()
|
|
|
|
@Before
|
|
fun setUp() {
|
|
whenever(context.registerReceiver(anyOrNull(), anyOrNull())).thenReturn(intent)
|
|
}
|
|
|
|
@Test
|
|
fun `battery charging status on API 17+`() {
|
|
// GIVEN
|
|
// device has API level 17+
|
|
// battery status sticky intent is available
|
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
|
val powerSources = setOf(
|
|
BatteryManager.BATTERY_PLUGGED_AC,
|
|
BatteryManager.BATTERY_PLUGGED_USB,
|
|
BatteryManager.BATTERY_PLUGGED_WIRELESS
|
|
)
|
|
|
|
for (row in powerSources) {
|
|
// WHEN
|
|
// device is charging using supported power source
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_PLUGGED), any()))
|
|
.thenReturn(row)
|
|
|
|
// THEN
|
|
// charging flag is true
|
|
assertTrue(powerManagementService.battery.isCharging)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `battery charging status on API 16`() {
|
|
// GIVEN
|
|
// device has API level 16
|
|
// battery status sticky intent is available
|
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.JELLY_BEAN)
|
|
val powerSources = setOf(
|
|
BatteryManager.BATTERY_PLUGGED_AC,
|
|
BatteryManager.BATTERY_PLUGGED_USB
|
|
)
|
|
|
|
for (row in powerSources) {
|
|
// WHEN
|
|
// device is charging using AC or USB
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_PLUGGED), any()))
|
|
.thenReturn(row)
|
|
|
|
// THEN
|
|
// charging flag is true
|
|
assertTrue(powerManagementService.battery.isCharging)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `wireless charging is not supported in API 16`() {
|
|
// GIVEN
|
|
// device has API level 16
|
|
// battery status sticky intent is available
|
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.JELLY_BEAN)
|
|
|
|
// WHEN
|
|
// spurious wireless power source is returned
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_PLUGGED), any()))
|
|
.thenReturn(BatteryManager.BATTERY_PLUGGED_WIRELESS)
|
|
|
|
// THEN
|
|
// power source value is ignored on this API level
|
|
// charging flag is false
|
|
assertFalse(powerManagementService.battery.isCharging)
|
|
}
|
|
|
|
@Test
|
|
fun `battery status sticky intent is not available`() {
|
|
// GIVEN
|
|
// device has API level P or below
|
|
// battery status sticky intent is NOT available
|
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.P)
|
|
whenever(context.registerReceiver(anyOrNull(), anyOrNull())).thenReturn(null)
|
|
|
|
// THEN
|
|
// charging flag is false
|
|
assertFalse(powerManagementService.battery.isCharging)
|
|
verify(context).registerReceiver(anyOrNull(), any())
|
|
}
|
|
|
|
@Test
|
|
@Suppress("MagicNumber")
|
|
fun `battery level is available`() {
|
|
// GIVEN
|
|
// battery level info is available
|
|
// battery is at 50%
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_LEVEL), any()))
|
|
.thenReturn(HALF_RANGE)
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_SCALE), any()))
|
|
.thenReturn(FULL_RAGE)
|
|
|
|
// THEN
|
|
// battery level is calculated from extra values
|
|
assertEquals(50, powerManagementService.battery.level)
|
|
}
|
|
|
|
@Test
|
|
fun `battery level is not available`() {
|
|
// GIVEN
|
|
// battery level is not available
|
|
val defaultValueArgIndex = 1
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_LEVEL), any()))
|
|
.thenAnswer { it.getArgument(defaultValueArgIndex) }
|
|
whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_SCALE), any()))
|
|
.thenAnswer { it.getArgument(defaultValueArgIndex) }
|
|
|
|
// THEN
|
|
// battery level is 100
|
|
assertEquals(BatteryStatus.BATTERY_FULL, powerManagementService.battery.level)
|
|
}
|
|
}
|
|
}
|