blob: c726bee9f402d87bff6ce99cc2a25946596eb9ec [file] [log] [blame]
Craig Mautner48d0d182013-06-11 07:53:06 -07001/*
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
17package android.view;
18
Diego Veladd184002020-04-03 16:33:46 -070019import android.annotation.NonNull;
20import android.annotation.Nullable;
Artur Satayevad9254c2019-12-10 17:47:54 +000021import android.compat.annotation.UnsupportedAppUsage;
Craig Mautner48d0d182013-06-11 07:53:06 -070022import android.content.res.CompatibilityInfo;
Wale Ogunwale7c726682015-02-06 17:34:28 -080023import android.content.res.Configuration;
Riddle Hsuca70b012020-03-06 21:01:13 +080024import android.graphics.Point;
25import android.os.Parcel;
26import android.os.Parcelable;
27import android.util.DisplayMetrics;
Craig Mautner48d0d182013-06-11 07:53:06 -070028
Kenny Roote6585b32013-12-13 12:00:26 -080029import java.util.Objects;
Craig Mautner48d0d182013-06-11 07:53:06 -070030
31/** @hide */
32public class DisplayAdjustments {
Craig Mautner48d0d182013-06-11 07:53:06 -070033 public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
34
35 private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
Diego Veladd184002020-04-03 16:33:46 -070036 private final Configuration mConfiguration = new Configuration(Configuration.EMPTY);
Riddle Hsuca70b012020-03-06 21:01:13 +080037 private FixedRotationAdjustments mFixedRotationAdjustments;
Craig Mautner48d0d182013-06-11 07:53:06 -070038
Mathew Inwooda570dee2018-08-17 14:56:00 +010039 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -070040 public DisplayAdjustments() {
41 }
42
Diego Veladd184002020-04-03 16:33:46 -070043 public DisplayAdjustments(@Nullable Configuration configuration) {
44 if (configuration != null) {
45 mConfiguration.setTo(configuration);
46 }
Craig Mautner48d0d182013-06-11 07:53:06 -070047 }
48
Diego Veladd184002020-04-03 16:33:46 -070049 public DisplayAdjustments(@NonNull DisplayAdjustments daj) {
Wale Ogunwale7c726682015-02-06 17:34:28 -080050 setCompatibilityInfo(daj.mCompatInfo);
Diego Veladd184002020-04-03 16:33:46 -070051 mConfiguration.setTo(daj.getConfiguration());
Riddle Hsuca70b012020-03-06 21:01:13 +080052 mFixedRotationAdjustments = daj.mFixedRotationAdjustments;
Craig Mautner48d0d182013-06-11 07:53:06 -070053 }
54
Mathew Inwooda570dee2018-08-17 14:56:00 +010055 @UnsupportedAppUsage
Diego Veladd184002020-04-03 16:33:46 -070056 public void setCompatibilityInfo(@Nullable CompatibilityInfo compatInfo) {
Craig Mautner48d0d182013-06-11 07:53:06 -070057 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
69 public CompatibilityInfo getCompatibilityInfo() {
70 return mCompatInfo;
71 }
72
Diego Veladd184002020-04-03 16:33:46 -070073 /**
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 */
79 public void setConfiguration(@Nullable Configuration configuration) {
Craig Mautner48d0d182013-06-11 07:53:06 -070080 if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
81 throw new IllegalArgumentException(
Wale Ogunwale7c726682015-02-06 17:34:28 -080082 "setConfiguration: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
Craig Mautner48d0d182013-06-11 07:53:06 -070083 }
Andrii Kuliana8a9bc52016-10-14 11:00:13 -070084 mConfiguration.setTo(configuration != null ? configuration : Configuration.EMPTY);
Craig Mautner48d0d182013-06-11 07:53:06 -070085 }
86
Mathew Inwooda570dee2018-08-17 14:56:00 +010087 @UnsupportedAppUsage
Diego Veladd184002020-04-03 16:33:46 -070088 @NonNull
Wale Ogunwale7c726682015-02-06 17:34:28 -080089 public Configuration getConfiguration() {
90 return mConfiguration;
Craig Mautner48d0d182013-06-11 07:53:06 -070091 }
92
Riddle Hsuca70b012020-03-06 21:01:13 +080093 public void setFixedRotationAdjustments(FixedRotationAdjustments fixedRotationAdjustments) {
94 mFixedRotationAdjustments = fixedRotationAdjustments;
95 }
96
97 public FixedRotationAdjustments getFixedRotationAdjustments() {
98 return mFixedRotationAdjustments;
99 }
100
101 /** Returns {@code false} if the width and height of display should swap. */
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. */
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. */
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 float x = metrics.xdpi;
135 metrics.xdpi = metrics.ydpi;
136 metrics.ydpi = x;
137
138 x = metrics.noncompatXdpi;
139 metrics.noncompatXdpi = metrics.noncompatYdpi;
140 metrics.noncompatYdpi = x;
141 }
142
143 /** Returns the adjusted cutout if available. Otherwise the original cutout is returned. */
144 @Nullable
145 public DisplayCutout getDisplayCutout(@Nullable DisplayCutout realCutout) {
146 final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
147 return rotationAdjustments != null && rotationAdjustments.mRotatedDisplayCutout != null
148 ? rotationAdjustments.mRotatedDisplayCutout
149 : realCutout;
150 }
151
152 /** Returns the adjusted rotation if available. Otherwise the original rotation is returned. */
153 @Surface.Rotation
154 public int getRotation(@Surface.Rotation int realRotation) {
155 final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
156 return rotationAdjustments != null ? rotationAdjustments.mRotation : realRotation;
157 }
158
Craig Mautner48d0d182013-06-11 07:53:06 -0700159 @Override
160 public int hashCode() {
161 int hash = 17;
Adam Lesinski4ece3d62016-06-16 18:05:41 -0700162 hash = hash * 31 + Objects.hashCode(mCompatInfo);
163 hash = hash * 31 + Objects.hashCode(mConfiguration);
Riddle Hsuca70b012020-03-06 21:01:13 +0800164 hash = hash * 31 + Objects.hashCode(mFixedRotationAdjustments);
Craig Mautner48d0d182013-06-11 07:53:06 -0700165 return hash;
166 }
167
168 @Override
169 public boolean equals(Object o) {
170 if (!(o instanceof DisplayAdjustments)) {
171 return false;
172 }
173 DisplayAdjustments daj = (DisplayAdjustments)o;
Riddle Hsuca70b012020-03-06 21:01:13 +0800174 return Objects.equals(daj.mCompatInfo, mCompatInfo)
175 && Objects.equals(daj.mConfiguration, mConfiguration)
176 && Objects.equals(daj.mFixedRotationAdjustments, mFixedRotationAdjustments);
177 }
178
179 /**
180 * An application can be launched in different rotation than the real display. This class
181 * provides the information to adjust the values returned by {@link #Display}.
182 * @hide
183 */
184 public static class FixedRotationAdjustments implements Parcelable {
185 /** The application-based rotation. */
186 @Surface.Rotation
187 final int mRotation;
188
189 /** Non-null if the device has cutout. */
190 @Nullable
191 final DisplayCutout mRotatedDisplayCutout;
192
193 public FixedRotationAdjustments(@Surface.Rotation int rotation, DisplayCutout cutout) {
194 mRotation = rotation;
195 mRotatedDisplayCutout = cutout;
196 }
197
198 @Override
199 public int hashCode() {
200 int hash = 17;
201 hash = hash * 31 + mRotation;
202 hash = hash * 31 + Objects.hashCode(mRotatedDisplayCutout);
203 return hash;
204 }
205
206 @Override
207 public boolean equals(Object o) {
208 if (!(o instanceof FixedRotationAdjustments)) {
209 return false;
210 }
211 final FixedRotationAdjustments other = (FixedRotationAdjustments) o;
212 return mRotation == other.mRotation
213 && Objects.equals(mRotatedDisplayCutout, other.mRotatedDisplayCutout);
214 }
215
216 @Override
217 public String toString() {
218 return "FixedRotationAdjustments{rotation=" + Surface.rotationToString(mRotation)
219 + " cutout=" + mRotatedDisplayCutout + "}";
220 }
221
222 @Override
223 public int describeContents() {
224 return 0;
225 }
226
227 @Override
228 public void writeToParcel(Parcel dest, int flags) {
229 dest.writeInt(mRotation);
230 dest.writeTypedObject(
231 new DisplayCutout.ParcelableWrapper(mRotatedDisplayCutout), flags);
232 }
233
234 private FixedRotationAdjustments(Parcel in) {
235 mRotation = in.readInt();
236 final DisplayCutout.ParcelableWrapper cutoutWrapper =
237 in.readTypedObject(DisplayCutout.ParcelableWrapper.CREATOR);
238 mRotatedDisplayCutout = cutoutWrapper != null ? cutoutWrapper.get() : null;
239 }
240
241 public static final Creator<FixedRotationAdjustments> CREATOR =
242 new Creator<FixedRotationAdjustments>() {
243 public FixedRotationAdjustments createFromParcel(Parcel in) {
244 return new FixedRotationAdjustments(in);
245 }
246
247 public FixedRotationAdjustments[] newArray(int size) {
248 return new FixedRotationAdjustments[size];
249 }
250 };
Craig Mautner48d0d182013-06-11 07:53:06 -0700251 }
252}