• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 android.view;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.content.res.CompatibilityInfo;
23 import android.content.res.Configuration;
24 import android.graphics.Point;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 import android.util.DisplayMetrics;
28 
29 import java.util.Objects;
30 
31 /** @hide */
32 public class DisplayAdjustments {
33     public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
34 
35     private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
36     private final Configuration mConfiguration = new Configuration(Configuration.EMPTY);
37     private FixedRotationAdjustments mFixedRotationAdjustments;
38 
39     @UnsupportedAppUsage
DisplayAdjustments()40     public DisplayAdjustments() {
41     }
42 
DisplayAdjustments(@ullable Configuration configuration)43     public DisplayAdjustments(@Nullable Configuration configuration) {
44         if (configuration != null) {
45             mConfiguration.setTo(configuration);
46         }
47     }
48 
DisplayAdjustments(@onNull DisplayAdjustments daj)49     public DisplayAdjustments(@NonNull DisplayAdjustments daj) {
50         setCompatibilityInfo(daj.mCompatInfo);
51         mConfiguration.setTo(daj.getConfiguration());
52         mFixedRotationAdjustments = daj.mFixedRotationAdjustments;
53     }
54 
55     @UnsupportedAppUsage
setCompatibilityInfo(@ullable CompatibilityInfo compatInfo)56     public void setCompatibilityInfo(@Nullable CompatibilityInfo compatInfo) {
57         if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
58             throw new IllegalArgumentException(
59                     "setCompatbilityInfo: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
60         }
61         if (compatInfo != null && (compatInfo.isScalingRequired()
62                 || !compatInfo.supportsScreen())) {
63             mCompatInfo = compatInfo;
64         } else {
65             mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
66         }
67     }
68 
getCompatibilityInfo()69     public CompatibilityInfo getCompatibilityInfo() {
70         return mCompatInfo;
71     }
72 
73     /**
74      * Updates the configuration for the DisplayAdjustments with new configuration.
75      * Default to EMPTY configuration if new configuration is {@code null}
76      * @param configuration new configuration
77      * @throws IllegalArgumentException if trying to modify DEFAULT_DISPLAY_ADJUSTMENTS
78      */
setConfiguration(@ullable Configuration configuration)79     public void setConfiguration(@Nullable Configuration configuration) {
80         if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
81             throw new IllegalArgumentException(
82                     "setConfiguration: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
83         }
84         mConfiguration.setTo(configuration != null ? configuration : Configuration.EMPTY);
85     }
86 
87     @UnsupportedAppUsage
88     @NonNull
getConfiguration()89     public Configuration getConfiguration() {
90         return mConfiguration;
91     }
92 
setFixedRotationAdjustments(FixedRotationAdjustments fixedRotationAdjustments)93     public void setFixedRotationAdjustments(FixedRotationAdjustments fixedRotationAdjustments) {
94         mFixedRotationAdjustments = fixedRotationAdjustments;
95     }
96 
getFixedRotationAdjustments()97     public FixedRotationAdjustments getFixedRotationAdjustments() {
98         return mFixedRotationAdjustments;
99     }
100 
101     /** Returns {@code false} if the width and height of display should swap. */
noFlip(@urface.Rotation int realRotation)102     private boolean noFlip(@Surface.Rotation int realRotation) {
103         final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
104         if (rotationAdjustments == null) {
105             return true;
106         }
107         // Check if the delta is rotated by 90 degrees.
108         return (realRotation - rotationAdjustments.mRotation + 4) % 2 == 0;
109     }
110 
111     /** Adjusts the given size if possible. */
adjustSize(@onNull Point size, @Surface.Rotation int realRotation)112     public void adjustSize(@NonNull Point size, @Surface.Rotation int realRotation) {
113         if (noFlip(realRotation)) {
114             return;
115         }
116         final int w = size.x;
117         size.x = size.y;
118         size.y = w;
119     }
120 
121     /** Adjusts the given metrics if possible. */
adjustMetrics(@onNull DisplayMetrics metrics, @Surface.Rotation int realRotation)122     public void adjustMetrics(@NonNull DisplayMetrics metrics, @Surface.Rotation int realRotation) {
123         if (noFlip(realRotation)) {
124             return;
125         }
126         int w = metrics.widthPixels;
127         metrics.widthPixels = metrics.heightPixels;
128         metrics.heightPixels = w;
129 
130         w = metrics.noncompatWidthPixels;
131         metrics.noncompatWidthPixels = metrics.noncompatHeightPixels;
132         metrics.noncompatHeightPixels = w;
133     }
134 
135     /** Adjusts global display metrics that is available to applications. */
adjustGlobalAppMetrics(@onNull DisplayMetrics metrics)136     public void adjustGlobalAppMetrics(@NonNull DisplayMetrics metrics) {
137         final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
138         if (rotationAdjustments == null) {
139             return;
140         }
141         metrics.noncompatWidthPixels = metrics.widthPixels = rotationAdjustments.mAppWidth;
142         metrics.noncompatHeightPixels = metrics.heightPixels = rotationAdjustments.mAppHeight;
143     }
144 
145     /** Returns the adjusted cutout if available. Otherwise the original cutout is returned. */
146     @Nullable
getDisplayCutout(@ullable DisplayCutout realCutout)147     public DisplayCutout getDisplayCutout(@Nullable DisplayCutout realCutout) {
148         final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
149         return rotationAdjustments != null && rotationAdjustments.mRotatedDisplayCutout != null
150                 ? rotationAdjustments.mRotatedDisplayCutout
151                 : realCutout;
152     }
153 
154     /**
155      * Returns the adjusted {@link RoundedCorners} if available. Otherwise the original
156      * {@link RoundedCorners} is returned.
157      */
158     @Nullable
adjustRoundedCorner(@ullable RoundedCorners realRoundedCorners, @Surface.Rotation int realRotation, int displayWidth, int displayHeight)159     public RoundedCorners adjustRoundedCorner(@Nullable RoundedCorners realRoundedCorners,
160             @Surface.Rotation int realRotation, int displayWidth, int displayHeight) {
161         final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
162         if (realRoundedCorners == null || rotationAdjustments == null
163                 || rotationAdjustments.mRotation == realRotation) {
164             return realRoundedCorners;
165         }
166 
167         return realRoundedCorners.rotate(
168                 rotationAdjustments.mRotation, displayWidth, displayHeight);
169     }
170 
171     /** Returns the adjusted rotation if available. Otherwise the original rotation is returned. */
172     @Surface.Rotation
getRotation(@urface.Rotation int realRotation)173     public int getRotation(@Surface.Rotation int realRotation) {
174         final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
175         return rotationAdjustments != null ? rotationAdjustments.mRotation : realRotation;
176     }
177 
178     @Override
hashCode()179     public int hashCode() {
180         int hash = 17;
181         hash = hash * 31 + Objects.hashCode(mCompatInfo);
182         hash = hash * 31 + Objects.hashCode(mConfiguration);
183         hash = hash * 31 + Objects.hashCode(mFixedRotationAdjustments);
184         return hash;
185     }
186 
187     @Override
equals(@ullable Object o)188     public boolean equals(@Nullable Object o) {
189         if (!(o instanceof DisplayAdjustments)) {
190             return false;
191         }
192         DisplayAdjustments daj = (DisplayAdjustments)o;
193         return Objects.equals(daj.mCompatInfo, mCompatInfo)
194                 && Objects.equals(daj.mConfiguration, mConfiguration)
195                 && Objects.equals(daj.mFixedRotationAdjustments, mFixedRotationAdjustments);
196     }
197 
198     /**
199      * An application can be launched in different rotation than the real display. This class
200      * provides the information to adjust the values returned by {@link Display}.
201      * @hide
202      */
203     public static class FixedRotationAdjustments implements Parcelable {
204         /** The application-based rotation. */
205         @Surface.Rotation
206         final int mRotation;
207 
208         /**
209          * The rotated {@link DisplayInfo#appWidth}. The value cannot be simply swapped according
210          * to rotation because it minus the region of screen decorations.
211          */
212         final int mAppWidth;
213 
214         /** The rotated {@link DisplayInfo#appHeight}. */
215         final int mAppHeight;
216 
217         /** Non-null if the device has cutout. */
218         @Nullable
219         final DisplayCutout mRotatedDisplayCutout;
220 
FixedRotationAdjustments(@urface.Rotation int rotation, int appWidth, int appHeight, DisplayCutout cutout)221         public FixedRotationAdjustments(@Surface.Rotation int rotation, int appWidth, int appHeight,
222                 DisplayCutout cutout) {
223             mRotation = rotation;
224             mAppWidth = appWidth;
225             mAppHeight = appHeight;
226             mRotatedDisplayCutout = cutout;
227         }
228 
229         @Override
hashCode()230         public int hashCode() {
231             int hash = 17;
232             hash = hash * 31 + mRotation;
233             hash = hash * 31 + mAppWidth;
234             hash = hash * 31 + mAppHeight;
235             hash = hash * 31 + Objects.hashCode(mRotatedDisplayCutout);
236             return hash;
237         }
238 
239         @Override
equals(@ullable Object o)240         public boolean equals(@Nullable Object o) {
241             if (!(o instanceof FixedRotationAdjustments)) {
242                 return false;
243             }
244             final FixedRotationAdjustments other = (FixedRotationAdjustments) o;
245             return mRotation == other.mRotation
246                     && mAppWidth == other.mAppWidth && mAppHeight == other.mAppHeight
247                     && Objects.equals(mRotatedDisplayCutout, other.mRotatedDisplayCutout);
248         }
249 
250         @Override
toString()251         public String toString() {
252             return "FixedRotationAdjustments{rotation=" + Surface.rotationToString(mRotation)
253                     + " appWidth=" + mAppWidth + " appHeight=" + mAppHeight
254                     + " cutout=" + mRotatedDisplayCutout + "}";
255         }
256 
257         @Override
describeContents()258         public int describeContents() {
259             return 0;
260         }
261 
262         @Override
writeToParcel(Parcel dest, int flags)263         public void writeToParcel(Parcel dest, int flags) {
264             dest.writeInt(mRotation);
265             dest.writeInt(mAppWidth);
266             dest.writeInt(mAppHeight);
267             dest.writeTypedObject(
268                     new DisplayCutout.ParcelableWrapper(mRotatedDisplayCutout), flags);
269         }
270 
FixedRotationAdjustments(Parcel in)271         private FixedRotationAdjustments(Parcel in) {
272             mRotation = in.readInt();
273             mAppWidth = in.readInt();
274             mAppHeight = in.readInt();
275             final DisplayCutout.ParcelableWrapper cutoutWrapper =
276                     in.readTypedObject(DisplayCutout.ParcelableWrapper.CREATOR);
277             mRotatedDisplayCutout = cutoutWrapper != null ? cutoutWrapper.get() : null;
278         }
279 
280         public static final Creator<FixedRotationAdjustments> CREATOR =
281                 new Creator<FixedRotationAdjustments>() {
282             public FixedRotationAdjustments createFromParcel(Parcel in) {
283                 return new FixedRotationAdjustments(in);
284             }
285 
286             public FixedRotationAdjustments[] newArray(int size) {
287                 return new FixedRotationAdjustments[size];
288             }
289         };
290     }
291 }
292