mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-03-28 10:22:16 +00:00
Added safetynet to the rewritten home fragment
This commit is contained in:
parent
f332746188
commit
ffec64d209
@ -13,3 +13,5 @@ class MagiskChangelogEvent : ViewEvent()
|
|||||||
|
|
||||||
class UninstallEvent : ViewEvent()
|
class UninstallEvent : ViewEvent()
|
||||||
class EnvFixEvent : ViewEvent()
|
class EnvFixEvent : ViewEvent()
|
||||||
|
|
||||||
|
class UpdateSafetyNetEvent : ViewEvent()
|
||||||
|
@ -8,6 +8,7 @@ import com.topjohnwu.magisk.model.observer.Observer
|
|||||||
import com.topjohnwu.magisk.tasks.CheckUpdates
|
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.toggle
|
import com.topjohnwu.magisk.utils.toggle
|
||||||
import com.topjohnwu.net.Networking
|
import com.topjohnwu.net.Networking
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
@ -66,6 +67,21 @@ class HomeViewModel(
|
|||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val safetyNetTitle = KObservableField(resources.getString(R.string.safetyNet_check_text))
|
||||||
|
val ctsState = KObservableField(SafetyNetState.IDLE)
|
||||||
|
val basicIntegrityState = KObservableField(SafetyNetState.IDLE)
|
||||||
|
val safetyNetState = Observer(ctsState, basicIntegrityState) {
|
||||||
|
val cts = ctsState.value
|
||||||
|
val basic = basicIntegrityState.value
|
||||||
|
val states = listOf(cts, basic)
|
||||||
|
|
||||||
|
when {
|
||||||
|
states.any { it == SafetyNetState.LOADING } -> State.LOADING
|
||||||
|
states.any { it == SafetyNetState.IDLE } -> State.LOADING
|
||||||
|
else -> State.LOADED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val hasRoot = KObservableField(false)
|
val hasRoot = KObservableField(false)
|
||||||
|
|
||||||
private var shownDialog = false
|
private var shownDialog = false
|
||||||
@ -103,8 +119,46 @@ class HomeViewModel(
|
|||||||
MagiskItem.MAGISK -> MagiskChangelogEvent().publish()
|
MagiskItem.MAGISK -> MagiskChangelogEvent().publish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun safetyNetPressed() {
|
||||||
|
ctsState.value = SafetyNetState.LOADING
|
||||||
|
basicIntegrityState.value = SafetyNetState.LOADING
|
||||||
|
safetyNetTitle.value = resources.getString(R.string.checking_safetyNet_status)
|
||||||
|
|
||||||
|
UpdateSafetyNetEvent().publish()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun finishSafetyNetCheck(response: Int) = when {
|
||||||
|
response and 0x0F == 0 -> {
|
||||||
|
val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0
|
||||||
|
val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0
|
||||||
|
safetyNetTitle.value = resources.getString(R.string.safetyNet_check_success)
|
||||||
|
ctsState.value = if (hasCtsPassed) {
|
||||||
|
SafetyNetState.PASS
|
||||||
|
} else {
|
||||||
|
SafetyNetState.FAILED
|
||||||
|
}
|
||||||
|
basicIntegrityState.value = if (hasBasicIntegrityPassed) {
|
||||||
|
SafetyNetState.PASS
|
||||||
|
} else {
|
||||||
|
SafetyNetState.FAILED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response == -2 -> {
|
||||||
|
ctsState.value = SafetyNetState.IDLE
|
||||||
|
basicIntegrityState.value = SafetyNetState.IDLE
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
ctsState.value = SafetyNetState.IDLE
|
||||||
|
basicIntegrityState.value = SafetyNetState.IDLE
|
||||||
|
val errorString = when (response) {
|
||||||
|
ISafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid
|
||||||
|
else -> R.string.safetyNet_api_error
|
||||||
|
}
|
||||||
|
safetyNetTitle.value = resources.getString(errorString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
shownDialog = false
|
|
||||||
state = State.LOADING
|
state = State.LOADING
|
||||||
magiskState.value = MagiskState.LOADING
|
magiskState.value = MagiskState.LOADING
|
||||||
managerState.value = MagiskState.LOADING
|
managerState.value = MagiskState.LOADING
|
||||||
@ -155,7 +209,8 @@ class HomeViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ensureEnv() {
|
private fun ensureEnv() {
|
||||||
val invalidStates = listOf(MagiskState.NOT_INSTALLED, MagiskState.NO_ROOT, MagiskState.LOADING)
|
val invalidStates =
|
||||||
|
listOf(MagiskState.NOT_INSTALLED, MagiskState.NO_ROOT, MagiskState.LOADING)
|
||||||
|
|
||||||
// Don't bother checking env when magisk is not installed, loading or already has been shown
|
// Don't bother checking env when magisk is not installed, loading or already has been shown
|
||||||
if (invalidStates.any { it == magiskState.value } || shownDialog) return
|
if (invalidStates.any { it == magiskState.value } || shownDialog) return
|
||||||
|
@ -3,56 +3,31 @@ package com.topjohnwu.magisk.ui.home
|
|||||||
import com.skoumal.teanity.viewevents.ViewEvent
|
import com.skoumal.teanity.viewevents.ViewEvent
|
||||||
import com.topjohnwu.magisk.BuildConfig
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.databinding.FragmentMagiskBinding
|
||||||
import com.topjohnwu.magisk.model.events.*
|
import com.topjohnwu.magisk.model.events.*
|
||||||
|
import com.topjohnwu.magisk.utils.ISafetyNetHelper
|
||||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||||
|
import com.topjohnwu.magisk.view.SafetyNet
|
||||||
|
import com.topjohnwu.magisk.view.SafetyNet.EXT_APK
|
||||||
|
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog
|
||||||
import com.topjohnwu.magisk.view.dialogs.EnvFixDialog
|
import com.topjohnwu.magisk.view.dialogs.EnvFixDialog
|
||||||
import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog
|
import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog
|
||||||
import com.topjohnwu.magisk.view.dialogs.UninstallDialog
|
import com.topjohnwu.magisk.view.dialogs.UninstallDialog
|
||||||
|
import com.topjohnwu.net.Networking
|
||||||
|
import com.topjohnwu.superuser.Shell
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskFragment as NewMagiskFragment
|
import com.topjohnwu.magisk.ui.base.MagiskFragment as NewMagiskFragment
|
||||||
|
|
||||||
class MagiskFragment : NewMagiskFragment<HomeViewModel, com.topjohnwu.magisk.databinding.FragmentMagiskBinding>() {
|
class MagiskFragment : NewMagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
|
||||||
|
ISafetyNetHelper.Callback {
|
||||||
/*@BindView(R.id.swipeRefreshLayout)
|
|
||||||
internal var mSwipeRefreshLayout: SwipeRefreshLayout? = null
|
|
||||||
@BindView(R.id.linearLayout)
|
|
||||||
internal var root: LinearLayout? = null
|
|
||||||
|
|
||||||
@BindView(R.id.install_option_card)
|
|
||||||
internal var installOptionCard: CardView? = null
|
|
||||||
@BindView(R.id.keep_force_enc)
|
|
||||||
internal var keepEncChkbox: CheckBox? = null
|
|
||||||
@BindView(R.id.keep_verity)
|
|
||||||
internal var keepVerityChkbox: CheckBox? = null
|
|
||||||
@BindView(R.id.install_option_expand)
|
|
||||||
internal var optionExpandLayout: ViewGroup? = null
|
|
||||||
@BindView(R.id.arrow)
|
|
||||||
internal var arrow: ImageView? = null
|
|
||||||
|
|
||||||
@BindView(R.id.uninstall_button)
|
|
||||||
internal var uninstallButton: CardView? = null
|
|
||||||
|
|
||||||
@BindColor(R.color.red500)
|
|
||||||
internal var colorBad: Int = 0
|
|
||||||
@BindColor(R.color.green500)
|
|
||||||
internal var colorOK: Int = 0
|
|
||||||
@BindColor(R.color.yellow500)
|
|
||||||
internal var colorWarn: Int = 0
|
|
||||||
@BindColor(R.color.green500)
|
|
||||||
internal var colorNeutral: Int = 0
|
|
||||||
@BindColor(R.color.blue500)
|
|
||||||
internal var colorInfo: Int = 0*/
|
|
||||||
|
|
||||||
/*private var magisk: UpdateCardHolder? = null
|
|
||||||
private var manager: UpdateCardHolder? = null
|
|
||||||
private var safetyNet: SafetyNet? = null
|
|
||||||
private var transition: Transition? = null
|
|
||||||
private var optionExpand: Expandable? = null*/
|
|
||||||
|
|
||||||
override val layoutRes: Int = R.layout.fragment_magisk
|
override val layoutRes: Int = R.layout.fragment_magisk
|
||||||
override val viewModel: HomeViewModel by viewModel()
|
override val viewModel: HomeViewModel by viewModel()
|
||||||
|
|
||||||
|
override fun onResponse(responseCode: Int) = viewModel.finishSafetyNetCheck(responseCode)
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) {
|
||||||
super.onEventDispatched(event)
|
super.onEventDispatched(event)
|
||||||
when (event) {
|
when (event) {
|
||||||
@ -62,6 +37,7 @@ class MagiskFragment : NewMagiskFragment<HomeViewModel, com.topjohnwu.magisk.dat
|
|||||||
is UninstallEvent -> uninstall()
|
is UninstallEvent -> uninstall()
|
||||||
is ManagerChangelogEvent -> changelogManager()
|
is ManagerChangelogEvent -> changelogManager()
|
||||||
is EnvFixEvent -> fixEnv()
|
is EnvFixEvent -> fixEnv()
|
||||||
|
is UpdateSafetyNetEvent -> updateSafetyNet(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,184 +58,37 @@ class MagiskFragment : NewMagiskFragment<HomeViewModel, com.topjohnwu.magisk.dat
|
|||||||
private fun changelogManager() = MarkDownWindow
|
private fun changelogManager() = MarkDownWindow
|
||||||
.show(requireActivity(), null, resources.openRawResource(R.raw.changelog))
|
.show(requireActivity(), null, resources.openRawResource(R.raw.changelog))
|
||||||
|
|
||||||
/*override fun onCreateView(
|
private fun downloadSafetyNet(requiresUserInput: Boolean = true) {
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
fun download() = Networking
|
||||||
savedInstanceState: Bundle?
|
.get(Const.Url.SNET_URL)
|
||||||
): View? {
|
.getAsFile(EXT_APK) { updateSafetyNet(true) }
|
||||||
val v = inflater.inflate(R.layout.fragment_magisk, container, false)
|
|
||||||
requireActivity().setTitle(R.string.magisk)
|
|
||||||
|
|
||||||
//safetyNet = SafetyNet(v)
|
if (!requiresUserInput) {
|
||||||
|
download()
|
||||||
*//*transition = TransitionSet()
|
return
|
||||||
.setOrdering(TransitionSet.ORDERING_TOGETHER)
|
|
||||||
.addTransition(Fade(Fade.OUT))
|
|
||||||
.addTransition(ChangeBounds())
|
|
||||||
.addTransition(Fade(Fade.IN))*//*
|
|
||||||
|
|
||||||
updateUI()
|
|
||||||
return v
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private fun onRefresh() {
|
|
||||||
/*mSwipeRefreshLayout!!.isRefreshing = false
|
|
||||||
TransitionManager.beginDelayedTransition(root!!, transition)
|
|
||||||
safetyNet!!.reset()
|
|
||||||
magisk!!.reset()
|
|
||||||
manager!!.reset()*/
|
|
||||||
|
|
||||||
Config.loadMagiskInfo()
|
|
||||||
updateUI()
|
|
||||||
|
|
||||||
//FIXME requires old base
|
|
||||||
/*Event.reset(this)
|
|
||||||
Config.remoteMagiskVersionString = null
|
|
||||||
Config.remoteMagiskVersionCode = -1*/
|
|
||||||
|
|
||||||
shownDialog = false
|
|
||||||
|
|
||||||
// Trigger state check
|
|
||||||
/*if (Networking.checkNetworkStatus(app)) {
|
|
||||||
CheckUpdates.check()
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateUI() {
|
|
||||||
/*(requireActivity() as MainActivity).checkHideSection()
|
|
||||||
val image: Int
|
|
||||||
val color: Int
|
|
||||||
val status: String
|
|
||||||
if (Config.magiskVersionCode < 0) {
|
|
||||||
color = colorBad
|
|
||||||
image = R.drawable.ic_cancel
|
|
||||||
status = getString(R.string.magisk_version_error)
|
|
||||||
magisk!!.status.text = status
|
|
||||||
magisk!!.currentVersion.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
color = colorOK
|
|
||||||
image = R.drawable.ic_check_circle
|
|
||||||
status = getString(R.string.magisk)
|
|
||||||
magisk!!.currentVersion.text = getString(
|
|
||||||
R.string.current_installed,
|
|
||||||
String.format(
|
|
||||||
Locale.US, "v%s (%d)",
|
|
||||||
Config.magiskVersionString, Config.magiskVersionCode
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
magisk!!.statusIcon.setColorFilter(color)
|
|
||||||
magisk!!.statusIcon.setImageResource(image)
|
|
||||||
|
|
||||||
manager!!.statusIcon.setColorFilter(colorOK)
|
CustomAlertDialog(requireActivity())
|
||||||
manager!!.statusIcon.setImageResource(R.drawable.ic_check_circle)
|
.setTitle(R.string.proprietary_title)
|
||||||
manager!!.currentVersion.text = getString(
|
.setMessage(R.string.proprietary_notice)
|
||||||
R.string.current_installed,
|
.setCancelable(false)
|
||||||
String.format(
|
.setPositiveButton(R.string.yes) { _, _ -> download() }
|
||||||
Locale.US, "v%s (%d)",
|
.setNegativeButton(R.string.no_thanks) { _, _ -> viewModel.finishSafetyNetCheck(-2) }
|
||||||
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE
|
.show()
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!Networking.checkNetworkStatus(app)) {
|
|
||||||
// No network, updateCheckUI will not be triggered
|
|
||||||
magisk!!.status.text = status
|
|
||||||
manager!!.status.setText(R.string.app_name)
|
|
||||||
magisk!!.setValid(false)
|
|
||||||
manager!!.setValid(false)
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCheckUI() {
|
private fun updateSafetyNet(dieOnError: Boolean) {
|
||||||
/*var image: Int
|
try {
|
||||||
var color: Int
|
SafetyNet.dyRun(requireActivity(), this)
|
||||||
var status: String
|
} catch (e: Exception) {
|
||||||
var button = ""
|
if (dieOnError) {
|
||||||
|
viewModel.finishSafetyNetCheck(-1)
|
||||||
|
return
|
||||||
if (Config.remoteMagiskVersionCode < 0) {
|
|
||||||
color = colorNeutral
|
|
||||||
image = R.drawable.ic_help
|
|
||||||
status = getString(R.string.invalid_update_channel)
|
|
||||||
} else {
|
|
||||||
magisk!!.latestVersion.text = getString(
|
|
||||||
R.string.latest_version,
|
|
||||||
String.format(
|
|
||||||
Locale.US, "v%s (%d)",
|
|
||||||
Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if (Config.remoteMagiskVersionCode > Config.magiskVersionCode) {
|
|
||||||
color = colorInfo
|
|
||||||
image = R.drawable.ic_update
|
|
||||||
status = getString(R.string.magisk_update_title)
|
|
||||||
button = getString(R.string.update)
|
|
||||||
} else {
|
|
||||||
color = colorOK
|
|
||||||
image = R.drawable.ic_check_circle
|
|
||||||
status = getString(R.string.magisk_up_to_date)
|
|
||||||
button = getString(R.string.install)
|
|
||||||
}
|
}
|
||||||
|
Shell.sh("rm -rf " + EXT_APK.parent).exec()
|
||||||
|
EXT_APK.parentFile?.mkdir()
|
||||||
|
downloadSafetyNet(!dieOnError)
|
||||||
}
|
}
|
||||||
if (Config.magiskVersionCode > 0) {
|
|
||||||
// Only override status if Magisk is installed
|
|
||||||
magisk!!.statusIcon.setImageResource(image)
|
|
||||||
magisk!!.statusIcon.setColorFilter(color)
|
|
||||||
magisk!!.status.text = status
|
|
||||||
magisk!!.install.text = button
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.remoteManagerVersionCode < 0) {
|
|
||||||
color = colorNeutral
|
|
||||||
image = R.drawable.ic_help
|
|
||||||
status = getString(R.string.invalid_update_channel)
|
|
||||||
} else {
|
|
||||||
manager!!.latestVersion.text = getString(
|
|
||||||
R.string.latest_version,
|
|
||||||
String.format(
|
|
||||||
Locale.US, "v%s (%d)",
|
|
||||||
Config.remoteManagerVersionString, Config.remoteManagerVersionCode
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if (Config.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
|
||||||
color = colorInfo
|
|
||||||
image = R.drawable.ic_update
|
|
||||||
status = getString(R.string.manager_update_title)
|
|
||||||
manager!!.install.setText(R.string.update)
|
|
||||||
} else {
|
|
||||||
color = colorOK
|
|
||||||
image = R.drawable.ic_check_circle
|
|
||||||
status = getString(R.string.manager_up_to_date)
|
|
||||||
manager!!.install.setText(R.string.install)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
manager!!.statusIcon.setImageResource(image)
|
|
||||||
manager!!.statusIcon.setColorFilter(color)
|
|
||||||
manager!!.status.text = status
|
|
||||||
|
|
||||||
magisk!!.setValid(Config.remoteMagiskVersionCode > 0)
|
|
||||||
manager!!.setValid(Config.remoteManagerVersionCode > 0)
|
|
||||||
|
|
||||||
if (Config.remoteMagiskVersionCode < 0) {
|
|
||||||
// Hide install related components
|
|
||||||
installOptionCard!!.visibility = View.GONE
|
|
||||||
uninstallButton!!.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
// Show install related components
|
|
||||||
installOptionCard!!.visibility = View.VISIBLE
|
|
||||||
uninstallButton!!.visibility = if (Shell.rootAccess()) View.VISIBLE else View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shownDialog && Config.magiskVersionCode > 0 &&
|
|
||||||
!Shell.su("env_check").exec().isSuccess
|
|
||||||
) {
|
|
||||||
shownDialog = true
|
|
||||||
EnvFixDialog(requireActivity()).show()
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
private var shownDialog = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.topjohnwu.magisk.ui.home
|
||||||
|
|
||||||
|
enum class SafetyNetState {
|
||||||
|
LOADING, PASS, FAILED, IDLE
|
||||||
|
}
|
@ -9,12 +9,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.StringRes;
|
|
||||||
import androidx.cardview.widget.CardView;
|
|
||||||
import butterknife.BindColor;
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
import butterknife.Unbinder;
|
|
||||||
import com.topjohnwu.magisk.App;
|
import com.topjohnwu.magisk.App;
|
||||||
import com.topjohnwu.magisk.Const;
|
import com.topjohnwu.magisk.Const;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
@ -22,13 +17,20 @@ import com.topjohnwu.magisk.utils.ISafetyNetHelper;
|
|||||||
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog;
|
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog;
|
||||||
import com.topjohnwu.net.Networking;
|
import com.topjohnwu.net.Networking;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
import dalvik.system.DexClassLoader;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.cardview.widget.CardView;
|
||||||
|
import butterknife.BindColor;
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import butterknife.Unbinder;
|
||||||
|
import dalvik.system.DexClassLoader;
|
||||||
|
|
||||||
public class SafetyNet implements ISafetyNetHelper.Callback {
|
public class SafetyNet implements ISafetyNetHelper.Callback {
|
||||||
|
|
||||||
private static final File EXT_APK =
|
public static final File EXT_APK =
|
||||||
new File(App.self.getFilesDir().getParent() + "/snet", "snet.apk");
|
new File(App.self.getFilesDir().getParent() + "/snet", "snet.apk");
|
||||||
|
|
||||||
/*@BindView(R.id.safetyNet_card) */ CardView safetyNetCard;
|
/*@BindView(R.id.safetyNet_card) */ CardView safetyNetCard;
|
||||||
@ -45,7 +47,7 @@ public class SafetyNet implements ISafetyNetHelper.Callback {
|
|||||||
@BindColor(R.color.green500) int colorOK;
|
@BindColor(R.color.green500) int colorOK;
|
||||||
|
|
||||||
public Unbinder unbinder;
|
public Unbinder unbinder;
|
||||||
private ExpandableViewHolder expandable;
|
private final ExpandableViewHolder expandable;
|
||||||
|
|
||||||
public SafetyNet(View v) {
|
public SafetyNet(View v) {
|
||||||
unbinder = new SafetyNet_ViewBinding(this, v);
|
unbinder = new SafetyNet_ViewBinding(this, v);
|
||||||
@ -55,27 +57,16 @@ public class SafetyNet implements ISafetyNetHelper.Callback {
|
|||||||
View.VISIBLE : View.GONE);
|
View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.safetyNet_refresh)
|
public static void dyRun(Activity activity, Object callback) throws Exception {
|
||||||
void safetyNet(View v) {
|
DexClassLoader loader = new DexClassLoader(EXT_APK.getPath(), EXT_APK.getParent(),
|
||||||
Runnable task = () -> {
|
null, ISafetyNetHelper.class.getClassLoader());
|
||||||
safetyNetProgress.setVisibility(View.VISIBLE);
|
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.Snet");
|
||||||
safetyNetRefreshIcon.setVisibility(View.INVISIBLE);
|
ISafetyNetHelper helper = (ISafetyNetHelper) clazz.getMethod("newHelper",
|
||||||
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
Class.class, String.class, Activity.class, Object.class)
|
||||||
check((Activity) v.getContext());
|
.invoke(null, ISafetyNetHelper.class, EXT_APK.getPath(), activity, callback);
|
||||||
expandable.collapse();
|
if (helper.getVersion() < Const.SNET_EXT_VER)
|
||||||
};
|
throw new Exception();
|
||||||
if (!SafetyNet.EXT_APK.exists()) {
|
helper.attest();
|
||||||
// Show dialog
|
|
||||||
new CustomAlertDialog((Activity) v.getContext())
|
|
||||||
.setTitle(R.string.proprietary_title)
|
|
||||||
.setMessage(R.string.proprietary_notice)
|
|
||||||
.setCancelable(true)
|
|
||||||
.setPositiveButton(R.string.yes, (d, i) -> task.run())
|
|
||||||
.setNegativeButton(R.string.no_thanks, null)
|
|
||||||
.show();
|
|
||||||
} else {
|
|
||||||
task.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@ -117,27 +108,38 @@ public class SafetyNet implements ISafetyNetHelper.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dyRun(Activity activity) throws Exception {
|
@OnClick(R.id.safetyNet_refresh)
|
||||||
DexClassLoader loader = new DexClassLoader(EXT_APK.getPath(), EXT_APK.getParent(),
|
void safetyNet(View v) {
|
||||||
null, ISafetyNetHelper.class.getClassLoader());
|
Runnable task = () -> {
|
||||||
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.Snet");
|
safetyNetProgress.setVisibility(View.VISIBLE);
|
||||||
ISafetyNetHelper helper = (ISafetyNetHelper) clazz.getMethod("newHelper",
|
safetyNetRefreshIcon.setVisibility(View.INVISIBLE);
|
||||||
Class.class, String.class, Activity.class, Object.class)
|
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
||||||
.invoke(null, ISafetyNetHelper.class, EXT_APK.getPath(), activity, this);
|
check((Activity) v.getContext());
|
||||||
if (helper.getVersion() < Const.SNET_EXT_VER)
|
expandable.collapse();
|
||||||
throw new Exception();
|
};
|
||||||
helper.attest();
|
if (!EXT_APK.exists()) {
|
||||||
|
// Show dialog
|
||||||
|
new CustomAlertDialog((Activity) v.getContext())
|
||||||
|
.setTitle(R.string.proprietary_title)
|
||||||
|
.setMessage(R.string.proprietary_notice)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setPositiveButton(R.string.yes, (d, i) -> task.run())
|
||||||
|
.setNegativeButton(R.string.no_thanks, null)
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void check(Activity activity) {
|
private void check(Activity activity) {
|
||||||
try {
|
try {
|
||||||
dyRun(activity);
|
dyRun(activity, this);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
Shell.sh("rm -rf " + EXT_APK.getParent()).exec();
|
Shell.sh("rm -rf " + EXT_APK.getParent()).exec();
|
||||||
EXT_APK.getParentFile().mkdir();
|
EXT_APK.getParentFile().mkdir();
|
||||||
Networking.get(Const.Url.SNET_URL).getAsFile(EXT_APK, f -> {
|
Networking.get(Const.Url.SNET_URL).getAsFile(EXT_APK, f -> {
|
||||||
try {
|
try {
|
||||||
dyRun(activity);
|
dyRun(activity, this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
onResponse(-1);
|
onResponse(-1);
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
|
<import type="com.skoumal.teanity.viewmodel.LoadingViewModel.State" />
|
||||||
|
|
||||||
|
<import type="com.topjohnwu.magisk.ui.home.SafetyNetState" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskItem" />
|
<import type="com.topjohnwu.magisk.ui.home.MagiskItem" />
|
||||||
|
|
||||||
|
<import type="com.topjohnwu.magisk.R" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
type="com.topjohnwu.magisk.ui.home.HomeViewModel" />
|
type="com.topjohnwu.magisk.ui.home.HomeViewModel" />
|
||||||
@ -38,8 +45,8 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_marginBottom="5dp">
|
android:layout_marginTop="5dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/icon"
|
android:id="@+id/icon"
|
||||||
@ -59,8 +66,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:paddingTop="10dp"
|
|
||||||
android:paddingBottom="10dp"
|
android:paddingBottom="10dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
android:text="@string/app_name"
|
android:text="@string/app_name"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
|
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
@ -114,8 +121,8 @@
|
|||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:onClick="@{() -> viewModel.advancedPressed()}"
|
android:onClick="@{() -> viewModel.advancedPressed()}"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingTop="10dp"
|
android:paddingBottom="10dp"
|
||||||
android:paddingBottom="10dp">
|
android:paddingTop="10dp">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -198,90 +205,87 @@
|
|||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="@dimen/margin_generic_half"
|
||||||
|
android:paddingTop="@dimen/margin_generic_half">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/sn_logo"
|
android:id="@+id/sn_logo"
|
||||||
android:layout_width="30dp"
|
android:layout_width="30dp"
|
||||||
android:layout_height="30dp"
|
android:layout_height="30dp"
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:tint="@color/green500"
|
android:tint="@color/green500"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/safetyNet_status"
|
app:layout_constraintEnd_toStartOf="@+id/safetyNet_status"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/ic_safetynet" />
|
app:srcCompat="@drawable/ic_safetynet" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/safetyNet_status"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/margin_generic"
|
||||||
|
android:layout_marginRight="@dimen/margin_generic"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@{viewModel.safetyNetTitle}"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:autoSizeMaxTextSize="14sp"
|
||||||
|
app:autoSizeTextType="uniform"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/safetyNet_refresh"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/sn_logo"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_min="200dp" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/safetyNet_refresh"
|
android:id="@+id/safetyNet_refresh"
|
||||||
|
invisible="@{viewModel.ctsState == SafetyNetState.LOADING || viewModel.basicIntegrityState == SafetyNetState.LOADING}"
|
||||||
android:layout_width="25dp"
|
android:layout_width="25dp"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginStart="24dp"
|
android:onClick="@{() -> viewModel.safetyNetPressed()}"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/safetyNet_status"
|
app:layout_constraintStart_toEndOf="@+id/safetyNet_status"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/ic_refresh" />
|
app:srcCompat="@drawable/ic_refresh" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/safetyNet_check_progress"
|
android:id="@+id/safetyNet_check_progress"
|
||||||
|
goneUnless="@{viewModel.ctsState == SafetyNetState.LOADING || viewModel.basicIntegrityState == SafetyNetState.LOADING}"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/safetyNet_refresh"
|
app:layout_constraintBottom_toBottomOf="@+id/safetyNet_refresh"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/safetyNet_refresh"
|
app:layout_constraintEnd_toEndOf="@+id/safetyNet_refresh"
|
||||||
app:layout_constraintStart_toStartOf="@+id/safetyNet_refresh"
|
app:layout_constraintStart_toStartOf="@+id/safetyNet_refresh"
|
||||||
app:layout_constraintTop_toTopOf="@+id/safetyNet_refresh" />
|
app:layout_constraintTop_toTopOf="@+id/safetyNet_refresh" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/safetyNet_status"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:minWidth="200dp"
|
|
||||||
android:text="@string/safetyNet_check_text"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:autoSizeMaxTextSize="14sp"
|
|
||||||
app:autoSizeTextType="uniform"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/sn_status_end"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/sn_status_start"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/sn_status_start"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_percent="0.25" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/sn_status_end"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_percent="0.75" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/safetyNet_expand"
|
android:id="@+id/safetyNet_expand"
|
||||||
|
gone="@{viewModel.safetyNetState == State.LOADING}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="10dp">
|
android:paddingBottom="10dp">
|
||||||
|
|
||||||
<ImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/cts_status_icon"
|
android:id="@+id/cts_status_icon"
|
||||||
|
srcCompat="@{viewModel.ctsState == SafetyNetState.PASS ? R.drawable.ic_check_circle : R.drawable.ic_cancel}"
|
||||||
|
app:tint="@{viewModel.ctsState == SafetyNetState.PASS ? @color/colorCorrect : @color/colorError}"
|
||||||
android:layout_width="25dp"
|
android:layout_width="25dp"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/cts_status"
|
app:layout_constraintBottom_toBottomOf="@+id/cts_status"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/cts_status"
|
app:layout_constraintEnd_toStartOf="@+id/cts_status"
|
||||||
app:layout_constraintTop_toTopOf="@+id/cts_status" />
|
app:layout_constraintTop_toTopOf="@+id/cts_status"
|
||||||
|
tools:srcCompat="@drawable/ic_check_circle" />
|
||||||
|
|
||||||
<ImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/basic_status_icon"
|
android:id="@+id/basic_status_icon"
|
||||||
|
srcCompat="@{viewModel.basicIntegrityState == SafetyNetState.PASS ? R.drawable.ic_check_circle : R.drawable.ic_cancel}"
|
||||||
|
app:tint="@{viewModel.basicIntegrityState == SafetyNetState.PASS ? @color/colorCorrect : @color/colorError}"
|
||||||
android:layout_width="25dp"
|
android:layout_width="25dp"
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
@ -290,17 +294,20 @@
|
|||||||
app:layout_constraintHorizontal_bias="0.5"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/basic_status" />
|
app:layout_constraintTop_toTopOf="@+id/basic_status"
|
||||||
|
tools:srcCompat="@drawable/ic_check_circle" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/cts_status"
|
android:id="@+id/cts_status"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
|
android:text="@{String.format(`ctsProfile: %b`, viewModel.ctsState == SafetyNetState.PASS)}"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/basic_status"
|
app:layout_constraintEnd_toEndOf="@+id/basic_status"
|
||||||
app:layout_constraintStart_toStartOf="@+id/basic_status"
|
app:layout_constraintStart_toStartOf="@+id/basic_status"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="ctsProfile: true" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/basic_status"
|
android:id="@+id/basic_status"
|
||||||
@ -308,12 +315,14 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
|
android:text="@{String.format(`basicIntegrity: %b`, viewModel.basicIntegrityState == SafetyNetState.PASS)}"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
app:layout_constraintStart_toEndOf="@+id/basic_status_icon"
|
app:layout_constraintStart_toEndOf="@+id/basic_status_icon"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/cts_status" />
|
app:layout_constraintTop_toBottomOf="@+id/cts_status"
|
||||||
|
tools:text="basicIntegrity: true" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user