summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ViewRootImpl.java7
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIHostDialogProvider.kt9
4 files changed, 105 insertions, 8 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4c0c82fe5c2e..74ecf282750c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -879,6 +879,13 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ /** Remove a static config callback. */
+ public static void removeConfigCallback(ConfigChangedCallback callback) {
+ synchronized (sConfigCallbacks) {
+ sConfigCallbacks.remove(callback);
+ }
+ }
+
/** Add activity config callback to be notified about override config changes. */
public void setActivityConfigCallback(ActivityConfigCallback callback) {
mActivityConfigCallback = callback;
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index 53f29b6f963a..865f96be1775 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -116,6 +116,10 @@ class DialogLaunchAnimator(
launchAnimation.ignoreNextCallToHide = true
dialog.hide()
}
+
+ override fun onSizeChanged() {
+ launchAnimation.onOriginalDialogSizeChanged()
+ }
})
}
@@ -146,6 +150,7 @@ interface HostDialogProvider {
* 2. call [dismissOverride] instead of doing any dismissing logic. The actual dismissing
* logic should instead be done inside the lambda passed to [dismissOverride], which will
* be called after the exit animation.
+ * 3. Be full screen, i.e. have a window matching its parent size.
*
* See SystemUIHostDialogProvider for an example of implementation.
*/
@@ -183,6 +188,9 @@ interface DialogListener {
/** Called when this dialog show() is called. */
fun onShow()
+
+ /** Called when this dialog size might have changed, e.g. because of configuration changes. */
+ fun onSizeChanged()
}
private class DialogLaunchAnimation(
@@ -261,10 +269,6 @@ private class DialogLaunchAnimation(
val window = hostDialog.window
?: throw IllegalStateException("There is no window associated to the host dialog")
window.setBackgroundDrawableResource(android.R.color.transparent)
- window.setLayout(
- WindowManager.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.MATCH_PARENT
- )
// If we are using gesture navigation, then we can overlay the navigation/task bars with
// the host dialog.
@@ -432,6 +436,19 @@ private class DialogLaunchAnimation(
})
}
+ fun onOriginalDialogSizeChanged() {
+ // The dialog is the single child of the root.
+ if (hostDialogRoot.childCount != 1) {
+ return
+ }
+
+ val dialogView = hostDialogRoot.getChildAt(0)
+ val layoutParams = dialogView.layoutParams as? FrameLayout.LayoutParams ?: return
+ layoutParams.width = originalDialog.window.attributes.width
+ layoutParams.height = originalDialog.window.attributes.height
+ dialogView.layoutParams = layoutParams
+ }
+
private fun maybeStartLaunchAnimation() {
if (!isTouchSurfaceGhostDrawn || !isOriginalDialogViewLaidOut) {
return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 189abe2d55d0..cf4aaba107cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -22,11 +22,15 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.TypedValue;
import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.Window;
import android.view.WindowInsets.Type;
import android.view.WindowManager;
@@ -49,7 +53,8 @@ import java.util.Set;
* The SystemUIDialog registers a listener for the screen off / close system dialogs broadcast,
* and dismisses itself when it receives the broadcast.
*/
-public class SystemUIDialog extends AlertDialog implements ListenableDialog {
+public class SystemUIDialog extends AlertDialog implements ListenableDialog,
+ ViewRootImpl.ConfigChangedCallback {
// TODO(b/203389579): Remove this once the dialog width on large screens has been agreed on.
private static final String FLAG_TABLET_DIALOG_WIDTH =
"persist.systemui.flag_tablet_dialog_width";
@@ -57,6 +62,12 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
private final Context mContext;
private final DismissReceiver mDismissReceiver;
private final Set<DialogListener> mDialogListeners = new LinkedHashSet<>();
+ private final Handler mHandler = new Handler();
+
+ private int mLastWidth = Integer.MIN_VALUE;
+ private int mLastHeight = Integer.MIN_VALUE;
+ private int mLastConfigurationWidthDp = -1;
+ private int mLastConfigurationHeightDp = -1;
public SystemUIDialog(Context context) {
this(context, R.style.Theme_SystemUI_Dialog);
@@ -82,11 +93,50 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // Set the dialog window size.
- getWindow().setLayout(getDialogWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
+ Configuration config = getContext().getResources().getConfiguration();
+ mLastConfigurationWidthDp = config.screenWidthDp;
+ mLastConfigurationHeightDp = config.screenHeightDp;
+ updateWindowSize();
+ }
+
+ private void updateWindowSize() {
+ // Only the thread that created this dialog can update its window size.
+ if (Looper.myLooper() != mHandler.getLooper()) {
+ mHandler.post(this::updateWindowSize);
+ return;
+ }
+
+ int width = getWidth();
+ int height = getHeight();
+ if (width == mLastWidth && height == mLastHeight) {
+ return;
+ }
+
+ mLastWidth = width;
+ mLastHeight = height;
+ getWindow().setLayout(width, height);
+
+ for (DialogListener listener : new LinkedHashSet<>(mDialogListeners)) {
+ listener.onSizeChanged();
+ }
}
- private int getDialogWidth() {
+ @Override
+ public void onConfigurationChanged(Configuration configuration) {
+ if (mLastConfigurationWidthDp != configuration.screenWidthDp
+ || mLastConfigurationHeightDp != configuration.screenHeightDp) {
+ mLastConfigurationWidthDp = configuration.screenWidthDp;
+ mLastConfigurationHeightDp = configuration.compatScreenWidthDp;
+
+ updateWindowSize();
+ }
+ }
+
+ /**
+ * Return this dialog width. This method will be invoked when this dialog is created and when
+ * the device configuration changes, and the result will be used to resize this dialog window.
+ */
+ protected int getWidth() {
boolean isOnTablet =
mContext.getResources().getConfiguration().smallestScreenWidthDp >= 600;
if (!isOnTablet) {
@@ -113,6 +163,14 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
}
}
+ /**
+ * Return this dialog height. This method will be invoked when this dialog is created and when
+ * the device configuration changes, and the result will be used to resize this dialog window.
+ */
+ protected int getHeight() {
+ return ViewGroup.LayoutParams.WRAP_CONTENT;
+ }
+
@Override
protected void onStart() {
super.onStart();
@@ -120,6 +178,10 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
if (mDismissReceiver != null) {
mDismissReceiver.register();
}
+
+ // Listen for configuration changes to resize this dialog window. This is mostly necessary
+ // for foldables that often go from large <=> small screen when folding/unfolding.
+ ViewRootImpl.addConfigCallback(this);
}
@Override
@@ -129,6 +191,8 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
if (mDismissReceiver != null) {
mDismissReceiver.unregister();
}
+
+ ViewRootImpl.removeConfigCallback(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIHostDialogProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIHostDialogProvider.kt
index 7b65bccfa0e8..4f18f8c597b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIHostDialogProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIHostDialogProvider.kt
@@ -3,6 +3,7 @@ package com.android.systemui.statusbar.phone
import android.app.Dialog
import android.content.Context
import android.os.Bundle
+import android.view.ViewGroup
import com.android.systemui.animation.HostDialogProvider
/** An implementation of [HostDialogProvider] to be used when animating SysUI dialogs. */
@@ -38,5 +39,13 @@ class SystemUIHostDialogProvider : HostDialogProvider {
super.dismiss()
}
}
+
+ override fun getWidth(): Int {
+ return ViewGroup.LayoutParams.MATCH_PARENT
+ }
+
+ override fun getHeight(): Int {
+ return ViewGroup.LayoutParams.MATCH_PARENT
+ }
}
} \ No newline at end of file