diff options
Diffstat (limited to 'services/core/java/com/android/server/wm/LetterboxUiController.java')
-rw-r--r-- | services/core/java/com/android/server/wm/LetterboxUiController.java | 83 |
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; |