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.ValueAnimator
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.Rect
import android.graphics.RenderEffect
import android.graphics.Shader
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.PowerManager
import android.view.LayoutInflater
import android.view.View
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.databinding.FullCoverDialogBinding
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.view.animateBlur
import uy.kohesive.injekt.injectLazy
@ -43,10 +51,33 @@ class FullCoverDialog(val controller: MangaDetailsController, drawable: Drawable
) ?: 0
).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 {
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)
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 {
onBackPressed()
}
@ -162,6 +193,11 @@ class FullCoverDialog(val controller: MangaDetailsController, drawable: Drawable
}
private fun animateBack() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
try {
context.unregisterReceiver(powerSaverChangeReceiver)
} catch (_: Exception) { }
}
val rect2 = Rect()
thumbView.getGlobalVisibleRect(rect2)
binding.mangaCoverFull.isClickable = false

View file

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

View file

@ -6,7 +6,11 @@ import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Point
@ -14,6 +18,7 @@ import android.graphics.RenderEffect
import android.graphics.Shader
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.PowerManager
import android.view.Gravity
import android.view.MenuItem
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.getResourceColor
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.rootWindowInsetsCompat
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
@ -430,21 +436,55 @@ fun Dialog.blurBehindWindow(
onDismiss: DialogInterface.OnDismissListener? = 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 {
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()
}
}
setOnDismissListener {
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()
}
}
setOnCancelListener {
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()
}
}
@ -456,7 +496,13 @@ fun View.animateBlur(
@FloatRange(from = 0.1) to: Float,
duration: Long,
removeBlurAtEnd: Boolean = false
): ValueAnimator {
): ValueAnimator? {
if (context.powerManager.isPowerSaveMode) {
if (to <= 0.1f) {
setRenderEffect(null)
}
return null
}
return ValueAnimator.ofFloat(from, to).apply {
interpolator = FastOutLinearInInterpolator()
this.duration = duration

View file

@ -130,6 +130,9 @@
<style name="OverflowDialogTheme" parent="BottomSheetDialogTheme">
<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 name="Theme.Widget.Animation.DropFromAbove" parent="android:Animation">