diff --git a/app/build.gradle b/app/build.gradle index 84ac3affd..fc25ba0cb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,6 +73,9 @@ dependencies { implementation("org.koin:koin-android:${koin}") implementation("org.koin:koin-androidx-viewmodel:${koin}") + def timber = "4.7.1" + implementation "com.jakewharton.timber:timber:${timber}" + implementation("com.github.skoumalcz:teanity:0.3.3") { exclude group: 'androidx.work', module: 'work-runtime-ktx' exclude group: 'androidx.room', module: 'room-runtime' diff --git a/app/src/main/java/com/topjohnwu/magisk/App.kt b/app/src/main/java/com/topjohnwu/magisk/App.kt index 2d9b5d679..bbe501fb9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/App.kt +++ b/app/src/main/java/com/topjohnwu/magisk/App.kt @@ -20,6 +20,7 @@ import com.topjohnwu.net.Networking import com.topjohnwu.superuser.Shell import org.koin.android.ext.koin.androidContext import org.koin.core.context.startKoin +import timber.log.Timber import java.util.concurrent.ThreadPoolExecutor open class App : Application(), Application.ActivityLifecycleCallbacks { @@ -39,6 +40,8 @@ open class App : Application(), Application.ActivityLifecycleCallbacks { androidContext(this@App) modules(koinModules) } + + Timber.plant(Timber.DebugTree()) } override fun attachBaseContext(base: Context) { diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskViewModel.kt index c6f6ad86e..8c1349c68 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskViewModel.kt @@ -1,6 +1,17 @@ package com.topjohnwu.magisk.ui.base import com.skoumal.teanity.viewmodel.LoadingViewModel +import com.topjohnwu.magisk.utils.Event +import timber.log.Timber -abstract class MagiskViewModel : LoadingViewModel() +abstract class MagiskViewModel : LoadingViewModel(), Event.AutoListener { + + init { + Event.register(this) + } + + override fun onEvent(event: Int) = Timber.i("Event of $event was not handled") + override fun getListeningEvents(): IntArray = intArrayOf() + +} diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt index f223c1087..76fafc1d0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt @@ -2,14 +2,14 @@ package com.topjohnwu.magisk.ui.home import android.content.res.Resources import com.skoumal.teanity.util.KObservableField -import com.topjohnwu.magisk.App -import com.topjohnwu.magisk.Config -import com.topjohnwu.magisk.Const -import com.topjohnwu.magisk.R +import com.topjohnwu.magisk.* import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.observer.Observer +import com.topjohnwu.magisk.tasks.CheckUpdates import com.topjohnwu.magisk.ui.base.MagiskViewModel +import com.topjohnwu.magisk.utils.Event import com.topjohnwu.magisk.utils.toggle +import com.topjohnwu.net.Networking class HomeViewModel( @@ -19,8 +19,8 @@ class HomeViewModel( val isAdvancedExpanded = KObservableField(false) - val isForceEncryption = KObservableField(false /*todo*/) - val isKeepVerity = KObservableField(false /*todo*/) + val isForceEncryption = KObservableField(Config.keepEnc) + val isKeepVerity = KObservableField(Config.keepVerity) private val prefsObserver = Observer(isForceEncryption, isKeepVerity) { Config.keepEnc = isForceEncryption.value @@ -29,13 +29,12 @@ class HomeViewModel( val magiskState = KObservableField(MagiskState.LOADING) val magiskStateText = Observer(magiskState) { - @Suppress("WhenWithOnlyElse") when (magiskState.value) { MagiskState.NO_ROOT -> TODO() - MagiskState.NOT_INSTALLED -> TODO() - MagiskState.UP_TO_DATE -> TODO() - MagiskState.LOADING -> TODO() - MagiskState.OBSOLETE -> TODO() + MagiskState.NOT_INSTALLED -> resources.getString(R.string.magisk_version_error) + MagiskState.UP_TO_DATE -> resources.getString(R.string.magisk_up_to_date) + MagiskState.LOADING -> resources.getString(R.string.checking_for_updates) + MagiskState.OBSOLETE -> resources.getString(R.string.magisk_update_title) } } val magiskCurrentVersion = KObservableField("") @@ -49,13 +48,12 @@ class HomeViewModel( val managerState = KObservableField(MagiskState.LOADING) val managerStateText = Observer(managerState) { - @Suppress("WhenWithOnlyElse") when (managerState.value) { - MagiskState.NO_ROOT -> TODO() - MagiskState.NOT_INSTALLED -> TODO() - MagiskState.UP_TO_DATE -> TODO() - MagiskState.LOADING -> TODO() - MagiskState.OBSOLETE -> TODO() + MagiskState.NO_ROOT -> "wtf" + MagiskState.NOT_INSTALLED -> resources.getString(R.string.invalid_update_channel) + MagiskState.UP_TO_DATE -> resources.getString(R.string.manager_up_to_date) + MagiskState.LOADING -> resources.getString(R.string.checking_for_updates) + MagiskState.OBSOLETE -> resources.getString(R.string.manager_update_title) } } val managerCurrentVersion = KObservableField("") @@ -67,6 +65,16 @@ class HomeViewModel( "" } + private val current = resources.getString(R.string.current_installed) + private val latest = resources.getString(R.string.latest_version) + + init { + refresh() + } + + override fun onEvent(event: Int) = updateSelf() + override fun getListeningEvents(): IntArray = intArrayOf(Event.UPDATE_CHECK_DONE) + fun paypalPressed() = OpenLinkEvent(Const.Url.PAYPAL_URL).publish() fun patreonPressed() = OpenLinkEvent(Const.Url.PATREON_URL).publish() fun twitterPressed() = OpenLinkEvent(Const.Url.TWITTER_URL).publish() @@ -74,8 +82,6 @@ class HomeViewModel( fun xdaPressed() = OpenLinkEvent(Const.Url.XDA_THREAD).publish() fun uninstallPressed() = UninstallEvent.publish() - fun refresh() {} - fun advancedPressed() = isAdvancedExpanded.toggle() fun installPressed(item: MagiskItem) = when (item) { @@ -88,4 +94,52 @@ class HomeViewModel( MagiskItem.MAGISK -> MagiskChangelogEvent.publish() } + fun refresh() { + state = State.LOADING + magiskState.value = MagiskState.LOADING + managerState.value = MagiskState.LOADING + Event.reset(this) + Config.remoteMagiskVersionString = null + Config.remoteMagiskVersionCode = -1 + + if (Networking.checkNetworkStatus(app)) { + CheckUpdates.check() + } else { + state = State.LOADING_FAILED + } + } + + private fun updateSelf() { + state = State.LOADED + magiskState.value = when (Config.magiskVersionCode) { + in Int.MIN_VALUE until 0 -> MagiskState.NOT_INSTALLED + !in Config.remoteMagiskVersionCode..Int.MAX_VALUE -> MagiskState.OBSOLETE + else -> MagiskState.UP_TO_DATE + } + + magiskCurrentVersion.value = version + .format(Config.magiskVersionString, Config.magiskVersionCode) + .let { current.format(it) } + magiskLatestVersion.value = version + .format(Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode) + .let { latest.format(it) } + + managerState.value = when (Config.remoteManagerVersionCode) { + in Int.MIN_VALUE until 0 -> MagiskState.NOT_INSTALLED //wrong update channel + in (BuildConfig.VERSION_CODE + 1)..Int.MAX_VALUE -> MagiskState.OBSOLETE + else -> MagiskState.UP_TO_DATE + } + + managerCurrentVersion.value = version + .format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE) + .let { current.format(it) } + managerLatestVersion.value = version + .format(Config.remoteManagerVersionString, Config.remoteManagerVersionCode) + .let { latest.format(it) } + } + + companion object { + private const val version = "%s (%d)" + } + } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt index 77f435eea..5f602cc1f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt @@ -1,12 +1,10 @@ package com.topjohnwu.magisk.ui.home import com.skoumal.teanity.viewevents.ViewEvent +import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.model.events.MagiskInstallEvent -import com.topjohnwu.magisk.model.events.ManagerInstallEvent -import com.topjohnwu.magisk.model.events.OpenLinkEvent -import com.topjohnwu.magisk.model.events.UninstallEvent +import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.utils.Event import com.topjohnwu.magisk.view.MarkDownWindow import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog @@ -62,6 +60,7 @@ class MagiskFragment : NewMagiskFragment installManager() is MagiskInstallEvent -> installMagisk() is UninstallEvent -> uninstall() + is ManagerChangelogEvent -> changelogManager() } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt b/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt index 61d27118b..4f1e27800 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt @@ -1,6 +1,7 @@ package com.topjohnwu.magisk.utils import android.view.View +import androidx.annotation.ColorInt import androidx.annotation.DrawableRes import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.Toolbar @@ -16,3 +17,8 @@ fun setOnNavigationClickedListener(view: Toolbar, listener: View.OnClickListener fun setImageResource(view: AppCompatImageView, @DrawableRes resId: Int) { view.setImageResource(resId) } + +@BindingAdapter("app:tint") +fun setTint(view: AppCompatImageView, @ColorInt tint: Int) { + view.setColorFilter(tint) +} diff --git a/app/src/main/res/layout/include_update_card.xml b/app/src/main/res/layout/include_update_card.xml index 03a6d003f..a772a4811 100644 --- a/app/src/main/res/layout/include_update_card.xml +++ b/app/src/main/res/layout/include_update_card.xml @@ -79,6 +79,7 @@ android:layout_height="25dp" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" + app:tint="@{state == MagiskState.UP_TO_DATE ? @color/colorCorrect : (state == MagiskState.OBSOLETE ? @color/colorUpdate : @color/colorError)}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/status" app:layout_constraintStart_toStartOf="parent" @@ -86,7 +87,7 @@ #66000000 + @color/green500 + @color/red500 + @color/blue500 #009688