Added (ported back) features from initial design [retrofit,moshi,kotpref]

Marked most of the old classes using Networking as deprecated to clearly visualise their future removal
This commit is contained in:
Viktor De Pasquale
2019-05-06 19:03:28 +02:00
parent 5d632d0d90
commit b018124226
39 changed files with 1374 additions and 19 deletions
@@ -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
}
@@ -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<Delete> {
condition {
lessThan("time", suTimeout.toString())
}
}.ignoreElement()
fun deleteAll() = query<Delete> {}.ignoreElement()
fun fetchAll() = query<Select> {
orderBy("time", Order.DESC)
}.flattenAsFlowable { it }
.map { it.toLog() }
.toList()
fun put(log: MagiskLog) = query<Insert> {
values(log.toMap())
}.ignoreElement()
}
@@ -20,6 +20,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
@Deprecated
public class MagiskDB {
private static final String POLICY_TABLE = "policies";
@@ -27,20 +28,24 @@ public class MagiskDB {
private static final String SETTINGS_TABLE = "settings";
private static final String STRINGS_TABLE = "strings";
private PackageManager pm;
private final PackageManager pm;
@Deprecated
public MagiskDB(Context context) {
pm = context.getPackageManager();
}
@Deprecated
public void deletePolicy(Policy policy) {
deletePolicy(policy.uid);
}
@Deprecated
private List<String> rawSQL(String fmt, Object... args) {
return Shell.su("magisk --sqlite '" + Utils.fmt(fmt, args) + "'").exec().getOut();
}
@Deprecated
private List<ContentValues> SQL(String fmt, Object... args) {
List<ContentValues> list = new ArrayList<>();
for (String raw : rawSQL(fmt, args)) {
@@ -57,6 +62,7 @@ public class MagiskDB {
return list;
}
@Deprecated
private String toSQL(ContentValues values) {
StringBuilder keys = new StringBuilder(), vals = new StringBuilder();
keys.append('(');
@@ -80,6 +86,7 @@ public class MagiskDB {
return keys.toString();
}
@Deprecated
public void clearOutdated() {
rawSQL(
"DELETE FROM %s WHERE until > 0 AND until < %d;" +
@@ -89,14 +96,17 @@ public class MagiskDB {
);
}
@Deprecated
public void deletePolicy(String pkg) {
rawSQL("DELETE FROM %s WHERE package_name=\"%s\"", POLICY_TABLE, pkg);
}
@Deprecated
public void deletePolicy(int uid) {
rawSQL("DELETE FROM %s WHERE uid=%d", POLICY_TABLE, uid);
}
@Deprecated
public Policy getPolicy(int uid) {
List<ContentValues> res =
SQL("SELECT * FROM %s WHERE uid=%d", POLICY_TABLE, uid);
@@ -110,10 +120,12 @@ public class MagiskDB {
return null;
}
@Deprecated
public void updatePolicy(Policy policy) {
rawSQL("REPLACE INTO %s %s", POLICY_TABLE, toSQL(policy.getContentValues()));
}
@Deprecated
public List<Policy> getPolicyList() {
List<Policy> list = new ArrayList<>();
for (ContentValues values : SQL("SELECT * FROM %s WHERE uid/100000=%d", POLICY_TABLE, Const.USER_ID)) {
@@ -127,6 +139,7 @@ public class MagiskDB {
return list;
}
@Deprecated
public List<List<SuLogEntry>> getLogs() {
List<List<SuLogEntry>> ret = new ArrayList<>();
List<SuLogEntry> list = null;
@@ -144,18 +157,22 @@ public class MagiskDB {
return ret;
}
@Deprecated
public void addLog(SuLogEntry log) {
rawSQL("INSERT INTO %s %s", LOG_TABLE, toSQL(log.getContentValues()));
}
@Deprecated
public void clearLogs() {
rawSQL("DELETE FROM %s", LOG_TABLE);
}
@Deprecated
public void rmSettings(String key) {
rawSQL("DELETE FROM %s WHERE key=\"%s\"", SETTINGS_TABLE, key);
}
@Deprecated
public void setSettings(String key, int value) {
ContentValues data = new ContentValues();
data.put("key", key);
@@ -163,6 +180,7 @@ public class MagiskDB {
rawSQL("REPLACE INTO %s %s", SETTINGS_TABLE, toSQL(data));
}
@Deprecated
public int getSettings(String key, int defaultValue) {
List<ContentValues> res = SQL("SELECT value FROM %s WHERE key=\"%s\"", SETTINGS_TABLE, key);
if (res.isEmpty())
@@ -170,6 +188,7 @@ public class MagiskDB {
return res.get(0).getAsInteger("value");
}
@Deprecated
public void setStrings(String key, String value) {
if (value == null) {
rawSQL("DELETE FROM %s WHERE key=\"%s\"", STRINGS_TABLE, key);
@@ -181,6 +200,7 @@ public class MagiskDB {
rawSQL("REPLACE INTO %s %s", STRINGS_TABLE, toSQL(data));
}
@Deprecated
public String getStrings(String key, String defaultValue) {
List<ContentValues> res = SQL("SELECT value FROM %s WHERE key=\"%s\"", STRINGS_TABLE, key);
if (res.isEmpty())
@@ -0,0 +1,67 @@
package com.topjohnwu.magisk.data.database
import android.content.Context
import android.content.pm.PackageManager
import com.topjohnwu.magisk.Constants
import com.topjohnwu.magisk.data.database.base.*
import com.topjohnwu.magisk.model.entity.MagiskPolicy
import com.topjohnwu.magisk.model.entity.toMap
import com.topjohnwu.magisk.model.entity.toPolicy
import com.topjohnwu.magisk.utils.now
import java.util.concurrent.TimeUnit
class PolicyDao(
private val context: Context
) : BaseDao() {
override val table: String = DatabaseDefinition.Table.POLICY
fun deleteOutdated(
nowSeconds: Long = TimeUnit.MILLISECONDS.toSeconds(now)
) = query<Delete> {
condition {
greaterThan("until", "0")
and {
lessThan("until", nowSeconds.toString())
}
}
}.ignoreElement()
fun delete(packageName: String) = query<Delete> {
condition {
equals("package_name", packageName)
}
}.ignoreElement()
fun delete(uid: Int) = query<Delete> {
condition {
equals("uid", uid.toString())
}
}.ignoreElement()
fun fetch(uid: Int) = query<Select> {
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<Replace> {
values(policy.toMap())
}.ignoreElement()
fun fetchAll() = query<Select> {
condition {
equals("uid/100000", Constants.USER_ID.toString())
}
}.flattenAsFlowable { it }
.map { it.toPolicy(context.packageManager) }
.toList()
}
@@ -11,13 +11,15 @@ import com.topjohnwu.magisk.model.entity.Repo;
import java.util.HashSet;
import java.util.Set;
@Deprecated
public class RepoDatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VER = 5;
private static final String TABLE_NAME = "repos";
private SQLiteDatabase mDb;
private final SQLiteDatabase mDb;
@Deprecated
public RepoDatabaseHelper(Context context) {
super(context, "repo.db", null, DATABASE_VER);
mDb = getWritableDatabase();
@@ -46,19 +48,23 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
onUpgrade(db, 0, DATABASE_VER);
}
@Deprecated
public void clearRepo() {
mDb.delete(TABLE_NAME, null, null);
}
@Deprecated
public void removeRepo(String id) {
mDb.delete(TABLE_NAME, "id=?", new String[] { id });
}
@Deprecated
public void removeRepo(Repo repo) {
removeRepo(repo.getId());
}
@Deprecated
public void removeRepo(Iterable<String> list) {
for (String id : list) {
if (id == null) continue;
@@ -66,10 +72,12 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
}
}
@Deprecated
public void addRepo(Repo repo) {
mDb.replace(TABLE_NAME, null, repo.getContentValues());
}
@Deprecated
public Repo getRepo(String id) {
try (Cursor c = mDb.query(TABLE_NAME, null, "id=?", new String[] { id }, null, null, null)) {
if (c.moveToNext()) {
@@ -79,10 +87,12 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
return null;
}
@Deprecated
public Cursor getRawCursor() {
return mDb.query(TABLE_NAME, null, null, null, null, null, null);
}
@Deprecated
public Cursor getRepoCursor() {
String orderBy = null;
switch ((int) Config.get(Config.Key.REPO_ORDER)) {
@@ -95,6 +105,7 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
return mDb.query(TABLE_NAME, null, null, null, null, null, orderBy);
}
@Deprecated
public Set<String> getRepoIDSet() {
HashSet<String> set = new HashSet<>(300);
try (Cursor c = mDb.query(TABLE_NAME, null, null, null, null, null, null)) {
@@ -0,0 +1,17 @@
package com.topjohnwu.magisk.data.database
import androidx.room.Dao
import androidx.room.Query
import com.skoumal.teanity.database.BaseDao
import com.topjohnwu.magisk.model.entity.Repository
@Dao
interface RepositoryDao : BaseDao<Repository> {
@Query("DELETE FROM repos")
override fun deleteAll()
@Query("SELECT * FROM repos")
override fun fetchAll(): List<Repository>
}
@@ -0,0 +1,21 @@
package com.topjohnwu.magisk.data.database
import com.topjohnwu.magisk.data.database.base.*
class SettingsDao : BaseDao() {
override val table = DatabaseDefinition.Table.SETTINGS
fun delete(key: String) = query<Delete> {
condition { equals("key", key) }
}.ignoreElement()
fun put(key: String, value: Int) = query<Insert> {
values(key to value.toString())
}.ignoreElement()
fun fetch(key: String) = query<Select> {
condition { equals("key", key) }
}.map { it.first().values.first().toIntOrNull() ?: -1 }
}
@@ -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<Delete> {
condition { equals("key", key) }
}.ignoreElement()
fun put(key: String, value: String) = query<Insert> {
values(key to value)
}.ignoreElement()
fun fetch(key: String, default: String = "") = query<Select> {
fields("value")
condition { equals("key", key) }
}.map { it.firstOrNull()?.values?.firstOrNull() ?: default }
}
@@ -0,0 +1,15 @@
package com.topjohnwu.magisk.data.database.base
abstract class BaseDao {
abstract val table: String
inline fun <reified Builder : MagiskQueryBuilder> query(builder: Builder.() -> Unit) =
Builder::class.java.newInstance()
.apply { table = this@BaseDao.table }
.apply(builder)
.toString()
.let { MagiskQuery(it) }
.query()
}
@@ -0,0 +1,33 @@
package com.topjohnwu.magisk.data.database.base
import androidx.annotation.AnyThread
import com.topjohnwu.superuser.Shell
import io.reactivex.Single
object DatabaseDefinition {
object Table {
const val POLICY = "policies"
const val LOG = "logs"
const val SETTINGS = "settings"
const val STRINGS = "strings"
}
}
@AnyThread
fun MagiskQuery.query() = query.su()
fun String.suRaw() = Single.just(Shell.su(this))
.map { it.exec().out }
fun String.su() = suRaw()
.map { it.toMap() }
fun List<String>.toMap() = map { it.split(Regex("\\|")) }
.map { it.toMapInternal() }
private fun List<String>.toMapInternal() = map { it.split("=", limit = 2) }
.filter { it.size == 2 }
.map { Pair(it[0], it[1]) }
.toMap()
@@ -0,0 +1,5 @@
package com.topjohnwu.magisk.data.database.base
data class MagiskQuery(private val _query: String) {
val query = "magisk --sqlite $_query"
}
@@ -0,0 +1,157 @@
package com.topjohnwu.magisk.data.database.base
import androidx.annotation.StringDef
import com.topjohnwu.magisk.data.database.base.Order.Companion.ASC
import com.topjohnwu.magisk.data.database.base.Order.Companion.DESC
interface MagiskQueryBuilder {
val requestType: String
var table: String
companion object {
inline operator fun <reified Builder : MagiskQueryBuilder> invoke(builder: Builder.() -> Unit): MagiskQuery =
Builder::class.java.newInstance()
.apply(builder)
.toString()
.let { MagiskQuery(it) }
}
}
class Delete : MagiskQueryBuilder {
override val requestType: String = "DELETE FROM"
override var table = ""
private var condition = ""
fun condition(builder: Condition.() -> Unit) {
condition = Condition().apply(builder).toString()
}
override fun toString(): String {
return StringBuilder()
.appendln(requestType)
.appendln(table)
.appendln(condition)
.toString()
}
}
class Select : MagiskQueryBuilder {
override val requestType: String get() = "SELECT $fields FROM"
override lateinit var table: String
private var fields = "*"
private var condition = ""
private var orderField = ""
fun fields(vararg newFields: String) {
if (newFields.isEmpty()) {
fields = "*"
return
}
fields = newFields.joinToString(", ")
}
fun condition(builder: Condition.() -> Unit) {
condition = Condition().apply(builder).toString()
}
fun orderBy(field: String, @OrderStrict order: String) {
orderField = "ORDER BY $field $order"
}
override fun toString(): String {
return StringBuilder()
.appendln(requestType)
.appendln(table)
.appendln(condition)
.appendln(orderField)
.toString()
}
}
class Replace : Insert() {
override val requestType: String = "REPLACE INTO"
}
open class Insert : MagiskQueryBuilder {
override val requestType: String = "INSERT INTO"
override lateinit var table: String
private val keys get() = _values.keys.joinToString(",")
private val values get() = _values.values.joinToString(",")
private var _values: Map<String, String> = mapOf()
fun values(vararg pairs: Pair<String, String>) {
_values = pairs.toMap()
}
fun values(values: Map<String, String>) {
_values = values
}
override fun toString(): String {
return StringBuilder()
.appendln(requestType)
.appendln(table)
.appendln("($keys) VALUES($values)")
.toString()
}
}
class Condition {
private val conditionWord = "WHERE %s"
private var condition: String = ""
fun equals(field: String, value: String) {
condition = "$field=\"$value\""
}
fun greaterThan(field: String, value: String) {
condition = "$field > $value"
}
fun lessThan(field: String, value: String) {
condition = "$field < $value"
}
fun greaterOrEqualTo(field: String, value: String) {
condition = "$field >= $value"
}
fun lessOrEqualTo(field: String, value: String) {
condition = "$field <= $value"
}
fun and(builder: Condition.() -> Unit) {
condition += " " + Condition().apply(builder).condition
}
fun or(builder: Condition.() -> Unit) {
condition += " " + Condition().apply(builder).condition
}
override fun toString(): String {
return conditionWord.format(condition)
}
}
class Order {
@set:OrderStrict
var order = DESC
var field = ""
companion object {
const val ASC = "ASC"
const val DESC = "DESC"
}
}
@StringDef(ASC, DESC)
@Retention(AnnotationRetention.SOURCE)
annotation class OrderStrict