From 717c6475ba41f0ce5596d3fde4b1b16818d3be30 Mon Sep 17 00:00:00 2001 From: Art_Chen Date: Sun, 19 May 2024 20:36:52 +0800 Subject: [PATCH] HomeHandleAnim: optimize and add anim custom settings * Fix Blur not working as experted * Add Animation customize feature * support disable movement for home handle but keep anim * a little power & performance optimize * Workaround home handle can not hide when window hide Signed-off-by: Art_Chen --- .idea/deploymentTargetDropDown.xml | 3 + app/src/main/AndroidManifest.xml | 4 + .../miuiextra/hooker/entity/SystemHooker.kt | 2 + .../framework/StartingWindowOptimize.kt | 18 ++ .../entity/framework/VibratorMapHooker.kt | 2 +- .../systemui/HomeHandleAnimatorHooker.kt | 217 ++++++++++++------ .../view/activity/HomeHandleCustomActivity.kt | 128 +++++++++++ .../view/activity/SettingsActivity.kt | 5 +- app/src/main/res/values-ja/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 12 +- app/src/main/res/values/strings.xml | 14 +- app/src/main/res/xml/chen_preferences.xml | 33 +-- .../main/res/xml/home_handle_anim_pref.xml | 136 +++++++++++ 13 files changed, 472 insertions(+), 106 deletions(-) create mode 100644 app/src/main/java/moe/chenxy/miuiextra/hooker/entity/framework/StartingWindowOptimize.kt create mode 100644 app/src/main/java/moe/chenxy/miuiextra/view/activity/HomeHandleCustomActivity.kt create mode 100644 app/src/main/res/xml/home_handle_anim_pref.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 0c0c338..8d62ae6 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -5,6 +5,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d5dbf70..1b7ee58 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,10 @@ android:name=".view.activity.WallpaperZoomActivity" android:exported="false" android:parentActivityName=".view.activity.SettingsActivity" /> + onHomeSettings.alphaAnimDuration + -> onHomeSettings.alphaAnimDuration + type == EventType.NORMAL && mHomeHandle.alpha != 0f // Pressed to Normal - -> normalSettings.alphaAnimDuration * 2 + -> normalSettings.alphaAnimDuration * 2 + type == EventType.NORMAL // Home to Normal - -> normalSettings.alphaAnimDuration + -> normalSettings.alphaAnimDuration + else // Normal to Press - -> pressedSettings.alphaAnimDuration + -> pressedSettings.alphaAnimDuration } - if (type != EventType.HOME && useMiBlur && !isAppliedMiBlur) { + if (useMiBlur) { if (mHomeHandle.isSupportMiBlur()) { mHomeHandle.alpha = 1f mDarkColor = 0x55191919 mLightColor = 0x77ffffff mHomeHandle.setMiBackgroundBlurModeCompat(1) - mHomeHandle.setPassWindowBlurEnabledCompat(true) mHomeHandle.setMiViewBlurMode(2) mHomeHandle.setMiBackgroundBlurRadius(normalSettings.transDegree) + mHomeHandle.setPassWindowBlurEnabledCompat(true) // setDarkIntensity(currentIntensity) - isAppliedMiBlur = true + + alphaAnimator.doOnEnd { + if (currBlurRadius == 0) { + // Clear Blur if radius == 0 + mHomeHandle.setPassWindowBlurEnabledCompat(false) + } + } } - } else if (!useMiBlur && isAppliedMiBlur) { - isAppliedMiBlur = false - mDarkColor = 0xff191919.toInt() - mLightColor = 0xffffffff.toInt() + } else { + mDarkColor = 0xee191919.toInt() + mLightColor = 0xddffffff.toInt() // mHomeHandle.setMiBackgroundBlurModeCompat(0) // mHomeHandle.setMiViewBlurMode(2) mHomeHandle.setMiBackgroundBlurRadius(0) @@ -287,32 +316,40 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } if (useMiBlur) { + val to = when (type) { + EventType.HOME -> onHomeSettings.transDegree.toFloat() + EventType.NORMAL -> normalSettings.transDegree.toFloat() + else -> pressedSettings.transDegree.toFloat() + } + if (currBlurRadius.toFloat() == to) notStart = true + alphaAnimator.setFloatValues( currBlurRadius.toFloat(), - when (type) { - EventType.HOME -> onHomeSettings.transDegree.toFloat() - EventType.NORMAL -> normalSettings.transDegree.toFloat() - else -> pressedSettings.transDegree.toFloat() - } + to ) + } else { // Normal alpha + val to = when (type) { + EventType.HOME -> 1 - (onHomeSettings.transDegree.toFloat() / 100) + EventType.NORMAL -> 1 - (normalSettings.transDegree.toFloat() / 100) + else -> 1 - (pressedSettings.transDegree.toFloat() / 100) + } + if (mHomeHandle.alpha == to) notStart = true alphaAnimator.setFloatValues( mHomeHandle.alpha, - when (type) { - EventType.HOME -> 1 - (onHomeSettings.transDegree.toFloat() / 100) - EventType.NORMAL -> 1 - (normalSettings.transDegree.toFloat() / 100) - else -> 1 - (pressedSettings.transDegree.toFloat() / 100) - } + to ) } alphaAnimator.duration = duration - mHandler?.removeCallbacks(opacityHomeHandleRunnable) - if (type == EventType.NORMAL && !mIsInHome) { - mHandler?.postDelayed(opacityHomeHandleRunnable, 5000) - } else { - mHandler?.post(opacityHomeHandleRunnable) + if (!notStart) { + mHandler?.removeCallbacks(opacityHomeHandleRunnable) + if (lastOpacityType == EventType.PRESSED && type == EventType.NORMAL && !mIsInHome) { + mHandler?.postDelayed(opacityHomeHandleRunnable, 5000) + } else { + mHandler?.post(opacityHomeHandleRunnable) + } } when (type) { @@ -323,17 +360,19 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { else -> animateZoomTo(pressedSettings.scaleX, pressedSettings.scaleY, pressedSettings.scaleAnimDuration) } } - + var motionTriggered = false fun leaveHome() { opacityHomeHandle(EventType.NORMAL) } fun enterHome() { - opacityHomeHandle(EventType.HOME) + // Opacity after current motion released + if (!motionTriggered) + opacityHomeHandle(EventType.HOME) } var baseX = -1f var baseY = -1f - var motionTriggered = false + val isBoostMode = mainPrefs.getBoolean("chen_home_handle_anim_turbo_mode", false) var orientation = 0 // Cache Screen Height. IPC is expensive @@ -349,40 +388,48 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { // ) if (mHandler != null) { mHandler!!.post { - if (motionEvent.actionMasked == MotionEvent.ACTION_DOWN && mHomeHandle.alpha == 0f) { + if (motionEvent.actionMasked == MotionEvent.ACTION_DOWN + && (mHomeHandle.alpha == 0f || (mHomeHandle.windowVisibility != View.VISIBLE || isHidden))) { // drop if home handle is transparent. return@post } + if (disableHomeHandleMovement && motionEvent.actionMasked == MotionEvent.ACTION_MOVE) { + // drop if disable home handle movement + return@post + } + screenRealHeight = getScreenRealHeight(mContext!!) screenHeight = getScreenHeight(mContext!!) - // onInputEvent will be done if mHandler post, so the original motionEvent will be recycled, so that we use the copy of event and recycle by ourself + // onInputEvent will be done if mHandler post, so the original motionEvent will be recycled, + // so that we use the copy of event and recycle by ourself val isNavigationBarArea: Boolean = if (!isAboveU && screenRealHeight - screenHeight > 1) { motionEvent.y > screenHeight } else { // on U, look like the real height - orig bar height is better - if (!isAboveU) { - Log.v( - "Art_Chen", - "Screen Height incorrect to calculate nav bar height, using fallback, value: ${ - screenRealHeight - origBarHeight - }" - ) - } + + // Remove useless logs +// if (!isAboveU) { +// Log.v( +// "Art_Chen", +// "Screen Height incorrect to calculate nav bar height, using fallback, value: ${ +// screenRealHeight - origBarHeight +// }" +// ) +// } motionEvent.y > screenRealHeight - origBarHeight } if (isNavigationBarArea) { if (motionEvent.actionMasked == MotionEvent.ACTION_DOWN) { - Log.v( - "Art_Chen", - "current touch is in navigation area! motionTriggered!" - ) +// Log.v( +// "Art_Chen", +// "current touch is in navigation area! motionTriggered!" +// ) if (!mIsInHome || mHomeHandle.alpha != 0f) { opacityHomeHandle(EventType.PRESSED) } -// animateZoomTo() baseX = motionEvent.x baseY = motionEvent.y @@ -398,6 +445,7 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } if (motionEvent.actionMasked == MotionEvent.ACTION_MOVE && motionTriggered) { + cancelHomeHandleXYAnim() if (isBoostMode && orientation == 0) { val offsetNeeded = -(baseY - motionEvent.y) * 0.2f + yOffset.toFloat() @@ -420,7 +468,7 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { if (!mIsInHome) { // Pressed to Normal opacityHomeHandle(EventType.NORMAL) - } else if (onHomeSettings.transDegree == 100 && mHomeHandle.alpha != 0f) { + } else { opacityHomeHandle(EventType.HOME) } motionTriggered = false @@ -455,6 +503,7 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { mHandler = Handler(Looper.getMainLooper()) appClassLoader?.let { ChenInputEventDispatcher.init(mContext!!, it) } + updateSettings(true) if (ChenInputEventDispatcher.isInited()) { ChenInputEventDispatcher.registerInputEventListener(object : ChenInputEventListener { @@ -519,7 +568,7 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } if (isTurboMode && orientationFor == 0) { - lp.height = lp.height * 2 + lp.height *= 2 } lateinit var inset: Insets @@ -643,6 +692,30 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } } } + + if (mainPrefs.getBoolean("chen_home_handle_no_space", false)) { + // Workaround immersive mode can not hide the handle + "com.android.systemui.navigationbar.NavigationBar".toClass().method { + name("setWindowState") + param(IntType, IntType, IntType) + }.hook { + after { + isHidden = XposedHelpers.getBooleanField( + this.instance, + "mShowOrientedHandleForImmersiveMode" + ) + if (lastIsHidden == isHidden) return@after + + if (isHidden) { +// opacityTo(0f, 300, forceAlpha = true) + mHomeHandle.alpha = 0f + } else { + opacityHomeHandle(EventType.NORMAL) + } + lastIsHidden = isHidden + } + } + } } private fun getScreenHeight(context: Context): Int { @@ -677,7 +750,7 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } - fun extractButton(str: String): String { + private fun extractButton(str: String): String { return if (!str.contains("[")) str else str.substring(0, str.indexOf("[")) } diff --git a/app/src/main/java/moe/chenxy/miuiextra/view/activity/HomeHandleCustomActivity.kt b/app/src/main/java/moe/chenxy/miuiextra/view/activity/HomeHandleCustomActivity.kt new file mode 100644 index 0000000..f2bd1f4 --- /dev/null +++ b/app/src/main/java/moe/chenxy/miuiextra/view/activity/HomeHandleCustomActivity.kt @@ -0,0 +1,128 @@ +package moe.chenxy.miuiextra.view.activity + +import android.content.Context +import android.content.DialogInterface +import android.graphics.Color +import android.os.Bundle +import android.text.InputType +import android.view.LayoutInflater +import android.view.WindowManager +import android.widget.EditText +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.WindowCompat +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.SeekBarPreference +import androidx.preference.SwitchPreferenceCompat +import androidx.preference.iterator +import com.google.android.material.appbar.MaterialToolbar +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar +import moe.chenxy.miuiextra.R +import moe.chenxy.miuiextra.utils.ChenUtils +import rikka.preference.MainSwitchPreference + +class HomeHandleCustomActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + theme.applyStyle(rikka.material.preference.R.style.ThemeOverlay_Rikka_Material3_Preference, true) + setContentView(R.layout.settings_activity) + if (savedInstanceState == null) { + supportFragmentManager + .beginTransaction() + .replace(R.id.settings, SettingsFragment()) + .commit() + } + val toolbar = findViewById(R.id.toolbar) + setSupportActionBar(toolbar) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setTitle(R.string.home_handle_header) + // Adapt transparent navbar + WindowCompat.setDecorFitsSystemWindows(window, false) + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.navigationBarColor = Color.TRANSPARENT + + try { + // getSharedPreferences will hooked by LSPosed and change xml file path to /data/misc/edxp** + // will not throw SecurityException + getSharedPreferences("chen_main_settings", Context.MODE_WORLD_READABLE) + } catch (_: SecurityException) { + } + } + + class SettingsFragment : PreferenceFragmentCompat() { + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + preferenceManager.sharedPreferencesName = "chen_main_settings" + setPreferencesFromResource(R.xml.home_handle_anim_pref, rootKey) + + for (pref in preferenceScreen.iterator()) { + if (pref is PreferenceCategory) { + for (pref1 in pref) { + if (pref1 is SeekBarPreference) { + pref1.title?.let { + bindAnimationSeekBar( + pref1, + it, + if (pref1.key.contains("duration")) "ms" else "%" + ) + } + } + } + } + if (pref is SeekBarPreference) { + pref.title?.let { bindAnimationSeekBar(pref, it, if (pref.key.contains("duration")) "ms" else "%") } + } + } + } + +// private fun bindAnimationSeekBarNoEditText(preference: SeekBarPreference?, scale: Int, endsWith: String) { +// preference?.summary = "${(preference?.value as Int).toFloat() / scale} $endsWith" +// preference.setOnPreferenceChangeListener { pref, newValue -> +// pref.summary = "${(newValue as Int).toFloat() / scale} $endsWith" +// ChenUtils.performVibrateClick(requireContext()) +// return@setOnPreferenceChangeListener true +// } +// } + + private fun bindAnimationSeekBar(preference: SeekBarPreference?, title: CharSequence, endsWith: String) { + preference?.summary = "${(preference?.value as Int)} $endsWith" + preference.setOnPreferenceChangeListener { pref, newValue -> + pref.summary = "${(newValue as Int)} $endsWith" + this.context?.let { ChenUtils.performVibrateClick(it) } + return@setOnPreferenceChangeListener true + } + preference.setOnPreferenceClickListener { + val inputDialog = MaterialAlertDialogBuilder(this.requireContext()) + val chenView = LayoutInflater.from(activity).inflate(R.layout.chen_edittext_dialog, null) + val editText = chenView.findViewById(R.id.chen_edittext_dialog_edittext) + editText.hint = (preference.value).toString() + inputDialog + .setTitle(title) + .setView(chenView) + .setPositiveButton( + R.string.confirm + ) { _, _ -> + val inputText = editText.text.toString() + var inputFloat = 0 + if (inputText.isNotEmpty()) inputFloat = inputText.toInt() + if (inputFloat > preference.max || inputFloat < preference.min) { + Toast.makeText( + this.context, + "Input Value Invalid!!", + Toast.LENGTH_SHORT + ).show() + } else { + preference.value = inputFloat + preference.summary = "$inputFloat $endsWith" + } + } + .show() + this.context?.let { ChenUtils.performVibrateHeavyClick(it) } + return@setOnPreferenceClickListener true + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/moe/chenxy/miuiextra/view/activity/SettingsActivity.kt b/app/src/main/java/moe/chenxy/miuiextra/view/activity/SettingsActivity.kt index cee85e9..a3226f8 100644 --- a/app/src/main/java/moe/chenxy/miuiextra/view/activity/SettingsActivity.kt +++ b/app/src/main/java/moe/chenxy/miuiextra/view/activity/SettingsActivity.kt @@ -42,8 +42,6 @@ const val SHELL_RESTART_MIUI_HOME = "am force-stop com.miui.home" const val SHELL_RESTART_SYSTEMUI = "killall com.android.systemui" const val SHELL_RESTART_MI_WALLPAPER = "killall com.miui.miwallpaper" class SettingsActivity : AppCompatActivity() { - - @SuppressLint("WorldReadableFiles") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -84,7 +82,6 @@ class SettingsActivity : AppCompatActivity() { // .show() isActivated = false } - } class SettingsFragment : PreferenceFragmentCompat() { @@ -134,6 +131,7 @@ class SettingsActivity : AppCompatActivity() { findPreference("vibrator_map")?.intent = Intent(context, VibratorRemapActivity::class.java) findPreference("vibrator_effect_map")?.intent = Intent(context, VibratorEffectRemapActivity::class.java) findPreference("wallpaper_zoom")?.intent = Intent(context, WallpaperZoomActivity::class.java) + findPreference("home_handle_anim_custom")?.intent = Intent(context, HomeHandleCustomActivity::class.java) findPreference("miui_home_anim_enhance")?.setOnPreferenceChangeListener { _, _ -> showRebootSnackBar(R.string.may_need_reboot_miui_home, SHELL_RESTART_MIUI_HOME) @@ -212,7 +210,6 @@ class SettingsActivity : AppCompatActivity() { } bindAnimationSeekBarNoEditText(findPreference("blur_scale_val"), 1) - bindAnimationSeekBarNoEditText(findPreference("home_handle_auto_trans_alpha_val"), 1) } private val setColorFadeSettings : Runnable = Runnable { diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 50d4d8d..d1afae0 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -38,7 +38,7 @@ システムランチャーのアニメーションを強化します 再起動 スムーズな ON/OFF アニメーション - カラーフェードアニメーションを MIUI のデフォルト設定より遅くします + カラーフェードアニメーションを HyperOS のデフォルト設定より遅くします MIUI ミュージック通知の最適化 アーティスト変更時のアニメーションを壊さずにアートワークを素早く更新します @@ -87,7 +87,7 @@ ホームハンドルを自動で透過する ホームハンドルはデフォルトで透過され、タッチをすると変化します アプリがトランジションアニメーションを上書きしないようにする - 一部のアプリでのダーティーなアニメーションを MIUI スタイルに戻す事ができます + 一部のアプリでのダーティーなアニメーションを HyperOS スタイルに戻す事ができます 壁紙の自動暗転を無効化する ホーム画面でホームハンドルを透過する ホームハンドル diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 415d5c0..b837d5a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -37,7 +37,7 @@ 此设置需要重启PowerKeeper才能生效 重启 更舒服的亮灭屏动画 - 让Color Fade动画比MIUI原来的设置更慢一些 (俺的动画!!!!) + 让Color Fade动画比HyperOS原来的设置更慢一些 (俺的动画!!!!) 优化音乐通知 修复异常的歌曲切换动画和App不规范导致的专辑图不同步问题 优化音乐通知的文字和按钮的颜色 @@ -114,4 +114,14 @@ 位移 + 缩放 自动透明程度 默认 + 自定义小白条动画 + 默认时 + 按下时 + 在桌面时 + 横向缩放 + 纵向缩放 + 透明或模糊动画时长 + 缩放动画时长 + 位移动画时长 + 禁用小白条跟手位移 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3fe99cf..f92430d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,7 +39,7 @@ Enhance Animations for MiuiHome Reboot Smooth Screen On / Off Anim - Make Color Fade Animation Slower Than MIUI Default Settings + Make Color Fade Animation Slower Than HyperOS Default Settings Optimize MIUI Music Notification Don\'t break the Artist change anim and update Artwork quickly @@ -88,7 +88,7 @@ Home Handle Auto Transparent Translucent for Home Handle by Default, and change when touch Prevent App to Override Transition Animation - It may restore some app dirty anim to miui style + It may restore some app dirty anim to HyperOS style Disable Wallpaper Auto Darken Transparent Home Handle when on Home Screen Home Handle @@ -116,4 +116,14 @@ Shift and Scale Auto Transparent Degree Default + Custom Home Handle Animation + Normal State + Pressed State + Home State + Scale X + Scale Y + Alpha/Blur Anim Duration + Scale Anim Duration + Zoom Anim Duration + Disable Home Handle Movement \ No newline at end of file diff --git a/app/src/main/res/xml/chen_preferences.xml b/app/src/main/res/xml/chen_preferences.xml index f91a5da..07df80d 100644 --- a/app/src/main/res/xml/chen_preferences.xml +++ b/app/src/main/res/xml/chen_preferences.xml @@ -48,8 +48,7 @@ + app:title="@string/color_fade_anim_smoothly_title" /> - - - - - + app:title="@string/home_handle_anim_custom_title" + app:useSimpleSummaryProvider="true" /> + app:title="@string/chen_home_handle_blur_effect_title" /> + app:title="@string/home_handle_disable_move_event_title" /> diff --git a/app/src/main/res/xml/home_handle_anim_pref.xml b/app/src/main/res/xml/home_handle_anim_pref.xml new file mode 100644 index 0000000..e6410e6 --- /dev/null +++ b/app/src/main/res/xml/home_handle_anim_pref.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file