blob: 8b02cae8d64e9b76af8bc833c5ec63f135db66b4 [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
2 * Copyright (C) 2008 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017package android.content.res;
18
Dianne Hackborn337e01a2018-02-27 17:16:37 -080019import static android.content.ConfigurationProto.COLOR_MODE;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070020import static android.content.ConfigurationProto.DENSITY_DPI;
21import static android.content.ConfigurationProto.FONT_SCALE;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080022import static android.content.ConfigurationProto.HARD_KEYBOARD_HIDDEN;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080023import static android.content.ConfigurationProto.KEYBOARD;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080024import static android.content.ConfigurationProto.KEYBOARD_HIDDEN;
25import static android.content.ConfigurationProto.LOCALES;
26import static android.content.ConfigurationProto.MCC;
27import static android.content.ConfigurationProto.MNC;
28import static android.content.ConfigurationProto.NAVIGATION;
29import static android.content.ConfigurationProto.NAVIGATION_HIDDEN;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070030import static android.content.ConfigurationProto.ORIENTATION;
31import static android.content.ConfigurationProto.SCREEN_HEIGHT_DP;
32import static android.content.ConfigurationProto.SCREEN_LAYOUT;
33import static android.content.ConfigurationProto.SCREEN_WIDTH_DP;
34import static android.content.ConfigurationProto.SMALLEST_SCREEN_WIDTH_DP;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080035import static android.content.ConfigurationProto.TOUCHSCREEN;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070036import static android.content.ConfigurationProto.UI_MODE;
37import static android.content.ConfigurationProto.WINDOW_CONFIGURATION;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080038import static android.content.ResourcesConfigurationProto.CONFIGURATION;
39import static android.content.ResourcesConfigurationProto.SCREEN_HEIGHT_PX;
40import static android.content.ResourcesConfigurationProto.SCREEN_WIDTH_PX;
41import static android.content.ResourcesConfigurationProto.SDK_VERSION;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070042
Alan Viveretteac85f902016-03-11 15:15:51 -050043import android.annotation.IntDef;
44import android.annotation.NonNull;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -070045import android.annotation.Nullable;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070046import android.annotation.TestApi;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010047import android.annotation.UnsupportedAppUsage;
Wale Ogunwale822e5122017-07-26 06:02:24 -070048import android.app.WindowConfiguration;
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -070049import android.content.LocaleProto;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.content.pm.ActivityInfo;
Alan Viveretteac85f902016-03-11 15:15:51 -050051import android.content.pm.ActivityInfo.Config;
Adam Lesinski2c749d22014-06-04 13:00:29 -070052import android.os.Build;
Yohei Yukawa23cbe852016-05-17 16:42:58 -070053import android.os.LocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.Parcel;
55import android.os.Parcelable;
Fabrice Di Megliod3d9f3f2012-09-18 12:55:32 -070056import android.text.TextUtils;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080057import android.util.DisplayMetrics;
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -070058import android.util.proto.ProtoInputStream;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070059import android.util.proto.ProtoOutputStream;
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -070060import android.util.proto.WireTypeMismatchException;
Fabrice Di Meglio3fb824b2012-02-28 17:58:31 -080061import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
Romain Guye89d0bb2017-06-20 12:23:42 -070063import com.android.internal.util.XmlUtils;
64
65import org.xmlpull.v1.XmlPullParser;
66import org.xmlpull.v1.XmlPullParserException;
67import org.xmlpull.v1.XmlSerializer;
68
Adam Lesinski7f61e962014-09-02 16:43:52 -070069import java.io.IOException;
Alan Viveretteac85f902016-03-11 15:15:51 -050070import java.lang.annotation.Retention;
71import java.lang.annotation.RetentionPolicy;
Adam Lesinski2c749d22014-06-04 13:00:29 -070072import java.util.ArrayList;
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -070073import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import java.util.Locale;
75
76/**
77 * This class describes all device configuration information that can
78 * impact the resources the application retrieves. This includes both
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -070079 * user-specified configuration options (locale list and scaling) as well
Scott Main63848e32011-04-20 22:20:46 -070080 * as device configurations (such as input modes, screen size and screen orientation).
81 * <p>You can acquire this object from {@link Resources}, using {@link
82 * Resources#getConfiguration}. Thus, from an activity, you can get it by chaining the request
83 * with {@link android.app.Activity#getResources}:</p>
84 * <pre>Configuration config = getResources().getConfiguration();</pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 */
86public final class Configuration implements Parcelable, Comparable<Configuration> {
Dianne Hackborn756220b2012-08-14 16:45:30 -070087 /** @hide */
88 public static final Configuration EMPTY = new Configuration();
89
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 /**
91 * Current user preference for the scaling factor for fonts, relative
92 * to the base density scaling.
93 */
94 public float fontScale;
95
96 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070097 * IMSI MCC (Mobile Country Code), corresponding to
98 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mcc</a>
99 * resource qualifier. 0 if undefined.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 */
101 public int mcc;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700104 * IMSI MNC (Mobile Network Code), corresponding to
105 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mnc</a>
Mattias Petersson1d766b52011-10-07 09:33:52 +0200106 * resource qualifier. 0 if undefined. Note that the actual MNC may be 0; in order to check
107 * for this use the {@link #MNC_ZERO} symbol.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 */
109 public int mnc;
Mattias Petersson1d766b52011-10-07 09:33:52 +0200110
111 /**
112 * Constant used to to represent MNC (Mobile Network Code) zero.
113 * 0 cannot be used, since it is used to represent an undefined MNC.
114 */
115 public static final int MNC_ZERO = 0xffff;
116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700118 * Current user preference for the locale, corresponding to
119 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
120 * resource qualifier.
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700121 *
122 * @deprecated Do not set or read this directly. Use {@link #getLocales()} and
Raph Levienb1638702016-04-27 11:02:12 -0700123 * {@link #setLocales(LocaleList)}. If only the primary locale is needed,
124 * <code>getLocales().get(0)</code> is now the preferred accessor.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 */
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700126 @Deprecated public Locale locale;
127
128 private LocaleList mLocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129
130 /**
Andy Stadlerf8a7cea2009-04-10 16:24:47 -0700131 * Locale should persist on setting. This is hidden because it is really
132 * questionable whether this is the right way to expose the functionality.
133 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100135 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 public boolean userSetLocale;
137
Romain Guyc9ba5592017-01-18 16:34:42 -0800138
Romain Guy48327452017-01-23 17:03:35 -0800139 /** Constant for {@link #colorMode}: bits that encode whether the screen is wide gamut. */
140 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_MASK = 0x3;
Romain Guyc9ba5592017-01-18 16:34:42 -0800141 /**
Romain Guy48327452017-01-23 17:03:35 -0800142 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800143 * indicating that it is unknown whether or not the screen is wide gamut.
144 */
Romain Guy48327452017-01-23 17:03:35 -0800145 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED = 0x0;
Romain Guyc9ba5592017-01-18 16:34:42 -0800146 /**
Romain Guy48327452017-01-23 17:03:35 -0800147 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800148 * indicating that the screen is not wide gamut.
149 * <p>Corresponds to the <code>-nowidecg</code> resource qualifier.</p>
150 */
Romain Guy48327452017-01-23 17:03:35 -0800151 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_NO = 0x1;
Romain Guyc9ba5592017-01-18 16:34:42 -0800152 /**
Romain Guy48327452017-01-23 17:03:35 -0800153 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800154 * indicating that the screen is wide gamut.
155 * <p>Corresponds to the <code>-widecg</code> resource qualifier.</p>
156 */
Romain Guy48327452017-01-23 17:03:35 -0800157 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_YES = 0x2;
Romain Guyc9ba5592017-01-18 16:34:42 -0800158
Romain Guyb3f69262017-04-13 20:06:41 -0700159 /** Constant for {@link #colorMode}: bits that encode the dynamic range of the screen. */
Romain Guy48327452017-01-23 17:03:35 -0800160 public static final int COLOR_MODE_HDR_MASK = 0xc;
161 /** Constant for {@link #colorMode}: bits shift to get the screen dynamic range. */
162 public static final int COLOR_MODE_HDR_SHIFT = 2;
Romain Guyc9ba5592017-01-18 16:34:42 -0800163 /**
Romain Guy48327452017-01-23 17:03:35 -0800164 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_HDR_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800165 * indicating that it is unknown whether or not the screen is HDR.
166 */
Romain Guy48327452017-01-23 17:03:35 -0800167 public static final int COLOR_MODE_HDR_UNDEFINED = 0x0;
Romain Guyc9ba5592017-01-18 16:34:42 -0800168 /**
Romain Guy48327452017-01-23 17:03:35 -0800169 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_HDR_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800170 * indicating that the screen is not HDR (low/standard dynamic range).
171 * <p>Corresponds to the <code>-lowdr</code> resource qualifier.</p>
172 */
Romain Guy48327452017-01-23 17:03:35 -0800173 public static final int COLOR_MODE_HDR_NO = 0x1 << COLOR_MODE_HDR_SHIFT;
Romain Guyc9ba5592017-01-18 16:34:42 -0800174 /**
Romain Guy48327452017-01-23 17:03:35 -0800175 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_HDR_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800176 * indicating that the screen is HDR (dynamic range).
177 * <p>Corresponds to the <code>-highdr</code> resource qualifier.</p>
178 */
Romain Guy48327452017-01-23 17:03:35 -0800179 public static final int COLOR_MODE_HDR_YES = 0x2 << COLOR_MODE_HDR_SHIFT;
Romain Guyc9ba5592017-01-18 16:34:42 -0800180
Romain Guy48327452017-01-23 17:03:35 -0800181 /** Constant for {@link #colorMode}: a value indicating that the color mode is undefined */
Romain Guyc9ba5592017-01-18 16:34:42 -0800182 @SuppressWarnings("PointlessBitwiseExpression")
Romain Guy48327452017-01-23 17:03:35 -0800183 public static final int COLOR_MODE_UNDEFINED = COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED |
184 COLOR_MODE_HDR_UNDEFINED;
Romain Guyc9ba5592017-01-18 16:34:42 -0800185
186 /**
Romain Guyb3f69262017-04-13 20:06:41 -0700187 * Bit mask of color capabilities of the screen. Currently there are two fields:
Romain Guy48327452017-01-23 17:03:35 -0800188 * <p>The {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} bits define the color gamut of
Romain Guyc9ba5592017-01-18 16:34:42 -0800189 * the screen. They may be one of
Romain Guy48327452017-01-23 17:03:35 -0800190 * {@link #COLOR_MODE_WIDE_COLOR_GAMUT_NO} or {@link #COLOR_MODE_WIDE_COLOR_GAMUT_YES}.</p>
Romain Guyc9ba5592017-01-18 16:34:42 -0800191 *
Romain Guy48327452017-01-23 17:03:35 -0800192 * <p>The {@link #COLOR_MODE_HDR_MASK} defines the dynamic range of the screen. They may be
193 * one of {@link #COLOR_MODE_HDR_NO} or {@link #COLOR_MODE_HDR_YES}.</p>
Romain Guyc9ba5592017-01-18 16:34:42 -0800194 *
195 * <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
196 * Multiple Screens</a> for more information.</p>
197 */
Romain Guy48327452017-01-23 17:03:35 -0800198 public int colorMode;
Romain Guyc9ba5592017-01-18 16:34:42 -0800199
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700200 /** Constant for {@link #screenLayout}: bits that encode the size. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700201 public static final int SCREENLAYOUT_SIZE_MASK = 0x0f;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700202 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
203 * value indicating that no size has been set. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700204 public static final int SCREENLAYOUT_SIZE_UNDEFINED = 0x00;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700205 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700206 * value indicating the screen is at least approximately 320x426 dp units,
207 * corresponds to the
208 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">small</a>
209 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700210 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
211 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700212 public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700213 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700214 * value indicating the screen is at least approximately 320x470 dp units,
215 * corresponds to the
216 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">normal</a>
217 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700218 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
219 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700220 public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700221 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700222 * value indicating the screen is at least approximately 480x640 dp units,
223 * corresponds to the
224 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">large</a>
225 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700226 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
227 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700228 public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700229 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700230 * value indicating the screen is at least approximately 720x960 dp units,
231 * corresponds to the
232 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">xlarge</a>
233 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700234 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
235 * Multiple Screens</a> for more information.*/
Dianne Hackborn14cee9f2010-04-23 17:51:26 -0700236 public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700237
238 /** Constant for {@link #screenLayout}: bits that encode the aspect ratio. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700239 public static final int SCREENLAYOUT_LONG_MASK = 0x30;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700240 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
241 * value indicating that no size has been set. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700242 public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700243 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
244 * value that corresponds to the
245 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">notlong</a>
246 * resource qualifier. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700247 public static final int SCREENLAYOUT_LONG_NO = 0x10;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700248 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
249 * value that corresponds to the
250 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">long</a>
251 * resource qualifier. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700252 public static final int SCREENLAYOUT_LONG_YES = 0x20;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700253
254 /** Constant for {@link #screenLayout}: bits that encode the layout direction. */
255 public static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
256 /** Constant for {@link #screenLayout}: bits shift to get the layout direction. */
257 public static final int SCREENLAYOUT_LAYOUTDIR_SHIFT = 6;
258 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
259 * value indicating that no layout dir has been set. */
260 public static final int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0x00;
261 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
262 * value indicating that a layout dir has been set to LTR. */
263 public static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x01 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
264 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
265 * value indicating that a layout dir has been set to RTL. */
266 public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x02 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
267
Adam Powell49e7ff92015-05-14 16:18:53 -0700268 /** Constant for {@link #screenLayout}: bits that encode roundness of the screen. */
269 public static final int SCREENLAYOUT_ROUND_MASK = 0x300;
270 /** @hide Constant for {@link #screenLayout}: bit shift to get to screen roundness bits */
271 public static final int SCREENLAYOUT_ROUND_SHIFT = 8;
272 /**
273 * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
274 * that it is unknown whether or not the screen has a round shape.
275 */
276 public static final int SCREENLAYOUT_ROUND_UNDEFINED = 0x00;
277 /**
278 * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
279 * that the screen does not have a rounded shape.
280 */
281 public static final int SCREENLAYOUT_ROUND_NO = 0x1 << SCREENLAYOUT_ROUND_SHIFT;
282 /**
283 * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
284 * that the screen has a rounded shape. Corners may not be visible to the user;
285 * developers should pay special attention to the {@link android.view.WindowInsets} delivered
286 * to views for more information about ensuring content is not obscured.
287 *
288 * <p>Corresponds to the <code>-round</code> resource qualifier.</p>
289 */
290 public static final int SCREENLAYOUT_ROUND_YES = 0x2 << SCREENLAYOUT_ROUND_SHIFT;
291
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700292 /** Constant for {@link #screenLayout}: a value indicating that screenLayout is undefined */
293 public static final int SCREENLAYOUT_UNDEFINED = SCREENLAYOUT_SIZE_UNDEFINED |
Adam Powell49e7ff92015-05-14 16:18:53 -0700294 SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED |
295 SCREENLAYOUT_ROUND_UNDEFINED;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700296
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700297 /**
298 * Special flag we generate to indicate that the screen layout requires
299 * us to use a compatibility mode for apps that are not modern layout
300 * aware.
301 * @hide
302 */
303 public static final int SCREENLAYOUT_COMPAT_NEEDED = 0x10000000;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700304
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700305 /**
Andrii Kulianf12fce12016-05-27 17:30:16 -0700306 * Bit mask of overall layout of the screen. Currently there are four
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700307 * fields:
308 * <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
309 * of the screen. They may be one of
310 * {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
Adam Powell49e7ff92015-05-14 16:18:53 -0700311 * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.</p>
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700312 *
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700313 * <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
314 * is wider/taller than normal. They may be one of
Adam Powell49e7ff92015-05-14 16:18:53 -0700315 * {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.</p>
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700316 *
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700317 * <p>The {@link #SCREENLAYOUT_LAYOUTDIR_MASK} defines whether the screen layout
318 * is either LTR or RTL. They may be one of
Adam Powell49e7ff92015-05-14 16:18:53 -0700319 * {@link #SCREENLAYOUT_LAYOUTDIR_LTR} or {@link #SCREENLAYOUT_LAYOUTDIR_RTL}.</p>
320 *
321 * <p>The {@link #SCREENLAYOUT_ROUND_MASK} defines whether the screen has a rounded
322 * shape. They may be one of {@link #SCREENLAYOUT_ROUND_NO} or {@link #SCREENLAYOUT_ROUND_YES}.
323 * </p>
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700324 *
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700325 * <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
Adam Powell49e7ff92015-05-14 16:18:53 -0700326 * Multiple Screens</a> for more information.</p>
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700327 */
328 public int screenLayout;
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -0700329
Bryce Lee7566d762017-03-30 09:34:15 -0700330 /**
Wale Ogunwale822e5122017-07-26 06:02:24 -0700331 * Configuration relating to the windowing state of the object associated with this
332 * Configuration. Contents of this field are not intended to affect resources, but need to be
333 * communicated and propagated at the same time as the rest of Configuration.
Wale Ogunwale0d5609b2017-09-13 05:55:07 -0700334 * @hide
Bryce Lee7566d762017-03-30 09:34:15 -0700335 */
Wale Ogunwale0d5609b2017-09-13 05:55:07 -0700336 @TestApi
Wale Ogunwale822e5122017-07-26 06:02:24 -0700337 public final WindowConfiguration windowConfiguration = new WindowConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -0700338
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -0700339 /** @hide */
340 static public int resetScreenLayout(int curLayout) {
341 return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK
342 | SCREENLAYOUT_COMPAT_NEEDED))
343 | (SCREENLAYOUT_LONG_YES | SCREENLAYOUT_SIZE_XLARGE);
344 }
345
346 /** @hide */
347 static public int reduceScreenLayout(int curLayout, int longSizeDp, int shortSizeDp) {
348 int screenLayoutSize;
349 boolean screenLayoutLong;
350 boolean screenLayoutCompatNeeded;
351
352 // These semi-magic numbers define our compatibility modes for
353 // applications with different screens. These are guarantees to
354 // app developers about the space they can expect for a particular
355 // configuration. DO NOT CHANGE!
356 if (longSizeDp < 470) {
357 // This is shorter than an HVGA normal density screen (which
358 // is 480 pixels on its long side).
359 screenLayoutSize = SCREENLAYOUT_SIZE_SMALL;
360 screenLayoutLong = false;
361 screenLayoutCompatNeeded = false;
362 } else {
363 // What size is this screen screen?
364 if (longSizeDp >= 960 && shortSizeDp >= 720) {
365 // 1.5xVGA or larger screens at medium density are the point
366 // at which we consider it to be an extra large screen.
367 screenLayoutSize = SCREENLAYOUT_SIZE_XLARGE;
368 } else if (longSizeDp >= 640 && shortSizeDp >= 480) {
369 // VGA or larger screens at medium density are the point
370 // at which we consider it to be a large screen.
371 screenLayoutSize = SCREENLAYOUT_SIZE_LARGE;
372 } else {
373 screenLayoutSize = SCREENLAYOUT_SIZE_NORMAL;
374 }
375
376 // If this screen is wider than normal HVGA, or taller
377 // than FWVGA, then for old apps we want to run in size
378 // compatibility mode.
379 if (shortSizeDp > 321 || longSizeDp > 570) {
380 screenLayoutCompatNeeded = true;
381 } else {
382 screenLayoutCompatNeeded = false;
383 }
384
385 // Is this a long screen?
386 if (((longSizeDp*3)/5) >= (shortSizeDp-1)) {
387 // Anything wider than WVGA (5:3) is considering to be long.
388 screenLayoutLong = true;
389 } else {
390 screenLayoutLong = false;
391 }
392 }
393
394 // Now reduce the last screenLayout to not be better than what we
395 // have found.
396 if (!screenLayoutLong) {
397 curLayout = (curLayout&~SCREENLAYOUT_LONG_MASK) | SCREENLAYOUT_LONG_NO;
398 }
399 if (screenLayoutCompatNeeded) {
400 curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
401 }
402 int curSize = curLayout&SCREENLAYOUT_SIZE_MASK;
403 if (screenLayoutSize < curSize) {
404 curLayout = (curLayout&~SCREENLAYOUT_SIZE_MASK) | screenLayoutSize;
405 }
406 return curLayout;
407 }
408
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700409 /** @hide */
410 public static String configurationDiffToString(int diff) {
411 ArrayList<String> list = new ArrayList<>();
412 if ((diff & ActivityInfo.CONFIG_MCC) != 0) {
413 list.add("CONFIG_MCC");
414 }
415 if ((diff & ActivityInfo.CONFIG_MNC) != 0) {
416 list.add("CONFIG_MNC");
417 }
418 if ((diff & ActivityInfo.CONFIG_LOCALE) != 0) {
419 list.add("CONFIG_LOCALE");
420 }
421 if ((diff & ActivityInfo.CONFIG_TOUCHSCREEN) != 0) {
422 list.add("CONFIG_TOUCHSCREEN");
423 }
424 if ((diff & ActivityInfo.CONFIG_KEYBOARD) != 0) {
425 list.add("CONFIG_KEYBOARD");
426 }
427 if ((diff & ActivityInfo.CONFIG_KEYBOARD_HIDDEN) != 0) {
428 list.add("CONFIG_KEYBOARD_HIDDEN");
429 }
430 if ((diff & ActivityInfo.CONFIG_NAVIGATION) != 0) {
431 list.add("CONFIG_NAVIGATION");
432 }
433 if ((diff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
434 list.add("CONFIG_ORIENTATION");
435 }
436 if ((diff & ActivityInfo.CONFIG_SCREEN_LAYOUT) != 0) {
437 list.add("CONFIG_SCREEN_LAYOUT");
438 }
Romain Guy48327452017-01-23 17:03:35 -0800439 if ((diff & ActivityInfo.CONFIG_COLOR_MODE) != 0) {
440 list.add("CONFIG_COLOR_MODE");
Romain Guyc9ba5592017-01-18 16:34:42 -0800441 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700442 if ((diff & ActivityInfo.CONFIG_UI_MODE) != 0) {
443 list.add("CONFIG_UI_MODE");
444 }
445 if ((diff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0) {
446 list.add("CONFIG_SCREEN_SIZE");
447 }
448 if ((diff & ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
449 list.add("CONFIG_SMALLEST_SCREEN_SIZE");
450 }
451 if ((diff & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0) {
452 list.add("CONFIG_LAYOUT_DIRECTION");
453 }
454 if ((diff & ActivityInfo.CONFIG_FONT_SCALE) != 0) {
455 list.add("CONFIG_FONT_SCALE");
456 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100457 if ((diff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
458 list.add("CONFIG_ASSETS_PATHS");
459 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700460 StringBuilder builder = new StringBuilder("{");
461 for (int i = 0, n = list.size(); i < n; i++) {
462 builder.append(list.get(i));
463 if (i != n - 1) {
464 builder.append(", ");
465 }
466 }
467 builder.append("}");
468 return builder.toString();
469 }
470
Dianne Hackborn711e62a2010-11-29 16:38:22 -0800471 /**
472 * Check if the Configuration's current {@link #screenLayout} is at
473 * least the given size.
474 *
475 * @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
476 * {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
477 * {@link #SCREENLAYOUT_SIZE_XLARGE}.
478 * @return Returns true if the current screen layout size is at least
479 * the given size.
480 */
481 public boolean isLayoutSizeAtLeast(int size) {
482 int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
483 if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
Dianne Hackborn7d3a5bc2010-11-29 22:52:12 -0800484 return cur >= size;
Dianne Hackborn711e62a2010-11-29 16:38:22 -0800485 }
486
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700487 /** Constant for {@link #touchscreen}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 public static final int TOUCHSCREEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700489 /** Constant for {@link #touchscreen}, value corresponding to the
490 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#TouchscreenQualifier">notouch</a>
491 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 public static final int TOUCHSCREEN_NOTOUCH = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700493 /** @deprecated Not currently supported or used. */
494 @Deprecated public static final int TOUCHSCREEN_STYLUS = 2;
495 /** Constant for {@link #touchscreen}, value corresponding to the
496 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#TouchscreenQualifier">finger</a>
497 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 public static final int TOUCHSCREEN_FINGER = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 /**
501 * The kind of touch screen attached to the device.
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700502 * One of: {@link #TOUCHSCREEN_NOTOUCH}, {@link #TOUCHSCREEN_FINGER}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 */
504 public int touchscreen;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700505
506 /** Constant for {@link #keyboard}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 public static final int KEYBOARD_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700508 /** Constant for {@link #keyboard}, value corresponding to the
509 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">nokeys</a>
510 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 public static final int KEYBOARD_NOKEYS = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700512 /** Constant for {@link #keyboard}, value corresponding to the
513 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">qwerty</a>
514 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 public static final int KEYBOARD_QWERTY = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700516 /** Constant for {@link #keyboard}, value corresponding to the
517 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">12key</a>
518 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 public static final int KEYBOARD_12KEY = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 /**
522 * The kind of keyboard attached to the device.
Kenny Root507f8ed2009-06-09 11:21:11 -0500523 * One of: {@link #KEYBOARD_NOKEYS}, {@link #KEYBOARD_QWERTY},
524 * {@link #KEYBOARD_12KEY}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 */
526 public int keyboard;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700527
528 /** Constant for {@link #keyboardHidden}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700530 /** Constant for {@link #keyboardHidden}, value corresponding to the
531 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keysexposed</a>
532 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 public static final int KEYBOARDHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700534 /** Constant for {@link #keyboardHidden}, value corresponding to the
535 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyshidden</a>
536 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 public static final int KEYBOARDHIDDEN_YES = 2;
538 /** Constant matching actual resource implementation. {@hide} */
539 public static final int KEYBOARDHIDDEN_SOFT = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 /**
542 * A flag indicating whether any keyboard is available. Unlike
543 * {@link #hardKeyboardHidden}, this also takes into account a soft
544 * keyboard, so if the hard keyboard is hidden but there is soft
545 * keyboard available, it will be set to NO. Value is one of:
546 * {@link #KEYBOARDHIDDEN_NO}, {@link #KEYBOARDHIDDEN_YES}.
547 */
548 public int keyboardHidden;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700549
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700550 /** Constant for {@link #hardKeyboardHidden}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700552 /** Constant for {@link #hardKeyboardHidden}, value corresponding to the
553 * physical keyboard being exposed. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 public static final int HARDKEYBOARDHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700555 /** Constant for {@link #hardKeyboardHidden}, value corresponding to the
556 * physical keyboard being hidden. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 public static final int HARDKEYBOARDHIDDEN_YES = 2;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 /**
560 * A flag indicating whether the hard keyboard has been hidden. This will
561 * be set on a device with a mechanism to hide the keyboard from the
562 * user, when that mechanism is closed. One of:
563 * {@link #HARDKEYBOARDHIDDEN_NO}, {@link #HARDKEYBOARDHIDDEN_YES}.
564 */
565 public int hardKeyboardHidden;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700566
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700567 /** Constant for {@link #navigation}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 public static final int NAVIGATION_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700569 /** Constant for {@link #navigation}, value corresponding to the
570 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">nonav</a>
571 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 public static final int NAVIGATION_NONAV = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700573 /** Constant for {@link #navigation}, value corresponding to the
574 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">dpad</a>
575 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 public static final int NAVIGATION_DPAD = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700577 /** Constant for {@link #navigation}, value corresponding to the
578 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">trackball</a>
579 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 public static final int NAVIGATION_TRACKBALL = 3;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700581 /** Constant for {@link #navigation}, value corresponding to the
582 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">wheel</a>
583 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 public static final int NAVIGATION_WHEEL = 4;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 /**
587 * The kind of navigation method available on the device.
Kenny Root507f8ed2009-06-09 11:21:11 -0500588 * One of: {@link #NAVIGATION_NONAV}, {@link #NAVIGATION_DPAD},
589 * {@link #NAVIGATION_TRACKBALL}, {@link #NAVIGATION_WHEEL}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 */
591 public int navigation;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700592
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700593 /** Constant for {@link #navigationHidden}: a value indicating that no value has been set. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700594 public static final int NAVIGATIONHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700595 /** Constant for {@link #navigationHidden}, value corresponding to the
596 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavAvailQualifier">navexposed</a>
597 * resource qualifier. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700598 public static final int NAVIGATIONHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700599 /** Constant for {@link #navigationHidden}, value corresponding to the
600 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavAvailQualifier">navhidden</a>
601 * resource qualifier. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700602 public static final int NAVIGATIONHIDDEN_YES = 2;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700603
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700604 /**
605 * A flag indicating whether any 5-way or DPAD navigation available.
606 * This will be set on a device with a mechanism to hide the navigation
607 * controls from the user, when that mechanism is closed. One of:
608 * {@link #NAVIGATIONHIDDEN_NO}, {@link #NAVIGATIONHIDDEN_YES}.
609 */
610 public int navigationHidden;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700611
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700612 /** Constant for {@link #orientation}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 public static final int ORIENTATION_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700614 /** Constant for {@link #orientation}, value corresponding to the
615 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#OrientationQualifier">port</a>
616 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 public static final int ORIENTATION_PORTRAIT = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700618 /** Constant for {@link #orientation}, value corresponding to the
619 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#OrientationQualifier">land</a>
620 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 public static final int ORIENTATION_LANDSCAPE = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700622 /** @deprecated Not currently supported or used. */
623 @Deprecated public static final int ORIENTATION_SQUARE = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 /**
626 * Overall orientation of the screen. May be one of
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700627 * {@link #ORIENTATION_LANDSCAPE}, {@link #ORIENTATION_PORTRAIT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 */
629 public int orientation;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100630
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700631 /** Constant for {@link #uiMode}: bits that encode the mode type. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100632 public static final int UI_MODE_TYPE_MASK = 0x0f;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700633 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
634 * value indicating that no mode type has been set. */
Dianne Hackbornef05e072010-03-01 17:43:39 -0800635 public static final int UI_MODE_TYPE_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700636 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
637 * value that corresponds to
638 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">no
639 * UI mode</a> resource qualifier specified. */
Dianne Hackbornef05e072010-03-01 17:43:39 -0800640 public static final int UI_MODE_TYPE_NORMAL = 0x01;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700641 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
642 * value that corresponds to the
643 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">desk</a>
644 * resource qualifier. */
Dianne Hackborn7299c412010-03-04 18:41:49 -0800645 public static final int UI_MODE_TYPE_DESK = 0x02;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700646 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
647 * value that corresponds to the
648 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">car</a>
649 * resource qualifier. */
Dianne Hackborn7299c412010-03-04 18:41:49 -0800650 public static final int UI_MODE_TYPE_CAR = 0x03;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700651 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
652 * value that corresponds to the
653 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">television</a>
654 * resource qualifier. */
Dianne Hackborne360bb62011-05-20 16:11:04 -0700655 public static final int UI_MODE_TYPE_TELEVISION = 0x04;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700656 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
657 * value that corresponds to the
658 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">appliance</a>
659 * resource qualifier. */
Joe Onorato44fcb832011-12-14 20:59:30 -0800660 public static final int UI_MODE_TYPE_APPLIANCE = 0x05;
John Spurlock6c191292014-04-03 16:37:27 -0400661 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
662 * value that corresponds to the
663 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">watch</a>
664 * resource qualifier. */
665 public static final int UI_MODE_TYPE_WATCH = 0x06;
Zak Cohen1a6acdb2016-12-12 15:21:21 -0800666 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
667 * value that corresponds to the
668 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">vrheadset</a>
669 * resource qualifier. */
670 public static final int UI_MODE_TYPE_VR_HEADSET = 0x07;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100671
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700672 /** Constant for {@link #uiMode}: bits that encode the night mode. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100673 public static final int UI_MODE_NIGHT_MASK = 0x30;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700674 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
675 * value indicating that no mode type has been set. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100676 public static final int UI_MODE_NIGHT_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700677 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
678 * value that corresponds to the
679 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NightQualifier">notnight</a>
680 * resource qualifier. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100681 public static final int UI_MODE_NIGHT_NO = 0x10;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700682 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
683 * value that corresponds to the
684 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NightQualifier">night</a>
685 * resource qualifier. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100686 public static final int UI_MODE_NIGHT_YES = 0x20;
687
688 /**
689 * Bit mask of the ui mode. Currently there are two fields:
690 * <p>The {@link #UI_MODE_TYPE_MASK} bits define the overall ui mode of the
Dianne Hackborn7299c412010-03-04 18:41:49 -0800691 * device. They may be one of {@link #UI_MODE_TYPE_UNDEFINED},
692 * {@link #UI_MODE_TYPE_NORMAL}, {@link #UI_MODE_TYPE_DESK},
John Spurlock6c191292014-04-03 16:37:27 -0400693 * {@link #UI_MODE_TYPE_CAR}, {@link #UI_MODE_TYPE_TELEVISION},
Zak Cohen1a6acdb2016-12-12 15:21:21 -0800694 * {@link #UI_MODE_TYPE_APPLIANCE}, {@link #UI_MODE_TYPE_WATCH},
695 * or {@link #UI_MODE_TYPE_VR_HEADSET}.
Tobias Haamel27b28b32010-02-09 23:09:17 +0100696 *
697 * <p>The {@link #UI_MODE_NIGHT_MASK} defines whether the screen
Dianne Hackborn7299c412010-03-04 18:41:49 -0800698 * is in a special mode. They may be one of {@link #UI_MODE_NIGHT_UNDEFINED},
Tobias Haamel27b28b32010-02-09 23:09:17 +0100699 * {@link #UI_MODE_NIGHT_NO} or {@link #UI_MODE_NIGHT_YES}.
Tobias Haamel27b28b32010-02-09 23:09:17 +0100700 */
701 public int uiMode;
702
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700703 /**
704 * Default value for {@link #screenWidthDp} indicating that no width
705 * has been specified.
706 */
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700707 public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
708
709 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700710 * The current width of the available screen space, in dp units,
711 * corresponding to
712 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenWidthQualifier">screen
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700713 * width</a> resource qualifier. Set to
714 * {@link #SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700715 */
716 public int screenWidthDp;
717
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700718 /**
719 * Default value for {@link #screenHeightDp} indicating that no width
720 * has been specified.
721 */
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700722 public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
723
724 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700725 * The current height of the available screen space, in dp units,
726 * corresponding to
727 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenHeightQualifier">screen
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700728 * height</a> resource qualifier. Set to
729 * {@link #SCREEN_HEIGHT_DP_UNDEFINED} if no height is specified.
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700730 */
731 public int screenHeightDp;
732
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700733 /**
734 * Default value for {@link #smallestScreenWidthDp} indicating that no width
735 * has been specified.
736 */
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700737 public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0;
738
739 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700740 * The smallest screen size an application will see in normal operation,
741 * corresponding to
742 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">smallest
743 * screen width</a> resource qualifier.
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700744 * This is the smallest value of both screenWidthDp and screenHeightDp
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700745 * in both portrait and landscape. Set to
746 * {@link #SMALLEST_SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700747 */
748 public int smallestScreenWidthDp;
749
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700750 /**
751 * Default value for {@link #densityDpi} indicating that no width
752 * has been specified.
753 */
754 public static final int DENSITY_DPI_UNDEFINED = 0;
755
756 /**
Adam Lesinski31245b42014-08-22 19:10:56 -0700757 * Value for {@link #densityDpi} for resources that scale to any density (vector drawables).
758 * {@hide}
759 */
760 public static final int DENSITY_DPI_ANY = 0xfffe;
761
762 /**
763 * Value for {@link #densityDpi} for resources that are not meant to be scaled.
764 * {@hide}
765 */
766 public static final int DENSITY_DPI_NONE = 0xffff;
767
768 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700769 * The target screen density being rendered to,
770 * corresponding to
771 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#DensityQualifier">density</a>
772 * resource qualifier. Set to
773 * {@link #DENSITY_DPI_UNDEFINED} if no density is specified.
774 */
775 public int densityDpi;
776
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700777 /** @hide Hack to get this information from WM to app running in compat mode. */
778 public int compatScreenWidthDp;
779 /** @hide Hack to get this information from WM to app running in compat mode. */
780 public int compatScreenHeightDp;
781 /** @hide Hack to get this information from WM to app running in compat mode. */
782 public int compatSmallestScreenWidthDp;
783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 /**
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100785 * An undefined assetsSeq. This will not override an existing assetsSeq.
786 * @hide
787 */
788 public static final int ASSETS_SEQ_UNDEFINED = 0;
789
790 /**
791 * Internal counter that allows us to piggyback off the configuration change mechanism to
792 * signal to apps that the the assets for an Application have changed. A difference in these
793 * between two Configurations will yield a diff flag of
794 * {@link ActivityInfo#CONFIG_ASSETS_PATHS}.
795 * @hide
796 */
Riddle Hsue716d722019-01-09 15:56:46 +0800797 @TestApi
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100798 public int assetsSeq;
799
800 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800801 * @hide Internal book-keeping.
802 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100803 @UnsupportedAppUsage
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800804 public int seq;
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700805
Alan Viveretteac85f902016-03-11 15:15:51 -0500806 /** @hide */
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700807 @IntDef(flag = true, prefix = { "NATIVE_CONFIG_" }, value = {
808 NATIVE_CONFIG_MCC,
809 NATIVE_CONFIG_MNC,
810 NATIVE_CONFIG_LOCALE,
811 NATIVE_CONFIG_TOUCHSCREEN,
812 NATIVE_CONFIG_KEYBOARD,
813 NATIVE_CONFIG_KEYBOARD_HIDDEN,
814 NATIVE_CONFIG_NAVIGATION,
815 NATIVE_CONFIG_ORIENTATION,
816 NATIVE_CONFIG_DENSITY,
817 NATIVE_CONFIG_SCREEN_SIZE,
818 NATIVE_CONFIG_VERSION,
819 NATIVE_CONFIG_SCREEN_LAYOUT,
820 NATIVE_CONFIG_UI_MODE,
821 NATIVE_CONFIG_SMALLEST_SCREEN_SIZE,
822 NATIVE_CONFIG_LAYOUTDIR,
823 NATIVE_CONFIG_COLOR_MODE,
824 })
Alan Viveretteac85f902016-03-11 15:15:51 -0500825 @Retention(RetentionPolicy.SOURCE)
826 public @interface NativeConfig {}
827
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700828 /** @hide Native-specific bit mask for MCC config; DO NOT USE UNLESS YOU ARE SURE. */
829 public static final int NATIVE_CONFIG_MCC = 0x0001;
830 /** @hide Native-specific bit mask for MNC config; DO NOT USE UNLESS YOU ARE SURE. */
831 public static final int NATIVE_CONFIG_MNC = 0x0002;
832 /** @hide Native-specific bit mask for LOCALE config; DO NOT USE UNLESS YOU ARE SURE. */
833 public static final int NATIVE_CONFIG_LOCALE = 0x0004;
834 /** @hide Native-specific bit mask for TOUCHSCREEN config; DO NOT USE UNLESS YOU ARE SURE. */
835 public static final int NATIVE_CONFIG_TOUCHSCREEN = 0x0008;
836 /** @hide Native-specific bit mask for KEYBOARD config; DO NOT USE UNLESS YOU ARE SURE. */
837 public static final int NATIVE_CONFIG_KEYBOARD = 0x0010;
838 /** @hide Native-specific bit mask for KEYBOARD_HIDDEN config; DO NOT USE UNLESS YOU
839 * ARE SURE. */
840 public static final int NATIVE_CONFIG_KEYBOARD_HIDDEN = 0x0020;
841 /** @hide Native-specific bit mask for NAVIGATION config; DO NOT USE UNLESS YOU ARE SURE. */
842 public static final int NATIVE_CONFIG_NAVIGATION = 0x0040;
843 /** @hide Native-specific bit mask for ORIENTATION config; DO NOT USE UNLESS YOU ARE SURE. */
844 public static final int NATIVE_CONFIG_ORIENTATION = 0x0080;
845 /** @hide Native-specific bit mask for DENSITY config; DO NOT USE UNLESS YOU ARE SURE. */
846 public static final int NATIVE_CONFIG_DENSITY = 0x0100;
847 /** @hide Native-specific bit mask for SCREEN_SIZE config; DO NOT USE UNLESS YOU ARE SURE. */
848 public static final int NATIVE_CONFIG_SCREEN_SIZE = 0x0200;
849 /** @hide Native-specific bit mask for VERSION config; DO NOT USE UNLESS YOU ARE SURE. */
850 public static final int NATIVE_CONFIG_VERSION = 0x0400;
851 /** @hide Native-specific bit mask for SCREEN_LAYOUT config; DO NOT USE UNLESS YOU ARE SURE. */
852 public static final int NATIVE_CONFIG_SCREEN_LAYOUT = 0x0800;
853 /** @hide Native-specific bit mask for UI_MODE config; DO NOT USE UNLESS YOU ARE SURE. */
854 public static final int NATIVE_CONFIG_UI_MODE = 0x1000;
855 /** @hide Native-specific bit mask for SMALLEST_SCREEN_SIZE config; DO NOT USE UNLESS YOU
856 * ARE SURE. */
857 public static final int NATIVE_CONFIG_SMALLEST_SCREEN_SIZE = 0x2000;
858 /** @hide Native-specific bit mask for LAYOUTDIR config ; DO NOT USE UNLESS YOU ARE SURE.*/
859 public static final int NATIVE_CONFIG_LAYOUTDIR = 0x4000;
Romain Guy48327452017-01-23 17:03:35 -0800860 /** @hide Native-specific bit mask for COLOR_MODE config ; DO NOT USE UNLESS YOU ARE SURE.*/
861 public static final int NATIVE_CONFIG_COLOR_MODE = 0x10000;
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700862
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800863 /**
Adam Lesinskibad43fc2016-07-19 13:35:01 -0700864 * <p>Construct an invalid Configuration. This state is only suitable for constructing a
865 * Configuration delta that will be applied to some valid Configuration object. In order to
866 * create a valid standalone Configuration, you must call {@link #setToDefaults}. </p>
867 *
868 * <p>Example:</p>
869 * <pre class="prettyprint">
870 * Configuration validConfig = new Configuration();
871 * validConfig.setToDefaults();
872 *
873 * Configuration deltaOnlyConfig = new Configuration();
874 * deltaOnlyConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
875 *
876 * validConfig.updateFrom(deltaOnlyConfig);
877 * </pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 */
879 public Configuration() {
Adam Lesinskibad43fc2016-07-19 13:35:01 -0700880 unset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 }
882
883 /**
884 * Makes a deep copy suitable for modification.
885 */
886 public Configuration(Configuration o) {
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700887 setTo(o);
888 }
889
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700890 /* This brings mLocaleList in sync with locale in case a user of the older API who doesn't know
891 * about setLocales() has changed locale directly. */
892 private void fixUpLocaleList() {
893 if ((locale == null && !mLocaleList.isEmpty()) ||
Roozbeh Pournaderfee44842016-02-04 15:24:24 -0800894 (locale != null && !locale.equals(mLocaleList.get(0)))) {
Raph Levien10ea92a2016-05-02 12:56:01 -0700895 mLocaleList = locale == null ? LocaleList.getEmptyLocaleList() : new LocaleList(locale);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700896 }
897 }
898
Chet Haased30149e2017-01-13 12:55:16 -0800899 /**
900 * Sets the fields in this object to those in the given Configuration.
901 *
902 * @param o The Configuration object used to set the values of this Configuration's fields.
903 */
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700904 public void setTo(Configuration o) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905 fontScale = o.fontScale;
906 mcc = o.mcc;
907 mnc = o.mnc;
Roozbeh Pournader8a412e02015-12-02 18:39:50 -0800908 locale = o.locale == null ? null : (Locale) o.locale.clone();
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700909 o.fixUpLocaleList();
910 mLocaleList = o.mLocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 userSetLocale = o.userSetLocale;
912 touchscreen = o.touchscreen;
913 keyboard = o.keyboard;
914 keyboardHidden = o.keyboardHidden;
915 hardKeyboardHidden = o.hardKeyboardHidden;
916 navigation = o.navigation;
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700917 navigationHidden = o.navigationHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 orientation = o.orientation;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700919 screenLayout = o.screenLayout;
Romain Guy48327452017-01-23 17:03:35 -0800920 colorMode = o.colorMode;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100921 uiMode = o.uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700922 screenWidthDp = o.screenWidthDp;
923 screenHeightDp = o.screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700924 smallestScreenWidthDp = o.smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700925 densityDpi = o.densityDpi;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700926 compatScreenWidthDp = o.compatScreenWidthDp;
927 compatScreenHeightDp = o.compatScreenHeightDp;
928 compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100929 assetsSeq = o.assetsSeq;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800930 seq = o.seq;
Wale Ogunwale822e5122017-07-26 06:02:24 -0700931 windowConfiguration.setTo(o.windowConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700935 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn29735682011-04-21 17:26:39 -0700936 sb.append("{");
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700937 sb.append(fontScale);
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700938 sb.append(" ");
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700939 if (mcc != 0) {
940 sb.append(mcc);
941 sb.append("mcc");
942 } else {
943 sb.append("?mcc");
944 }
945 if (mnc != 0) {
946 sb.append(mnc);
947 sb.append("mnc");
948 } else {
949 sb.append("?mnc");
950 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700951 fixUpLocaleList();
952 if (!mLocaleList.isEmpty()) {
Dianne Hackborn9a849832011-04-07 15:11:57 -0700953 sb.append(" ");
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700954 sb.append(mLocaleList);
Dianne Hackborn9a849832011-04-07 15:11:57 -0700955 } else {
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700956 sb.append(" ?localeList");
Daniel Sandler7d6bddc2010-07-22 16:11:55 -0400957 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700958 int layoutDir = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK);
959 switch (layoutDir) {
960 case SCREENLAYOUT_LAYOUTDIR_UNDEFINED: sb.append(" ?layoutDir"); break;
Fabrice Di Meglio8a802db2012-09-05 13:12:02 -0700961 case SCREENLAYOUT_LAYOUTDIR_LTR: sb.append(" ldltr"); break;
962 case SCREENLAYOUT_LAYOUTDIR_RTL: sb.append(" ldrtl"); break;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700963 default: sb.append(" layoutDir=");
964 sb.append(layoutDir >> SCREENLAYOUT_LAYOUTDIR_SHIFT); break;
Fabrice Di Meglio7a736fb2011-06-09 20:20:36 -0700965 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700966 if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
967 sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
968 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700969 sb.append(" ?swdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700970 }
971 if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
972 sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");
973 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700974 sb.append(" ?wdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700975 }
976 if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
977 sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");
978 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700979 sb.append(" ?hdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700980 }
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700981 if (densityDpi != DENSITY_DPI_UNDEFINED) {
982 sb.append(" "); sb.append(densityDpi); sb.append("dpi");
983 } else {
984 sb.append(" ?density");
985 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700986 switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {
987 case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;
988 case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break;
989 case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break;
990 case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break;
991 case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break;
992 default: sb.append(" layoutSize=");
993 sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break;
994 }
995 switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) {
996 case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break;
997 case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break;
998 case SCREENLAYOUT_LONG_YES: sb.append(" long"); break;
999 default: sb.append(" layoutLong=");
1000 sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break;
1001 }
Romain Guy48327452017-01-23 17:03:35 -08001002 switch ((colorMode &COLOR_MODE_HDR_MASK)) {
1003 case COLOR_MODE_HDR_UNDEFINED: sb.append(" ?ldr"); break; // most likely not HDR
1004 case COLOR_MODE_HDR_NO: /* ldr is not interesting to print */ break;
1005 case COLOR_MODE_HDR_YES: sb.append(" hdr"); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001006 default: sb.append(" dynamicRange=");
Romain Guy48327452017-01-23 17:03:35 -08001007 sb.append(colorMode &COLOR_MODE_HDR_MASK); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001008 }
Romain Guy48327452017-01-23 17:03:35 -08001009 switch ((colorMode &COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
1010 case COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED: sb.append(" ?wideColorGamut"); break;
1011 case COLOR_MODE_WIDE_COLOR_GAMUT_NO: /* not wide is not interesting to print */ break;
1012 case COLOR_MODE_WIDE_COLOR_GAMUT_YES: sb.append(" widecg"); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001013 default: sb.append(" wideColorGamut=");
Romain Guy48327452017-01-23 17:03:35 -08001014 sb.append(colorMode &COLOR_MODE_WIDE_COLOR_GAMUT_MASK); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001015 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001016 switch (orientation) {
1017 case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break;
1018 case ORIENTATION_LANDSCAPE: sb.append(" land"); break;
1019 case ORIENTATION_PORTRAIT: sb.append(" port"); break;
1020 default: sb.append(" orien="); sb.append(orientation); break;
1021 }
1022 switch ((uiMode&UI_MODE_TYPE_MASK)) {
1023 case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
1024 case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
1025 case UI_MODE_TYPE_DESK: sb.append(" desk"); break;
1026 case UI_MODE_TYPE_CAR: sb.append(" car"); break;
Dianne Hackborne360bb62011-05-20 16:11:04 -07001027 case UI_MODE_TYPE_TELEVISION: sb.append(" television"); break;
Joe Onorato44fcb832011-12-14 20:59:30 -08001028 case UI_MODE_TYPE_APPLIANCE: sb.append(" appliance"); break;
John Spurlock6c191292014-04-03 16:37:27 -04001029 case UI_MODE_TYPE_WATCH: sb.append(" watch"); break;
Zak Cohen1a6acdb2016-12-12 15:21:21 -08001030 case UI_MODE_TYPE_VR_HEADSET: sb.append(" vrheadset"); break;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001031 default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break;
1032 }
1033 switch ((uiMode&UI_MODE_NIGHT_MASK)) {
1034 case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break;
1035 case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break;
1036 case UI_MODE_NIGHT_YES: sb.append(" night"); break;
1037 default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break;
1038 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07001039 switch (touchscreen) {
1040 case TOUCHSCREEN_UNDEFINED: sb.append(" ?touch"); break;
1041 case TOUCHSCREEN_NOTOUCH: sb.append(" -touch"); break;
1042 case TOUCHSCREEN_STYLUS: sb.append(" stylus"); break;
1043 case TOUCHSCREEN_FINGER: sb.append(" finger"); break;
1044 default: sb.append(" touch="); sb.append(touchscreen); break;
1045 }
1046 switch (keyboard) {
1047 case KEYBOARD_UNDEFINED: sb.append(" ?keyb"); break;
1048 case KEYBOARD_NOKEYS: sb.append(" -keyb"); break;
1049 case KEYBOARD_QWERTY: sb.append(" qwerty"); break;
1050 case KEYBOARD_12KEY: sb.append(" 12key"); break;
1051 default: sb.append(" keys="); sb.append(keyboard); break;
1052 }
1053 switch (keyboardHidden) {
1054 case KEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;
1055 case KEYBOARDHIDDEN_NO: sb.append("/v"); break;
1056 case KEYBOARDHIDDEN_YES: sb.append("/h"); break;
1057 case KEYBOARDHIDDEN_SOFT: sb.append("/s"); break;
1058 default: sb.append("/"); sb.append(keyboardHidden); break;
1059 }
1060 switch (hardKeyboardHidden) {
1061 case HARDKEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;
1062 case HARDKEYBOARDHIDDEN_NO: sb.append("/v"); break;
1063 case HARDKEYBOARDHIDDEN_YES: sb.append("/h"); break;
1064 default: sb.append("/"); sb.append(hardKeyboardHidden); break;
1065 }
1066 switch (navigation) {
1067 case NAVIGATION_UNDEFINED: sb.append(" ?nav"); break;
1068 case NAVIGATION_NONAV: sb.append(" -nav"); break;
1069 case NAVIGATION_DPAD: sb.append(" dpad"); break;
1070 case NAVIGATION_TRACKBALL: sb.append(" tball"); break;
1071 case NAVIGATION_WHEEL: sb.append(" wheel"); break;
1072 default: sb.append(" nav="); sb.append(navigation); break;
1073 }
1074 switch (navigationHidden) {
1075 case NAVIGATIONHIDDEN_UNDEFINED: sb.append("/?"); break;
1076 case NAVIGATIONHIDDEN_NO: sb.append("/v"); break;
1077 case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
1078 default: sb.append("/"); sb.append(navigationHidden); break;
1079 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07001080 sb.append(" winConfig="); sb.append(windowConfiguration);
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001081 if (assetsSeq != 0) {
1082 sb.append(" as.").append(assetsSeq);
1083 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001084 if (seq != 0) {
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001085 sb.append(" s.").append(seq);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001086 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001087 sb.append('}');
1088 return sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 }
1090
1091 /**
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001092 * Write to a protocol buffer output stream.
1093 * Protocol buffer message definition at {@link android.content.ConfigurationProto}
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -07001094 * Has the option to ignore fields that don't need to be persisted to disk.
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001095 *
1096 * @param protoOutputStream Stream to write the Configuration object to.
1097 * @param fieldId Field Id of the Configuration as defined in the parent message
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -07001098 * @param persisted Note if this proto will be persisted to disk
Nataniel Borges023ecb52019-01-16 14:15:43 -08001099 * @param critical If true, reduce amount of data written.
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001100 * @hide
1101 */
Nataniel Borges023ecb52019-01-16 14:15:43 -08001102 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted,
1103 boolean critical) {
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001104 final long token = protoOutputStream.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08001105 if (!critical) {
1106 protoOutputStream.write(FONT_SCALE, fontScale);
1107 protoOutputStream.write(MCC, mcc);
1108 protoOutputStream.write(MNC, mnc);
1109 if (mLocaleList != null) {
1110 mLocaleList.writeToProto(protoOutputStream, LOCALES);
1111 }
1112 protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
1113 protoOutputStream.write(COLOR_MODE, colorMode);
1114 protoOutputStream.write(TOUCHSCREEN, touchscreen);
1115 protoOutputStream.write(KEYBOARD, keyboard);
1116 protoOutputStream.write(KEYBOARD_HIDDEN, keyboardHidden);
1117 protoOutputStream.write(HARD_KEYBOARD_HIDDEN, hardKeyboardHidden);
1118 protoOutputStream.write(NAVIGATION, navigation);
1119 protoOutputStream.write(NAVIGATION_HIDDEN, navigationHidden);
1120 protoOutputStream.write(UI_MODE, uiMode);
1121 protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp);
1122 protoOutputStream.write(DENSITY_DPI, densityDpi);
1123 // For persistence, we do not care about window configuration
1124 if (!persisted && windowConfiguration != null) {
1125 windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
1126 }
Kweku Adams15afdeb2018-09-04 11:54:46 -07001127 }
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001128 protoOutputStream.write(ORIENTATION, orientation);
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001129 protoOutputStream.write(SCREEN_WIDTH_DP, screenWidthDp);
1130 protoOutputStream.write(SCREEN_HEIGHT_DP, screenHeightDp);
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001131 protoOutputStream.end(token);
1132 }
1133
1134 /**
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -07001135 * Write to a protocol buffer output stream.
1136 * Protocol buffer message definition at {@link android.content.ConfigurationProto}
1137 *
1138 * @param protoOutputStream Stream to write the Configuration object to.
1139 * @param fieldId Field Id of the Configuration as defined in the parent message
1140 * @hide
1141 */
1142 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
Nataniel Borges023ecb52019-01-16 14:15:43 -08001143 writeToProto(protoOutputStream, fieldId, false /* persisted */, false /* critical */);
1144 }
1145
1146 /**
1147 * Write to a protocol buffer output stream.
1148 * Protocol buffer message definition at {@link android.content.ConfigurationProto}
1149 *
1150 * @param protoOutputStream Stream to write the Configuration object to.
1151 * @param fieldId Field Id of the Configuration as defined in the parent message
1152 * @param critical If true, reduce amount of data written.
1153 * @hide
1154 */
1155 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean critical) {
1156 writeToProto(protoOutputStream, fieldId, false /* persisted */, critical);
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -07001157 }
1158
1159 /**
1160 * Read from a protocol buffer output stream.
1161 * Protocol buffer message definition at {@link android.content.ConfigurationProto}
1162 *
1163 * @param protoInputStream Stream to read the Configuration object from.
1164 * @param fieldId Field Id of the Configuration as defined in the parent message
1165 * @hide
1166 */
1167 public void readFromProto(ProtoInputStream protoInputStream, long fieldId) throws IOException {
1168 final long token = protoInputStream.start(fieldId);
1169 final List<Locale> list = new ArrayList();
1170 try {
1171 while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
1172 switch (protoInputStream.getFieldNumber()) {
1173 case (int) FONT_SCALE:
1174 fontScale = protoInputStream.readFloat(FONT_SCALE);
1175 break;
1176 case (int) MCC:
1177 mcc = protoInputStream.readInt(MCC);
1178 break;
1179 case (int) MNC:
1180 mnc = protoInputStream.readInt(MNC);
1181 break;
1182 case (int) LOCALES:
1183 // Parse the Locale here to handle all the repeated Locales
1184 // The LocaleList will be created when the message is completed
1185 final long localeToken = protoInputStream.start(LOCALES);
1186 String language = "";
1187 String country = "";
1188 String variant = "";
1189 try {
1190 while (protoInputStream.nextField()
1191 != ProtoInputStream.NO_MORE_FIELDS) {
1192 switch (protoInputStream.getFieldNumber()) {
1193 case (int) LocaleProto.LANGUAGE:
1194 language = protoInputStream.readString(
1195 LocaleProto.LANGUAGE);
1196 break;
1197 case (int) LocaleProto.COUNTRY:
1198 country = protoInputStream.readString(LocaleProto.COUNTRY);
1199 break;
1200 case (int) LocaleProto.VARIANT:
1201 variant = protoInputStream.readString(LocaleProto.VARIANT);
1202 break;
1203 }
1204 }
1205 } catch (WireTypeMismatchException wtme) {
1206 // rethrow for caller deal with
1207 throw wtme;
1208 } finally {
1209 protoInputStream.end(localeToken);
1210 list.add(new Locale(language, country, variant));
1211 }
1212 break;
1213 case (int) SCREEN_LAYOUT:
1214 screenLayout = protoInputStream.readInt(SCREEN_LAYOUT);
1215 break;
1216 case (int) COLOR_MODE:
1217 colorMode = protoInputStream.readInt(COLOR_MODE);
1218 break;
1219 case (int) TOUCHSCREEN:
1220 touchscreen = protoInputStream.readInt(TOUCHSCREEN);
1221 break;
1222 case (int) KEYBOARD:
1223 keyboard = protoInputStream.readInt(KEYBOARD);
1224 break;
1225 case (int) KEYBOARD_HIDDEN:
1226 keyboardHidden = protoInputStream.readInt(KEYBOARD_HIDDEN);
1227 break;
1228 case (int) HARD_KEYBOARD_HIDDEN:
1229 hardKeyboardHidden = protoInputStream.readInt(HARD_KEYBOARD_HIDDEN);
1230 break;
1231 case (int) NAVIGATION:
1232 navigation = protoInputStream.readInt(NAVIGATION);
1233 break;
1234 case (int) NAVIGATION_HIDDEN:
1235 navigationHidden = protoInputStream.readInt(NAVIGATION_HIDDEN);
1236 break;
1237 case (int) ORIENTATION:
1238 orientation = protoInputStream.readInt(ORIENTATION);
1239 break;
1240 case (int) UI_MODE:
1241 uiMode = protoInputStream.readInt(UI_MODE);
1242 break;
1243 case (int) SCREEN_WIDTH_DP:
1244 screenWidthDp = protoInputStream.readInt(SCREEN_WIDTH_DP);
1245 break;
1246 case (int) SCREEN_HEIGHT_DP:
1247 screenHeightDp = protoInputStream.readInt(SCREEN_HEIGHT_DP);
1248 break;
1249 case (int) SMALLEST_SCREEN_WIDTH_DP:
1250 smallestScreenWidthDp = protoInputStream.readInt(SMALLEST_SCREEN_WIDTH_DP);
1251 break;
1252 case (int) DENSITY_DPI:
1253 densityDpi = protoInputStream.readInt(DENSITY_DPI);
1254 break;
1255 case (int) WINDOW_CONFIGURATION:
1256 windowConfiguration.readFromProto(protoInputStream, WINDOW_CONFIGURATION);
1257 break;
1258 }
1259 }
1260 } finally {
1261 // Let caller handle any exceptions
1262 if (list.size() > 0) {
1263 //Create the LocaleList from the collected Locales
1264 setLocales(new LocaleList(list.toArray(new Locale[list.size()])));
1265 }
1266 protoInputStream.end(token);
1267 }
1268 }
1269
1270 /**
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001271 * Write full {@link android.content.ResourcesConfigurationProto} to protocol buffer output
1272 * stream.
1273 *
1274 * @param protoOutputStream Stream to write the Configuration object to.
1275 * @param fieldId Field Id of the Configuration as defined in the parent message
1276 * @param metrics Current display information
1277 * @hide
1278 */
1279 public void writeResConfigToProto(ProtoOutputStream protoOutputStream, long fieldId,
1280 DisplayMetrics metrics) {
1281 final int width, height;
1282 if (metrics.widthPixels >= metrics.heightPixels) {
1283 width = metrics.widthPixels;
1284 height = metrics.heightPixels;
1285 } else {
1286 //noinspection SuspiciousNameCombination
1287 width = metrics.heightPixels;
1288 //noinspection SuspiciousNameCombination
1289 height = metrics.widthPixels;
1290 }
1291
1292 final long token = protoOutputStream.start(fieldId);
1293 writeToProto(protoOutputStream, CONFIGURATION);
1294 protoOutputStream.write(SDK_VERSION, Build.VERSION.RESOURCES_SDK_INT);
1295 protoOutputStream.write(SCREEN_WIDTH_PX, width);
1296 protoOutputStream.write(SCREEN_HEIGHT_PX, height);
1297 protoOutputStream.end(token);
1298 }
1299
1300 /**
Michael Wright19859762017-09-18 20:57:58 +01001301 * Convert the UI mode to a human readable format.
1302 * @hide
1303 */
1304 public static String uiModeToString(int uiMode) {
1305 switch (uiMode) {
1306 case UI_MODE_TYPE_UNDEFINED:
1307 return "UI_MODE_TYPE_UNDEFINED";
1308 case UI_MODE_TYPE_NORMAL:
1309 return "UI_MODE_TYPE_NORMAL";
1310 case UI_MODE_TYPE_DESK:
1311 return "UI_MODE_TYPE_DESK";
1312 case UI_MODE_TYPE_CAR:
1313 return "UI_MODE_TYPE_CAR";
1314 case UI_MODE_TYPE_TELEVISION:
1315 return "UI_MODE_TYPE_TELEVISION";
1316 case UI_MODE_TYPE_APPLIANCE:
1317 return "UI_MODE_TYPE_APPLIANCE";
1318 case UI_MODE_TYPE_WATCH:
1319 return "UI_MODE_TYPE_WATCH";
1320 case UI_MODE_TYPE_VR_HEADSET:
1321 return "UI_MODE_TYPE_VR_HEADSET";
1322 default:
1323 return Integer.toString(uiMode);
1324 }
1325 }
1326
1327 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 * Set this object to the system defaults.
1329 */
1330 public void setToDefaults() {
1331 fontScale = 1;
1332 mcc = mnc = 0;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001333 mLocaleList = LocaleList.getEmptyLocaleList();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001334 locale = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 userSetLocale = false;
1336 touchscreen = TOUCHSCREEN_UNDEFINED;
1337 keyboard = KEYBOARD_UNDEFINED;
1338 keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
1339 hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
1340 navigation = NAVIGATION_UNDEFINED;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001341 navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 orientation = ORIENTATION_UNDEFINED;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001343 screenLayout = SCREENLAYOUT_UNDEFINED;
Romain Guy48327452017-01-23 17:03:35 -08001344 colorMode = COLOR_MODE_UNDEFINED;
Dianne Hackborn7299c412010-03-04 18:41:49 -08001345 uiMode = UI_MODE_TYPE_UNDEFINED;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001346 screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
1347 screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
1348 smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001349 densityDpi = DENSITY_DPI_UNDEFINED;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001350 assetsSeq = ASSETS_SEQ_UNDEFINED;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001351 seq = 0;
Wale Ogunwale822e5122017-07-26 06:02:24 -07001352 windowConfiguration.setToDefaults();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 }
1354
Adam Lesinskibad43fc2016-07-19 13:35:01 -07001355 /**
1356 * Set this object to completely undefined.
1357 * @hide
1358 */
1359 public void unset() {
1360 setToDefaults();
1361 fontScale = 0;
1362 }
1363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 /** {@hide} */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001365 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 @Deprecated public void makeDefault() {
1367 setToDefaults();
1368 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 /**
Alan Viveretteac85f902016-03-11 15:15:51 -05001371 * Copies the fields from delta into this Configuration object, keeping
1372 * track of which ones have changed. Any undefined fields in {@code delta}
1373 * are ignored and not copied in to the current Configuration.
1374 *
1375 * @return a bit mask of the changed fields, as per {@link #diff}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001377 public @Config int updateFrom(@NonNull Configuration delta) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 int changed = 0;
1379 if (delta.fontScale > 0 && fontScale != delta.fontScale) {
1380 changed |= ActivityInfo.CONFIG_FONT_SCALE;
1381 fontScale = delta.fontScale;
1382 }
1383 if (delta.mcc != 0 && mcc != delta.mcc) {
1384 changed |= ActivityInfo.CONFIG_MCC;
1385 mcc = delta.mcc;
1386 }
1387 if (delta.mnc != 0 && mnc != delta.mnc) {
1388 changed |= ActivityInfo.CONFIG_MNC;
1389 mnc = delta.mnc;
1390 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001391 fixUpLocaleList();
1392 delta.fixUpLocaleList();
1393 if (!delta.mLocaleList.isEmpty() && !mLocaleList.equals(delta.mLocaleList)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 changed |= ActivityInfo.CONFIG_LOCALE;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001395 mLocaleList = delta.mLocaleList;
1396 // delta.locale can't be null, since delta.mLocaleList is not empty.
1397 if (!delta.locale.equals(locale)) {
1398 locale = (Locale) delta.locale.clone();
1399 // If locale has changed, then layout direction is also changed ...
1400 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
1401 // ... and we need to update the layout direction (represented by the first
1402 // 2 most significant bits in screenLayout).
1403 setLayoutDirection(locale);
1404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
Craig Mautner31678b52013-08-12 17:56:34 -07001406 final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
1407 if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
1408 deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
1409 screenLayout = (screenLayout & ~SCREENLAYOUT_LAYOUTDIR_MASK) | deltaScreenLayoutDir;
Amith Yamasanid8415f42013-08-07 20:15:10 -07001410 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
Amith Yamasanid8415f42013-08-07 20:15:10 -07001411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
1413 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 changed |= ActivityInfo.CONFIG_LOCALE;
Amith Yamasanid8415f42013-08-07 20:15:10 -07001415 userSetLocale = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 }
1417 if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
1418 && touchscreen != delta.touchscreen) {
1419 changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
1420 touchscreen = delta.touchscreen;
1421 }
1422 if (delta.keyboard != KEYBOARD_UNDEFINED
1423 && keyboard != delta.keyboard) {
1424 changed |= ActivityInfo.CONFIG_KEYBOARD;
1425 keyboard = delta.keyboard;
1426 }
1427 if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
1428 && keyboardHidden != delta.keyboardHidden) {
1429 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1430 keyboardHidden = delta.keyboardHidden;
1431 }
1432 if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
1433 && hardKeyboardHidden != delta.hardKeyboardHidden) {
1434 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1435 hardKeyboardHidden = delta.hardKeyboardHidden;
1436 }
1437 if (delta.navigation != NAVIGATION_UNDEFINED
1438 && navigation != delta.navigation) {
1439 changed |= ActivityInfo.CONFIG_NAVIGATION;
1440 navigation = delta.navigation;
1441 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001442 if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
1443 && navigationHidden != delta.navigationHidden) {
1444 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1445 navigationHidden = delta.navigationHidden;
1446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 if (delta.orientation != ORIENTATION_UNDEFINED
1448 && orientation != delta.orientation) {
1449 changed |= ActivityInfo.CONFIG_ORIENTATION;
1450 orientation = delta.orientation;
1451 }
Robert Carrdf259d32016-12-05 20:33:10 -08001452 if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
1453 && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
1454 != (screenLayout & SCREENLAYOUT_SIZE_MASK)) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07001455 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
Robert Carrdf259d32016-12-05 20:33:10 -08001456 screenLayout = (screenLayout & ~SCREENLAYOUT_SIZE_MASK)
1457 | (delta.screenLayout & SCREENLAYOUT_SIZE_MASK);
Dianne Hackborn723738c2009-06-25 19:48:04 -07001458 }
Robert Carrdf259d32016-12-05 20:33:10 -08001459 if (((delta.screenLayout & SCREENLAYOUT_LONG_MASK) != SCREENLAYOUT_LONG_UNDEFINED)
1460 && (delta.screenLayout & SCREENLAYOUT_LONG_MASK)
1461 != (screenLayout & SCREENLAYOUT_LONG_MASK)) {
1462 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1463 screenLayout = (screenLayout & ~SCREENLAYOUT_LONG_MASK)
1464 | (delta.screenLayout & SCREENLAYOUT_LONG_MASK);
1465 }
1466 if (((delta.screenLayout & SCREENLAYOUT_ROUND_MASK) != SCREENLAYOUT_ROUND_UNDEFINED)
1467 && (delta.screenLayout & SCREENLAYOUT_ROUND_MASK)
1468 != (screenLayout & SCREENLAYOUT_ROUND_MASK)) {
1469 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1470 screenLayout = (screenLayout & ~SCREENLAYOUT_ROUND_MASK)
1471 | (delta.screenLayout & SCREENLAYOUT_ROUND_MASK);
1472 }
1473 if ((delta.screenLayout & SCREENLAYOUT_COMPAT_NEEDED)
1474 != (screenLayout & SCREENLAYOUT_COMPAT_NEEDED)
1475 && delta.screenLayout != 0) {
1476 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1477 screenLayout = (screenLayout & ~SCREENLAYOUT_COMPAT_NEEDED)
1478 | (delta.screenLayout & SCREENLAYOUT_COMPAT_NEEDED);
1479 }
1480
Romain Guy48327452017-01-23 17:03:35 -08001481 if (((delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
1482 COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED)
1483 && (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)
1484 != (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
1485 changed |= ActivityInfo.CONFIG_COLOR_MODE;
1486 colorMode = (colorMode & ~COLOR_MODE_WIDE_COLOR_GAMUT_MASK)
1487 | (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK);
Romain Guyc9ba5592017-01-18 16:34:42 -08001488 }
1489
Romain Guy48327452017-01-23 17:03:35 -08001490 if (((delta.colorMode & COLOR_MODE_HDR_MASK) != COLOR_MODE_HDR_UNDEFINED)
1491 && (delta.colorMode & COLOR_MODE_HDR_MASK)
1492 != (colorMode & COLOR_MODE_HDR_MASK)) {
1493 changed |= ActivityInfo.CONFIG_COLOR_MODE;
1494 colorMode = (colorMode & ~COLOR_MODE_HDR_MASK)
1495 | (delta.colorMode & COLOR_MODE_HDR_MASK);
Romain Guyc9ba5592017-01-18 16:34:42 -08001496 }
1497
Dianne Hackborn7299c412010-03-04 18:41:49 -08001498 if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
Tobias Haamel27b28b32010-02-09 23:09:17 +01001499 && uiMode != delta.uiMode) {
1500 changed |= ActivityInfo.CONFIG_UI_MODE;
Dianne Hackborn7299c412010-03-04 18:41:49 -08001501 if ((delta.uiMode&UI_MODE_TYPE_MASK) != UI_MODE_TYPE_UNDEFINED) {
1502 uiMode = (uiMode&~UI_MODE_TYPE_MASK)
1503 | (delta.uiMode&UI_MODE_TYPE_MASK);
1504 }
1505 if ((delta.uiMode&UI_MODE_NIGHT_MASK) != UI_MODE_NIGHT_UNDEFINED) {
1506 uiMode = (uiMode&~UI_MODE_NIGHT_MASK)
1507 | (delta.uiMode&UI_MODE_NIGHT_MASK);
1508 }
Tobias Haamel27b28b32010-02-09 23:09:17 +01001509 }
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001510 if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
1511 && screenWidthDp != delta.screenWidthDp) {
1512 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1513 screenWidthDp = delta.screenWidthDp;
1514 }
1515 if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
1516 && screenHeightDp != delta.screenHeightDp) {
1517 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1518 screenHeightDp = delta.screenHeightDp;
1519 }
Danny Baumanne7123a62013-05-15 10:21:40 +02001520 if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
1521 && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
1522 changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001523 smallestScreenWidthDp = delta.smallestScreenWidthDp;
1524 }
Danny Baumanne7123a62013-05-15 10:21:40 +02001525 if (delta.densityDpi != DENSITY_DPI_UNDEFINED &&
1526 densityDpi != delta.densityDpi) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001527 changed |= ActivityInfo.CONFIG_DENSITY;
1528 densityDpi = delta.densityDpi;
1529 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001530 if (delta.compatScreenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
1531 compatScreenWidthDp = delta.compatScreenWidthDp;
1532 }
1533 if (delta.compatScreenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
1534 compatScreenHeightDp = delta.compatScreenHeightDp;
1535 }
1536 if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
1537 compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
1538 }
Adam Lesinski4eb41292017-07-06 12:06:13 -07001539 if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) {
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001540 changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
1541 assetsSeq = delta.assetsSeq;
1542 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001543 if (delta.seq != 0) {
1544 seq = delta.seq;
1545 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07001546 if (windowConfiguration.updateFrom(delta.windowConfiguration) != 0) {
1547 changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
1548 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 return changed;
1551 }
1552
1553 /**
1554 * Return a bit mask of the differences between this Configuration
1555 * object and the given one. Does not change the values of either. Any
1556 * undefined fields in <var>delta</var> are ignored.
1557 * @return Returns a bit mask indicating which configuration
1558 * values has changed, containing any combination of
1559 * {@link android.content.pm.ActivityInfo#CONFIG_FONT_SCALE
1560 * PackageManager.ActivityInfo.CONFIG_FONT_SCALE},
1561 * {@link android.content.pm.ActivityInfo#CONFIG_MCC
1562 * PackageManager.ActivityInfo.CONFIG_MCC},
1563 * {@link android.content.pm.ActivityInfo#CONFIG_MNC
1564 * PackageManager.ActivityInfo.CONFIG_MNC},
1565 * {@link android.content.pm.ActivityInfo#CONFIG_LOCALE
1566 * PackageManager.ActivityInfo.CONFIG_LOCALE},
1567 * {@link android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
1568 * PackageManager.ActivityInfo.CONFIG_TOUCHSCREEN},
1569 * {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
1570 * PackageManager.ActivityInfo.CONFIG_KEYBOARD},
1571 * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
Dianne Hackborn723738c2009-06-25 19:48:04 -07001572 * PackageManager.ActivityInfo.CONFIG_NAVIGATION},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001574 * PackageManager.ActivityInfo.CONFIG_ORIENTATION},
Dianne Hackborn723738c2009-06-25 19:48:04 -07001575 * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001576 * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or
1577 * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001578 * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}, or
1579 * {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
1580 * PackageManager.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001581 * {@link android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
1582 * PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 */
1584 public int diff(Configuration delta) {
Bryce Lee658d9842017-07-28 08:33:36 -07001585 return diff(delta, false /* compareUndefined */, false /* publicOnly */);
1586 }
1587
1588 /**
1589 * Returns the diff against the provided {@link Configuration} excluding values that would
1590 * publicly be equivalent, such as appBounds.
1591 * @param delta {@link Configuration} to compare to.
1592 *
1593 * TODO(b/36812336): Remove once appBounds has been moved out of Configuration.
1594 * {@hide}
1595 */
1596 public int diffPublicOnly(Configuration delta) {
1597 return diff(delta, false /* compareUndefined */, true /* publicOnly */);
Andrii Kulianb10330d2016-09-16 13:51:46 -07001598 }
1599
1600 /**
1601 * Variation of {@link #diff(Configuration)} with an option to skip checks for undefined values.
1602 *
1603 * @hide
1604 */
Bryce Lee658d9842017-07-28 08:33:36 -07001605 public int diff(Configuration delta, boolean compareUndefined, boolean publicOnly) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 int changed = 0;
Andrii Kulianb10330d2016-09-16 13:51:46 -07001607 if ((compareUndefined || delta.fontScale > 0) && fontScale != delta.fontScale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 changed |= ActivityInfo.CONFIG_FONT_SCALE;
1609 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001610 if ((compareUndefined || delta.mcc != 0) && mcc != delta.mcc) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 changed |= ActivityInfo.CONFIG_MCC;
1612 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001613 if ((compareUndefined || delta.mnc != 0) && mnc != delta.mnc) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 changed |= ActivityInfo.CONFIG_MNC;
1615 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001616 fixUpLocaleList();
1617 delta.fixUpLocaleList();
Andrii Kulianb10330d2016-09-16 13:51:46 -07001618 if ((compareUndefined || !delta.mLocaleList.isEmpty())
1619 && !mLocaleList.equals(delta.mLocaleList)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 changed |= ActivityInfo.CONFIG_LOCALE;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001621 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 }
Craig Mautner31678b52013-08-12 17:56:34 -07001623 final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
Andrii Kulianb10330d2016-09-16 13:51:46 -07001624 if ((compareUndefined || deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED)
1625 && deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
Amith Yamasanid8415f42013-08-07 20:15:10 -07001626 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
1627 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001628 if ((compareUndefined || delta.touchscreen != TOUCHSCREEN_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 && touchscreen != delta.touchscreen) {
1630 changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
1631 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001632 if ((compareUndefined || delta.keyboard != KEYBOARD_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 && keyboard != delta.keyboard) {
1634 changed |= ActivityInfo.CONFIG_KEYBOARD;
1635 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001636 if ((compareUndefined || delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 && keyboardHidden != delta.keyboardHidden) {
1638 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1639 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001640 if ((compareUndefined || delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 && hardKeyboardHidden != delta.hardKeyboardHidden) {
1642 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1643 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001644 if ((compareUndefined || delta.navigation != NAVIGATION_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 && navigation != delta.navigation) {
1646 changed |= ActivityInfo.CONFIG_NAVIGATION;
1647 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001648 if ((compareUndefined || delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED)
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001649 && navigationHidden != delta.navigationHidden) {
1650 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1651 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001652 if ((compareUndefined || delta.orientation != ORIENTATION_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 && orientation != delta.orientation) {
1654 changed |= ActivityInfo.CONFIG_ORIENTATION;
1655 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001656 if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) !=
1657 (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED))
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001658 && getScreenLayoutNoDirection(screenLayout) !=
Andrii Kulianb10330d2016-09-16 13:51:46 -07001659 getScreenLayoutNoDirection(delta.screenLayout)) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07001660 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1661 }
Romain Guyc9ba5592017-01-18 16:34:42 -08001662 if ((compareUndefined ||
Romain Guy48327452017-01-23 17:03:35 -08001663 (delta.colorMode & COLOR_MODE_HDR_MASK) != COLOR_MODE_HDR_UNDEFINED)
1664 && (colorMode & COLOR_MODE_HDR_MASK) !=
1665 (delta.colorMode & COLOR_MODE_HDR_MASK)) {
1666 changed |= ActivityInfo.CONFIG_COLOR_MODE;
Romain Guyc9ba5592017-01-18 16:34:42 -08001667 }
1668 if ((compareUndefined ||
Romain Guy48327452017-01-23 17:03:35 -08001669 (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
1670 COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED)
1671 && (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
1672 (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
1673 changed |= ActivityInfo.CONFIG_COLOR_MODE;
Romain Guyc9ba5592017-01-18 16:34:42 -08001674 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001675 if ((compareUndefined || delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED))
Tobias Haamel27b28b32010-02-09 23:09:17 +01001676 && uiMode != delta.uiMode) {
1677 changed |= ActivityInfo.CONFIG_UI_MODE;
1678 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001679 if ((compareUndefined || delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED)
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001680 && screenWidthDp != delta.screenWidthDp) {
1681 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1682 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001683 if ((compareUndefined || delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED)
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001684 && screenHeightDp != delta.screenHeightDp) {
1685 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1686 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001687 if ((compareUndefined || delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED)
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001688 && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
1689 changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
1690 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001691 if ((compareUndefined || delta.densityDpi != DENSITY_DPI_UNDEFINED)
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001692 && densityDpi != delta.densityDpi) {
1693 changed |= ActivityInfo.CONFIG_DENSITY;
1694 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001695 if ((compareUndefined || delta.assetsSeq != ASSETS_SEQ_UNDEFINED)
1696 && assetsSeq != delta.assetsSeq) {
1697 changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
1698 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001699
Wale Ogunwale822e5122017-07-26 06:02:24 -07001700 // WindowConfiguration differences aren't considered public...
1701 if (!publicOnly
1702 && windowConfiguration.diff(delta.windowConfiguration, compareUndefined) != 0) {
1703 changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Bryce Lee7566d762017-03-30 09:34:15 -07001704 }
1705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 return changed;
1707 }
1708
1709 /**
Alan Viveretteac85f902016-03-11 15:15:51 -05001710 * Determines if a new resource needs to be loaded from the bit set of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 * configuration changes returned by {@link #updateFrom(Configuration)}.
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001712 *
Alan Viveretteac85f902016-03-11 15:15:51 -05001713 * @param configChanges the mask of changes configurations as returned by
1714 * {@link #updateFrom(Configuration)}
1715 * @param interestingChanges the configuration changes that the resource
1716 * can handle as given in
1717 * {@link android.util.TypedValue#changingConfigurations}
1718 * @return {@code true} if the resource needs to be loaded, {@code false}
1719 * otherwise
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001721 public static boolean needNewResources(@Config int configChanges,
1722 @Config int interestingChanges) {
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001723 // CONFIG_ASSETS_PATHS and CONFIG_FONT_SCALE are higher level configuration changes that
1724 // all resources are subject to change with.
1725 interestingChanges = interestingChanges | ActivityInfo.CONFIG_ASSETS_PATHS
1726 | ActivityInfo.CONFIG_FONT_SCALE;
1727 return (configChanges & interestingChanges) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001728 }
Amith Yamasanid8415f42013-08-07 20:15:10 -07001729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001731 * @hide Return true if the sequence of 'other' is better than this. Assumes
1732 * that 'this' is your current sequence and 'other' is a new one you have
1733 * received some how and want to compare with what you have.
1734 */
1735 public boolean isOtherSeqNewer(Configuration other) {
1736 if (other == null) {
1737 // Sanity check.
1738 return false;
1739 }
1740 if (other.seq == 0) {
1741 // If the other sequence is not specified, then we must assume
1742 // it is newer since we don't know any better.
1743 return true;
1744 }
1745 if (seq == 0) {
1746 // If this sequence is not specified, then we also consider the
1747 // other is better. Yes we have a preference for other. Sue us.
1748 return true;
1749 }
1750 int diff = other.seq - seq;
1751 if (diff > 0x10000) {
1752 // If there has been a sufficiently large jump, assume the
1753 // sequence has wrapped around.
1754 return false;
1755 }
1756 return diff > 0;
1757 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001758
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001759 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 * Parcelable methods
1761 */
1762 public int describeContents() {
1763 return 0;
1764 }
1765
1766 public void writeToParcel(Parcel dest, int flags) {
1767 dest.writeFloat(fontScale);
1768 dest.writeInt(mcc);
1769 dest.writeInt(mnc);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001770
1771 fixUpLocaleList();
Siyamed Sinir27ddd8a2018-02-27 13:07:22 -08001772 dest.writeParcelable(mLocaleList, flags);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001774 if(userSetLocale) {
1775 dest.writeInt(1);
1776 } else {
1777 dest.writeInt(0);
1778 }
1779 dest.writeInt(touchscreen);
1780 dest.writeInt(keyboard);
1781 dest.writeInt(keyboardHidden);
1782 dest.writeInt(hardKeyboardHidden);
1783 dest.writeInt(navigation);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001784 dest.writeInt(navigationHidden);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 dest.writeInt(orientation);
Dianne Hackborn723738c2009-06-25 19:48:04 -07001786 dest.writeInt(screenLayout);
Romain Guy48327452017-01-23 17:03:35 -08001787 dest.writeInt(colorMode);
Tobias Haamel27b28b32010-02-09 23:09:17 +01001788 dest.writeInt(uiMode);
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001789 dest.writeInt(screenWidthDp);
1790 dest.writeInt(screenHeightDp);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001791 dest.writeInt(smallestScreenWidthDp);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001792 dest.writeInt(densityDpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001793 dest.writeInt(compatScreenWidthDp);
1794 dest.writeInt(compatScreenHeightDp);
1795 dest.writeInt(compatSmallestScreenWidthDp);
Wale Ogunwale822e5122017-07-26 06:02:24 -07001796 dest.writeValue(windowConfiguration);
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001797 dest.writeInt(assetsSeq);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001798 dest.writeInt(seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 }
1800
Dianne Hackborn694f79b2010-03-17 19:44:59 -07001801 public void readFromParcel(Parcel source) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 fontScale = source.readFloat();
1803 mcc = source.readInt();
1804 mnc = source.readInt();
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001805
Siyamed Sinir27ddd8a2018-02-27 13:07:22 -08001806 mLocaleList = source.readParcelable(LocaleList.class.getClassLoader());
Roozbeh Pournaderfee44842016-02-04 15:24:24 -08001807 locale = mLocaleList.get(0);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 userSetLocale = (source.readInt()==1);
1810 touchscreen = source.readInt();
1811 keyboard = source.readInt();
1812 keyboardHidden = source.readInt();
1813 hardKeyboardHidden = source.readInt();
1814 navigation = source.readInt();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001815 navigationHidden = source.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 orientation = source.readInt();
Dianne Hackborn723738c2009-06-25 19:48:04 -07001817 screenLayout = source.readInt();
Romain Guy48327452017-01-23 17:03:35 -08001818 colorMode = source.readInt();
Tobias Haamel27b28b32010-02-09 23:09:17 +01001819 uiMode = source.readInt();
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001820 screenWidthDp = source.readInt();
1821 screenHeightDp = source.readInt();
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001822 smallestScreenWidthDp = source.readInt();
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001823 densityDpi = source.readInt();
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001824 compatScreenWidthDp = source.readInt();
1825 compatScreenHeightDp = source.readInt();
1826 compatSmallestScreenWidthDp = source.readInt();
Wale Ogunwale822e5122017-07-26 06:02:24 -07001827 windowConfiguration.setTo((WindowConfiguration) source.readValue(null));
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001828 assetsSeq = source.readInt();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001829 seq = source.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001830 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001831
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001832 public static final @android.annotation.NonNull Parcelable.Creator<Configuration> CREATOR
Dianne Hackborn694f79b2010-03-17 19:44:59 -07001833 = new Parcelable.Creator<Configuration>() {
1834 public Configuration createFromParcel(Parcel source) {
1835 return new Configuration(source);
1836 }
1837
1838 public Configuration[] newArray(int size) {
1839 return new Configuration[size];
1840 }
1841 };
1842
1843 /**
1844 * Construct this Configuration object, reading from the Parcel.
1845 */
1846 private Configuration(Parcel source) {
1847 readFromParcel(source);
1848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849
1850 public int compareTo(Configuration that) {
1851 int n;
1852 float a = this.fontScale;
1853 float b = that.fontScale;
1854 if (a < b) return -1;
1855 if (a > b) return 1;
1856 n = this.mcc - that.mcc;
1857 if (n != 0) return n;
1858 n = this.mnc - that.mnc;
1859 if (n != 0) return n;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001860
1861 fixUpLocaleList();
1862 that.fixUpLocaleList();
1863 // for backward compatibility, we consider an empty locale list to be greater
1864 // than any non-empty locale list.
1865 if (this.mLocaleList.isEmpty()) {
1866 if (!that.mLocaleList.isEmpty()) return 1;
1867 } else if (that.mLocaleList.isEmpty()) {
Dianne Hackborna8397032010-03-12 10:52:22 -08001868 return -1;
1869 } else {
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001870 final int minSize = Math.min(this.mLocaleList.size(), that.mLocaleList.size());
1871 for (int i = 0; i < minSize; ++i) {
1872 final Locale thisLocale = this.mLocaleList.get(i);
1873 final Locale thatLocale = that.mLocaleList.get(i);
1874 n = thisLocale.getLanguage().compareTo(thatLocale.getLanguage());
1875 if (n != 0) return n;
1876 n = thisLocale.getCountry().compareTo(thatLocale.getCountry());
1877 if (n != 0) return n;
1878 n = thisLocale.getVariant().compareTo(thatLocale.getVariant());
1879 if (n != 0) return n;
1880 n = thisLocale.toLanguageTag().compareTo(thatLocale.toLanguageTag());
1881 if (n != 0) return n;
1882 }
1883 n = this.mLocaleList.size() - that.mLocaleList.size();
Dianne Hackborna8397032010-03-12 10:52:22 -08001884 if (n != 0) return n;
1885 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 n = this.touchscreen - that.touchscreen;
1888 if (n != 0) return n;
1889 n = this.keyboard - that.keyboard;
1890 if (n != 0) return n;
1891 n = this.keyboardHidden - that.keyboardHidden;
1892 if (n != 0) return n;
1893 n = this.hardKeyboardHidden - that.hardKeyboardHidden;
1894 if (n != 0) return n;
1895 n = this.navigation - that.navigation;
1896 if (n != 0) return n;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001897 n = this.navigationHidden - that.navigationHidden;
1898 if (n != 0) return n;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001899 n = this.orientation - that.orientation;
Dianne Hackborn723738c2009-06-25 19:48:04 -07001900 if (n != 0) return n;
Romain Guy48327452017-01-23 17:03:35 -08001901 n = this.colorMode - that.colorMode;
Romain Guyc9ba5592017-01-18 16:34:42 -08001902 if (n != 0) return n;
Dianne Hackborn723738c2009-06-25 19:48:04 -07001903 n = this.screenLayout - that.screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +01001904 if (n != 0) return n;
1905 n = this.uiMode - that.uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001906 if (n != 0) return n;
1907 n = this.screenWidthDp - that.screenWidthDp;
1908 if (n != 0) return n;
1909 n = this.screenHeightDp - that.screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001910 if (n != 0) return n;
1911 n = this.smallestScreenWidthDp - that.smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001912 if (n != 0) return n;
1913 n = this.densityDpi - that.densityDpi;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001914 if (n != 0) return n;
1915 n = this.assetsSeq - that.assetsSeq;
Bryce Leec5fe0ee2017-06-30 09:03:09 -07001916 if (n != 0) return n;
Wale Ogunwale822e5122017-07-26 06:02:24 -07001917 n = windowConfiguration.compareTo(that.windowConfiguration);
1918 if (n != 0) return n;
Bryce Leec5fe0ee2017-06-30 09:03:09 -07001919
1920 // if (n != 0) return n;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001921 return n;
1922 }
1923
1924 public boolean equals(Configuration that) {
1925 if (that == null) return false;
1926 if (that == this) return true;
1927 return this.compareTo(that) == 0;
1928 }
1929
1930 public boolean equals(Object that) {
1931 try {
1932 return equals((Configuration)that);
1933 } catch (ClassCastException e) {
1934 }
1935 return false;
1936 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001938 public int hashCode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001939 int result = 17;
1940 result = 31 * result + Float.floatToIntBits(fontScale);
1941 result = 31 * result + mcc;
1942 result = 31 * result + mnc;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001943 result = 31 * result + mLocaleList.hashCode();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001944 result = 31 * result + touchscreen;
1945 result = 31 * result + keyboard;
1946 result = 31 * result + keyboardHidden;
1947 result = 31 * result + hardKeyboardHidden;
1948 result = 31 * result + navigation;
1949 result = 31 * result + navigationHidden;
1950 result = 31 * result + orientation;
1951 result = 31 * result + screenLayout;
Romain Guy48327452017-01-23 17:03:35 -08001952 result = 31 * result + colorMode;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001953 result = 31 * result + uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001954 result = 31 * result + screenWidthDp;
1955 result = 31 * result + screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001956 result = 31 * result + smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001957 result = 31 * result + densityDpi;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001958 result = 31 * result + assetsSeq;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001959 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001961
1962 /**
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001963 * Get the locale list. This is the preferred way for getting the locales (instead of using
1964 * the direct accessor to {@link #locale}, which would only provide the primary locale).
1965 *
1966 * @return The locale list.
1967 */
Adam Lesinskib61e4052016-05-19 18:23:05 -07001968 public @NonNull LocaleList getLocales() {
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001969 fixUpLocaleList();
1970 return mLocaleList;
1971 }
1972
1973 /**
1974 * Set the locale list. This is the preferred way for setting up the locales (instead of using
1975 * the direct accessor or {@link #setLocale(Locale)}). This will also set the layout direction
1976 * according to the first locale in the list.
1977 *
1978 * Note that the layout direction will always come from the first locale in the locale list,
1979 * even if the locale is not supported by the resources (the resources may only support
1980 * another locale further down the list which has a different direction).
1981 *
1982 * @param locales The locale list. If null, an empty LocaleList will be assigned.
1983 */
1984 public void setLocales(@Nullable LocaleList locales) {
1985 mLocaleList = locales == null ? LocaleList.getEmptyLocaleList() : locales;
Roozbeh Pournaderfee44842016-02-04 15:24:24 -08001986 locale = mLocaleList.get(0);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001987 setLayoutDirection(locale);
1988 }
1989
1990 /**
1991 * Set the locale list to a list of just one locale. This will also set the layout direction
1992 * according to the locale.
1993 *
1994 * Note that after this is run, calling <code>.equals()</code> on the input locale and the
1995 * {@link #locale} attribute would return <code>true</code> if they are not null, but there is
1996 * no guarantee that they would be the same object.
1997 *
1998 * See also the note about layout direction in {@link #setLocales(LocaleList)}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001999 *
2000 * @param loc The locale. Can be null.
2001 */
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002002 public void setLocale(@Nullable Locale loc) {
Raph Levien10ea92a2016-05-02 12:56:01 -07002003 setLocales(loc == null ? LocaleList.getEmptyLocaleList() : new LocaleList(loc));
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002004 }
2005
2006 /**
Seigo Nonakabd5cac62016-05-13 15:11:37 +09002007 * @hide
2008 *
2009 * Clears the locale without changing layout direction.
2010 */
2011 public void clearLocales() {
2012 mLocaleList = LocaleList.getEmptyLocaleList();
2013 locale = null;
2014 }
2015
2016 /**
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002017 * Return the layout direction. Will be either {@link View#LAYOUT_DIRECTION_LTR} or
2018 * {@link View#LAYOUT_DIRECTION_RTL}.
2019 *
Dianne Hackbornf1ae2692013-04-19 14:09:37 -07002020 * @return Returns {@link View#LAYOUT_DIRECTION_RTL} if the configuration
2021 * is {@link #SCREENLAYOUT_LAYOUTDIR_RTL}, otherwise {@link View#LAYOUT_DIRECTION_LTR}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002022 */
2023 public int getLayoutDirection() {
Dianne Hackbornf1ae2692013-04-19 14:09:37 -07002024 return (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == SCREENLAYOUT_LAYOUTDIR_RTL
2025 ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002026 }
2027
2028 /**
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002029 * Set the layout direction from a Locale.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002030 *
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002031 * @param loc The Locale. If null will set the layout direction to
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002032 * {@link View#LAYOUT_DIRECTION_LTR}. If not null will set it to the layout direction
2033 * corresponding to the Locale.
2034 *
John Spurlockbc4cf002015-03-24 21:51:20 -04002035 * @see View#LAYOUT_DIRECTION_LTR
2036 * @see View#LAYOUT_DIRECTION_RTL
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002037 */
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002038 public void setLayoutDirection(Locale loc) {
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002039 // There is a "1" difference between the configuration values for
2040 // layout direction and View constants for layout direction, just add "1".
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002041 final int layoutDirection = 1 + TextUtils.getLayoutDirectionFromLocale(loc);
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07002042 screenLayout = (screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK)|
2043 (layoutDirection << SCREENLAYOUT_LAYOUTDIR_SHIFT);
2044 }
2045
2046 private static int getScreenLayoutNoDirection(int screenLayout) {
2047 return screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK;
2048 }
Adam Lesinski2c749d22014-06-04 13:00:29 -07002049
2050 /**
Adam Powell49e7ff92015-05-14 16:18:53 -07002051 * Return whether the screen has a round shape. Apps may choose to change styling based
2052 * on this property, such as the alignment or layout of text or informational icons.
2053 *
2054 * @return true if the screen is rounded, false otherwise
2055 */
2056 public boolean isScreenRound() {
2057 return (screenLayout & SCREENLAYOUT_ROUND_MASK) == SCREENLAYOUT_ROUND_YES;
2058 }
2059
2060 /**
Romain Guye89d0bb2017-06-20 12:23:42 -07002061 * Return whether the screen has a wide color gamut and wide color gamut rendering
2062 * is supported by this device.
Romain Guyc9ba5592017-01-18 16:34:42 -08002063 *
Chia-I Wu53e86ba2018-05-02 10:13:22 -07002064 * When true, it implies the screen is colorspace aware but not
2065 * necessarily color-managed. The final colors may still be changed by the
2066 * screen depending on user settings.
2067 *
Romain Guye89d0bb2017-06-20 12:23:42 -07002068 * @return true if the screen has a wide color gamut and wide color gamut rendering
2069 * is supported, false otherwise
Romain Guyc9ba5592017-01-18 16:34:42 -08002070 */
2071 public boolean isScreenWideColorGamut() {
Romain Guy48327452017-01-23 17:03:35 -08002072 return (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) == COLOR_MODE_WIDE_COLOR_GAMUT_YES;
Romain Guyc9ba5592017-01-18 16:34:42 -08002073 }
2074
2075 /**
2076 * Return whether the screen has a high dynamic range.
2077 *
2078 * @return true if the screen has a high dynamic range, false otherwise
2079 */
2080 public boolean isScreenHdr() {
Romain Guy48327452017-01-23 17:03:35 -08002081 return (colorMode & COLOR_MODE_HDR_MASK) == COLOR_MODE_HDR_YES;
Romain Guyc9ba5592017-01-18 16:34:42 -08002082 }
2083
2084 /**
Adam Lesinski2c749d22014-06-04 13:00:29 -07002085 *
2086 * @hide
2087 */
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08002088 public static String localesToResourceQualifier(LocaleList locs) {
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07002089 final StringBuilder sb = new StringBuilder();
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08002090 for (int i = 0; i < locs.size(); i++) {
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07002091 final Locale loc = locs.get(i);
2092 final int l = loc.getLanguage().length();
2093 if (l == 0) {
2094 continue;
2095 }
2096 final int s = loc.getScript().length();
2097 final int c = loc.getCountry().length();
2098 final int v = loc.getVariant().length();
2099 // We ignore locale extensions, since they are not supported by AAPT
2100
2101 if (sb.length() != 0) {
2102 sb.append(",");
2103 }
2104 if (l == 2 && s == 0 && (c == 0 || c == 2) && v == 0) {
2105 // Traditional locale format: xx or xx-rYY
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08002106 sb.append(loc.getLanguage());
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07002107 if (c == 2) {
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08002108 sb.append("-r").append(loc.getCountry());
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07002109 }
2110 } else {
2111 sb.append("b+");
2112 sb.append(loc.getLanguage());
2113 if (s != 0) {
2114 sb.append("+");
2115 sb.append(loc.getScript());
2116 }
2117 if (c != 0) {
2118 sb.append("+");
2119 sb.append(loc.getCountry());
2120 }
2121 if (v != 0) {
2122 sb.append("+");
2123 sb.append(loc.getVariant());
Adam Lesinski2c749d22014-06-04 13:00:29 -07002124 }
2125 }
2126 }
2127 return sb.toString();
2128 }
2129
2130
2131 /**
2132 * Returns a string representation of the configuration that can be parsed
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002133 * by build tools (like AAPT), without display metrics included
Adam Lesinski2c749d22014-06-04 13:00:29 -07002134 *
Adam Lesinski2c749d22014-06-04 13:00:29 -07002135 * @hide
2136 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002137 @UnsupportedAppUsage
Adam Lesinski2c749d22014-06-04 13:00:29 -07002138 public static String resourceQualifierString(Configuration config) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002139 return resourceQualifierString(config, null);
2140 }
2141
2142 /**
2143 * Returns a string representation of the configuration that can be parsed
2144 * by build tools (like AAPT).
2145 *
2146 * @hide
2147 */
2148 public static String resourceQualifierString(Configuration config, DisplayMetrics metrics) {
Adam Lesinski2c749d22014-06-04 13:00:29 -07002149 ArrayList<String> parts = new ArrayList<String>();
2150
2151 if (config.mcc != 0) {
Adam Lesinski90865622014-10-16 18:18:10 -07002152 parts.add("mcc" + config.mcc);
Adam Lesinski2c749d22014-06-04 13:00:29 -07002153 if (config.mnc != 0) {
Adam Lesinski90865622014-10-16 18:18:10 -07002154 parts.add("mnc" + config.mnc);
Adam Lesinski2c749d22014-06-04 13:00:29 -07002155 }
2156 }
2157
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08002158 if (!config.mLocaleList.isEmpty()) {
Roozbeh Pournader417bbe02015-11-09 17:09:15 -08002159 final String resourceQualifier = localesToResourceQualifier(config.mLocaleList);
2160 if (!resourceQualifier.isEmpty()) {
2161 parts.add(resourceQualifier);
2162 }
Adam Lesinski2c749d22014-06-04 13:00:29 -07002163 }
2164
2165 switch (config.screenLayout & Configuration.SCREENLAYOUT_LAYOUTDIR_MASK) {
2166 case Configuration.SCREENLAYOUT_LAYOUTDIR_LTR:
2167 parts.add("ldltr");
2168 break;
2169 case Configuration.SCREENLAYOUT_LAYOUTDIR_RTL:
2170 parts.add("ldrtl");
2171 break;
2172 default:
2173 break;
2174 }
2175
2176 if (config.smallestScreenWidthDp != 0) {
2177 parts.add("sw" + config.smallestScreenWidthDp + "dp");
2178 }
2179
2180 if (config.screenWidthDp != 0) {
2181 parts.add("w" + config.screenWidthDp + "dp");
2182 }
2183
2184 if (config.screenHeightDp != 0) {
2185 parts.add("h" + config.screenHeightDp + "dp");
2186 }
2187
2188 switch (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) {
2189 case Configuration.SCREENLAYOUT_SIZE_SMALL:
2190 parts.add("small");
2191 break;
2192 case Configuration.SCREENLAYOUT_SIZE_NORMAL:
2193 parts.add("normal");
2194 break;
2195 case Configuration.SCREENLAYOUT_SIZE_LARGE:
2196 parts.add("large");
2197 break;
2198 case Configuration.SCREENLAYOUT_SIZE_XLARGE:
2199 parts.add("xlarge");
2200 break;
2201 default:
2202 break;
2203 }
2204
2205 switch (config.screenLayout & Configuration.SCREENLAYOUT_LONG_MASK) {
2206 case Configuration.SCREENLAYOUT_LONG_YES:
2207 parts.add("long");
2208 break;
2209 case Configuration.SCREENLAYOUT_LONG_NO:
2210 parts.add("notlong");
2211 break;
2212 default:
2213 break;
2214 }
2215
Adam Powell49e7ff92015-05-14 16:18:53 -07002216 switch (config.screenLayout & Configuration.SCREENLAYOUT_ROUND_MASK) {
2217 case Configuration.SCREENLAYOUT_ROUND_YES:
2218 parts.add("round");
2219 break;
2220 case Configuration.SCREENLAYOUT_ROUND_NO:
2221 parts.add("notround");
2222 break;
2223 default:
2224 break;
2225 }
2226
Romain Guy48327452017-01-23 17:03:35 -08002227 switch (config.colorMode & Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_MASK) {
2228 case Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES:
Romain Guyc9ba5592017-01-18 16:34:42 -08002229 parts.add("widecg");
2230 break;
Romain Guy48327452017-01-23 17:03:35 -08002231 case Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO:
Romain Guyc9ba5592017-01-18 16:34:42 -08002232 parts.add("nowidecg");
2233 break;
2234 default:
2235 break;
2236 }
2237
Chia-I Wu0d8acf52018-05-09 12:08:05 -07002238 switch (config.colorMode & Configuration.COLOR_MODE_HDR_MASK) {
2239 case Configuration.COLOR_MODE_HDR_YES:
2240 parts.add("highdr");
2241 break;
2242 case Configuration.COLOR_MODE_HDR_NO:
2243 parts.add("lowdr");
2244 break;
2245 default:
2246 break;
2247 }
2248
Adam Lesinski2c749d22014-06-04 13:00:29 -07002249 switch (config.orientation) {
2250 case Configuration.ORIENTATION_LANDSCAPE:
2251 parts.add("land");
2252 break;
2253 case Configuration.ORIENTATION_PORTRAIT:
2254 parts.add("port");
2255 break;
2256 default:
2257 break;
2258 }
2259
2260 switch (config.uiMode & Configuration.UI_MODE_TYPE_MASK) {
2261 case Configuration.UI_MODE_TYPE_APPLIANCE:
2262 parts.add("appliance");
2263 break;
2264 case Configuration.UI_MODE_TYPE_DESK:
2265 parts.add("desk");
2266 break;
2267 case Configuration.UI_MODE_TYPE_TELEVISION:
2268 parts.add("television");
2269 break;
2270 case Configuration.UI_MODE_TYPE_CAR:
2271 parts.add("car");
2272 break;
2273 case Configuration.UI_MODE_TYPE_WATCH:
2274 parts.add("watch");
2275 break;
Zak Cohen1a6acdb2016-12-12 15:21:21 -08002276 case Configuration.UI_MODE_TYPE_VR_HEADSET:
2277 parts.add("vrheadset");
2278 break;
Adam Lesinski2c749d22014-06-04 13:00:29 -07002279 default:
2280 break;
2281 }
2282
2283 switch (config.uiMode & Configuration.UI_MODE_NIGHT_MASK) {
2284 case Configuration.UI_MODE_NIGHT_YES:
2285 parts.add("night");
2286 break;
2287 case Configuration.UI_MODE_NIGHT_NO:
2288 parts.add("notnight");
2289 break;
2290 default:
2291 break;
2292 }
2293
2294 switch (config.densityDpi) {
Adam Lesinski31245b42014-08-22 19:10:56 -07002295 case DENSITY_DPI_UNDEFINED:
Adam Lesinski2c749d22014-06-04 13:00:29 -07002296 break;
2297 case 120:
2298 parts.add("ldpi");
2299 break;
2300 case 160:
2301 parts.add("mdpi");
2302 break;
2303 case 213:
2304 parts.add("tvdpi");
2305 break;
2306 case 240:
2307 parts.add("hdpi");
2308 break;
2309 case 320:
2310 parts.add("xhdpi");
2311 break;
Adam Lesinskiebc3e4c2014-08-21 12:21:45 -07002312 case 480:
2313 parts.add("xxhdpi");
2314 break;
2315 case 640:
2316 parts.add("xxxhdpi");
2317 break;
Adam Lesinski31245b42014-08-22 19:10:56 -07002318 case DENSITY_DPI_ANY:
2319 parts.add("anydpi");
2320 break;
2321 case DENSITY_DPI_NONE:
2322 parts.add("nodpi");
Christian Williamsb709f3c2017-11-02 17:19:27 -07002323 break;
Adam Lesinski2c749d22014-06-04 13:00:29 -07002324 default:
2325 parts.add(config.densityDpi + "dpi");
2326 break;
2327 }
2328
2329 switch (config.touchscreen) {
2330 case Configuration.TOUCHSCREEN_NOTOUCH:
2331 parts.add("notouch");
2332 break;
2333 case Configuration.TOUCHSCREEN_FINGER:
2334 parts.add("finger");
2335 break;
2336 default:
2337 break;
2338 }
2339
2340 switch (config.keyboardHidden) {
2341 case Configuration.KEYBOARDHIDDEN_NO:
2342 parts.add("keysexposed");
2343 break;
2344 case Configuration.KEYBOARDHIDDEN_YES:
2345 parts.add("keyshidden");
2346 break;
2347 case Configuration.KEYBOARDHIDDEN_SOFT:
2348 parts.add("keyssoft");
2349 break;
2350 default:
2351 break;
2352 }
2353
2354 switch (config.keyboard) {
2355 case Configuration.KEYBOARD_NOKEYS:
2356 parts.add("nokeys");
2357 break;
2358 case Configuration.KEYBOARD_QWERTY:
2359 parts.add("qwerty");
2360 break;
2361 case Configuration.KEYBOARD_12KEY:
2362 parts.add("12key");
2363 break;
2364 default:
2365 break;
2366 }
2367
2368 switch (config.navigationHidden) {
2369 case Configuration.NAVIGATIONHIDDEN_NO:
2370 parts.add("navexposed");
2371 break;
2372 case Configuration.NAVIGATIONHIDDEN_YES:
2373 parts.add("navhidden");
2374 break;
2375 default:
2376 break;
2377 }
2378
2379 switch (config.navigation) {
2380 case Configuration.NAVIGATION_NONAV:
2381 parts.add("nonav");
2382 break;
2383 case Configuration.NAVIGATION_DPAD:
2384 parts.add("dpad");
2385 break;
2386 case Configuration.NAVIGATION_TRACKBALL:
2387 parts.add("trackball");
2388 break;
2389 case Configuration.NAVIGATION_WHEEL:
2390 parts.add("wheel");
2391 break;
2392 default:
2393 break;
2394 }
2395
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002396 if (metrics != null) {
2397 final int width, height;
2398 if (metrics.widthPixels >= metrics.heightPixels) {
2399 width = metrics.widthPixels;
2400 height = metrics.heightPixels;
2401 } else {
2402 //noinspection SuspiciousNameCombination
2403 width = metrics.heightPixels;
2404 //noinspection SuspiciousNameCombination
2405 height = metrics.widthPixels;
2406 }
2407 parts.add(width + "x" + height);
2408 }
2409
Adam Lesinskiebc3e4c2014-08-21 12:21:45 -07002410 parts.add("v" + Build.VERSION.RESOURCES_SDK_INT);
Adam Lesinski2c749d22014-06-04 13:00:29 -07002411 return TextUtils.join("-", parts);
2412 }
Adam Lesinski7f61e962014-09-02 16:43:52 -07002413
2414 /**
2415 * Generate a delta Configuration between <code>base</code> and <code>change</code>. The
2416 * resulting delta can be used with {@link #updateFrom(Configuration)}.
2417 * <p />
2418 * Caveat: If the any of the Configuration's members becomes undefined, then
2419 * {@link #updateFrom(Configuration)} will treat it as a no-op and not update that member.
2420 *
2421 * This is fine for device configurations as no member is ever undefined.
2422 * {@hide}
2423 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002424 @UnsupportedAppUsage
Adam Lesinski7f61e962014-09-02 16:43:52 -07002425 public static Configuration generateDelta(Configuration base, Configuration change) {
2426 final Configuration delta = new Configuration();
2427 if (base.fontScale != change.fontScale) {
2428 delta.fontScale = change.fontScale;
2429 }
2430
2431 if (base.mcc != change.mcc) {
2432 delta.mcc = change.mcc;
2433 }
2434
2435 if (base.mnc != change.mnc) {
2436 delta.mnc = change.mnc;
2437 }
2438
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002439 base.fixUpLocaleList();
2440 change.fixUpLocaleList();
2441 if (!base.mLocaleList.equals(change.mLocaleList)) {
2442 delta.mLocaleList = change.mLocaleList;
Adam Lesinski7f61e962014-09-02 16:43:52 -07002443 delta.locale = change.locale;
2444 }
2445
2446 if (base.touchscreen != change.touchscreen) {
2447 delta.touchscreen = change.touchscreen;
2448 }
2449
2450 if (base.keyboard != change.keyboard) {
2451 delta.keyboard = change.keyboard;
2452 }
2453
2454 if (base.keyboardHidden != change.keyboardHidden) {
2455 delta.keyboardHidden = change.keyboardHidden;
2456 }
2457
2458 if (base.navigation != change.navigation) {
2459 delta.navigation = change.navigation;
2460 }
2461
2462 if (base.navigationHidden != change.navigationHidden) {
2463 delta.navigationHidden = change.navigationHidden;
2464 }
2465
2466 if (base.orientation != change.orientation) {
2467 delta.orientation = change.orientation;
2468 }
2469
2470 if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) !=
2471 (change.screenLayout & SCREENLAYOUT_SIZE_MASK)) {
2472 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK;
2473 }
2474
2475 if ((base.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK) !=
2476 (change.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
2477 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
2478 }
2479
2480 if ((base.screenLayout & SCREENLAYOUT_LONG_MASK) !=
2481 (change.screenLayout & SCREENLAYOUT_LONG_MASK)) {
2482 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_LONG_MASK;
2483 }
2484
Adam Powell49e7ff92015-05-14 16:18:53 -07002485 if ((base.screenLayout & SCREENLAYOUT_ROUND_MASK) !=
2486 (change.screenLayout & SCREENLAYOUT_ROUND_MASK)) {
2487 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_ROUND_MASK;
2488 }
2489
Romain Guy48327452017-01-23 17:03:35 -08002490 if ((base.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
2491 (change.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
2492 delta.colorMode |= change.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK;
Romain Guyc9ba5592017-01-18 16:34:42 -08002493 }
2494
Romain Guy48327452017-01-23 17:03:35 -08002495 if ((base.colorMode & COLOR_MODE_HDR_MASK) !=
2496 (change.colorMode & COLOR_MODE_HDR_MASK)) {
2497 delta.colorMode |= change.colorMode & COLOR_MODE_HDR_MASK;
Romain Guyc9ba5592017-01-18 16:34:42 -08002498 }
2499
Adam Lesinski7f61e962014-09-02 16:43:52 -07002500 if ((base.uiMode & UI_MODE_TYPE_MASK) != (change.uiMode & UI_MODE_TYPE_MASK)) {
2501 delta.uiMode |= change.uiMode & UI_MODE_TYPE_MASK;
2502 }
2503
2504 if ((base.uiMode & UI_MODE_NIGHT_MASK) != (change.uiMode & UI_MODE_NIGHT_MASK)) {
2505 delta.uiMode |= change.uiMode & UI_MODE_NIGHT_MASK;
2506 }
2507
2508 if (base.screenWidthDp != change.screenWidthDp) {
2509 delta.screenWidthDp = change.screenWidthDp;
2510 }
2511
2512 if (base.screenHeightDp != change.screenHeightDp) {
2513 delta.screenHeightDp = change.screenHeightDp;
2514 }
2515
2516 if (base.smallestScreenWidthDp != change.smallestScreenWidthDp) {
2517 delta.smallestScreenWidthDp = change.smallestScreenWidthDp;
2518 }
2519
2520 if (base.densityDpi != change.densityDpi) {
2521 delta.densityDpi = change.densityDpi;
2522 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01002523
2524 if (base.assetsSeq != change.assetsSeq) {
2525 delta.assetsSeq = change.assetsSeq;
2526 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07002527
2528 if (!base.windowConfiguration.equals(change.windowConfiguration)) {
2529 delta.windowConfiguration.setTo(change.windowConfiguration);
2530 }
Adam Lesinski7f61e962014-09-02 16:43:52 -07002531 return delta;
2532 }
2533
2534 private static final String XML_ATTR_FONT_SCALE = "fs";
2535 private static final String XML_ATTR_MCC = "mcc";
2536 private static final String XML_ATTR_MNC = "mnc";
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002537 private static final String XML_ATTR_LOCALES = "locales";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002538 private static final String XML_ATTR_TOUCHSCREEN = "touch";
2539 private static final String XML_ATTR_KEYBOARD = "key";
2540 private static final String XML_ATTR_KEYBOARD_HIDDEN = "keyHid";
2541 private static final String XML_ATTR_HARD_KEYBOARD_HIDDEN = "hardKeyHid";
2542 private static final String XML_ATTR_NAVIGATION = "nav";
2543 private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
2544 private static final String XML_ATTR_ORIENTATION = "ori";
Bryce Leec1f2f2a2017-06-22 15:29:42 -07002545 private static final String XML_ATTR_ROTATION = "rot";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002546 private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
Romain Guy48327452017-01-23 17:03:35 -08002547 private static final String XML_ATTR_COLOR_MODE = "clrMod";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002548 private static final String XML_ATTR_UI_MODE = "ui";
2549 private static final String XML_ATTR_SCREEN_WIDTH = "width";
2550 private static final String XML_ATTR_SCREEN_HEIGHT = "height";
2551 private static final String XML_ATTR_SMALLEST_WIDTH = "sw";
2552 private static final String XML_ATTR_DENSITY = "density";
Bryce Lee7566d762017-03-30 09:34:15 -07002553 private static final String XML_ATTR_APP_BOUNDS = "app_bounds";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002554
2555 /**
2556 * Reads the attributes corresponding to Configuration member fields from the Xml parser.
2557 * The parser is expected to be on a tag which has Configuration attributes.
2558 *
2559 * @param parser The Xml parser from which to read attributes.
2560 * @param configOut The Configuration to populate from the Xml attributes.
2561 * {@hide}
2562 */
2563 public static void readXmlAttrs(XmlPullParser parser, Configuration configOut)
2564 throws XmlPullParserException, IOException {
2565 configOut.fontScale = Float.intBitsToFloat(
2566 XmlUtils.readIntAttribute(parser, XML_ATTR_FONT_SCALE, 0));
2567 configOut.mcc = XmlUtils.readIntAttribute(parser, XML_ATTR_MCC, 0);
2568 configOut.mnc = XmlUtils.readIntAttribute(parser, XML_ATTR_MNC, 0);
2569
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002570 final String localesStr = XmlUtils.readStringAttribute(parser, XML_ATTR_LOCALES);
2571 configOut.mLocaleList = LocaleList.forLanguageTags(localesStr);
Roozbeh Pournaderfee44842016-02-04 15:24:24 -08002572 configOut.locale = configOut.mLocaleList.get(0);
Adam Lesinski7f61e962014-09-02 16:43:52 -07002573
2574 configOut.touchscreen = XmlUtils.readIntAttribute(parser, XML_ATTR_TOUCHSCREEN,
2575 TOUCHSCREEN_UNDEFINED);
2576 configOut.keyboard = XmlUtils.readIntAttribute(parser, XML_ATTR_KEYBOARD,
2577 KEYBOARD_UNDEFINED);
2578 configOut.keyboardHidden = XmlUtils.readIntAttribute(parser, XML_ATTR_KEYBOARD_HIDDEN,
2579 KEYBOARDHIDDEN_UNDEFINED);
2580 configOut.hardKeyboardHidden =
2581 XmlUtils.readIntAttribute(parser, XML_ATTR_HARD_KEYBOARD_HIDDEN,
2582 HARDKEYBOARDHIDDEN_UNDEFINED);
2583 configOut.navigation = XmlUtils.readIntAttribute(parser, XML_ATTR_NAVIGATION,
2584 NAVIGATION_UNDEFINED);
2585 configOut.navigationHidden = XmlUtils.readIntAttribute(parser, XML_ATTR_NAVIGATION_HIDDEN,
2586 NAVIGATIONHIDDEN_UNDEFINED);
2587 configOut.orientation = XmlUtils.readIntAttribute(parser, XML_ATTR_ORIENTATION,
2588 ORIENTATION_UNDEFINED);
2589 configOut.screenLayout = XmlUtils.readIntAttribute(parser, XML_ATTR_SCREEN_LAYOUT,
2590 SCREENLAYOUT_UNDEFINED);
Romain Guy48327452017-01-23 17:03:35 -08002591 configOut.colorMode = XmlUtils.readIntAttribute(parser, XML_ATTR_COLOR_MODE,
2592 COLOR_MODE_UNDEFINED);
Adam Lesinski7f61e962014-09-02 16:43:52 -07002593 configOut.uiMode = XmlUtils.readIntAttribute(parser, XML_ATTR_UI_MODE, 0);
2594 configOut.screenWidthDp = XmlUtils.readIntAttribute(parser, XML_ATTR_SCREEN_WIDTH,
2595 SCREEN_WIDTH_DP_UNDEFINED);
2596 configOut.screenHeightDp = XmlUtils.readIntAttribute(parser, XML_ATTR_SCREEN_HEIGHT,
2597 SCREEN_HEIGHT_DP_UNDEFINED);
2598 configOut.smallestScreenWidthDp =
2599 XmlUtils.readIntAttribute(parser, XML_ATTR_SMALLEST_WIDTH,
2600 SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
2601 configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY,
2602 DENSITY_DPI_UNDEFINED);
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01002603
Wale Ogunwale822e5122017-07-26 06:02:24 -07002604 // For persistence, we don't care about assetsSeq and WindowConfiguration, so do not read it
2605 // out.
Adam Lesinski7f61e962014-09-02 16:43:52 -07002606 }
2607
2608
2609 /**
2610 * Writes the Configuration's member fields as attributes into the XmlSerializer.
2611 * The serializer is expected to have already started a tag so that attributes can be
2612 * immediately written.
2613 *
2614 * @param xml The serializer to which to write the attributes.
2615 * @param config The Configuration whose member fields to write.
2616 * {@hide}
2617 */
2618 public static void writeXmlAttrs(XmlSerializer xml, Configuration config) throws IOException {
2619 XmlUtils.writeIntAttribute(xml, XML_ATTR_FONT_SCALE,
2620 Float.floatToIntBits(config.fontScale));
2621 if (config.mcc != 0) {
2622 XmlUtils.writeIntAttribute(xml, XML_ATTR_MCC, config.mcc);
2623 }
2624 if (config.mnc != 0) {
2625 XmlUtils.writeIntAttribute(xml, XML_ATTR_MNC, config.mnc);
2626 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002627 config.fixUpLocaleList();
2628 if (!config.mLocaleList.isEmpty()) {
2629 XmlUtils.writeStringAttribute(xml, XML_ATTR_LOCALES, config.mLocaleList.toLanguageTags());
Adam Lesinski7f61e962014-09-02 16:43:52 -07002630 }
2631 if (config.touchscreen != TOUCHSCREEN_UNDEFINED) {
2632 XmlUtils.writeIntAttribute(xml, XML_ATTR_TOUCHSCREEN, config.touchscreen);
2633 }
2634 if (config.keyboard != KEYBOARD_UNDEFINED) {
2635 XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD, config.keyboard);
2636 }
2637 if (config.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED) {
2638 XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD_HIDDEN, config.keyboardHidden);
2639 }
2640 if (config.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED) {
2641 XmlUtils.writeIntAttribute(xml, XML_ATTR_HARD_KEYBOARD_HIDDEN,
2642 config.hardKeyboardHidden);
2643 }
2644 if (config.navigation != NAVIGATION_UNDEFINED) {
2645 XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION, config.navigation);
2646 }
2647 if (config.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED) {
2648 XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION_HIDDEN, config.navigationHidden);
2649 }
2650 if (config.orientation != ORIENTATION_UNDEFINED) {
2651 XmlUtils.writeIntAttribute(xml, XML_ATTR_ORIENTATION, config.orientation);
2652 }
2653 if (config.screenLayout != SCREENLAYOUT_UNDEFINED) {
2654 XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_LAYOUT, config.screenLayout);
2655 }
Romain Guy48327452017-01-23 17:03:35 -08002656 if (config.colorMode != COLOR_MODE_UNDEFINED) {
2657 XmlUtils.writeIntAttribute(xml, XML_ATTR_COLOR_MODE, config.colorMode);
Romain Guyc9ba5592017-01-18 16:34:42 -08002658 }
Adam Lesinski7f61e962014-09-02 16:43:52 -07002659 if (config.uiMode != 0) {
2660 XmlUtils.writeIntAttribute(xml, XML_ATTR_UI_MODE, config.uiMode);
2661 }
2662 if (config.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
2663 XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_WIDTH, config.screenWidthDp);
2664 }
2665 if (config.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
2666 XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_HEIGHT, config.screenHeightDp);
2667 }
2668 if (config.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2669 XmlUtils.writeIntAttribute(xml, XML_ATTR_SMALLEST_WIDTH, config.smallestScreenWidthDp);
2670 }
2671 if (config.densityDpi != DENSITY_DPI_UNDEFINED) {
2672 XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi);
2673 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01002674
Wale Ogunwale822e5122017-07-26 06:02:24 -07002675 // For persistence, we do not care about assetsSeq and window configuration, so do not write
2676 // it out.
Adam Lesinski7f61e962014-09-02 16:43:52 -07002677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678}