Window Blurs

In Android 12 public APIs are available for implementing window-blur effects (such as background blur and blur behind). Note that although you might see window blur also called cross-window blur in code, developer documentation, or UI notation, cross-window blur is the same thing as window blur.

With these APIs, you can blur whatever is behind your own window. You can create windows with blurred backgrounds, creating a frosted glass effect, or show windows with the entire screen behind them blurred, creating a depth of field effect. You can also combine the two effects.

background blur only

1

blur behind only

2

behind and background blur

3

Figure 1. Background blur only (1), blur behind only (2), background blur and blur behind (3)

The window blur feature works across windows, which means it also works when there’s another app behind the window you’re viewing. This isn’t the same as a blur render effect, which blurs the content inside a window within the same app. Window blurs are useful for dialogs and bottom sheets, and other floating windows.

It’s important to note that this feature uses significant GPU resources. So although it’s available for all Android devices, it’s only supported on those devices that have sufficient GPU power.

Implementation

OEMs and partners

Window blurs are disabled by default. To enable the blur functionality on devices, do the following:

  • Ensure that the device can handle the extra GPU load - the blur operation is expensive and on lower-end devices, it might cause dropped frames. Only enable this on devices with sufficient GPU power.
  • Ensure that your librenderengine implements the blurring logic - the default Android 12 render engine does, but any custom render engine must implement the blurring logic itself.
  • Enable blurs by setting the following surface flinger sysprop:
# enable surface flinger window blurs
PRODUCT_PROPERTY_OVERRIDES += \
       ro.surface_flinger.supports_background_blur=1

Third Party Developers

Refer to the Examples and Source section to see example code. Window blurs can be disabled at runtime by the system server. Therefore, an app must provide a fallback, blurrless version. Otherwise, if the blurs aren’t rendered because they were disabled, the window background might be so transparent that the content inside the window becomes illegible. If your app doesn’t provide a fallback app version, ensure that your UI works both with blurs enabled and blurs disabled. These are the three conditions under which blurs could be disabled at any time:

  1. The device is running Android 11 or lower. Since the window blurs are available only on Android 12 and higher devices, apps must implement a fallback, blurless experience alternative for devices running Android 11 and lower.
  2. The device doesn’t support window blurs because they’re expensive, so lower-end devices might drop frames when rendering them. For such cases, apps must provide a fallback blurless experience.
  3. The system server (for example, during Battery Saver mode, or due to a developer setting or tunnel mode) disables blur at runtime.

Points 2 and 3 above are both reported by a listener registered with WindowManager.addCrossWindowBlurEnabledListener. If your apps use the blur APIs, register this listener and update your UI whenever the listener is called, if you want to use a different UI for the blur-enabled and blur-disabled states. When it’s registered, the listener is called immediately to report whether blurs are currently enabled.

Implement the blur functionalities by using the following methods:

Examples and source

public class BlurActivity extends Activity {
   private final int mBackgroundBlurRadius = 150;
   private final Drawable mBackgroundDrawableWithBlur;
   private final Drawable mBackgroundDrawableNoBlur;

   private final int mBlurBehindRadius = 50;
   private final float mDimAmountWithBlur = 0.1f;
   private final float mDimAmountNoBlur = 0.6f;


   private Consumer<Boolean> mCrossWindowBlurEnabledListener = enabled -> {
       getWindow().setBackgroundDrawable(
               enabled ? mBackgroundDrawableWithBlur : mBackgroundDrawableNoBlur);
       getWindow().setDimAmount(enabled ? mDimAmountWithBlur : mDimAmountNoBlur);
   };

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.blur_activity);

       mBackgroundDrawableWithBlur = getContext().getResources().getDrawable(
               R.drawable.window_background_with_blur);
       mBackgroundDrawableNoBlur = getContext().getResources().getDrawable(
               R.drawable.window_background_no_blur);

       if (Android version >= Android S) {
           getWindow().addFlags(
                   WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
           window.getAttributes().setBlurBehindRadius(mBlurBehindRadius);
           window.setBackgroundBlurRadius(mBackgroundBlurRadius);
           getWindow().getDecorView().addOnAttachStateChangeListener(
                                         new View.OnAttachStateChangeListener() {
                    @Override
                    public void onViewAttachedToWindow(View v) {
                        getWindowManager().addCrossWindowBlurEnabledListener(
                                                     blurEnabledListener);
                    }

                       @Override
                   public void onViewDetachedFromWindow(View v) {
                       getWindowManager().removeCrossWindowBlurEnabledListener(
                                                      blurEnabledListener);
                     }
           });
       }
       getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
   }

Turning window blur on and off

There are two ways to allow and disallow window blurs.

  1. From the UI:

    Settings -> System -> Developer options -> Hardware accelerated rendering -> Allow window-level blurs

  2. From the terminal (the device must be rooted):

adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them

You can only turn the window blur functionality on or off if your device has the capability to support blurs. (Devices that don’t support window blurs can’t enable the feature.) By default, the blurs are enabled on devices that support them.

When you enable blurs for your devices, consider that other things like battery-saving mode or multimedia tunneling can disable them. Blurs are enabled when all necessary conditions are met–they’re supported, and nothing is disabling them. To see if the current state of blur functionality is "enabled," use the adb shell wm disable-blur command.

Validation

To ensure your version of the blur features works as you intended, implement the UI logic so that it redraws the UI elements whenever blurEnabled changes (as reported by addCrossWindowBlurEnabledListener).

  1. Open the UI that has blur.
  2. Use the steps given for Turning window blur on and off from the UI or by CLI.
  3. Verify that the UI changes to and from a blurless one as expected.

Troubleshooting

Use the following as a guide for troubleshooting during validation.

No blur drawn

  • Verify the blurs are currently enabled (and that your hardware supports them) by either using the CLI or navigating to Settings.

    1. Use the adb shell wm disable-blur command, which prints out whether blurs are supported on that device and whether they are currently enabled.
    2. Navigate to Settings -> System -> Developer options -> Hardware accelerated rendering -> Allow window-level blurs. If you can’t find the option there, the blurs aren’t supported on your device.
  • Ensure you set a translucent window background color; an opaque window background color hides (covers) the blurred area.

Test device doesn’t support window blurs

  • Test your application on the Android 12 emulator. To set up an Android emulator, refer to the Set up an Android emulator directions. Any Android virtual device you create with the emulator will support the window blurs.

No rounded corners

  • Define the rounded corners by setting a window background drawable - Window#setBackgroundDrawable. This determines the outline of the blur area.

Updating the developer option doesn’t enable blurs

  • Check whether the device is in battery-saving mode, if it’s using multimedia tunneling (for TV), or if something else is disabling the blur functionality.

Background blur drawn fullscreen, not within the window bounds

  • Ensure that your window is marked as floating - android:windowIsFloating
  • Ensure that you have set a window background drawable - Window#setBackgroundDrawable. This determines the outline of the blur area.

Updates from the listener aren’t applied on the screen

  • Check if the window is getting destroyed and recreated while the instance being operated on by the listener doesn't get updated. The listener updates might be getting applied to an old window instance.