• 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     /** Returns the adjusted rotation if available. Otherwise the original rotation is returned. */
155     @Surface.Rotation
getRotation(@urface.Rotation int realRotation)156     public int getRotation(@Surface.Rotation int realRotation) {
157         final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
158         return rotationAdjustments != null ? rotationAdjustments.mRotation : realRotation;
159     }
160 
161     @Override
hashCode()162     public int hashCode() {
163         int hash = 17;
164         hash = hash * 31 + Objects.hashCode(mCompatInfo);
165         hash = hash * 31 + Objects.hashCode(mConfiguration);
166         hash = hash * 31 + Objects.hashCode(mFixedRotationAdjustments);
167         return hash;
168     }
169 
170     @Override
equals(Object o)171     public boolean equals(Object o) {
172         if (!(o instanceof DisplayAdjustments)) {
173             return false;
174         }
175         DisplayAdjustments daj = (DisplayAdjustments)o;
176         return Objects.equals(daj.mCompatInfo, mCompatInfo)
177                 && Objects.equals(daj.mConfiguration, mConfiguration)
178                 && Objects.equals(daj.mFixedRotationAdjustments, mFixedRotationAdjustments);
179     }
180 
181     /**
182      * An application can be launched in different rotation than the real display. This class
183      * provides the information to adjust the values returned by {@link Display}.
184      * @hide
185      */
186     public static class FixedRotationAdjustments implements Parcelable {
187         /** The application-based rotation. */
188         @Surface.Rotation
189         final int mRotation;
190 
191         /**
192          * The rotated {@link DisplayInfo#appWidth}. The value cannot be simply swapped according
193          * to rotation because it minus the region of screen decorations.
194          */
195         final int mAppWidth;
196 
197         /** The rotated {@link DisplayInfo#appHeight}. */
198         final int mAppHeight;
199 
200         /** Non-null if the device has cutout. */
201         @Nullable
202         final DisplayCutout mRotatedDisplayCutout;
203 
FixedRotationAdjustments(@urface.Rotation int rotation, int appWidth, int appHeight, DisplayCutout cutout)204         public FixedRotationAdjustments(@Surface.Rotation int rotation, int appWidth, int appHeight,
205                 DisplayCutout cutout) {
206             mRotation = rotation;
207             mAppWidth = appWidth;
208             mAppHeight = appHeight;
209             mRotatedDisplayCutout = cutout;
210         }
211 
212         @Override
hashCode()213         public int hashCode() {
214             int hash = 17;
215             hash = hash * 31 + mRotation;
216             hash = hash * 31 + mAppWidth;
217             hash = hash * 31 + mAppHeight;
218             hash = hash * 31 + Objects.hashCode(mRotatedDisplayCutout);
219             return hash;
220         }
221 
222         @Override
equals(Object o)223         public boolean equals(Object o) {
224             if (!(o instanceof FixedRotationAdjustments)) {
225                 return false;
226             }
227             final FixedRotationAdjustments other = (FixedRotationAdjustments) o;
228             return mRotation == other.mRotation
229                     && mAppWidth == other.mAppWidth && mAppHeight == other.mAppHeight
230                     && Objects.equals(mRotatedDisplayCutout, other.mRotatedDisplayCutout);
231         }
232 
233         @Override
toString()234         public String toString() {
235             return "FixedRotationAdjustments{rotation=" + Surface.rotationToString(mRotation)
236                     + " appWidth=" + mAppWidth + " appHeight=" + mAppHeight
237                     + " cutout=" + mRotatedDisplayCutout + "}";
238         }
239 
240         @Override
describeContents()241         public int describeContents() {
242             return 0;
243         }
244 
245         @Override
writeToParcel(Parcel dest, int flags)246         public void writeToParcel(Parcel dest, int flags) {
247             dest.writeInt(mRotation);
248             dest.writeInt(mAppWidth);
249             dest.writeInt(mAppHeight);
250             dest.writeTypedObject(
251                     new DisplayCutout.ParcelableWrapper(mRotatedDisplayCutout), flags);
252         }
253 
FixedRotationAdjustments(Parcel in)254         private FixedRotationAdjustments(Parcel in) {
255             mRotation = in.readInt();
256             mAppWidth = in.readInt();
257             mAppHeight = in.readInt();
258             final DisplayCutout.ParcelableWrapper cutoutWrapper =
259                     in.readTypedObject(DisplayCutout.ParcelableWrapper.CREATOR);
260             mRotatedDisplayCutout = cutoutWrapper != null ? cutoutWrapper.get() : null;
261         }
262 
263         public static final Creator<FixedRotationAdjustments> CREATOR =
264                 new Creator<FixedRotationAdjustments>() {
265             public FixedRotationAdjustments createFromParcel(Parcel in) {
266                 return new FixedRotationAdjustments(in);
267             }
268 
269             public FixedRotationAdjustments[] newArray(int size) {
270                 return new FixedRotationAdjustments[size];
271             }
272         };
273     }
274 }
275