Merge "Expose blurs to SurfaceControl"
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 38416ee..bcc9e41 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -128,6 +128,8 @@
int l, int t, int r, int b);
private static native void nativeSetCornerRadius(long transactionObj, long nativeObject,
float cornerRadius);
+ private static native void nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject,
+ int blurRadius);
private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
int layerStack);
@@ -2505,6 +2507,20 @@
}
/**
+ * Sets the background blur radius of the {@link SurfaceControl}.
+ *
+ * @param sc SurfaceControl.
+ * @param radius Blur radius in pixels.
+ * @return itself.
+ * @hide
+ */
+ public Transaction setBackgroundBlurRadius(SurfaceControl sc, int radius) {
+ checkPreconditions(sc);
+ nativeSetBackgroundBlurRadius(mNativeObject, sc.mNativeObject, radius);
+ return this;
+ }
+
+ /**
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 50a60a9..e0f9571 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -560,6 +560,14 @@
transaction->setCornerRadius(ctrl, cornerRadius);
}
+static void nativeSetBackgroundBlurRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jlong nativeObject, jint blurRadius) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ transaction->setBackgroundBlurRadius(ctrl, blurRadius);
+}
+
static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jint layerStack) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1369,6 +1377,8 @@
(void*)nativeSetWindowCrop },
{"nativeSetCornerRadius", "(JJF)V",
(void*)nativeSetCornerRadius },
+ {"nativeSetBackgroundBlurRadius", "(JJI)V",
+ (void*)nativeSetBackgroundBlurRadius },
{"nativeSetLayerStack", "(JJI)V",
(void*)nativeSetLayerStack },
{"nativeSetShadowRadius", "(JJF)V",
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5c72270..26af4ec 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1086,6 +1086,10 @@
<dimen name="logout_button_margin_bottom">12dp</dimen>
<dimen name="logout_button_corner_radius">2dp</dimen>
+ <!-- Blur radius on status bar window and power menu -->
+ <dimen name="min_window_blur_radius">1px</dimen>
+ <dimen name="max_window_blur_radius">100px</dimen>
+
<!-- How much into a DisplayCutout's bounds we can go, on each side -->
<dimen name="display_cutout_margin_consumption">0px</dimen>
<!-- How much each bubble is elevated. -->
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index a6fa414..7506be09 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -19,17 +19,22 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.DumpController;
import com.android.systemui.assist.AssistModule;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarWindowBlurController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
@@ -82,6 +87,16 @@
keyguardUpdateMonitor, dumpController);
}
+ @Singleton
+ @Provides
+ @Nullable
+ static StatusBarWindowBlurController providesBlurController(BlurUtils blurUtils,
+ @Main Resources resources, SysuiStatusBarStateController statusBarStateController,
+ DumpController dumpController) {
+ return blurUtils.supportsBlursOnWindows() ? new StatusBarWindowBlurController(resources,
+ statusBarStateController, blurUtils, dumpController) : null;
+ }
+
/** */
@Binds
public abstract NotificationRowBinder bindNotificationRowBinder(
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 36a4a10..3735198 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -98,6 +98,7 @@
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -157,6 +158,7 @@
private final IActivityManager mIActivityManager;
private final TelecomManager mTelecomManager;
private final MetricsLogger mMetricsLogger;
+ private final BlurUtils mBlurUtils;
private ArrayList<Action> mItems;
private ActionsDialog mDialog;
@@ -177,6 +179,9 @@
private final ScreenshotHelper mScreenshotHelper;
private final ScreenRecordHelper mScreenRecordHelper;
private final ActivityStarter mActivityStarter;
+ private final SysuiColorExtractor mSysuiColorExtractor;
+ private final IStatusBarService mStatusBarService;
+ private final NotificationShadeWindowController mNotificationShadeWindowController;
private GlobalActionsPanelPlugin mPanelPlugin;
/**
@@ -192,7 +197,10 @@
ConfigurationController configurationController, ActivityStarter activityStarter,
KeyguardStateController keyguardStateController, UserManager userManager,
TrustManager trustManager, IActivityManager iActivityManager,
- TelecomManager telecomManager, MetricsLogger metricsLogger) {
+ TelecomManager telecomManager, MetricsLogger metricsLogger,
+ BlurUtils blurUtils, SysuiColorExtractor colorExtractor,
+ IStatusBarService statusBarService,
+ NotificationShadeWindowController notificationShadeWindowController) {
mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
mWindowManagerFuncs = windowManagerFuncs;
mAudioManager = audioManager;
@@ -208,6 +216,10 @@
mIActivityManager = iActivityManager;
mTelecomManager = telecomManager;
mMetricsLogger = metricsLogger;
+ mBlurUtils = blurUtils;
+ mSysuiColorExtractor = colorExtractor;
+ mStatusBarService = statusBarService;
+ mNotificationShadeWindowController = notificationShadeWindowController;
// receive broadcasts
IntentFilter filter = new IntentFilter();
@@ -443,8 +455,9 @@
mKeyguardManager.isDeviceLocked())
: null;
- ActionsDialog dialog = new ActionsDialog(
- mContext, mAdapter, panelViewController, isControlsEnabled(mContext));
+ ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController,
+ mBlurUtils, mSysuiColorExtractor, mStatusBarService,
+ mNotificationShadeWindowController, isControlsEnabled(mContext));
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.setKeyguardShowing(mKeyguardShowing);
@@ -1529,18 +1542,21 @@
private ResetOrientationData mResetOrientationData;
private boolean mHadTopUi;
private final NotificationShadeWindowController mNotificationShadeWindowController;
- private boolean mControlsEnabled;
+ private final BlurUtils mBlurUtils;
+ private final boolean mControlsEnabled;
ActionsDialog(Context context, MyAdapter adapter,
- GlobalActionsPanelPlugin.PanelViewController plugin,
+ GlobalActionsPanelPlugin.PanelViewController plugin, BlurUtils blurUtils,
+ SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
+ NotificationShadeWindowController notificationShadeWindowController,
boolean controlsEnabled) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
mContext = context;
mAdapter = adapter;
- mColorExtractor = Dependency.get(SysuiColorExtractor.class);
- mStatusBarService = Dependency.get(IStatusBarService.class);
- mNotificationShadeWindowController =
- Dependency.get(NotificationShadeWindowController.class);
+ mBlurUtils = blurUtils;
+ mColorExtractor = sysuiColorExtractor;
+ mStatusBarService = statusBarService;
+ mNotificationShadeWindowController = notificationShadeWindowController;
mControlsEnabled = controlsEnabled;
// Window initialization
@@ -1735,9 +1751,11 @@
.setDuration(300)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setUpdateListener(animation -> {
- int alpha = (int) ((Float) animation.getAnimatedValue()
- * mScrimAlpha * 255);
+ float animatedValue = animation.getAnimatedFraction();
+ int alpha = (int) (animatedValue * mScrimAlpha * 255);
mBackgroundDrawable.setAlpha(alpha);
+ mBlurUtils.applyBlur(mGlobalActionsLayout.getViewRootImpl(),
+ mBlurUtils.radiusForRatio(animatedValue));
})
.start();
}
@@ -1759,9 +1777,11 @@
.withEndAction(this::completeDismiss)
.setInterpolator(new LogAccelerateInterpolator())
.setUpdateListener(animation -> {
- int alpha = (int) ((1f - (Float) animation.getAnimatedValue())
- * mScrimAlpha * 255);
+ float animatedValue = 1f - animation.getAnimatedFraction();
+ int alpha = (int) (animatedValue * mScrimAlpha * 255);
mBackgroundDrawable.setAlpha(alpha);
+ mBlurUtils.applyBlur(mGlobalActionsLayout.getViewRootImpl(),
+ mBlurUtils.radiusForRatio(animatedValue));
})
.start();
dismissPanel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
new file mode 100644
index 0000000..083fbc9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar
+
+import android.app.ActivityManager
+import android.content.res.Resources
+import android.os.SystemProperties
+import android.util.MathUtils
+import android.view.SurfaceControl
+import android.view.ViewRootImpl
+import com.android.internal.util.IndentingPrintWriter
+import com.android.systemui.DumpController
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Main
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class BlurUtils @Inject constructor(
+ @Main private val resources: Resources,
+ val dumpController: DumpController
+) : Dumpable {
+ private val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
+ private val maxBlurRadius = resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
+ private val blurSysProp = SystemProperties
+ .getBoolean("ro.surface_flinger.supports_background_blur", false)
+
+ init {
+ dumpController.registerDumpable(this)
+ }
+
+ /**
+ * Translates a ratio from 0 to 1 to a blur radius in pixels.
+ */
+ fun radiusForRatio(ratio: Float): Int {
+ if (ratio == 0f) {
+ return 0
+ }
+ return MathUtils.lerp(minBlurRadius.toFloat(), maxBlurRadius.toFloat(), ratio).toInt()
+ }
+
+ /**
+ * Applies background blurs to a {@link ViewRootImpl}.
+ *
+ * @param viewRootImpl The window root.
+ * @param radius blur radius in pixels.
+ */
+ fun applyBlur(viewRootImpl: ViewRootImpl?, radius: Int) {
+ if (viewRootImpl == null || !supportsBlursOnWindows()) {
+ return
+ }
+ SurfaceControl.Transaction().use {
+ it.setBackgroundBlurRadius(viewRootImpl.surfaceControl, radius)
+ it.apply()
+ }
+ }
+
+ /**
+ * If this device can render blurs.
+ *
+ * @see android.view.SurfaceControl.Transaction#setBackgroundBlurRadius(SurfaceControl, int)
+ * @return {@code true} when supported.
+ */
+ fun supportsBlursOnWindows(): Boolean {
+ return blurSysProp && ActivityManager.isHighEndGfx()
+ }
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ IndentingPrintWriter(pw, " ").use {
+ it.println("BlurUtils:")
+ it.increaseIndent()
+ it.println("minBlurRadius: $minBlurRadius")
+ it.println("maxBlurRadius: $maxBlurRadius")
+ it.println("blurSysProp: $blurSysProp")
+ it.println("supportsBlursOnWindows: ${supportsBlursOnWindows()}")
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWindowBlurController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWindowBlurController.kt
new file mode 100644
index 0000000..2e72163
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWindowBlurController.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar
+
+import android.content.res.Resources
+import android.view.View
+import com.android.internal.util.IndentingPrintWriter
+import com.android.systemui.DumpController
+import com.android.systemui.Dumpable
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.phone.PanelExpansionListener
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Controller responsible for statusbar window blur.
+ */
+@Singleton
+class StatusBarWindowBlurController @Inject constructor(
+ @Main private val resources: Resources,
+ private val statusBarStateController: SysuiStatusBarStateController,
+ private val blurUtils: BlurUtils,
+ dumpController: DumpController
+) : PanelExpansionListener, Dumpable {
+
+ lateinit var root: View
+ private var blurRadius = 0
+
+ init {
+ dumpController.registerDumpable(this)
+ }
+
+ override fun onPanelExpansionChanged(expansion: Float, tracking: Boolean) {
+ val newBlur = if (statusBarStateController.state == StatusBarState.SHADE)
+ blurUtils.radiusForRatio(expansion)
+ else
+ 0
+
+ if (blurRadius == newBlur) {
+ return
+ }
+ blurRadius = newBlur
+ blurUtils.applyBlur(root.viewRootImpl, blurRadius)
+ }
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ IndentingPrintWriter(pw, " ").use {
+ it.println("StatusBarWindowBlurController:")
+ it.increaseIndent()
+ it.println("blurRadius: $blurRadius")
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index c691a35..ab1c8ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -18,6 +18,7 @@
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
+import android.annotation.Nullable;
import android.app.StatusBarManager;
import android.graphics.RectF;
import android.hardware.display.AmbientDisplayConfiguration;
@@ -44,6 +45,7 @@
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.StatusBarWindowBlurController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -79,6 +81,7 @@
private final CommandQueue mCommandQueue;
private final NotificationShadeWindowView mView;
private final ShadeController mShadeController;
+ private final StatusBarWindowBlurController mBlurController;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -120,6 +123,7 @@
CommandQueue commandQueue,
ShadeController shadeController,
DockManager dockManager,
+ @Nullable StatusBarWindowBlurController blurController,
NotificationShadeWindowView statusBarWindowView,
NotificationPanelViewController notificationPanelViewController) {
mInjectionInflationController = injectionInflationController;
@@ -141,6 +145,7 @@
mShadeController = shadeController;
mDockManager = dockManager;
mNotificationPanelViewController = notificationPanelViewController;
+ mBlurController = blurController;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
@@ -383,6 +388,11 @@
new DragDownHelper(
mView.getContext(), mView, expandHelperCallback,
dragDownCallback, mFalsingManager));
+
+ if (mBlurController != null) {
+ mBlurController.setRoot(mView);
+ mNotificationPanelViewController.addExpansionListener(mBlurController);
+ }
}
public NotificationShadeWindowView getView() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index 9853540..8936a2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -38,6 +38,7 @@
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.StatusBarWindowBlurController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -79,6 +80,7 @@
@Mock private DockManager mDockManager;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
+ @Mock private StatusBarWindowBlurController mStatusBarWindowBlurController;
@Before
public void setUp() {
@@ -112,6 +114,7 @@
new CommandQueue(mContext),
mShadeController,
mDockManager,
+ mStatusBarWindowBlurController,
mView,
mNotificationPanelViewController);
mController.setupExpandedStatusBar();