From 1f9ecfddc0ebf4c1a7bea387632341c846386a12 Mon Sep 17 00:00:00 2001 From: X1nto Date: Tue, 22 Dec 2020 21:36:11 +0400 Subject: [PATCH] added sleep timer adjuster and optimized views --- .../manager/ui/core/ThemedMaterialCheckbox.kt | 5 -- .../ui/core/ThemedMaterialRadioButton.kt | 5 -- .../ui/core/ThemedSwipeRefreshlayout.kt | 25 +++++++++ .../manager/ui/dialogs/ServiceDTimerDialog.kt | 55 +++++++++++++++++++ .../manager/ui/fragments/SettingsFragment.kt | 37 +++++++++++-- .../com/vanced/manager/utils/Extensions.kt | 9 +++ .../com/vanced/manager/utils/PackageHelper.kt | 40 +++++++------- .../main/res/layout/dialog_serviced_timer.xml | 50 +++++++++++++++++ app/src/main/res/layout/fragment_home.xml | 10 +++- app/src/main/res/layout/fragment_settings.xml | 11 ++++ app/src/main/res/values/attrs.xml | 4 ++ 11 files changed, 213 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/com/vanced/manager/ui/core/ThemedSwipeRefreshlayout.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/ServiceDTimerDialog.kt create mode 100644 app/src/main/res/layout/dialog_serviced_timer.xml diff --git a/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialCheckbox.kt b/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialCheckbox.kt index be062fca..b9dbfcb6 100644 --- a/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialCheckbox.kt +++ b/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialCheckbox.kt @@ -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()) - } - } } } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialRadioButton.kt b/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialRadioButton.kt index af1667ac..67314265 100644 --- a/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialRadioButton.kt +++ b/app/src/main/java/com/vanced/manager/ui/core/ThemedMaterialRadioButton.kt @@ -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()) - } - } } } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/ThemedSwipeRefreshlayout.kt b/app/src/main/java/com/vanced/manager/ui/core/ThemedSwipeRefreshlayout.kt new file mode 100644 index 00000000..5e7e9d97 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/core/ThemedSwipeRefreshlayout.kt @@ -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() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ServiceDTimerDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ServiceDTimerDialog.kt new file mode 100644 index 00000000..0534dad2 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ServiceDTimerDialog.kt @@ -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() { + + 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() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt index 2034ea1a..c629c6a1 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt @@ -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() { 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() { 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() { 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() { } 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()) } } } diff --git a/app/src/main/java/com/vanced/manager/utils/Extensions.kt b/app/src/main/java/com/vanced/manager/utils/Extensions.kt index 80c68da2..b31ba9c6 100644 --- a/app/src/main/java/com/vanced/manager/utils/Extensions.kt +++ b/app/src/main/java/com/vanced/manager/utils/Extensions.kt @@ -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())} + } + } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt b/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt index 2668e2c9..f6c70d03 100644 --- a/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt +++ b/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt @@ -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) diff --git a/app/src/main/res/layout/dialog_serviced_timer.xml b/app/src/main/res/layout/dialog_serviced_timer.xml new file mode 100644 index 00000000..ef47e0f1 --- /dev/null +++ b/app/src/main/res/layout/dialog_serviced_timer.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index f048e32d..69c896d5 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -1,9 +1,11 @@ - + android:layout_height="match_parent" + app:progressBackgroundColor="?colorSurface"> + - + + diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index dcc47043..d4d1ef5a 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -49,11 +49,19 @@ android:layout_height="wrap_content" app:preference_title="@string/variant" /> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 7d352f1c..903f4a49 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -32,4 +32,8 @@ + + + + \ No newline at end of file