From fcb17d89d18e40e582422b6b2931495e3f7173c7 Mon Sep 17 00:00:00 2001 From: "Re*Index. (ot_inc)" <32851879+reindex-ot@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:28:37 +0900 Subject: [PATCH 1/4] Add Japanese translate(#3) * Create strings.xml * Update strings.xml * Add Japanese translate Add Japanese translate --- app/src/main/res/values-ja/strings.xml | 118 +++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 app/src/main/res/values-ja/strings.xml diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml new file mode 100644 index 0000000..50d4d8d --- /dev/null +++ b/app/src/main/res/values-ja/strings.xml @@ -0,0 +1,118 @@ + + + MIUI Extra + + MIUI Extra + その他 + リフレッシュレート + 通常のバイブレーションマッパー + 通常のバイブレーションをバイブレーション効果にリマップします + 壁紙のスケール設定 + 壁紙のスケールをカスタマイズします + HyperOS のリフレッシュレートのカスタマイズを有効化する + HyperOS のリフレッシュレートポリシーを無効化する + リフレッシュレートは HyperOS によって動的に制御されます + リフレッシュレートは設定に従って動作します + HyperOS の世界へ出かけよう! @ Art_Chen + 90Hz のゲームアプリ + このリスト内のゲームは、90Hz で動作しますが、それ以外の場合はティアリングを回避するために 60Hz で動作します + 動画アプリ + すべての動画アプリは、消費電力を抑えるために 60Hz で動作します + 60Hz のアプリ + このリスト内のアプリは、 60Hz で動作しますが、それ以外の場合は設定したリフレッシュレートを維持します (ゲームと動画アプリを除く) + 確認 + キャンセル + ID マップの設定範囲 + バイブレーションのリマップを有効化 + この設定を適用するには再起動が必要です + この設定を適用するにはバッテリーとパフォーマンスの再起動が必要です + この設定を適用するにはシステムランチャーの再起動が必要です + MiBridge のリフレッシュレート制御を強制的に無効化する + MiBridge のリフレッシュレート制御を無効化するアプリの一覧 + MiBridge インターフェースでのリフレッシュレートの変更を拒否するアプリを設定します + 私について + 開発者 + CoolAPK + Weibo + システムランチャーのアニメーションを強化する + システムランチャーのアニメーションを強化します + 再起動 + スムーズな ON/OFF アニメーション + カラーフェードアニメーションを MIUI のデフォルト設定より遅くします + MIUI ミュージック通知の最適化 + アーティスト変更時のアニメーションを壊さずにアートワークを素早く更新します + + MIUI ダイナミックカラーの代わりに Monet カラーを使用し、可読性を向上させます + バイブレーション効果マッパーを有効化する + ID - ID マッパー + 追加 + バイブレーション効果マッパー + バイブレーション効果を別のバイブレーション効果にリマップします + 新しいマップを追加 + 効果を試す + 削除をしますか? + ランチャーからアイコンを隠す + モジュールの設定 + 画面 ON 時のアニメーションの長さ + 画面 OFF 時のアニメーションの長さ + 壁紙の拡大の最適化を有効化する + 壁紙の拡大のアニメーションのカスタマイズ + 一般 + 縮小のアニメーションの開始速度 + 拡大のアニメーションの開始速度 + 縮小のアニメーションの剛性を設定します + 拡大のアニメーションの剛性を設定します + 縮小のアニメーションの速度を設定します + ロック画面で自動的に拡大する + ロック解除のアニメーション + デスクトップの壁紙がキーガードを同じ場合のみサポートしています + デスクトップの壁紙にフェード効果を使用する + キーガードの壁紙がデスクトップと異なる場合にロック解除のスケールアニメーションをフェードアニメーションに置き換えます + 壁紙フェードアニメーションの再生時間 + 最近のタスクを開いたときにアイコンを非表示にしない + 有効化する事で、最近のタスクを開いたときにぼかし効果が強制的に適用されます + アプリのアニメーションに合せて壁紙のアニメーションを同期させる + 壁紙のアニメーション開始速度を -1.5f に設定する事を推奨します + 最近のタスクからアプリを開いたときに縮小で表示しない + (バグあり) アニメーションが未完了時にタップが速すぎるとズームバックできない場合があります + アニメーションで Chen の画面の最適化を使用する + MIUI の純正アニメーションを置き換えるために、愛を込めてスケール + グレー効果を使用します + Chen のジェスチャーラインアニメーションを有効化する + スムーズなジェスチャーラインアニメーションを有効化します with Love by Art_Chen + ホームハンドルのデフォルトオフセット -Y + ジェスチャーラインアニメーションにブーストモードを使用する + ジェスチャーラインをナビゲーションバー外まで移動可能にします + 没入型のジェスチャーバー + ナビゲーションバーウィンドウをすべてインセットモードにします + ホームハンドルを自動で透過する + ホームハンドルはデフォルトで透過され、タッチをすると変化します + アプリがトランジションアニメーションを上書きしないようにする + 一部のアプリでのダーティーなアニメーションを MIUI スタイルに戻す事ができます + 壁紙の自動暗転を無効化する + ホーム画面でホームハンドルを透過する + ホームハンドル + ミュージックの通知 + Chen の音量表示アニメーションを使用する + 音量の表示を滑らかにしよう! + Android T(13) 以降にのみ対応しています!一部の機能が正常に動作しない場合があります!! + サポートされていない Xposed が検出されました!LSPosed をインストールして有効化してください! + 有効化済み + 無効化済み + + 壁紙 + ぼかし効果を使用する + コントロールセンターとステータスバーをプルダウン時にスケール効果を適用します + ステータスバーの背景の Mi ぼかし効果を無効化する + + ぼかしのスケールの度合い + 消去または表示されたときにホームハンドルを拡大縮小する + ホームハンドルに Mi ぼかし効果を適用する + 音量アニメーション効果 + シフト + ストレッチ + シフトとストレッチ + スケール + シフトとスケール + 自動の透過度 + デフォルト + From 3c66f38c18f42c994cfefab4ab4292c7a01de9af Mon Sep 17 00:00:00 2001 From: Art_Chen Date: Wed, 1 May 2024 13:45:29 +0800 Subject: [PATCH 2/4] MiuiHomeHooker: fix User Present Anim not working on new Home Also drop modify if using default mode. Looks like the getSpringAnimator can not be hooked, LSPosed or YukiHookAPI issues? Signed-off-by: Art_Chen --- .idea/deploymentTargetDropDown.xml | 10 ++++++++++ .idea/migrations.xml | 10 ++++++++++ .../chenxy/miuiextra/hooker/entity/MiuiHomeHook.kt | 11 ++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 .idea/migrations.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..0c0c338 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/MiuiHomeHook.kt b/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/MiuiHomeHook.kt index 0117566..f085d24 100644 --- a/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/MiuiHomeHook.kt +++ b/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/MiuiHomeHook.kt @@ -1,6 +1,7 @@ package moe.chenxy.miuiextra.hooker.entity import android.util.Log +import android.view.View import androidx.dynamicanimation.animation.SpringAnimation import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.factory.method @@ -51,11 +52,15 @@ object MiuiHomeHook : YukiBaseHooker() { }.hook { after { mainPrefs.reload() + val view = this.args[0] as View + val id = this.args[1] as Int val mode = mainPrefs.getString("miui_unlock_anim_enhance_menu", "0")?.toInt() + if (mode == 0) return@after + val springAnimation = this.result if (this.args[2] == -1500.0f) { - var dumping = 0.78f - var response = 0.35f + var dumping = this.args[4] + var response = this.args[5] when (mode) { 1 -> { dumping = 0.68f @@ -72,8 +77,8 @@ object MiuiHomeHook : YukiBaseHooker() { dumping, response ) - } + view.setTag(id, springAnimation) this.result = springAnimation } } From 13c09a8860cb54ea16eb499fa8621de0cdc4072e Mon Sep 17 00:00:00 2001 From: Art_Chen Date: Wed, 1 May 2024 15:49:29 +0800 Subject: [PATCH 3/4] HomeHandle: Cache screen height Signed-off-by: Art_Chen --- .../entity/systemui/HomeHandleAnimatorHooker.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt b/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt index e214511..f24bda6 100644 --- a/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt +++ b/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt @@ -273,6 +273,9 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { var motionTriggered = false val isBoostMode = mainPrefs.getBoolean("chen_home_handle_anim_turbo_mode", false) var orientation = 0 + // Cache Screen Height. IPC is expensive + var screenRealHeight = -1 + var screenHeight = -1 fun onInputEvent(inputEvent: InputEvent) { if (inputEvent is MotionEvent) { // obtain the event to local runnable to fix the race condition @@ -283,21 +286,25 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { // ) if (mHandler != null) { mHandler!!.post { + if (screenRealHeight == -1) { + 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 val isNavigationBarArea: Boolean = - if (getScreenRealHeight(mContext!!) - getScreenHeight(mContext!!) > 1 && !isAboveU) { - motionEvent.y > getScreenHeight(mContext!!) + if (screenRealHeight - screenHeight > 1 && !isAboveU) { + 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: ${ - getScreenRealHeight(mContext!!) - origBarHeight + screenRealHeight - origBarHeight }" ) } - motionEvent.y > getScreenRealHeight(mContext!!) - origBarHeight + motionEvent.y > screenRealHeight - origBarHeight } if (isNavigationBarArea) { @@ -499,6 +506,8 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { "Art_Chen", "screenHeight is ${getScreenHeight(mContext!!)}, realScreenHeight is ${getScreenRealHeight(mContext!!)}, origBarHeight $origBarHeight, currentBarHeight $barHeight" ) + screenHeight = getScreenHeight(mContext!!) + screenRealHeight = getScreenRealHeight(mContext!!) } } From 22118a6700eafbc7fa80375e47ae2f53b5967498 Mon Sep 17 00:00:00 2001 From: Art_Chen Date: Sun, 5 May 2024 00:34:16 +0800 Subject: [PATCH 4/4] HomeHandle: hook: Optimize & add anim custom prop Signed-off-by: Art_Chen --- .idea/gradle.xml | 5 +- .idea/kotlinc.xml | 2 +- .idea/vcs.xml | 2 +- app/build.gradle | 3 +- .../systemui/HomeHandleAnimatorHooker.kt | 398 ++++++++++-------- build.gradle | 2 +- 6 files changed, 236 insertions(+), 176 deletions(-) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ae388c2..0897082 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,16 +4,15 @@ diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index f8467b4..fe63bb6 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index a26f069..f62db84 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' - id 'com.google.devtools.ksp' version '1.9.10-1.0.13' + id 'com.google.devtools.ksp' version '1.9.23-1.0.20' } android { @@ -64,6 +64,5 @@ dependencies { compileOnly("de.robv.android.xposed:api:82") implementation 'com.highcapable.yukihookapi:api:1.2.0' ksp 'com.highcapable.yukihookapi:ksp-xposed:1.2.0' -// implementation("com.highcapable.yukireflection:api:1.0.3") } \ No newline at end of file diff --git a/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt b/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt index f24bda6..d722a2c 100644 --- a/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt +++ b/app/src/main/java/moe/chenxy/miuiextra/hooker/entity/systemui/HomeHandleAnimatorHooker.kt @@ -5,22 +5,18 @@ import android.annotation.SuppressLint import android.content.ComponentName import android.content.Context import android.content.Intent -import android.graphics.Color import android.graphics.Insets import android.graphics.Point import android.os.Handler import android.os.Looper import android.util.Log -import android.view.Display import android.view.InputEvent import android.view.MotionEvent import android.view.View import android.view.WindowManager import android.view.animation.PathInterpolator import android.widget.FrameLayout -import androidx.appcompat.widget.LinearLayoutCompat.OrientationMode import androidx.core.animation.doOnEnd -import androidx.core.os.postDelayed import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.factory.constructor import com.highcapable.yukihookapi.hook.factory.method @@ -40,7 +36,6 @@ import moe.chenxy.miuiextra.hooker.entity.systemui.MiBlurCompatUtils.setMiBackgr import moe.chenxy.miuiextra.hooker.entity.systemui.MiBlurCompatUtils.setMiViewBlurMode import moe.chenxy.miuiextra.hooker.entity.systemui.MiBlurCompatUtils.setPassWindowBlurEnabledCompat import moe.chenxy.miuiextra.utils.ChenUtils -import java.lang.reflect.Proxy import kotlin.math.abs @@ -50,13 +45,31 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { @Volatile var mIsInHome = false - enum class ZoomType { + enum class EventType { NORMAL, - NORMAL_FOR_OPACITY, - ZOOM_IN, - ZOOM_OUT + HOME, + PRESSED } + data class HomeHandleSettings( + val transDegree: Int, + val scaleX: Float, + val scaleY: Float, + val alphaAnimDuration: Long, + val scaleAnimDuration: Long, + val xyAnimDuration: Long, + ) + + lateinit var zoomXAnimator: ValueAnimator + lateinit var zoomYAnimator: ValueAnimator + lateinit var xAnimator: ValueAnimator + lateinit var yAnimator: ValueAnimator + lateinit var alphaAnimator: ValueAnimator + + lateinit var normalSettings: HomeHandleSettings + lateinit var pressedSettings: HomeHandleSettings + lateinit var onHomeSettings: HomeHandleSettings + @SuppressLint("DiscouragedApi") override fun onHook() { val isAboveU = ChenUtils.isAboveAndroidVersion(ChenUtils.Companion.AndroidVersion.U) @@ -65,80 +78,116 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { lateinit var mHomeHandle: View - var zoomValueAnimator: ValueAnimator? = null - var homeHandleXAnimator: ValueAnimator? = null - var homeHandleYAnimator: ValueAnimator? = null - val homeHandleAlphaAnimator = ValueAnimator() - var mHomeHandleId: Int = -1 var barHeight = 0 var origBarHeight = 0 val yOffset = mainPrefs.getInt("home_handle_y_val", 7) - var mEnabledHomeAutoTransparent = - mainPrefs.getBoolean("chen_home_handle_full_transparent_at_miuihome", false) var useMiBlur = mainPrefs.getBoolean("chen_home_handle_blur_effect", false) var mLightColor = -1 var mDarkColor = -1 var mNavigationHandle : Any? = null - fun animateHomeHandleZoom(zoomType: ZoomType) { - if (zoomValueAnimator == null) { - zoomValueAnimator = ValueAnimator() - zoomValueAnimator!!.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) - zoomValueAnimator!!.addUpdateListener { - mHomeHandle.scaleY = it.animatedValue as Float + if (zoomType == ZoomType.ZOOM_IN) 0.1f else 0f + fun getSetting(type: EventType): HomeHandleSettings { + return HomeHandleSettings( + mainPrefs.getInt("home_handle_setting_transdegree_${type.name.lowercase()}", 30), + mainPrefs.getInt("home_handle_setting_scalex_${type.name.lowercase()}", 100) + .toFloat() / 100, + mainPrefs.getInt("home_handle_setting_scaley_${type.name.lowercase()}", 100) + .toFloat() / 100, + mainPrefs.getLong("home_handle_setting_duration_alpha_${type.name.lowercase()}", 600), + mainPrefs.getLong("home_handle_setting_duration_scale_${type.name.lowercase()}", 600), + mainPrefs.getLong("home_handle_setting_duration_xy_${type.name.lowercase()}", 600), + ) + } + + fun updateSettings() { + if (mainPrefs.hasFileChanged()) { + mainPrefs.reload() + normalSettings = getSetting(EventType.NORMAL) + pressedSettings = getSetting(EventType.PRESSED) + onHomeSettings = getSetting(EventType.HOME) + } + + } + + fun animateZoomTo(scaleX: Float, scaleY: Float, duration: Long) { + if (!this::zoomXAnimator.isInitialized) { + zoomXAnimator = ValueAnimator() + zoomYAnimator = ValueAnimator() + zoomXAnimator.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) + zoomYAnimator.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) + + zoomXAnimator.addUpdateListener { mHomeHandle.scaleX = it.animatedValue as Float } + zoomYAnimator.addUpdateListener { + mHomeHandle.scaleY = it.animatedValue as Float + } } + if (zoomXAnimator.isRunning) zoomXAnimator.cancel() + if (zoomYAnimator.isRunning) zoomYAnimator.cancel() + + zoomXAnimator.setFloatValues(mHomeHandle.scaleX, scaleX) + zoomYAnimator.setFloatValues(mHomeHandle.scaleY, scaleY) + zoomXAnimator.duration = duration + zoomYAnimator.duration = duration - zoomValueAnimator!!.duration = - when (zoomType) { - ZoomType.ZOOM_IN -> 600 - ZoomType.NORMAL_FOR_OPACITY, ZoomType.ZOOM_OUT -> 800 - else -> 400 - } - zoomValueAnimator!!.setFloatValues(mHomeHandle.scaleX, if (zoomType == ZoomType.ZOOM_IN) 1.05f else if (zoomType == ZoomType.ZOOM_OUT) 0.9f else 1.0f) if (mainPrefs.getBoolean("chen_home_handle_anim_turbo_mode", false)) { -// Log.i("Art_Chen", "pivotY ${mHomeHandle.pivotY} barheight $barHeight") mHomeHandle.pivotY = (barHeight - origBarHeight + origBarHeight / 2).toFloat() } - zoomValueAnimator!!.start() + zoomXAnimator.start() + zoomYAnimator.start() } +// fun animateHomeHandleZoom(zoomType: ZoomType) { +// val duration = +// when (zoomType) { +// ZoomType.ZOOM_IN -> 600 +// ZoomType.NORMAL_FOR_OPACITY, ZoomType.ZOOM_OUT -> 800 +// else -> 400 +// } +// zoomValueAnimator!!.setFloatValues(mHomeHandle.scaleX, if (zoomType == ZoomType.ZOOM_IN) 1.05f else if (zoomType == ZoomType.ZOOM_OUT) 0.9f else 1.0f) +// +// +// zoomValueAnimator!!.start() +// animateZoomTo() +// } + + fun animateHomeHandleX(duration: Long, offset: Float) { - if (homeHandleXAnimator == null) { - homeHandleXAnimator = ValueAnimator() - homeHandleXAnimator!!.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) + if (!this::xAnimator.isInitialized) { + xAnimator = ValueAnimator() + xAnimator.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) } - homeHandleXAnimator!!.duration = duration - homeHandleXAnimator!!.setFloatValues(mHomeHandle.translationX, offset) + xAnimator.duration = duration + xAnimator.setFloatValues(mHomeHandle.translationX, offset) - homeHandleXAnimator!!.addUpdateListener { + xAnimator.addUpdateListener { mHomeHandle.translationX = it.animatedValue as Float } - homeHandleXAnimator!!.start() + xAnimator.start() } fun animateHomeHandleY(duration: Long, offset: Float) { - if (homeHandleYAnimator == null) { - homeHandleYAnimator = ValueAnimator() - homeHandleYAnimator!!.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) + if (!this::yAnimator.isInitialized) { + yAnimator = ValueAnimator() + yAnimator.interpolator = PathInterpolator(0.39f, 1.58f, 0.44f, 1.07f) - homeHandleYAnimator!!.addUpdateListener { + yAnimator.addUpdateListener { mHomeHandle.translationY = it.animatedValue as Float } } - homeHandleYAnimator!!.duration = duration - homeHandleYAnimator!!.setFloatValues(mHomeHandle.translationY, offset) + yAnimator.duration = duration + yAnimator.setFloatValues(mHomeHandle.translationY, offset) - homeHandleYAnimator!!.start() + yAnimator.start() } - fun animateHomeHandleToNormal() { - animateHomeHandleX(600, 0f) - animateHomeHandleY(600, yOffset.toFloat()) + fun animateHomeHandleXYToNormal() { + animateHomeHandleX(normalSettings.xyAnimDuration, 0f) + animateHomeHandleY(normalSettings.xyAnimDuration, yOffset.toFloat()) } fun setDarkIntensity(int: Int) { @@ -147,135 +196,148 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } } - var mPendingOpacityStatus: Boolean - var isTransparent = false - val maxBlurRadius = 20 + var isAppliedMiBlur = true + var currBlurRadius = 0 val opacityHomeHandleRunnable = Runnable { - if (homeHandleAlphaAnimator.isRunning) { - homeHandleAlphaAnimator.cancel() + if (alphaAnimator.isRunning) { + alphaAnimator.cancel() } - homeHandleAlphaAnimator.start() + alphaAnimator.start() } - homeHandleAlphaAnimator.addUpdateListener { - if (!useMiBlur || !mHomeHandle.isSupportMiBlur() || mainPrefs.getBoolean("chen_home_handle_auto_transparent", false)) { + + val doOnOpacityUpdate = ValueAnimator.AnimatorUpdateListener { + if (!useMiBlur || !mHomeHandle.isSupportMiBlur()) { + // Non-Blur - Adjust alpha when doing anim mHomeHandle.alpha = it.animatedValue as Float } else { - if (isTransparent) { - mHomeHandle.alpha = it.animatedValue as Float - } else if (mHomeHandle.alpha == 0f) { - mHomeHandle.alpha = 1f - } - mHomeHandle.setMiBackgroundBlurRadius(((it.animatedValue as Float) * maxBlurRadius).toInt()) + // Adjust Blur Radius + currBlurRadius = (1 - (it.animatedValue as Float) * 10).toInt() + mHomeHandle.setMiBackgroundBlurRadius(currBlurRadius) } } - fun opacityHomeHandle(needOpacity: Boolean, needToTransparent: Boolean) { - mainPrefs.reload() - val autoTransparent = mainPrefs.getBoolean("chen_home_handle_auto_transparent", false) - val useScaleEffect = mainPrefs.getBoolean("home_handle_scale_on_full_transparent", false) - val transDegree = mainPrefs.getInt("home_handle_auto_trans_alpha_val", 30) + fun opacityTo(to: Float, duration: Long) { + if (!this::alphaAnimator.isInitialized) { + alphaAnimator = ValueAnimator() + } + alphaAnimator.duration = duration + alphaAnimator.addUpdateListener(doOnOpacityUpdate) + alphaAnimator.start() + } + + fun opacityHomeHandle(type: EventType) { + updateSettings() + useMiBlur = mainPrefs.getBoolean("chen_home_handle_blur_effect", false) val isHome = mIsInHome - if (!autoTransparent && needOpacity && !needToTransparent && !useMiBlur) { - return + + if (!this::alphaAnimator.isInitialized) { + alphaAnimator = ValueAnimator() } - if (homeHandleAlphaAnimator.isRunning) { + + if (alphaAnimator.isRunning) { if (isHome) { - homeHandleAlphaAnimator.cancel() + alphaAnimator.cancel() } else { - mPendingOpacityStatus = needOpacity - homeHandleAlphaAnimator.doOnEnd { + alphaAnimator.doOnEnd { it.removeAllListeners() - homeHandleAlphaAnimator.addUpdateListener { it1 -> - if (!useMiBlur || !mHomeHandle.isSupportMiBlur()) { - mHomeHandle.alpha = it1.animatedValue as Float - } else { - if (isTransparent) { - mHomeHandle.alpha = it1.animatedValue as Float - } else if (mHomeHandle.alpha == 0f) { - mHomeHandle.alpha = 1f - } - mHomeHandle.setMiBackgroundBlurRadius(((it1.animatedValue as Float) * maxBlurRadius).toInt()) - } - } - opacityHomeHandle(mPendingOpacityStatus, needToTransparent) + alphaAnimator.addUpdateListener(doOnOpacityUpdate) + opacityHomeHandle(type) } return } } - homeHandleAlphaAnimator.duration = - if (needToTransparent && isAboveU) - 600 - else if (needToTransparent) - 300 - else if (needOpacity && mHomeHandle.alpha != 0f) - 2000 - else if (needOpacity) - 800 - else - 400 - - if (needOpacity && !needToTransparent && useMiBlur) { + val duration = + when { + type == EventType.HOME + // Normal or Press to Home + -> onHomeSettings.alphaAnimDuration + type == EventType.NORMAL && mHomeHandle.alpha != 0f + // Pressed to Normal + -> normalSettings.alphaAnimDuration * 2 + type == EventType.NORMAL + // Home to Normal + -> normalSettings.alphaAnimDuration + else + // Normal to Press + -> pressedSettings.alphaAnimDuration + } + + if (type != EventType.HOME && useMiBlur && !isAppliedMiBlur) { if (mHomeHandle.isSupportMiBlur()) { mHomeHandle.alpha = 1f - mDarkColor = 0x55191919.toInt() - mLightColor = 0x77ffffff.toInt() + mDarkColor = 0x55191919 + mLightColor = 0x77ffffff mHomeHandle.setMiBackgroundBlurModeCompat(1) mHomeHandle.setPassWindowBlurEnabledCompat(true) mHomeHandle.setMiViewBlurMode(2) - mHomeHandle.setMiBackgroundBlurRadius(maxBlurRadius) + mHomeHandle.setMiBackgroundBlurRadius(normalSettings.transDegree) // setDarkIntensity(currentIntensity) + isAppliedMiBlur = true } + } else if (!useMiBlur && isAppliedMiBlur) { + isAppliedMiBlur = false + mDarkColor = 0xff191919.toInt() + mLightColor = 0xffffffff.toInt() +// mHomeHandle.setMiBackgroundBlurModeCompat(0) +// mHomeHandle.setMiViewBlurMode(2) + mHomeHandle.setMiBackgroundBlurRadius(0) + mHomeHandle.setPassWindowBlurEnabledCompat(false) + } + + if (useMiBlur) { + alphaAnimator.setFloatValues( + currBlurRadius.toFloat(), + when (type) { + EventType.HOME -> onHomeSettings.transDegree.toFloat() + EventType.NORMAL -> normalSettings.transDegree.toFloat() + else -> pressedSettings.transDegree.toFloat() + } + ) } else { - if (mHomeHandle.isSupportMiBlur()) { - mDarkColor = 0xcc191919.toInt() - mLightColor = 0xb3ffffff.toInt() - mHomeHandle.setMiBackgroundBlurModeCompat(0) - mHomeHandle.setPassWindowBlurEnabledCompat(false) -// mHomeHandle.setMiViewBlurMode(1) - mHomeHandle.setMiBackgroundBlurRadius(0) - } + // Normal alpha + 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) + } + ) } + alphaAnimator.duration = duration - isTransparent = needToTransparent -// homeHandleAlphaAnimator.interpolator = PathInterpolator(0.39f, 0f, 0.11f, 1.02f) - homeHandleAlphaAnimator.setFloatValues( - mHomeHandle.alpha, - if (needToTransparent) - 0f - else if (needOpacity) - 1 - (transDegree.toFloat() / 100) - else - 1.0f - ) mHandler?.removeCallbacks(opacityHomeHandleRunnable) - val mScaleOnOpacity: Boolean = - useScaleEffect && (needToTransparent || mHomeHandle.alpha == 0f) - if (needOpacity && !isHome) { + if (type == EventType.NORMAL && !mIsInHome) { mHandler?.postDelayed(opacityHomeHandleRunnable, 5000) } else { mHandler?.post(opacityHomeHandleRunnable) } - if (mScaleOnOpacity) { - if (!needToTransparent) { - animateHomeHandleZoom(ZoomType.ZOOM_OUT) - mHandler?.postDelayed(100) { - animateHomeHandleZoom(ZoomType.NORMAL_FOR_OPACITY) - } - } else { - animateHomeHandleZoom(ZoomType.ZOOM_OUT) - } + + when (type) { + EventType.NORMAL -> animateZoomTo(normalSettings.scaleX, + normalSettings.scaleY, + normalSettings.scaleAnimDuration) + EventType.HOME -> animateZoomTo(onHomeSettings.scaleX, onHomeSettings.scaleY, onHomeSettings.scaleAnimDuration) + else -> animateZoomTo(pressedSettings.scaleX, pressedSettings.scaleY, pressedSettings.scaleAnimDuration) } } + fun leaveHome() { + opacityHomeHandle(EventType.NORMAL) + } + fun enterHome() { + 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 - var screenRealHeight = -1 - var screenHeight = -1 + var screenRealHeight: Int + var screenHeight: Int fun onInputEvent(inputEvent: InputEvent) { if (inputEvent is MotionEvent) { // obtain the event to local runnable to fix the race condition @@ -286,13 +348,16 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { // ) if (mHandler != null) { mHandler!!.post { - if (screenRealHeight == -1) { - screenRealHeight = getScreenRealHeight(mContext!!) - screenHeight = getScreenHeight(mContext!!) + if (motionEvent.actionMasked == MotionEvent.ACTION_DOWN && mHomeHandle.alpha == 0f) { + // drop if home handle is transparent. + 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 val isNavigationBarArea: Boolean = - if (screenRealHeight - screenHeight > 1 && !isAboveU) { + if (!isAboveU && screenRealHeight - screenHeight > 1) { motionEvent.y > screenHeight } else { // on U, look like the real height - orig bar height is better @@ -313,14 +378,11 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { "Art_Chen", "current touch is in navigation area! motionTriggered!" ) - if (!mIsInHome) { - opacityHomeHandle(false, false) - } - animateHomeHandleZoom(ZoomType.ZOOM_IN) - if (homeHandleXAnimator!!.isRunning) { - homeHandleXAnimator!!.cancel() - homeHandleYAnimator!!.cancel() + if (!mIsInHome || mHomeHandle.alpha != 0f) { + opacityHomeHandle(EventType.PRESSED) } +// animateZoomTo() + baseX = motionEvent.x baseY = motionEvent.y motionTriggered = true @@ -353,12 +415,12 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { } if (motionEvent.actionMasked == MotionEvent.ACTION_UP && motionTriggered) { - animateHomeHandleToNormal() - if (!mEnabledHomeAutoTransparent || !mIsInHome) { - animateHomeHandleZoom(ZoomType.NORMAL) - } + animateHomeHandleXYToNormal() if (!mIsInHome) { - opacityHomeHandle(true, false) + // Pressed to Normal + opacityHomeHandle(EventType.NORMAL) + } else if (onHomeSettings.transDegree == 100 && mHomeHandle.alpha != 0f) { + opacityHomeHandle(EventType.HOME) } motionTriggered = false } @@ -412,21 +474,26 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { // init home handle status val mHorizontal = XposedHelpers.getObjectField(this.instance, "mHorizontal") as FrameLayout - val autoTransparent = mainPrefs.getBoolean("chen_home_handle_auto_transparent", false) if (isAboveU && mHomeHandleId == -1) { mHomeHandleId = appResources!!.getIdentifier("home_handle", "id", appContext?.packageName) } mHomeHandle = mHorizontal.findViewById(mHomeHandleId) - mHomeHandle.translationY = yOffset.toFloat() - if (!useMiBlur || !mHomeHandle.isSupportMiBlur()) { - mHomeHandle.alpha = if (mIsInHome) 0f else if (autoTransparent) 0.7f else 1f - } else { +// mHomeHandle.translationY = yOffset.toFloat() + // Let's Animate to our preset value + if (useMiBlur && mHomeHandle.isSupportMiBlur()){ + // Blur Mode mHomeHandle.alpha = if (mIsInHome) 0f else 1f - // init mi blur - opacityHomeHandle(true, false) } - animateHomeHandleToNormal() + + mainPrefs.reload() + normalSettings = getSetting(EventType.NORMAL) + pressedSettings = getSetting(EventType.PRESSED) + onHomeSettings = getSetting(EventType.HOME) + + opacityHomeHandle(EventType.NORMAL) + animateHomeHandleXYToNormal() + animateZoomTo(normalSettings.scaleX, normalSettings.scaleY, normalSettings.scaleAnimDuration) } } } @@ -541,25 +608,20 @@ object HomeHandleAnimatorHooker : YukiBaseHooker() { "mTopActivity" ) as ComponentName val intent = Intent("chen.action.top_activity.switched") + intent.`package`= "com.miui.home" val mUtilsContext = XposedHelpers.getObjectField(this.instance, "mContext") as Context - mEnabledHomeAutoTransparent = mainPrefs.getBoolean("chen_home_handle_full_transparent_at_miuihome", false) if (currentTopActivity.packageName == "com.miui.home") { // Log.i("Art_Chen", "Current Top Activity is MiuiHome, do sth") intent.putExtra("isEnteredHome", true) - if (mEnabledHomeAutoTransparent) { - mIsInHome = true - opacityHomeHandle(needOpacity = true, needToTransparent = true) - } + mIsInHome = true + enterHome() } else { // Log.i("Art_Chen", "Current Top Activity is Not MiuiHome!") intent.putExtra("isEnteredHome", false) - if (mEnabledHomeAutoTransparent) { - opacityHomeHandle(needOpacity = false, needToTransparent = false) - opacityHomeHandle(needOpacity = true, needToTransparent = false) - } mIsInHome = false + leaveHome() } mUtilsContext.sendBroadcast(intent) } diff --git a/build.gradle b/build.gradle index c361808..e24a87a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'com.android.application' version '8.1.2' apply false id 'com.android.library' version '8.1.2' apply false - id 'org.jetbrains.kotlin.android' version '1.9.10' apply false + id 'org.jetbrains.kotlin.android' version '1.9.23' apply false } tasks.register('clean', Delete) {