mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 13:45:35 +03:00
Move PowerUtils to dedicated power management service (#4073)
Move PowerUtils to dedicated power management service
This commit is contained in:
commit
df3ac186b4
8 changed files with 279 additions and 0 deletions
29
src/main/java/com/nextcloud/client/device/DeviceInfo.kt
Normal file
29
src/main/java/com/nextcloud/client/device/DeviceInfo.kt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.os.Build
|
||||||
|
|
||||||
|
class DeviceInfo {
|
||||||
|
val vendor: String = Build.MANUFACTURER.toLowerCase()
|
||||||
|
val apiLevel: Int = Build.VERSION.SDK_INT
|
||||||
|
}
|
40
src/main/java/com/nextcloud/client/device/DeviceModule.kt
Normal file
40
src/main/java/com/nextcloud/client/device/DeviceModule.kt
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.os.PowerManager
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
|
||||||
|
@Module
|
||||||
|
class DeviceModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun powerManagementService(context: Context): PowerManagementService {
|
||||||
|
val platformPowerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||||
|
return PowerManagementServiceImpl(
|
||||||
|
powerManager = platformPowerManager,
|
||||||
|
deviceInfo = DeviceInfo()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
4
src/main/java/com/nextcloud/client/device/Package.md
Normal file
4
src/main/java/com/nextcloud/client/device/Package.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Package com.nextcloud.client.device
|
||||||
|
|
||||||
|
This package provides utitilies to access underlying Android
|
||||||
|
hardware API and relevant abstractions.
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service provides all device power management
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
interface PowerManagementService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if power saving mode is enabled on this device.
|
||||||
|
* On platforms that do not support power saving mode it
|
||||||
|
* evaluates to false.
|
||||||
|
*
|
||||||
|
* @see android.os.PowerManager.isPowerSaveMode
|
||||||
|
*/
|
||||||
|
val isPowerSavingEnabled: Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the device vendor requires power saving
|
||||||
|
* exclusion workaround.
|
||||||
|
*
|
||||||
|
* @return true if workaround is required, false otherwise
|
||||||
|
*/
|
||||||
|
val isPowerSavingExclusionAvailable: Boolean
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.annotation.TargetApi
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.PowerManager
|
||||||
|
|
||||||
|
internal class PowerManagementServiceImpl(
|
||||||
|
private val powerManager: PowerManager,
|
||||||
|
private val deviceInfo: DeviceInfo = DeviceInfo()
|
||||||
|
) : PowerManagementService {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Vendors on this list use aggressive power saving methods that might
|
||||||
|
* break application experience.
|
||||||
|
*/
|
||||||
|
val OVERLY_AGGRESSIVE_POWER_SAVING_VENDORS = setOf("samsung", "huawei", "xiaomi")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isPowerSavingEnabled: Boolean
|
||||||
|
get() {
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
if (deviceInfo.apiLevel >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
return powerManager.isPowerSaveMode
|
||||||
|
}
|
||||||
|
// For older versions, we just say that device is not in power save mode
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isPowerSavingExclusionAvailable: Boolean
|
||||||
|
get() = deviceInfo.vendor in OVERLY_AGGRESSIVE_POWER_SAVING_VENDORS
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ package com.nextcloud.client.di;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
import com.nextcloud.client.appinfo.AppInfoModule;
|
import com.nextcloud.client.appinfo.AppInfoModule;
|
||||||
|
import com.nextcloud.client.device.DeviceModule;
|
||||||
import com.nextcloud.client.network.NetworkModule;
|
import com.nextcloud.client.network.NetworkModule;
|
||||||
import com.nextcloud.client.whatsnew.WhatsNewModule;
|
import com.nextcloud.client.whatsnew.WhatsNewModule;
|
||||||
import com.owncloud.android.MainApp;
|
import com.owncloud.android.MainApp;
|
||||||
|
@ -39,6 +40,7 @@ import dagger.android.support.AndroidSupportInjectionModule;
|
||||||
AppInfoModule.class,
|
AppInfoModule.class,
|
||||||
WhatsNewModule.class,
|
WhatsNewModule.class,
|
||||||
NetworkModule.class,
|
NetworkModule.class,
|
||||||
|
DeviceModule.class
|
||||||
})
|
})
|
||||||
@Singleton
|
@Singleton
|
||||||
public interface AppComponent {
|
public interface AppComponent {
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.os.Build
|
||||||
|
import android.os.PowerManager
|
||||||
|
import com.nhaarman.mockitokotlin2.never
|
||||||
|
import com.nhaarman.mockitokotlin2.verify
|
||||||
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
|
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.mockito.Mock
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner::class)
|
||||||
|
class TestPowerManagementService {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
lateinit var platformPowerManager: PowerManager
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
lateinit var deviceInfo: DeviceInfo
|
||||||
|
|
||||||
|
private lateinit var powerManagementService: PowerManagementServiceImpl
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
powerManagementService = PowerManagementServiceImpl(
|
||||||
|
powerManager = platformPowerManager,
|
||||||
|
deviceInfo = deviceInfo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `power saving queries power manager on API 21+`() {
|
||||||
|
// GIVEN
|
||||||
|
// API level >= 21
|
||||||
|
// power save mode is on
|
||||||
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
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 is not available below API 21`() {
|
||||||
|
// GIVEN
|
||||||
|
// API level <21
|
||||||
|
whenever(deviceInfo.apiLevel).thenReturn(Build.VERSION_CODES.KITKAT)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
// power save mode is checked
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
// power save mode is disabled
|
||||||
|
// power manager is not queried
|
||||||
|
assertFalse(powerManagementService.isPowerSavingEnabled)
|
||||||
|
verify(platformPowerManager, never()).isPowerSaveMode
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `power save 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 save exclusion is not available for other vendors`() {
|
||||||
|
whenever(deviceInfo.vendor).thenReturn("some_other_nice_vendor")
|
||||||
|
assertFalse(powerManagementService.isPowerSavingExclusionAvailable)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
mock-maker-inline
|
Loading…
Reference in a new issue