mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 01:39:22 +02:00
Self grant run_any_in_background if possible
This commit is contained in:
parent
f0b940a7e5
commit
8941639fe5
3 changed files with 77 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -50,6 +50,12 @@ object AppOps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val setMode by lazy { try {
|
||||||
|
AppOpsManager::class.java.getMethod("setMode", String::class.java, Int::class.java, String::class.java, Int::class.java)
|
||||||
|
} catch (ex: ReflectiveOperationException) {
|
||||||
|
null
|
||||||
|
} }
|
||||||
|
|
||||||
fun getOpMode(op: String, appOpsManager: AppOpsManager, context: Context): Mode {
|
fun getOpMode(op: String, appOpsManager: AppOpsManager, context: Context): Mode {
|
||||||
try {
|
try {
|
||||||
val reflectionData = reflectionData ?: return Mode.Unknown
|
val reflectionData = reflectionData ?: return Mode.Unknown
|
||||||
|
@ -88,6 +94,28 @@ object AppOps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setMode(op: String, appOpsManager: AppOpsManager, context: Context, mode: Mode) {
|
||||||
|
val setMode = setMode
|
||||||
|
|
||||||
|
if (setMode == null) throw SecurityException("blocked by the OS")
|
||||||
|
|
||||||
|
val realMode = when (mode) {
|
||||||
|
Mode.Allowed -> AppOpsManager.MODE_ALLOWED
|
||||||
|
Mode.Default -> AppOpsManager.MODE_DEFAULT
|
||||||
|
Mode.Ignored -> AppOpsManager.MODE_IGNORED
|
||||||
|
Mode.Blocked -> AppOpsManager.MODE_ERRORED
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setMode.invoke(appOpsManager, op, Process.myUid(), context.packageName, realMode)
|
||||||
|
} catch (ex: InvocationTargetException) {
|
||||||
|
ex.cause?.let { throw it }
|
||||||
|
|
||||||
|
throw ex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
Unknown,
|
Unknown,
|
||||||
Allowed,
|
Allowed,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 - 2023 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,7 +22,6 @@ import android.app.admin.DevicePolicyManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.os.Build.VERSION_CODES
|
import android.os.Build.VERSION_CODES
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
|
@ -67,7 +66,9 @@ class BackgroundService: Service() {
|
||||||
|
|
||||||
if (VERSION.SDK_INT >= VERSION_CODES.P) {
|
if (VERSION.SDK_INT >= VERSION_CODES.P) {
|
||||||
if (activityManager.isBackgroundRestricted) {
|
if (activityManager.isBackgroundRestricted) {
|
||||||
return true
|
if (RunInBackgroundPermission.trySelfGrant(context)) {
|
||||||
|
if (activityManager.isBackgroundRestricted) return true
|
||||||
|
} else return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
|
*
|
||||||
|
* 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 version 3 of the License.
|
||||||
|
*
|
||||||
|
* 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 io.timelimit.android.integration.platform.android
|
||||||
|
|
||||||
|
import android.app.AppOpsManager
|
||||||
|
import android.app.admin.DevicePolicyManager
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
import io.timelimit.android.BuildConfig
|
||||||
|
|
||||||
|
object RunInBackgroundPermission {
|
||||||
|
private const val OP = "android:run_any_in_background"
|
||||||
|
|
||||||
|
fun trySelfGrant(context: Context): Boolean {
|
||||||
|
if (BuildConfig.storeCompilant) return false
|
||||||
|
|
||||||
|
val devicePolicyManager = context.getSystemService<DevicePolicyManager>() ?: return false
|
||||||
|
|
||||||
|
if (!devicePolicyManager.isDeviceOwnerApp(context.packageName)) return false
|
||||||
|
|
||||||
|
val appOpsService = context.getSystemService<AppOpsManager>() ?: return false
|
||||||
|
|
||||||
|
return try {
|
||||||
|
AppOps.setMode(OP, appOpsService, context, AppOps.Mode.Allowed)
|
||||||
|
|
||||||
|
true
|
||||||
|
} catch (ex: SecurityException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue