Added direct fetch from network and fixed build issues

This commit is contained in:
Viktor De Pasquale 2019-05-06 20:12:31 +02:00
parent b018124226
commit 10e903c9fc
17 changed files with 139 additions and 84 deletions

View File

@ -38,12 +38,12 @@ android {
packagingOptions { packagingOptions {
exclude '/META-INF/*.version' exclude '/META-INF/*.version'
exclude '/META-INF/*.kotlin_module' //exclude '/META-INF/*.kotlin_module'
exclude '/META-INF/rxkotlin.properties' //exclude '/META-INF/rxkotlin.properties'
exclude '/androidsupportmultidexversion.txt' exclude '/androidsupportmultidexversion.txt'
exclude '/org/**' exclude '/org/**'
exclude '/kotlin/**' //exclude '/kotlin/**'
exclude '/kotlinx/**' //exclude '/kotlinx/**'
} }
} }
@ -62,6 +62,9 @@ dependencies {
implementation 'com.github.skoumalcz:teanity:0.3.3' implementation 'com.github.skoumalcz:teanity:0.3.3'
implementation 'com.ncapdevi:frag-nav:3.2.0' implementation 'com.ncapdevi:frag-nav:3.2.0'
def vRoom = "2.1.0-alpha05"
implementation "androidx.room:room-rxjava2:${vRoom}"
def markwonVersion = '3.0.0' def markwonVersion = '3.0.0'
implementation "ru.noties.markwon:core:${markwonVersion}" implementation "ru.noties.markwon:core:${markwonVersion}"
implementation "ru.noties.markwon:html:${markwonVersion}" implementation "ru.noties.markwon:html:${markwonVersion}"
@ -87,6 +90,9 @@ dependencies {
implementation "com.squareup.moshi:moshi:${vMoshi}" implementation "com.squareup.moshi:moshi:${vMoshi}"
implementation "com.squareup.moshi:moshi-kotlin:${vMoshi}" implementation "com.squareup.moshi:moshi-kotlin:${vMoshi}"
kapt "com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}"
kapt "androidx.room:room-compiler:${vRoom}"
def vKotpref = "2.8.0" def vKotpref = "2.8.0"
implementation "com.chibatching.kotpref:kotpref:${vKotpref}" implementation "com.chibatching.kotpref:kotpref:${vKotpref}"

View File

@ -11,6 +11,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDex import androidx.multidex.MultiDex
import com.chibatching.kotpref.Kotpref
import com.topjohnwu.magisk.data.database.MagiskDB import com.topjohnwu.magisk.data.database.MagiskDB
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
import com.topjohnwu.magisk.di.koinModules import com.topjohnwu.magisk.di.koinModules
@ -39,6 +40,12 @@ open class App : Application(), Application.ActivityLifecycleCallbacks {
@Volatile @Volatile
private var foreground: Activity? = null private var foreground: Activity? = null
override fun onCreate() {
super.onCreate()
Kotpref.init(this)
}
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
super.attachBaseContext(base) super.attachBaseContext(base)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)

View File

@ -1,12 +1,24 @@
package com.topjohnwu.magisk.di package com.topjohnwu.magisk.di
import android.content.Context
import androidx.room.Room
import com.topjohnwu.magisk.App import com.topjohnwu.magisk.App
import com.topjohnwu.magisk.data.database.MagiskDB import com.topjohnwu.magisk.data.database.*
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
import org.koin.dsl.module import org.koin.dsl.module
val databaseModule = module { val databaseModule = module {
single { MagiskDB(get<App>().protectedContext) } single { MagiskDB(get<App>().protectedContext) }
single { RepoDatabaseHelper(get()) } single { RepoDatabaseHelper(get()) }
single { createDatabase(get()) }
single { LogDao() }
single { PolicyDao(get()) }
single { SettingsDao() }
single { StringsDao() }
single { createRepositoryDao(get()) }
} }
fun createDatabase(context: Context): AppDatabase =
Room.databaseBuilder(context, AppDatabase::class.java, AppDatabase.NAME).build()
fun createRepositoryDao(db: AppDatabase) = db.repoDao()

View File

@ -1,6 +1,7 @@
package com.topjohnwu.magisk.di package com.topjohnwu.magisk.di
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.topjohnwu.magisk.Constants import com.topjohnwu.magisk.Constants
import com.topjohnwu.magisk.data.network.GithubApiServices import com.topjohnwu.magisk.data.network.GithubApiServices
import com.topjohnwu.magisk.data.network.GithubRawApiServices import com.topjohnwu.magisk.data.network.GithubRawApiServices
@ -38,7 +39,9 @@ fun createOkHttpClient(): OkHttpClient {
} }
fun createConverterFactory(): Converter.Factory { fun createConverterFactory(): Converter.Factory {
val moshi = Moshi.Builder().build() val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
return MoshiConverterFactory.create(moshi) return MoshiConverterFactory.create(moshi)
} }

View File

@ -1,6 +1,13 @@
package com.topjohnwu.magisk.di package com.topjohnwu.magisk.di
import com.topjohnwu.magisk.data.repository.LogRepository
import com.topjohnwu.magisk.data.repository.MagiskRepository
import com.topjohnwu.magisk.data.repository.ModuleRepository
import org.koin.dsl.module import org.koin.dsl.module
val repositoryModule = module {} val repositoryModule = module {
single { MagiskRepository(get(), get()) }
single { ModuleRepository(get(), get(), get(), get()) }
single { LogRepository(get()) }
}

View File

@ -15,7 +15,7 @@ import org.koin.dsl.module
val viewModelModules = module { val viewModelModules = module {
viewModel { MainViewModel() } viewModel { MainViewModel() }
viewModel { HomeViewModel(get(), get()) } viewModel { HomeViewModel(get(), get(), get()) }
viewModel { SuperuserViewModel(get(), get(), get(), get()) } viewModel { SuperuserViewModel(get(), get(), get(), get()) }
viewModel { HideViewModel(get(), get()) } viewModel { HideViewModel(get(), get()) }
viewModel { ModuleViewModel(get(), get()) } viewModel { ModuleViewModel(get(), get()) }

View File

@ -0,0 +1,11 @@
package com.topjohnwu.magisk.model.entity
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class MagiskApp(
val version: String,
val versionCode: String,
val link: String,
val note: String
)

View File

@ -1,32 +1,7 @@
package com.topjohnwu.magisk.model.entity package com.topjohnwu.magisk.model.entity
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
data class MagiskConfig( data class MagiskConfig(
val app: MagiskApp, val app: MagiskApp,
val uninstaller: MagiskLink, val uninstaller: MagiskLink,
val magisk: MagiskFlashable val magisk: MagiskFlashable
) )
@JsonClass(generateAdapter = true)
data class MagiskApp(
val version: String,
val versionCode: String,
val link: String,
val note: String
)
@JsonClass(generateAdapter = true)
data class MagiskLink(
val link: String
)
@JsonClass(generateAdapter = true)
data class MagiskFlashable(
val version: String,
val versionCode: String,
val link: String,
val note: String,
@Json(name = "md5") val hash: String
)

View File

@ -0,0 +1,13 @@
package com.topjohnwu.magisk.model.entity
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class MagiskFlashable(
val version: String,
val versionCode: String,
val link: String,
val note: String,
@Json(name = "md5") val hash: String
)

View File

@ -0,0 +1,8 @@
package com.topjohnwu.magisk.model.entity
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class MagiskLink(
val link: String
)

View File

@ -6,16 +6,33 @@ import android.os.Parcelable;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.io.SuFile; import com.topjohnwu.superuser.io.SuFile;
public class Module extends BaseModule { public class OldModule extends BaseModule {
private SuFile mRemoveFile, mDisableFile, mUpdateFile; public static final Parcelable.Creator<OldModule> CREATOR = new Creator<OldModule>() {
private boolean mEnable, mRemove, mUpdated; /* It won't be used at any place */
@Override
public OldModule createFromParcel(Parcel source) {
return null;
}
public Module(String path) { @Override
public OldModule[] newArray(int size) {
return null;
}
};
private final SuFile mRemoveFile;
private final SuFile mDisableFile;
private final SuFile mUpdateFile;
private final boolean mUpdated;
private boolean mEnable;
private boolean mRemove;
public OldModule(String path) {
try { try {
parseProps(Shell.su("dos2unix < " + path + "/module.prop").exec().getOut()); parseProps(Shell.su("dos2unix < " + path + "/module.prop").exec().getOut());
} catch (NumberFormatException ignored) {} } catch (NumberFormatException ignored) {
}
mRemoveFile = new SuFile(path, "remove"); mRemoveFile = new SuFile(path, "remove");
mDisableFile = new SuFile(path, "disable"); mDisableFile = new SuFile(path, "disable");
@ -35,19 +52,6 @@ public class Module extends BaseModule {
mUpdated = mUpdateFile.exists(); mUpdated = mUpdateFile.exists();
} }
public static final Parcelable.Creator<Module> CREATOR = new Creator<Module>() {
/* It won't be used at any place */
@Override
public Module createFromParcel(Parcel source) {
return null;
}
@Override
public Module[] newArray(int size) {
return null;
}
};
public void createDisableFile() { public void createDisableFile() {
mEnable = !mDisableFile.createNewFile(); mEnable = !mDisableFile.createNewFile();
} }

View File

@ -6,12 +6,12 @@ import com.skoumal.teanity.databinding.ComparableRvItem
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
import com.skoumal.teanity.util.KObservableField import com.skoumal.teanity.util.KObservableField
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.model.entity.Module import com.topjohnwu.magisk.model.entity.OldModule
import com.topjohnwu.magisk.model.entity.Repo import com.topjohnwu.magisk.model.entity.Repo
import com.topjohnwu.magisk.utils.get import com.topjohnwu.magisk.utils.get
import com.topjohnwu.magisk.utils.toggle import com.topjohnwu.magisk.utils.toggle
class ModuleRvItem(val item: Module) : ComparableRvItem<ModuleRvItem>() { class ModuleRvItem(val item: OldModule) : ComparableRvItem<ModuleRvItem>() {
override val layoutRes: Int = R.layout.item_module override val layoutRes: Int = R.layout.item_module

View File

@ -14,7 +14,10 @@ import timber.log.Timber
abstract class MagiskViewModel : LoadingViewModel(), Event.AutoListener { abstract class MagiskViewModel : LoadingViewModel(), Event.AutoListener {
@Deprecated("")
override fun onEvent(event: Int) = Timber.i("Event of $event was not handled") override fun onEvent(event: Int) = Timber.i("Event of $event was not handled")
@Deprecated("")
override fun getListeningEvents(): IntArray = intArrayOf() override fun getListeningEvents(): IntArray = intArrayOf()
fun withView(action: Activity.() -> Unit) { fun withView(action: Activity.() -> Unit) {

View File

@ -2,22 +2,24 @@ package com.topjohnwu.magisk.ui.home
import android.content.res.Resources import android.content.res.Resources
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
import com.skoumal.teanity.extensions.doOnSubscribeUi
import com.skoumal.teanity.extensions.subscribeK
import com.skoumal.teanity.util.KObservableField import com.skoumal.teanity.util.KObservableField
import com.topjohnwu.magisk.* import com.topjohnwu.magisk.*
import com.topjohnwu.magisk.data.repository.MagiskRepository
import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.tasks.CheckUpdates
import com.topjohnwu.magisk.ui.base.MagiskViewModel import com.topjohnwu.magisk.ui.base.MagiskViewModel
import com.topjohnwu.magisk.utils.Event import com.topjohnwu.magisk.utils.Event
import com.topjohnwu.magisk.utils.ISafetyNetHelper import com.topjohnwu.magisk.utils.ISafetyNetHelper
import com.topjohnwu.magisk.utils.toggle import com.topjohnwu.magisk.utils.toggle
import com.topjohnwu.net.Networking
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
class HomeViewModel( class HomeViewModel(
private val resources: Resources, private val resources: Resources,
private val app: App private val app: App,
private val magiskRepo: MagiskRepository
) : MagiskViewModel() { ) : MagiskViewModel() {
val isAdvancedExpanded = KObservableField(false) val isAdvancedExpanded = KObservableField(false)
@ -163,20 +165,26 @@ class HomeViewModel(
} }
fun refresh() { fun refresh() {
state = State.LOADING magiskRepo.fetchConfig()
magiskState.value = MagiskState.LOADING .applyViewModel(this)
managerState.value = MagiskState.LOADING .doOnSubscribeUi {
Event.reset(this) magiskState.value = MagiskState.LOADING
Config.remoteMagiskVersionString = null managerState.value = MagiskState.LOADING
Config.remoteMagiskVersionCode = -1 }
.subscribeK {
it.app.let {
Config.remoteManagerVersionCode = it.versionCode.toIntOrNull() ?: -1
Config.remoteManagerVersionString = it.version
}
it.magisk.let {
Config.remoteMagiskVersionCode = it.versionCode.toIntOrNull() ?: -1
Config.remoteMagiskVersionString = it.version
}
updateSelf()
ensureEnv()
}
hasRoot.value = Shell.rootAccess() hasRoot.value = Shell.rootAccess()
if (Networking.checkNetworkStatus(app)) {
CheckUpdates.check()
} else {
state = State.LOADING_FAILED
}
} }
private fun updateSelf() { private fun updateSelf() {

View File

@ -11,7 +11,7 @@ import com.skoumal.teanity.util.KObservableField
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
import com.topjohnwu.magisk.model.entity.Module import com.topjohnwu.magisk.model.entity.OldModule
import com.topjohnwu.magisk.model.entity.Repo import com.topjohnwu.magisk.model.entity.Repo
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
import com.topjohnwu.magisk.model.entity.recycler.RepoRvItem import com.topjohnwu.magisk.model.entity.recycler.RepoRvItem
@ -76,7 +76,7 @@ class ModuleViewModel(
UpdateRepos().exec(true) UpdateRepos().exec(true)
} }
private fun updateModules(result: Map<String, Module>) = result.values private fun updateModules(result: Map<String, OldModule>) = result.values
.map { ModuleRvItem(it) } .map { ModuleRvItem(it) }
.let { itemsInstalled.update(it) } .let { itemsInstalled.update(it) }

View File

@ -7,24 +7,16 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.provider.OpenableColumns;
import android.widget.Toast; import android.widget.Toast;
import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import com.topjohnwu.magisk.App; import com.topjohnwu.magisk.App;
import com.topjohnwu.magisk.BuildConfig; import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.ClassMap; import com.topjohnwu.magisk.ClassMap;
import com.topjohnwu.magisk.Config; import com.topjohnwu.magisk.Config;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.model.entity.Module; import com.topjohnwu.magisk.model.entity.OldModule;
import com.topjohnwu.magisk.model.update.UpdateCheckService; import com.topjohnwu.magisk.model.update.UpdateCheckService;
import com.topjohnwu.net.Networking; import com.topjohnwu.net.Networking;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
@ -35,6 +27,12 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
public class Utils { public class Utils {
public static void toast(CharSequence msg, int duration) { public static void toast(CharSequence msg, int duration) {
@ -93,13 +91,13 @@ public class Utils {
public static void loadModules(boolean async) { public static void loadModules(boolean async) {
Event.reset(Event.MODULE_LOAD_DONE); Event.reset(Event.MODULE_LOAD_DONE);
Runnable run = () -> { Runnable run = () -> {
Map<String, Module> moduleMap = new ValueSortedMap<>(); Map<String, OldModule> moduleMap = new ValueSortedMap<>();
SuFile path = new SuFile(Const.MAGISK_PATH); SuFile path = new SuFile(Const.MAGISK_PATH);
SuFile[] modules = path.listFiles( SuFile[] modules = path.listFiles(
(file, name) -> !name.equals("lost+found") && !name.equals(".core")); (file, name) -> !name.equals("lost+found") && !name.equals(".core"));
for (SuFile file : modules) { for (SuFile file : modules) {
if (file.isFile()) continue; if (file.isFile()) continue;
Module module = new Module(Const.MAGISK_PATH + "/" + file.getName()); OldModule module = new OldModule(Const.MAGISK_PATH + "/" + file.getName());
moduleMap.put(module.getId(), module); moduleMap.put(module.getId(), module);
} }
Event.trigger(Event.MODULE_LOAD_DONE, moduleMap); Event.trigger(Event.MODULE_LOAD_DONE, moduleMap);

View File

@ -5,7 +5,7 @@ import android.content.Intent
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toUri import androidx.core.net.toUri
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.KConfig
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import okhttp3.ResponseBody import okhttp3.ResponseBody
import java.io.File import java.io.File
@ -20,7 +20,7 @@ fun ResponseBody.writeToFile(context: Context, fileName: String): File {
fun ResponseBody.writeToString() = string() fun ResponseBody.writeToString() = string()
fun String.launch() = if (Config.useCustomTabs) { fun String.launch() = if (KConfig.useCustomTabs) {
launchWithCustomTabs() launchWithCustomTabs()
} else { } else {
launchWithIntent() launchWithIntent()