Support for native crossblur for devices that support it + removing in battery saver

ie A12 devices with battery saver enabled will now disable blurring windows throughout the app (backdrop will still remain blurred)
This commit is contained in:
Jays2Kings 2021-10-29 01:01:09 -04:00
parent 1953dd3d58
commit 8f1e239ef0
4 changed files with 91 additions and 6 deletions

View file

@ -3,10 +3,17 @@ package eu.kanade.tachiyomi.ui.manga
import android.animation.AnimatorSet import android.animation.AnimatorSet
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.app.Dialog import android.app.Dialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Color import android.graphics.Color
import android.graphics.Rect import android.graphics.Rect
import android.graphics.RenderEffect
import android.graphics.Shader
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.PowerManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
@ -24,6 +31,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.FullCoverDialogBinding import eu.kanade.tachiyomi.databinding.FullCoverDialogBinding
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.powerManager
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
import eu.kanade.tachiyomi.util.view.animateBlur import eu.kanade.tachiyomi.util.view.animateBlur
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -43,10 +51,33 @@ class FullCoverDialog(val controller: MangaDetailsController, drawable: Drawable
) ?: 0 ) ?: 0
).toLong() ).toLong()
private val powerSaverChangeReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val canBlur = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
!this@FullCoverDialog.context.powerManager.isPowerSaveMode
window?.setDimAmount(if (canBlur) 0.45f else 0.77f)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return
if (canBlur) {
activity?.window?.decorView?.setRenderEffect(
RenderEffect.createBlurEffect(20f, 20f, Shader.TileMode.CLAMP)
)
} else {
activity?.window?.decorView?.setRenderEffect(null)
}
}
}
init { init {
window?.setDimAmount(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) 0.45f else 0.77f) val canBlur = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !context.powerManager.isPowerSaveMode
window?.setDimAmount(if (canBlur) 0.45f else 0.77f)
setContentView(binding.root) setContentView(binding.root)
val filter = IntentFilter()
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
context.registerReceiver(powerSaverChangeReceiver, filter)
}
binding.touchOutside.setOnClickListener { binding.touchOutside.setOnClickListener {
onBackPressed() onBackPressed()
} }
@ -162,6 +193,11 @@ class FullCoverDialog(val controller: MangaDetailsController, drawable: Drawable
} }
private fun animateBack() { private fun animateBack() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
try {
context.unregisterReceiver(powerSaverChangeReceiver)
} catch (_: Exception) { }
}
val rect2 = Rect() val rect2 = Rect()
thumbView.getGlobalVisibleRect(rect2) thumbView.getGlobalVisibleRect(rect2)
binding.mangaCoverFull.isClickable = false binding.mangaCoverFull.isClickable = false

View file

@ -241,7 +241,7 @@ val Context.wifiManager: WifiManager
* Property to get the power manager from the context. * Property to get the power manager from the context.
*/ */
val Context.powerManager: PowerManager val Context.powerManager: PowerManager
get() = getSystemService(Context.POWER_SERVICE) as PowerManager get() = getSystemService()!!
/** /**
* Function used to send a local broadcast asynchronous * Function used to send a local broadcast asynchronous

View file

@ -6,7 +6,11 @@ import android.animation.ValueAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.app.Dialog import android.app.Dialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.graphics.Point import android.graphics.Point
@ -14,6 +18,7 @@ import android.graphics.RenderEffect
import android.graphics.Shader import android.graphics.Shader
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Build import android.os.Build
import android.os.PowerManager
import android.view.Gravity import android.view.Gravity
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -62,6 +67,7 @@ import eu.kanade.tachiyomi.util.system.ThemeUtil
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isLTR import eu.kanade.tachiyomi.util.system.isLTR
import eu.kanade.tachiyomi.util.system.powerManager
import eu.kanade.tachiyomi.util.system.pxToDp import eu.kanade.tachiyomi.util.system.pxToDp
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
@ -430,21 +436,55 @@ fun Dialog.blurBehindWindow(
onDismiss: DialogInterface.OnDismissListener? = null, onDismiss: DialogInterface.OnDismissListener? = null,
onCancel: DialogInterface.OnCancelListener? = null onCancel: DialogInterface.OnCancelListener? = null
) { ) {
var supportsBlur = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && window?.windowManager?.isCrossWindowBlurEnabled == true) {
supportsBlur = true
}
var registered = true
val powerSaverChangeReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && window?.windowManager?.isCrossWindowBlurEnabled == true) {
return
}
val canBlur = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
!this@blurBehindWindow.context.powerManager.isPowerSaveMode
window?.setDimAmount(if (canBlur) 0.45f else 0.77f)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return
if (canBlur) {
window?.decorView?.setRenderEffect(
RenderEffect.createBlurEffect(20f, 20f, Shader.TileMode.CLAMP)
)
} else {
window?.decorView?.setRenderEffect(null)
}
}
}
val filter = IntentFilter()
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
context.registerReceiver(powerSaverChangeReceiver, filter)
val unregister: () -> Unit = {
if (registered) {
context.unregisterReceiver(powerSaverChangeReceiver)
registered = false
}
}
setOnShowListener { setOnShowListener {
onShow?.onShow(it) onShow?.onShow(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (!supportsBlur && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
window?.decorView?.animateBlur(1f, blurAmount, 50)?.start() window?.decorView?.animateBlur(1f, blurAmount, 50)?.start()
} }
} }
setOnDismissListener { setOnDismissListener {
onDismiss?.onDismiss(it) onDismiss?.onDismiss(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { unregister()
if (!supportsBlur && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
window?.decorView?.animateBlur(blurAmount, 1f, 50, true)?.start() window?.decorView?.animateBlur(blurAmount, 1f, 50, true)?.start()
} }
} }
setOnCancelListener { setOnCancelListener {
onCancel?.onCancel(it) onCancel?.onCancel(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { unregister()
if (!supportsBlur && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
window?.decorView?.animateBlur(blurAmount, 1f, 50, true)?.start() window?.decorView?.animateBlur(blurAmount, 1f, 50, true)?.start()
} }
} }
@ -456,7 +496,13 @@ fun View.animateBlur(
@FloatRange(from = 0.1) to: Float, @FloatRange(from = 0.1) to: Float,
duration: Long, duration: Long,
removeBlurAtEnd: Boolean = false removeBlurAtEnd: Boolean = false
): ValueAnimator { ): ValueAnimator? {
if (context.powerManager.isPowerSaveMode) {
if (to <= 0.1f) {
setRenderEffect(null)
}
return null
}
return ValueAnimator.ofFloat(from, to).apply { return ValueAnimator.ofFloat(from, to).apply {
interpolator = FastOutLinearInInterpolator() interpolator = FastOutLinearInInterpolator()
this.duration = duration this.duration = duration

View file

@ -130,6 +130,9 @@
<style name="OverflowDialogTheme" parent="BottomSheetDialogTheme"> <style name="OverflowDialogTheme" parent="BottomSheetDialogTheme">
<item name="android:windowAnimationStyle">@style/Theme.Widget.Animation.DropFromAbove</item> <item name="android:windowAnimationStyle">@style/Theme.Widget.Animation.DropFromAbove</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBlurBehindEnabled" tools:targetApi="31">true</item>
<item name="android:windowBlurBehindRadius" tools:targetApi="31">10dp</item>
</style> </style>
<style name="Theme.Widget.Animation.DropFromAbove" parent="android:Animation"> <style name="Theme.Widget.Animation.DropFromAbove" parent="android:Animation">