• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wm;
18 
19 import android.annotation.NonNull;
20 import android.graphics.Point;
21 import android.graphics.Rect;
22 
23 /**
24  * Some utility methods used by different Letterbox implementations.
25  */
26 class AppCompatLetterboxUtils {
27     /**
28      * Provides the position of the top left letterbox area in the display coordinate system.
29      *
30      * @param activity             The Letterboxed activity.
31      * @param outLetterboxPosition InOut parameter that will contain the desired letterbox position.
32      */
calculateLetterboxPosition(@onNull ActivityRecord activity, @NonNull Point outLetterboxPosition)33     static void calculateLetterboxPosition(@NonNull ActivityRecord activity,
34             @NonNull Point outLetterboxPosition) {
35         if (!activity.mAppCompatController.getLetterboxPolicy().isRunning()) {
36             outLetterboxPosition.set(0, 0);
37             return;
38         }
39         activity.getPosition(outLetterboxPosition);
40     }
41 
42     /**
43      * Provides all the available space, in display coordinate, to fill with the letterboxed
44      * activity and the letterbox areas.
45      *
46      * @param activity       The Letterboxed activity.
47      * @param outOuterBounds InOut parameter that will contain the outer bounds for the letterboxed
48      *                       activity.
49      */
calculateLetterboxOuterBounds(@onNull ActivityRecord activity, @NonNull Rect outOuterBounds)50     static void calculateLetterboxOuterBounds(@NonNull ActivityRecord activity,
51             @NonNull Rect outOuterBounds) {
52         if (!activity.mAppCompatController.getLetterboxPolicy().isRunning()) {
53             outOuterBounds.setEmpty();
54             return;
55         }
56         // Get the bounds of the "space-to-fill". The transformed bounds have the highest
57         // priority because the activity is launched in a rotated environment. In multi-window
58         // mode, the taskFragment-level represents this for both split-screen
59         // and activity-embedding. In fullscreen-mode, the task container does
60         // (since the orientation letterbox is also applied to the task).
61         final Rect transformedBounds =
62                 activity.getFixedRotationTransformDisplayBounds();
63         outOuterBounds.set(transformedBounds != null
64                 ? transformedBounds
65                 : activity.inMultiWindowMode()
66                         ? activity.getTaskFragment().getBounds()
67                         : activity.getRootTask().getParent().getBounds());
68     }
69 
70     /**
71      * Provides the inner bounds for the letterboxed activity in display coordinates. This is the
72      * space the letterboxed activity will use.
73      *
74      * @param activity       The Letterboxed activity.
75      * @param outInnerBounds InOut parameter that will contain the inner bounds for the letterboxed
76      *                       activity.
77      */
calculateLetterboxInnerBounds(@onNull ActivityRecord activity, @NonNull WindowState window, @NonNull Rect outInnerBounds)78     static void calculateLetterboxInnerBounds(@NonNull ActivityRecord activity,
79             @NonNull WindowState window, @NonNull Rect outInnerBounds) {
80         if (!activity.mAppCompatController.getLetterboxPolicy().isRunning()) {
81             outInnerBounds.setEmpty();
82             return;
83         }
84         // In case of translucent activities an option is to use the WindowState#getFrame() of
85         // the first opaque activity beneath. In some cases (e.g. an opaque activity is using
86         // non MATCH_PARENT layouts or a Dialog theme) this might not provide the correct
87         // information and in particular it might provide a value for a smaller area making
88         // the letterbox overlap with the translucent activity's frame.
89         // If we use WindowState#getFrame() for the translucent activity's letterbox inner
90         // frame, the letterbox will then be overlapped with the translucent activity's frame.
91         // Because the surface layer of letterbox is lower than an activity window, this
92         // won't crop the content, but it may affect other features that rely on values stored
93         // in mLetterbox, e.g. transitions, a status bar scrim and recents preview in Launcher
94         // For this reason we use ActivityRecord#getBounds() that the translucent activity
95         // inherits from the first opaque activity beneath and also takes care of the scaling
96         // in case of activities in size compat mode.
97         final TransparentPolicy transparentPolicy =
98                 activity.mAppCompatController.getTransparentPolicy();
99         outInnerBounds.set(
100                 transparentPolicy.isRunning() ? activity.getBounds() : window.getFrame());
101     }
102 }
103