package exh.ui.lock import android.annotation.SuppressLint import android.annotation.TargetApi import android.content.Context import android.os.Build import android.util.AttributeSet import android.view.Gravity import android.view.ViewGroup import android.widget.TextView import androidx.appcompat.widget.LinearLayoutCompat import androidx.preference.SwitchPreferenceCompat import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.customview.customView import com.github.ajalt.reprint.core.AuthenticationResult import com.github.ajalt.reprint.core.Reprint import com.github.ajalt.reprint.rxjava.RxReprint import com.mattprecious.swirl.SwirlView import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.util.preference.onChange import exh.util.dpToPx import rx.android.schedulers.AndroidSchedulers import uy.kohesive.injekt.injectLazy class FingerLockPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : SwitchPreferenceCompat(context, attrs) { val prefs: PreferencesHelper by injectLazy() val fingerprintSupported get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Reprint.isHardwarePresent() && Reprint.hasFingerprintRegistered() val useFingerprint get() = fingerprintSupported && prefs.eh_lockUseFingerprint().getOrDefault() @SuppressLint("NewApi") override fun onAttached() { super.onAttached() if (fingerprintSupported) { updateSummary() onChange { if (it as Boolean) tryChange() else prefs.eh_lockUseFingerprint().set(false) !it } } else { title = "Fingerprint unsupported" shouldDisableView = true summary = if (!Reprint.hasFingerprintRegistered()) "No fingerprints enrolled!" else "Fingerprint unlock is unsupported on this device!" onChange { false } } } private fun updateSummary() { isChecked = useFingerprint title = if (isChecked) "Fingerprint enabled" else "Fingerprint disabled" } @TargetApi(Build.VERSION_CODES.M) fun tryChange() { val statusTextView = TextView(context).apply { text = "Please touch the fingerprint sensor" val size = ViewGroup.LayoutParams.WRAP_CONTENT layoutParams = (layoutParams ?: ViewGroup.LayoutParams( size, size )).apply { width = size height = size setPadding(0, 0, dpToPx(context, 8), 0) } } val iconView = SwirlView(context).apply { val size = dpToPx(context, 30) layoutParams = (layoutParams ?: ViewGroup.LayoutParams( size, size )).apply { width = size height = size } setState(SwirlView.State.OFF, false) } val linearLayout = LinearLayoutCompat(context).apply { orientation = LinearLayoutCompat.HORIZONTAL gravity = Gravity.CENTER_VERTICAL val size = LinearLayoutCompat.LayoutParams.WRAP_CONTENT layoutParams = (layoutParams ?: LinearLayoutCompat.LayoutParams( size, size )).apply { width = size height = size val pSize = dpToPx(context, 24) setPadding(pSize, 0, pSize, 0) } addView(statusTextView) addView(iconView) } val dialog = MaterialDialog(context) .title(text = "Fingerprint verification") .customView(view = linearLayout) .negativeButton(R.string.action_cancel) .cancelable(true) .cancelOnTouchOutside(true) dialog.show() iconView.setState(SwirlView.State.ON) val subscription = RxReprint.authenticate() .observeOn(AndroidSchedulers.mainThread()) .subscribe { result -> when (result.status) { AuthenticationResult.Status.SUCCESS -> { iconView.setState(SwirlView.State.ON) prefs.eh_lockUseFingerprint().set(true) dialog.dismiss() updateSummary() } AuthenticationResult.Status.NONFATAL_FAILURE -> { iconView.setState(SwirlView.State.ERROR) statusTextView.text = result.errorMessage } AuthenticationResult.Status.FATAL_FAILURE, null -> { MaterialDialog(context) .title(text = "Fingerprint verification failed!") .message(text = result.errorMessage) .positiveButton(android.R.string.ok) .cancelable(true) .cancelOnTouchOutside(false) .show() dialog.dismiss() } } } dialog.setOnDismissListener { subscription.unsubscribe() } } }