summaryrefslogtreecommitdiff
path: root/services/core/java/com/android/server/wm/LetterboxUiController.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/wm/LetterboxUiController.java')
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java83
1 files changed, 49 insertions, 34 deletions
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 684e787ec4cf..d69542c42548 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -112,6 +112,8 @@ import com.android.internal.statusbar.LetterboxDetails;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
@@ -126,8 +128,7 @@ import java.util.function.Predicate;
final class LetterboxUiController {
private static final Predicate<ActivityRecord> FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE =
- activityRecord -> activityRecord.fillsParent() && !activityRecord.isFinishing()
- && activityRecord.nowVisible;
+ activityRecord -> activityRecord.fillsParent() && !activityRecord.isFinishing();
private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
@@ -185,6 +186,10 @@ final class LetterboxUiController {
// Corresponds to OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS
private final boolean mIsOverrideEnableCompatFakeFocusEnabled;
+ // The list of observers for the destroy event of candidate opaque activities
+ // when dealing with translucent activities.
+ private final List<LetterboxUiController> mDestroyListeners = new ArrayList<>();
+
@Nullable
private final Boolean mBooleanPropertyAllowOrientationOverride;
@Nullable
@@ -198,6 +203,10 @@ final class LetterboxUiController {
@Nullable
private WindowContainerListener mLetterboxConfigListener;
+ @Nullable
+ @VisibleForTesting
+ ActivityRecord mFirstOpaqueActivityBeneath;
+
private boolean mShowWallpaperForLetterboxBackground;
// In case of transparent activities we might need to access the aspectRatio of the
@@ -361,6 +370,10 @@ final class LetterboxUiController {
mLetterbox.destroy();
mLetterbox = null;
}
+ for (int i = mDestroyListeners.size() - 1; i >= 0; i--) {
+ mDestroyListeners.get(i).updateInheritedLetterbox();
+ }
+ mDestroyListeners.clear();
if (mLetterboxConfigListener != null) {
mLetterboxConfigListener.onRemoved();
mLetterboxConfigListener = null;
@@ -1577,7 +1590,11 @@ final class LetterboxUiController {
* first opaque activity beneath.
* @param parent The parent container.
*/
- void onActivityParentChanged(WindowContainer<?> parent) {
+ void updateInheritedLetterbox() {
+ final WindowContainer<?> parent = mActivityRecord.getParent();
+ if (parent == null) {
+ return;
+ }
if (!mLetterboxConfiguration.isTranslucentLetterboxingEnabled()) {
return;
}
@@ -1587,27 +1604,28 @@ final class LetterboxUiController {
}
// In case mActivityRecord.hasCompatDisplayInsetsWithoutOverride() we don't apply the
// opaque activity constraints because we're expecting the activity is already letterboxed.
- if (mActivityRecord.getTask() == null || mActivityRecord.fillsParent()
- || mActivityRecord.hasCompatDisplayInsetsWithoutInheritance()) {
- return;
- }
- final ActivityRecord firstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity(
+ mFirstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity(
FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE /* callback */,
mActivityRecord /* boundary */, false /* includeBoundary */,
true /* traverseTopToBottom */);
- if (firstOpaqueActivityBeneath == null) {
+ if (mFirstOpaqueActivityBeneath == null || mFirstOpaqueActivityBeneath.isEmbedded()) {
// We skip letterboxing if the translucent activity doesn't have any opaque
- // activities beneath
+ // activities beneath or the activity below is embedded which never has letterbox.
+ mActivityRecord.recomputeConfiguration();
return;
}
- inheritConfiguration(firstOpaqueActivityBeneath);
+ if (mActivityRecord.getTask() == null || mActivityRecord.fillsParent()
+ || mActivityRecord.hasCompatDisplayInsetsWithoutInheritance()) {
+ return;
+ }
+ mFirstOpaqueActivityBeneath.mLetterboxUiController.mDestroyListeners.add(this);
+ inheritConfiguration(mFirstOpaqueActivityBeneath);
mLetterboxConfigListener = WindowContainer.overrideConfigurationPropagation(
- mActivityRecord, firstOpaqueActivityBeneath,
- (opaqueConfig, transparentConfig) -> {
- final Configuration mutatedConfiguration =
- fromOriginalTranslucentConfig(transparentConfig);
+ mActivityRecord, mFirstOpaqueActivityBeneath,
+ (opaqueConfig, transparentOverrideConfig) -> {
+ resetTranslucentOverrideConfig(transparentOverrideConfig);
final Rect parentBounds = parent.getWindowConfiguration().getBounds();
- final Rect bounds = mutatedConfiguration.windowConfiguration.getBounds();
+ final Rect bounds = transparentOverrideConfig.windowConfiguration.getBounds();
final Rect letterboxBounds = opaqueConfig.windowConfiguration.getBounds();
// We cannot use letterboxBounds directly here because the position relies on
// letterboxing. Using letterboxBounds directly, would produce a double offset.
@@ -1616,9 +1634,9 @@ final class LetterboxUiController {
parentBounds.top + letterboxBounds.height());
// We need to initialize appBounds to avoid NPE. The actual value will
// be set ahead when resolving the Configuration for the activity.
- mutatedConfiguration.windowConfiguration.setAppBounds(new Rect());
- inheritConfiguration(firstOpaqueActivityBeneath);
- return mutatedConfiguration;
+ transparentOverrideConfig.windowConfiguration.setAppBounds(new Rect());
+ inheritConfiguration(mFirstOpaqueActivityBeneath);
+ return transparentOverrideConfig;
});
}
@@ -1691,26 +1709,19 @@ final class LetterboxUiController {
if (!hasInheritedLetterboxBehavior() || mActivityRecord.getTask() == null) {
return Optional.empty();
}
- return Optional.ofNullable(mActivityRecord.getTask().getActivity(
- FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE /* callback */,
- mActivityRecord /* boundary */, false /* includeBoundary */,
- true /* traverseTopToBottom */));
+ return Optional.ofNullable(mFirstOpaqueActivityBeneath);
}
- // When overriding translucent activities configuration we need to keep some of the
- // original properties
- private Configuration fromOriginalTranslucentConfig(Configuration translucentConfig) {
- final Configuration configuration = new Configuration(translucentConfig);
+ /** Resets the screen size related fields so they can be resolved by requested bounds later. */
+ private static void resetTranslucentOverrideConfig(Configuration config) {
// The values for the following properties will be defined during the configuration
// resolution in {@link ActivityRecord#resolveOverrideConfiguration} using the
// properties inherited from the first not finishing opaque activity beneath.
- configuration.orientation = ORIENTATION_UNDEFINED;
- configuration.screenWidthDp = configuration.compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
- configuration.screenHeightDp =
- configuration.compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
- configuration.smallestScreenWidthDp =
- configuration.compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
- return configuration;
+ config.orientation = ORIENTATION_UNDEFINED;
+ config.screenWidthDp = config.compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
+ config.screenHeightDp = config.compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
+ config.smallestScreenWidthDp = config.compatSmallestScreenWidthDp =
+ SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
}
private void inheritConfiguration(ActivityRecord firstOpaque) {
@@ -1729,6 +1740,10 @@ final class LetterboxUiController {
}
private void clearInheritedConfig() {
+ if (mFirstOpaqueActivityBeneath != null) {
+ mFirstOpaqueActivityBeneath.mLetterboxUiController.mDestroyListeners.remove(this);
+ }
+ mFirstOpaqueActivityBeneath = null;
mLetterboxConfigListener = null;
mInheritedMinAspectRatio = UNDEFINED_ASPECT_RATIO;
mInheritedMaxAspectRatio = UNDEFINED_ASPECT_RATIO;