Add platform level

This commit is contained in:
Jonas Lochmann 2023-06-12 02:00:00 +02:00
parent a17d6d4fe3
commit 86d0592524
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
11 changed files with 1871 additions and 16 deletions

View file

@ -23,7 +23,7 @@ apply plugin: 'com.squareup.wire'
android {
namespace 'io.timelimit.android'
compileSdkVersion 33
compileSdkVersion 34
defaultConfig {
applicationId "io.timelimit.android"
minSdkVersion 21

File diff suppressed because it is too large Load diff

View file

@ -17,11 +17,11 @@ package io.timelimit.android.data
import android.annotation.SuppressLint
import android.content.Context
import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.InvalidationTracker
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import io.timelimit.android.async.Threads
import io.timelimit.android.data.dao.DerivedDataDao
@ -61,7 +61,9 @@ import java.util.concurrent.TimeUnit
UserU2FKey::class,
WidgetCategory::class,
WidgetConfig::class
], version = 46)
], version = 47, autoMigrations = [
AutoMigration(from = 46, to = 47)
])
abstract class RoomDatabase: RoomDatabase(), io.timelimit.android.data.Database {
companion object {
private val lock = Object()

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2023 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
@ -94,7 +94,11 @@ data class Device(
@ColumnInfo(name = "q_or_later")
val qOrLater: Boolean,
@ColumnInfo(name = "manipulation_flags")
val manipulationFlags: Long
val manipulationFlags: Long,
@ColumnInfo(name = "platform_type")
val platformType: String?,
@ColumnInfo(name = "platform_level", defaultValue = "0")
val platformLevel: Int
): JsonSerializable {
companion object {
private const val ID = "id"
@ -129,6 +133,8 @@ data class Device(
private const val ENABLE_ACTIVITY_LEVEL_BLOCKING = "ealb"
private const val Q_OR_LATER = "qol"
private const val MANIPULATION_FLAGS = "mf"
private const val PLATFORM_TYPE = "pt"
private const val PLATFORM_LEVEL = "pl"
fun parse(reader: JsonReader): Device {
var id: String? = null
@ -163,6 +169,8 @@ data class Device(
var enableActivityLevelBlocking = false
var qOrLater = false
var manipulationFlags = 0L
var platformType: String? = null
var platformLevel = 0
reader.beginObject()
@ -200,6 +208,8 @@ data class Device(
ENABLE_ACTIVITY_LEVEL_BLOCKING -> enableActivityLevelBlocking = reader.nextBoolean()
Q_OR_LATER -> qOrLater = reader.nextBoolean()
MANIPULATION_FLAGS -> manipulationFlags = reader.nextLong()
PLATFORM_TYPE -> platformType = reader.nextString()
PLATFORM_LEVEL -> platformLevel = reader.nextInt()
else -> reader.skipValue()
}
}
@ -238,7 +248,9 @@ data class Device(
wasAccessibilityServiceEnabled = wasAccessibilityServiceEnabled,
enableActivityLevelBlocking = enableActivityLevelBlocking,
qOrLater = qOrLater,
manipulationFlags = manipulationFlags
manipulationFlags = manipulationFlags,
platformType = platformType,
platformLevel = platformLevel
)
}
}
@ -310,6 +322,8 @@ data class Device(
writer.name(ENABLE_ACTIVITY_LEVEL_BLOCKING).value(enableActivityLevelBlocking)
writer.name(Q_OR_LATER).value(qOrLater)
writer.name(MANIPULATION_FLAGS).value(manipulationFlags)
platformType?.let { writer.name(PLATFORM_TYPE).value(it) }
writer.name(PLATFORM_LEVEL).value(platformLevel)
writer.endObject()
}
@ -392,4 +406,8 @@ object HadManipulationFlag {
object ManipulationFlag {
const val USED_FGS_KILLER = 1L shl 0
}
object DevicePlatform {
const val ANDROID = "android"
}

View file

@ -110,7 +110,9 @@ class AppSetupLogic(private val appLogic: AppLogic) {
wasAccessibilityServiceEnabled = false,
enableActivityLevelBlocking = false,
qOrLater = AndroidVersion.qOrLater,
manipulationFlags = 0
manipulationFlags = 0,
platformType = DevicePlatform.ANDROID,
platformLevel = AndroidVersion.platformLevel
)
appLogic.database.device().addDeviceSync(device)

View file

@ -26,6 +26,7 @@ import io.timelimit.android.coroutines.executeAndWait
import io.timelimit.android.coroutines.runAsync
import io.timelimit.android.coroutines.runAsyncExpectForever
import io.timelimit.android.data.backup.DatabaseBackup
import io.timelimit.android.data.model.DevicePlatform
import io.timelimit.android.data.model.ExperimentalFlags
import io.timelimit.android.data.model.ManipulationFlag
import io.timelimit.android.data.model.UserType
@ -982,6 +983,8 @@ class BackgroundTaskLogic(val appLogic: AppLogic) {
val overlayPermission = appLogic.platformIntegration.getDrawOverOtherAppsPermissionStatus(useStrictChecking)
val accessibilityService = appLogic.platformIntegration.isAccessibilityServiceEnabled()
val qOrLater = AndroidVersion.qOrLater
val platformType = DevicePlatform.ANDROID
val platformLevel = AndroidVersion.platformLevel
if (protectionLevel != deviceEntry.currentProtectionLevel) {
changes = changes.copy(
@ -1020,6 +1023,14 @@ class BackgroundTaskLogic(val appLogic: AppLogic) {
if (qOrLater && !deviceEntry.qOrLater) {
changes = changes.copy(isQOrLaterNow = true)
}
if (deviceEntry.platformType != platformType) {
changes = changes.copy(newPlatformType = platformType)
}
if (deviceEntry.platformLevel != platformLevel) {
changes = changes.copy(newPlatformLevel = platformLevel)
}
}
return changes

View file

@ -194,7 +194,9 @@ object ApplyServerDataStatus {
wasAccessibilityServiceEnabled = newDevice.wasAccessibilityServiceEnabled,
enableActivityLevelBlocking = newDevice.enableActivityLevelBlocking,
qOrLater = newDevice.qOrLater,
manipulationFlags = newDevice.manipulationFlags
manipulationFlags = newDevice.manipulationFlags,
platformType = newDevice.platformType,
platformLevel = newDevice.platformLevel ?: 0
))
newDeviceTitles.add(newDevice.name)
@ -231,7 +233,9 @@ object ApplyServerDataStatus {
wasAccessibilityServiceEnabled = newDevice.wasAccessibilityServiceEnabled,
enableActivityLevelBlocking = newDevice.enableActivityLevelBlocking,
qOrLater = newDevice.qOrLater,
manipulationFlags = newDevice.manipulationFlags
manipulationFlags = newDevice.manipulationFlags,
platformType = newDevice.platformType ?: oldDeviceEntry.platformType,
platformLevel = newDevice.platformLevel ?: oldDeviceEntry.platformLevel
)
if (updatedDeviceEntry != oldDeviceEntry) {

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2023 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
@ -1220,7 +1220,9 @@ data class UpdateDeviceStatusAction(
val newAppVersion: Int?,
val didReboot: Boolean,
val isQOrLaterNow: Boolean,
val addedManipulationFlags: Long
val addedManipulationFlags: Long,
val newPlatformType: String?,
val newPlatformLevel: Int?
): AppLogicAction() {
companion object {
const val TYPE_VALUE = "UPDATE_DEVICE_STATUS"
@ -1233,6 +1235,8 @@ data class UpdateDeviceStatusAction(
private const val DID_REBOOT = "didReboot"
private const val IS_Q_OR_LATER_NOW = "isQOrLaterNow"
private const val ADDED_MANIPULATION_FLAGS = "addedManipulationFlags"
private const val PLATFORM_TYPE = "platformType"
private const val PLATFORM_LEVEL = "platformLevel"
val empty = UpdateDeviceStatusAction(
newProtectionLevel = null,
@ -1243,7 +1247,9 @@ data class UpdateDeviceStatusAction(
newAppVersion = null,
didReboot = false,
isQOrLaterNow = false,
addedManipulationFlags = 0L
addedManipulationFlags = 0L,
newPlatformType = null,
newPlatformLevel = null
)
}
@ -1251,6 +1257,14 @@ data class UpdateDeviceStatusAction(
if (newAppVersion != null && newAppVersion < 0) {
throw IllegalArgumentException()
}
if (newPlatformType != null && newPlatformType.isEmpty()) {
throw IllegalArgumentException()
}
if (newPlatformLevel != null && newPlatformLevel < 0) {
throw IllegalArgumentException()
}
}
override fun serialize(writer: JsonWriter) {
@ -1304,6 +1318,14 @@ data class UpdateDeviceStatusAction(
writer.name(ADDED_MANIPULATION_FLAGS).value(addedManipulationFlags)
}
if (newPlatformType != null) {
writer.name(PLATFORM_TYPE).value(newPlatformType)
}
if (newPlatformLevel != null) {
writer.name(PLATFORM_LEVEL).value(newPlatformLevel)
}
writer.endObject()
}
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2023 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
@ -305,6 +305,14 @@ object LocalDatabaseAppLogicActionDispatcher {
device = device.copy(qOrLater = true)
}
if (action.newPlatformType != null) {
device = device.copy(platformType = action.newPlatformType)
}
if (action.newPlatformLevel != null) {
device = device.copy(platformLevel = action.newPlatformLevel)
}
if (action.addedManipulationFlags != 0L) {
device = device.copy(manipulationFlags = device.manipulationFlags or action.addedManipulationFlags)
}

View file

@ -323,7 +323,9 @@ data class ServerDeviceData(
val enableActivityLevelBlocking: Boolean,
val qOrLater: Boolean,
val manipulationFlags: Long,
val publicKey: ByteArray?
val publicKey: ByteArray?,
val platformType: String?,
val platformLevel: Int?
) {
companion object {
private const val DEVICE_ID = "deviceId"
@ -358,6 +360,8 @@ data class ServerDeviceData(
private const val Q_OR_LATER = "qOrLater"
private const val MANIPULATION_FLAGS = "mFlags"
private const val PUBLIC_KEY = "pk"
private const val PLATFORM_TYPE = "pType"
private const val PLATFORM_LEVEL = "pLevel"
fun parse(reader: JsonReader): ServerDeviceData {
var deviceId: String? = null
@ -392,6 +396,8 @@ data class ServerDeviceData(
var qOrLater = false
var manipulationFlags = 0L
var publicKey: ByteArray? = null
var platformType: String? = null
var platformLevel: Int? = null
reader.beginObject()
while (reader.hasNext()) {
@ -428,6 +434,8 @@ data class ServerDeviceData(
Q_OR_LATER -> qOrLater = reader.nextBoolean()
MANIPULATION_FLAGS -> manipulationFlags = reader.nextLong()
PUBLIC_KEY -> publicKey = reader.nextString().parseBase64()
PLATFORM_TYPE -> platformType = reader.nextString()
PLATFORM_LEVEL -> platformLevel = reader.nextInt()
else -> reader.skipValue()
}
}
@ -465,7 +473,9 @@ data class ServerDeviceData(
enableActivityLevelBlocking = enableActivityLevelBlocking,
qOrLater = qOrLater,
manipulationFlags = manipulationFlags,
publicKey = publicKey
publicKey = publicKey,
platformType = platformType,
platformLevel = platformLevel
)
}

View file

@ -1,5 +1,5 @@
/*
* TimeLimit Copyright <C> 2019 Jonas Lochmann
* TimeLimit Copyright <C> 2019 - 2023 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
@ -19,4 +19,9 @@ import android.os.Build
object AndroidVersion {
val qOrLater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
val platformLevel =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 2
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) 1
else 0
}