added sleep timer adjuster and optimized views

This commit is contained in:
X1nto 2020-12-22 21:36:11 +04:00
parent 2a5e46855c
commit 1f9ecfddc0
11 changed files with 213 additions and 38 deletions

View File

@ -16,10 +16,5 @@ class ThemedMaterialCheckbox @JvmOverloads constructor(
) : MaterialCheckBox(context, attributeSet, R.attr.checkboxStyle) {
init {
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
buttonTintList = ColorStateList.valueOf(color.toInt())
}
}
}
}

View File

@ -16,10 +16,5 @@ class ThemedMaterialRadioButton @JvmOverloads constructor(
) : MaterialRadioButton(context, attributeSet, R.attr.radioButtonStyle) {
init {
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
buttonTintList = ColorStateList.valueOf(color.toInt())
}
}
}
}

View File

@ -0,0 +1,25 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.util.AttributeSet
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedSwipeRefreshlayout @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null
) : SwipeRefreshLayout(context, attributeSet) {
init {
setColorSchemeColors(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
initAttrs(context, attributeSet)
}
private fun initAttrs(context: Context, attributeSet: AttributeSet?) {
attributeSet.let {
val typedAttrs = context.obtainStyledAttributes(it, R.styleable.ThemedSwipeRefreshlayout, 0, 0)
setProgressBackgroundColorSchemeColor(typedAttrs.getColor(R.styleable.ThemedSwipeRefreshlayout_progressBackgroundColor, 0))
typedAttrs.recycle()
}
}
}

View File

@ -0,0 +1,55 @@
package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogServicedTimerBinding
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.writeServiceDScript
import com.vanced.manager.utils.PackageHelper
import com.vanced.manager.utils.PackageHelper.getPackageDir
import com.vanced.manager.utils.PackageHelper.getPkgNameRoot
import java.io.IOException
import java.util.*
class ServiceDTimerDialog : BindingDialogFragment<DialogServicedTimerBinding>() {
private val prefs by lazy { requireActivity().getDefaultPrefs() }
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): DialogServicedTimerBinding = DialogServicedTimerBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData()
}
private fun bindData() {
with (binding) {
servicedSlider.value = prefs.getInt("serviced_sleep_timer", 1).toFloat()
servicedCancel.setOnClickListener {
dismiss()
}
servicedSave.setOnClickListener {
try {
arrayOf("vanced", "music").forEach { app ->
val apkFPath = "${PackageHelper.apkInstallPath}/${app.capitalize(Locale.ROOT)}/base.apk"
getPackageDir(requireActivity(), getPkgNameRoot(app))?.let { it1 -> requireActivity().writeServiceDScript(apkFPath, it1, app) }
}
} catch (e: IOException) {
return@setOnClickListener
}
prefs.edit {
putInt("serviced_sleep_timer", servicedSlider.value.toInt())
}
dismiss()
}
}
}
}

View File

