TestPowerManagementService.kt 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Nextcloud Android client application
  3. *
  4. * @author Chris Narkiewicz
  5. *
  6. * Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. package com.nextcloud.client.device
  22. import android.content.Context
  23. import android.content.Intent
  24. import android.os.BatteryManager
  25. import android.os.Build
  26. import android.os.PowerManager
  27. import com.nextcloud.client.preferences.AppPreferences
  28. import com.nhaarman.mockitokotlin2.any
  29. import com.nhaarman.mockitokotlin2.anyOrNull
  30. import com.nhaarman.mockitokotlin2.eq
  31. import com.nhaarman.mockitokotlin2.mock
  32. import com.nhaarman.mockitokotlin2.verify
  33. import com.nhaarman.mockitokotlin2.whenever
  34. import org.junit.Assert.assertEquals
  35. import org.junit.Assert.assertFalse
  36. import org.junit.Assert.assertTrue
  37. import org.junit.Before
  38. import org.junit.Test
  39. import org.junit.runner.RunWith
  40. import org.junit.runners.Suite
  41. import org.mockito.Mock
  42. import org.mockito.MockitoAnnotations
  43. @RunWith(Suite::class)
  44. @Suite.SuiteClasses(
  45. TestPowerManagementService.PowerSaveMode::class,
  46. TestPowerManagementService.Battery::class
  47. )
  48. class TestPowerManagementService {
  49. abstract class Base {
  50. @Mock
  51. lateinit var context: Context
  52. @Mock
  53. lateinit var platformPowerManager: PowerManager
  54. @Mock
  55. lateinit var deviceInfo: DeviceInfo
  56. internal lateinit var powerManagementService: PowerManagementServiceImpl
  57. @Mock
  58. lateinit var preferences: AppPreferences
  59. @Before
  60. fun setUpBase() {
  61. MockitoAnnotations.initMocks(this)
  62. powerManagementService = PowerManagementServiceImpl(
  63. context,
  64. platformPowerManager,
  65. preferences,
  66. deviceInfo
  67. )
  68. }
  69. }
  70. class PowerSaveMode : Base() {
  71. @Test
  72. fun `power saving queries power manager on API 21+`() {
  73. // GIVEN
  74. // API level >= 21
  75. // power save mode is on
  76. whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.Q)
  77. whenever(platformPowerManager.isPowerSaveMode).thenReturn(true)
  78. // WHEN
  79. // power save mode is checked
  80. // THEN
  81. // power save mode is enabled
  82. // state is obtained from platform power manager
  83. assertTrue(powerManagementService.isPowerSavingEnabled)
  84. verify(platformPowerManager).isPowerSaveMode
  85. }
  86. @Test
  87. fun `power saving exclusion is available for flagged vendors`() {
  88. for (vendor in PowerManagementServiceImpl.OVERLY_AGGRESSIVE_POWER_SAVING_VENDORS) {
  89. whenever(deviceInfo.vendor).thenReturn(vendor)
  90. assertTrue("Vendor $vendor check failed", powerManagementService.isPowerSavingExclusionAvailable)
  91. }
  92. }
  93. @Test
  94. fun `power saving exclusion is not available for other vendors`() {
  95. whenever(deviceInfo.vendor).thenReturn("some_other_nice_vendor")
  96. assertFalse(powerManagementService.isPowerSavingExclusionAvailable)
  97. }
  98. @Test
  99. fun `power saving check is disabled`() {
  100. // GIVEN
  101. // a device which falsely returns power save mode enabled
  102. // power check is overridden by user
  103. whenever(preferences.isPowerCheckDisabled).thenReturn(true)
  104. whenever(platformPowerManager.isPowerSaveMode).thenReturn(true)
  105. // WHEN
  106. // power save mode is checked
  107. // THEN
  108. // power saving is disabled
  109. assertFalse(powerManagementService.isPowerSavingEnabled)
  110. }
  111. }
  112. class Battery : Base() {
  113. companion object {
  114. const val FULL_RAGE = 32
  115. const val HALF_RANGE = 16
  116. }
  117. val intent: Intent = mock()
  118. @Before
  119. fun setUp() {
  120. whenever(context.registerReceiver(anyOrNull(), anyOrNull())).thenReturn(intent)
  121. }
  122. @Test
  123. fun `battery charging status on API 17+`() {
  124. // GIVEN
  125. // device has API level 17+
  126. // battery status sticky intent is available
  127. whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.JELLY_BEAN_MR1)
  128. val powerSources = setOf(
  129. BatteryManager.BATTERY_PLUGGED_AC,
  130. BatteryManager.BATTERY_PLUGGED_USB,
  131. BatteryManager.BATTERY_PLUGGED_WIRELESS
  132. )
  133. for (row in powerSources) {
  134. // WHEN
  135. // device is charging using supported power source
  136. whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_PLUGGED), any()))
  137. .thenReturn(row)
  138. // THEN
  139. // charging flag is true
  140. assertTrue(powerManagementService.battery.isCharging)
  141. }
  142. }
  143. @Test
  144. fun `battery charging status on API 16`() {
  145. // GIVEN
  146. // device has API level 16
  147. // battery status sticky intent is available
  148. whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.JELLY_BEAN)
  149. val powerSources = setOf(
  150. BatteryManager.BATTERY_PLUGGED_AC,
  151. BatteryManager.BATTERY_PLUGGED_USB
  152. )
  153. for (row in powerSources) {
  154. // WHEN
  155. // device is charging using AC or USB
  156. whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_PLUGGED), any()))
  157. .thenReturn(row)
  158. // THEN
  159. // charging flag is true
  160. assertTrue(powerManagementService.battery.isCharging)
  161. }
  162. }
  163. @Test
  164. fun `battery status sticky intent is not available`() {
  165. // GIVEN
  166. // device has API level P or below
  167. // battery status sticky intent is NOT available
  168. whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.P)
  169. whenever(context.registerReceiver(anyOrNull(), anyOrNull())).thenReturn(null)
  170. // THEN
  171. // charging flag is false
  172. assertFalse(powerManagementService.battery.isCharging)
  173. verify(context).registerReceiver(anyOrNull(), any())
  174. }
  175. @Test
  176. @Suppress("MagicNumber")
  177. fun `battery level is available`() {
  178. // GIVEN
  179. // battery level info is available
  180. // battery is at 50%
  181. whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_LEVEL), any()))
  182. .thenReturn(HALF_RANGE)
  183. whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_SCALE), any()))
  184. .thenReturn(FULL_RAGE)
  185. // THEN
  186. // battery level is calculated from extra values
  187. assertEquals(50, powerManagementService.battery.level)
  188. }
  189. @Test
  190. fun `battery level is not available`() {
  191. // GIVEN
  192. // battery level is not available
  193. val defaultValueArgIndex = 1
  194. whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_LEVEL), any()))
  195. .thenAnswer { it.getArgument(defaultValueArgIndex) }
  196. whenever(intent.getIntExtra(eq(BatteryManager.EXTRA_SCALE), any()))
  197. .thenAnswer { it.getArgument(defaultValueArgIndex) }
  198. // THEN
  199. // battery level is 100
  200. assertEquals(BatteryStatus.BATTERY_FULL, powerManagementService.battery.level)
  201. }
  202. }
  203. }