diff --git a/app/build.gradle b/app/build.gradle index 68be34143..9cb129bae 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,6 +47,10 @@ android { } } +androidExtensions { + experimental = true +} + dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation project(':net') @@ -72,8 +76,23 @@ dependencies { implementation "org.koin:koin-android:${koin}" implementation "org.koin:koin-androidx-viewmodel:${koin}" + def vRetrofit = "2.5.0" + def vOkHttp = "3.12.0" + def vMoshi = "1.8.0" + implementation "com.squareup.retrofit2:retrofit:${vRetrofit}" + implementation "com.squareup.retrofit2:converter-moshi:${vRetrofit}" + implementation "com.squareup.retrofit2:adapter-rxjava2:${vRetrofit}" + implementation "com.squareup.okhttp3:okhttp:${vOkHttp}" + implementation "com.squareup.okhttp3:logging-interceptor:${vOkHttp}" + implementation "com.squareup.moshi:moshi:${vMoshi}" + implementation "com.squareup.moshi:moshi-kotlin:${vMoshi}" + + def vKotpref = "2.8.0" + implementation "com.chibatching.kotpref:kotpref:${vKotpref}" + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.browser:browser:1.0.0' implementation 'androidx.preference:preference:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha04' implementation 'androidx.cardview:cardview:1.0.0' diff --git a/app/src/main/java/com/topjohnwu/magisk/Constants.kt b/app/src/main/java/com/topjohnwu/magisk/Constants.kt new file mode 100644 index 000000000..c23f3422a --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/Constants.kt @@ -0,0 +1,20 @@ +package com.topjohnwu.magisk + +import android.os.Process + +object Constants { + + // Paths + val MAGISK_PATH = "/sbin/.magisk/img" + val MAGISK_LOG = "/cache/magisk.log" + + val USER_ID = Process.myUid() / 100000 + + const val SNET_REVISION = "b66b1a914978e5f4c4bbfd74a59f4ad371bac107" + const val BOOTCTL_REVISION = "9c5dfc1b8245c0b5b524901ef0ff0f8335757b77" + + const val GITHUB_URL = "https://github.com/" + const val GITHUB_API_URL = "https://api.github.com/" + const val GITHUB_RAW_API_URL = "https://raw.githubusercontent.com/" + +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/KConfig.kt b/app/src/main/java/com/topjohnwu/magisk/KConfig.kt new file mode 100644 index 000000000..be3ecde27 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/KConfig.kt @@ -0,0 +1,36 @@ +package com.topjohnwu.magisk + +import androidx.appcompat.app.AppCompatDelegate +import com.chibatching.kotpref.KotprefModel +import com.topjohnwu.magisk.KConfig.UpdateChannel.* + +object KConfig : KotprefModel() { + override val kotprefName: String = "${context.packageName}_preferences" + + var darkMode by intPref(default = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, key = "darkMode") + var magiskChecksum by stringPref("", "magiskChecksum") + var forceEncrypt by booleanPref(false, "forceEncryption") + var keepVerity by booleanPref(false, "keepVerity") + var bootFormat by stringPref("img", "bootFormat") + var suLogTimeout by longPref(0, "suLogTimeout") + private var internalUpdateChannel by stringPref( + KConfig.UpdateChannel.STABLE.toString(), + "updateChannel" + ) + var useCustomTabs by booleanPref(true, "useCustomTabs") + + var updateChannel: UpdateChannel + get() = valueOf(internalUpdateChannel) + set(value) { + internalUpdateChannel = value.toString() + } + + val isStable get() = !(isCanary || isBeta) + val isCanary get() = updateChannel == CANARY || updateChannel == CANARY_DEBUG + val isBeta get() = updateChannel == BETA + + + enum class UpdateChannel { + STABLE, BETA, CANARY, CANARY_DEBUG + } +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/data/database/AppDatabase.kt b/app/src/main/java/com/topjohnwu/magisk/data/database/AppDatabase.kt new file mode 100644 index 000000000..e09f238bb --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/data/database/AppDatabase.kt @@ -0,0 +1,19 @@ +package com.topjohnwu.magisk.data.database + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.topjohnwu.magisk.model.entity.Repository + +@Database( + version = 1, + entities = [Repository::class] +) +abstract class AppDatabase : RoomDatabase() { + + companion object { + const val NAME = "database" + } + + abstract fun repoDao(): RepositoryDao + +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/data/database/LogDao.kt b/app/src/main/java/com/topjohnwu/magisk/data/database/LogDao.kt new file mode 100644 index 000000000..1bb589d2a --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/data/database/LogDao.kt @@ -0,0 +1,34 @@ +package com.topjohnwu.magisk.data.database + +import com.topjohnwu.magisk.Config +import com.topjohnwu.magisk.data.database.base.* +import com.topjohnwu.magisk.model.entity.MagiskLog +import com.topjohnwu.magisk.model.entity.toLog +import com.topjohnwu.magisk.model.entity.toMap +import java.util.concurrent.TimeUnit + +class LogDao : BaseDao() { + + override val table = DatabaseDefinition.Table.LOG + + fun deleteOutdated( + suTimeout: Long = Config.suLogTimeout * TimeUnit.DAYS.toMillis(1) + ) = query { + condition { + lessThan("time", suTimeout.toString()) + } + }.ignoreElement() + + fun deleteAll() = query {}.ignoreElement() + + fun fetchAll() = query { + condition { + equals("uid", uid.toString()) + } + }.map { it.first().toPolicy(context.packageManager) } + .doOnError { + if (it is PackageManager.NameNotFoundException) { + delete(uid).subscribe() + } + } + + fun update(policy: MagiskPolicy) = query { + + values(policy.toMap()) + }.ignoreElement() + + fun fetchAll() = query { + condition { equals("key", key) } + }.map { it.first().values.first().toIntOrNull() ?: -1 } + +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/data/database/StringsDao.kt b/app/src/main/java/com/topjohnwu/magisk/data/database/StringsDao.kt new file mode 100644 index 000000000..916c71d31 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/data/database/StringsDao.kt @@ -0,0 +1,22 @@ +package com.topjohnwu.magisk.data.database + +import com.topjohnwu.magisk.data.database.base.* + +class StringsDao : BaseDao() { + + override val table = DatabaseDefinition.Table.STRINGS + + fun delete(key: String) = query { + condition { equals("key", key) } + }.ignoreElement() + + fun put(key: String, value: String) = query { + values(key to value) + }.ignoreElement() + + fun fetch(key: String, default: String = "") = query