@ -1,11 +1,13 @@
package com.vanced.manager.ui.fragments
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.analytics.FirebaseAnalytics
@ -26,12 +28,20 @@ import java.io.File
class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private companion object {
const val LIGHT = "Light"
const val DARK = "Dark"
}
private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) }
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
when (key) {
"serviced_sleep_timer" -> {
binding.servicedTimer.setSummary(sharedPreferences.getInt(key, 1).toString())
}
}
}
private lateinit var variant: String
override fun binding(
inflater: LayoutInflater,
@ -41,14 +51,22 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
override fun otherSetups() {
setHasOptionsMenu(true)
prefs.registerOnSharedPreferenceChangeListener(listener)
bindData()
}
override fun onPause() {
super.onPause()
prefs.unregisterOnSharedPreferenceChangeListener(listener)
}
private fun bindData() {
with(binding) {
variant = prefs.getString("vanced_variant", "nonroot").toString()
bindRecycler()
bindFirebase()
bindManagerVariant()
bindServiceDTimer()
bindClearFiles()
bindManagerTheme()
bindManagerAccentColor()
@ -74,10 +92,19 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private fun FragmentSettingsBinding.bindManagerVariant() {
managerVariant.apply {
prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) }
setSummary(variant)
setOnClickListener { showDialog(ManagerVariantDialog()) }
}
}
private fun FragmentSettingsBinding.bindServiceDTimer() {
servicedTimer.apply {
if (variant == "root") this.isVisible = true
setSummary(prefs.getInt("serviced_sleep_timer", 1).toString())
setOnClickListener { showDialog(ServiceDTimerDialog()) }
}
}
private fun FragmentSettingsBinding.bindClearFiles() {
clearFiles.setOnClickListener {
with(requireActivity()) {
@ -104,11 +131,11 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
}
private fun FragmentSettingsBinding.bindManagerAccentColor() {
managerAccentColor.setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
managerAccentColor.apply {
managerAccentColor.apply{
setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
setOnClickListener { showDialog(ManagerAccentColorDialog()) }
accentColor.observe(viewLifecycleOwner) {
managerAccentColor.setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
setSummary(it.toHex())
}
}
}

View File

@ -13,6 +13,8 @@ import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.material.radiobutton.MaterialRadioButton
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.R
import com.vanced.manager.utils.InternetTools.baseUrl
import com.vanced.manager.utils.ThemeHelper.accentColor
@ -86,4 +88,11 @@ object Extensions {
}
}
fun Context.writeServiceDScript(path: String, apkFPath: String, app: String) {
val shellFileZ = SuFile.open("/data/adb/service.d/$app.sh")
shellFileZ.createNewFile()
val code = """#!/system/bin/sh${"\n"}while [ "`getprop sys.boot_completed | tr -d '\r' `" != "1" ]; do sleep ${getDefaultPrefs().getInt("serviced_sleep_timer", 1)}; done${"\n"}mount -o bind $apkFPath $path"""
SuFileOutputStream(shellFileZ).use { out -> out.write(code.toByteArray())}
}
}

View File

@ -10,7 +10,6 @@ import android.os.Build
import android.util.Log
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.BuildConfig
import com.vanced.manager.core.installer.AppInstallerService
import com.vanced.manager.core.installer.AppUninstallerService
@ -19,6 +18,7 @@ import com.vanced.manager.utils.AppUtils.sendCloseDialog
import com.vanced.manager.utils.AppUtils.sendFailure
import com.vanced.manager.utils.AppUtils.sendRefresh
import com.vanced.manager.utils.AppUtils.vancedRootPkg
import com.vanced.manager.utils.Extensions.writeServiceDScript
import com.vanced.manager.utils.InternetTools.music
import com.vanced.manager.utils.InternetTools.vanced
import kotlinx.coroutines.CoroutineScope
@ -33,7 +33,7 @@ import kotlin.collections.HashMap
object PackageHelper {
private const val apkInstallPath = "/data/adb"
const val apkInstallPath = "/data/adb"
private val vancedThemes = arrayOf("black", "dark", "pink", "blue")
init {
@ -45,7 +45,7 @@ object PackageHelper {
)
}
private fun getAppName(pkg: String): String {
private fun getAppNameRoot(pkg: String): String {
return when (pkg) {
vancedRootPkg -> "vanced"
musicRootPkg -> "music"
@ -53,6 +53,13 @@ object PackageHelper {
}
}
fun getPkgNameRoot(app: String): String {
return when (app) {
"vanced" -> vancedRootPkg
"music" -> musicRootPkg
else -> ""
}
}
fun isPackageInstalled(packageName: String, packageManager: PackageManager): Boolean {
return try {
packageManager.getPackageInfo(packageName, 0)
@ -127,7 +134,7 @@ object PackageHelper {
}
fun uninstallRootApk(pkg: String): Boolean {
val app = getAppName(pkg)
val app = getAppNameRoot(pkg)
Shell.su("rm -rf $apkInstallPath/${app.capitalize(Locale.ROOT)}").exec()
Shell.su("rm $apkInstallPath/post-fs-data.d/$app.sh").exec()
Shell.su("rm $apkInstallPath/service.d/$app.sh").exec()
@ -432,7 +439,7 @@ object PackageHelper {
val apkFPath = "$apkInstallPath/${app.capitalize(Locale.ROOT)}/base.apk"
if (moveAPK(apath, apkFPath, pkg, context)) {
if (chConV(apkFPath, context)) {
if (setupScript(apkFPath, path, app, pkg)) {
if (setupScript(apkFPath, path, app, pkg, context)) {
return linkApp(apkFPath, pkg, path)
}
}
@ -443,21 +450,14 @@ object PackageHelper {
return false
}
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String): Boolean
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String, context: Context): Boolean
{
val shellFileZ = SuFile.open("/data/adb/service.d/$app.sh")
shellFileZ.createNewFile()
val code = """#!/system/bin/sh${"\n"}while [ "`getprop sys.boot_completed | tr -d '\r' `" != "1" ]; do sleep 1; done${"\n"}mount -o bind $apkFPath $path"""
if (shellFileZ.exists()) {
try {
SuFileOutputStream(shellFileZ).use { out -> out.write(code.toByteArray())}
Shell.su("""echo "#!/system/bin/sh\nwhile read line; do echo \${"$"}{line} | grep $pkg | awk '{print \${'$'}2}' | xargs umount -l; done< /proc/mounts" > /data/adb/post-fs-data.d/$app.sh""").exec()
return Shell.su("chmod 744 /data/adb/service.d/$app.sh").exec().isSuccess
} catch (e: IOException) {
e.printStackTrace()
}
try {
context.writeServiceDScript(apkFPath, path, app)
Shell.su("""echo "#!/system/bin/sh\nwhile read line; do echo \${"$"}{line} | grep $pkg | awk '{print \${'$'}2}' | xargs umount -l; done< /proc/mounts" > /data/adb/post-fs-data.d/$app.sh""").exec()
return Shell.su("chmod 744 /data/adb/service.d/$app.sh").exec().isSuccess
} catch (e: IOException) {
e.printStackTrace()
}
return false
}
@ -603,7 +603,7 @@ object PackageHelper {
}
//get path of the installed youtube
private fun getPackageDir(context: Context, pkg: String): String?
fun getPackageDir(context: Context, pkg: String): String?
{
val p = getPkgInfo(pkg, context)
return if(p != null)

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.dialogs.AppDownloadDialog"
style="@style/DialogCard">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/serviced_header"
tools:text="Script Sleep Timer"
style="@style/DialogCardTitle" />
<com.google.android.material.slider.Slider
android:id="@+id/serviced_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/serviced_header"
android:layout_marginTop="24dp"
android:valueFrom="1"
android:valueTo="50"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/serviced_slider"
android:layout_marginTop="8dp">
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/serviced_cancel"
android:layout_alignParentStart="true"
android:textSize="15sp"
android:text="@string/cancel"
style="@style/OutlinedButtonStyle"/>
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/serviced_save"
android:layout_alignParentEnd="true"
android:text="@string/save"
app:layout_constraintEnd_toEndOf="parent"
style="@style/ButtonStyle"/>
</RelativeLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.vanced.manager.ui.core.ThemedSwipeRefreshlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/home_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
app:progressBackgroundColor="?colorSurface">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -58,5 +60,7 @@
tools:itemCount="6"
tools:listitem="@layout/view_social_link" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</com.vanced.manager.ui.core.ThemedSwipeRefreshlayout>

View File

@ -49,11 +49,19 @@
android:layout_height="wrap_content"
app:preference_title="@string/variant" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/serviced_timer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Script Sleep Timer"
android:visibility="gone"/>
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/clearFiles"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/clear_files" />
</com.vanced.manager.ui.core.PreferenceCategory>
<com.vanced.manager.ui.core.PreferenceCategory
@ -86,6 +94,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/select_apps" />
</com.vanced.manager.ui.core.PreferenceCategory>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -32,4 +32,8 @@
<attr name="preference_summary" format="reference|string"/>
</declare-styleable>
<declare-styleable name="ThemedSwipeRefreshlayout">
<attr name="progressBackgroundColor" format="reference|color" />
</declare-styleable>
</resources>