blob: 93690bf3aef9d93e2e768c1250c9c97bbb10b6ef [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
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070019import static android.content.ConfigurationProto.DENSITY_DPI;
20import static android.content.ConfigurationProto.FONT_SCALE;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080021import static android.content.ConfigurationProto.HARD_KEYBOARD_HIDDEN;
22import static android.content.ConfigurationProto.HDR_COLOR_MODE;
23import static android.content.ConfigurationProto.KEYBOARD_HIDDEN;
24import static android.content.ConfigurationProto.LOCALES;
25import static android.content.ConfigurationProto.MCC;
26import static android.content.ConfigurationProto.MNC;
27import static android.content.ConfigurationProto.NAVIGATION;
28import static android.content.ConfigurationProto.NAVIGATION_HIDDEN;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070029import static android.content.ConfigurationProto.ORIENTATION;
30import static android.content.ConfigurationProto.SCREEN_HEIGHT_DP;
31import static android.content.ConfigurationProto.SCREEN_LAYOUT;
32import static android.content.ConfigurationProto.SCREEN_WIDTH_DP;
33import static android.content.ConfigurationProto.SMALLEST_SCREEN_WIDTH_DP;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080034import static android.content.ConfigurationProto.TOUCHSCREEN;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070035import static android.content.ConfigurationProto.UI_MODE;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080036import static android.content.ConfigurationProto.WIDE_COLOR_GAMUT;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070037import 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;
Wale Ogunwale822e5122017-07-26 06:02:24 -070047import android.app.WindowConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.content.pm.ActivityInfo;
Alan Viveretteac85f902016-03-11 15:15:51 -050049import android.content.pm.ActivityInfo.Config;
Adam Lesinski2c749d22014-06-04 13:00:29 -070050import android.os.Build;
Yohei Yukawa23cbe852016-05-17 16:42:58 -070051import android.os.LocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.os.Parcel;
53import android.os.Parcelable;
Fabrice Di Megliod3d9f3f2012-09-18 12:55:32 -070054import android.text.TextUtils;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080055import android.util.DisplayMetrics;
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070056import android.util.proto.ProtoOutputStream;
Fabrice Di Meglio3fb824b2012-02-28 17:58:31 -080057import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
Romain Guye89d0bb2017-06-20 12:23:42 -070059import com.android.internal.util.XmlUtils;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
Adam Lesinski7f61e962014-09-02 16:43:52 -070065import java.io.IOException;
Alan Viveretteac85f902016-03-11 15:15:51 -050066import java.lang.annotation.Retention;
67import java.lang.annotation.RetentionPolicy;
Adam Lesinski2c749d22014-06-04 13:00:29 -070068import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import java.util.Locale;
70
71/**
72 * This class describes all device configuration information that can
73 * impact the resources the application retrieves. This includes both
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -070074 * user-specified configuration options (locale list and scaling) as well
Scott Main63848e32011-04-20 22:20:46 -070075 * as device configurations (such as input modes, screen size and screen orientation).
76 * <p>You can acquire this object from {@link Resources}, using {@link
77 * Resources#getConfiguration}. Thus, from an activity, you can get it by chaining the request
78 * with {@link android.app.Activity#getResources}:</p>
79 * <pre>Configuration config = getResources().getConfiguration();</pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 */
81public final class Configuration implements Parcelable, Comparable<Configuration> {
Dianne Hackborn756220b2012-08-14 16:45:30 -070082 /** @hide */
83 public static final Configuration EMPTY = new Configuration();
84
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 /**
86 * Current user preference for the scaling factor for fonts, relative
87 * to the base density scaling.
88 */
89 public float fontScale;
90
91 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070092 * IMSI MCC (Mobile Country Code), corresponding to
93 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mcc</a>
94 * resource qualifier. 0 if undefined.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 */
96 public int mcc;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070099 * IMSI MNC (Mobile Network Code), corresponding to
100 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mnc</a>
Mattias Petersson1d766b52011-10-07 09:33:52 +0200101 * resource qualifier. 0 if undefined. Note that the actual MNC may be 0; in order to check
102 * for this use the {@link #MNC_ZERO} symbol.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 */
104 public int mnc;
Mattias Petersson1d766b52011-10-07 09:33:52 +0200105
106 /**
107 * Constant used to to represent MNC (Mobile Network Code) zero.
108 * 0 cannot be used, since it is used to represent an undefined MNC.
109 */
110 public static final int MNC_ZERO = 0xffff;
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700113 * Current user preference for the locale, corresponding to
114 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
115 * resource qualifier.
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700116 *
117 * @deprecated Do not set or read this directly. Use {@link #getLocales()} and
Raph Levienb1638702016-04-27 11:02:12 -0700118 * {@link #setLocales(LocaleList)}. If only the primary locale is needed,
119 * <code>getLocales().get(0)</code> is now the preferred accessor.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 */
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700121 @Deprecated public Locale locale;
122
123 private LocaleList mLocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124
125 /**
Andy Stadlerf8a7cea2009-04-10 16:24:47 -0700126 * Locale should persist on setting. This is hidden because it is really
127 * questionable whether this is the right way to expose the functionality.
128 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 */
130 public boolean userSetLocale;
131
Romain Guyc9ba5592017-01-18 16:34:42 -0800132
Romain Guy48327452017-01-23 17:03:35 -0800133 /** Constant for {@link #colorMode}: bits that encode whether the screen is wide gamut. */
134 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_MASK = 0x3;
Romain Guyc9ba5592017-01-18 16:34:42 -0800135 /**
Romain Guy48327452017-01-23 17:03:35 -0800136 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800137 * indicating that it is unknown whether or not the screen is wide gamut.
138 */
Romain Guy48327452017-01-23 17:03:35 -0800139 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED = 0x0;
Romain Guyc9ba5592017-01-18 16:34:42 -0800140 /**
Romain Guy48327452017-01-23 17:03:35 -0800141 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800142 * indicating that the screen is not wide gamut.
143 * <p>Corresponds to the <code>-nowidecg</code> resource qualifier.</p>
144 */
Romain Guy48327452017-01-23 17:03:35 -0800145 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_NO = 0x1;
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 wide gamut.
149 * <p>Corresponds to the <code>-widecg</code> resource qualifier.</p>
150 */
Romain Guy48327452017-01-23 17:03:35 -0800151 public static final int COLOR_MODE_WIDE_COLOR_GAMUT_YES = 0x2;
Romain Guyc9ba5592017-01-18 16:34:42 -0800152
Romain Guyb3f69262017-04-13 20:06:41 -0700153 /** Constant for {@link #colorMode}: bits that encode the dynamic range of the screen. */
Romain Guy48327452017-01-23 17:03:35 -0800154 public static final int COLOR_MODE_HDR_MASK = 0xc;
155 /** Constant for {@link #colorMode}: bits shift to get the screen dynamic range. */
156 public static final int COLOR_MODE_HDR_SHIFT = 2;
Romain Guyc9ba5592017-01-18 16:34:42 -0800157 /**
Romain Guy48327452017-01-23 17:03:35 -0800158 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_HDR_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800159 * indicating that it is unknown whether or not the screen is HDR.
160 */
Romain Guy48327452017-01-23 17:03:35 -0800161 public static final int COLOR_MODE_HDR_UNDEFINED = 0x0;
Romain Guyc9ba5592017-01-18 16:34:42 -0800162 /**
Romain Guy48327452017-01-23 17:03:35 -0800163 * Constant for {@link #colorMode}: a {@link #COLOR_MODE_HDR_MASK} value
Romain Guyc9ba5592017-01-18 16:34:42 -0800164 * indicating that the screen is not HDR (low/standard dynamic range).
165 * <p>Corresponds to the <code>-lowdr</code> resource qualifier.</p>
166 */
Romain Guy48327452017-01-23 17:03:35 -0800167 public static final int COLOR_MODE_HDR_NO = 0x1 << COLOR_MODE_HDR_SHIFT;
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 HDR (dynamic range).
171 * <p>Corresponds to the <code>-highdr</code> resource qualifier.</p>
172 */
Romain Guy48327452017-01-23 17:03:35 -0800173 public static final int COLOR_MODE_HDR_YES = 0x2 << 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 value indicating that the color mode is undefined */
Romain Guyc9ba5592017-01-18 16:34:42 -0800176 @SuppressWarnings("PointlessBitwiseExpression")
Romain Guy48327452017-01-23 17:03:35 -0800177 public static final int COLOR_MODE_UNDEFINED = COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED |
178 COLOR_MODE_HDR_UNDEFINED;
Romain Guyc9ba5592017-01-18 16:34:42 -0800179
180 /**
Romain Guyb3f69262017-04-13 20:06:41 -0700181 * Bit mask of color capabilities of the screen. Currently there are two fields:
Romain Guy48327452017-01-23 17:03:35 -0800182 * <p>The {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} bits define the color gamut of
Romain Guyc9ba5592017-01-18 16:34:42 -0800183 * the screen. They may be one of
Romain Guy48327452017-01-23 17:03:35 -0800184 * {@link #COLOR_MODE_WIDE_COLOR_GAMUT_NO} or {@link #COLOR_MODE_WIDE_COLOR_GAMUT_YES}.</p>
Romain Guyc9ba5592017-01-18 16:34:42 -0800185 *
Romain Guy48327452017-01-23 17:03:35 -0800186 * <p>The {@link #COLOR_MODE_HDR_MASK} defines the dynamic range of the screen. They may be
187 * one of {@link #COLOR_MODE_HDR_NO} or {@link #COLOR_MODE_HDR_YES}.</p>
Romain Guyc9ba5592017-01-18 16:34:42 -0800188 *
189 * <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
190 * Multiple Screens</a> for more information.</p>
191 */
Romain Guy48327452017-01-23 17:03:35 -0800192 public int colorMode;
Romain Guyc9ba5592017-01-18 16:34:42 -0800193
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700194 /** Constant for {@link #screenLayout}: bits that encode the size. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700195 public static final int SCREENLAYOUT_SIZE_MASK = 0x0f;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700196 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
197 * value indicating that no size has been set. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700198 public static final int SCREENLAYOUT_SIZE_UNDEFINED = 0x00;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700199 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700200 * value indicating the screen is at least approximately 320x426 dp units,
201 * corresponds to the
202 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">small</a>
203 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700204 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
205 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700206 public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700207 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700208 * value indicating the screen is at least approximately 320x470 dp units,
209 * corresponds to the
210 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">normal</a>
211 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700212 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
213 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700214 public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700215 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700216 * value indicating the screen is at least approximately 480x640 dp units,
217 * corresponds to the
218 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">large</a>
219 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700220 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
221 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700222 public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700223 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700224 * value indicating the screen is at least approximately 720x960 dp units,
225 * corresponds to the
226 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">xlarge</a>
227 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700228 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
229 * Multiple Screens</a> for more information.*/
Dianne Hackborn14cee9f2010-04-23 17:51:26 -0700230 public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700231
232 /** Constant for {@link #screenLayout}: bits that encode the aspect ratio. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700233 public static final int SCREENLAYOUT_LONG_MASK = 0x30;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700234 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
235 * value indicating that no size has been set. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700236 public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700237 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
238 * value that corresponds to the
239 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">notlong</a>
240 * resource qualifier. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700241 public static final int SCREENLAYOUT_LONG_NO = 0x10;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700242 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
243 * value that corresponds to the
244 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">long</a>
245 * resource qualifier. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700246 public static final int SCREENLAYOUT_LONG_YES = 0x20;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700247
248 /** Constant for {@link #screenLayout}: bits that encode the layout direction. */
249 public static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
250 /** Constant for {@link #screenLayout}: bits shift to get the layout direction. */
251 public static final int SCREENLAYOUT_LAYOUTDIR_SHIFT = 6;
252 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
253 * value indicating that no layout dir has been set. */
254 public static final int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0x00;
255 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
256 * value indicating that a layout dir has been set to LTR. */
257 public static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x01 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
258 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
259 * value indicating that a layout dir has been set to RTL. */
260 public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x02 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
261
Adam Powell49e7ff92015-05-14 16:18:53 -0700262 /** Constant for {@link #screenLayout}: bits that encode roundness of the screen. */
263 public static final int SCREENLAYOUT_ROUND_MASK = 0x300;
264 /** @hide Constant for {@link #screenLayout}: bit shift to get to screen roundness bits */
265 public static final int SCREENLAYOUT_ROUND_SHIFT = 8;
266 /**
267 * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
268 * that it is unknown whether or not the screen has a round shape.
269 */
270 public static final int SCREENLAYOUT_ROUND_UNDEFINED = 0x00;
271 /**
272 * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
273 * that the screen does not have a rounded shape.
274 */
275 public static final int SCREENLAYOUT_ROUND_NO = 0x1 << SCREENLAYOUT_ROUND_SHIFT;
276 /**
277 * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
278 * that the screen has a rounded shape. Corners may not be visible to the user;
279 * developers should pay special attention to the {@link android.view.WindowInsets} delivered
280 * to views for more information about ensuring content is not obscured.
281 *
282 * <p>Corresponds to the <code>-round</code> resource qualifier.</p>
283 */
284 public static final int SCREENLAYOUT_ROUND_YES = 0x2 << SCREENLAYOUT_ROUND_SHIFT;
285
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700286 /** Constant for {@link #screenLayout}: a value indicating that screenLayout is undefined */
287 public static final int SCREENLAYOUT_UNDEFINED = SCREENLAYOUT_SIZE_UNDEFINED |
Adam Powell49e7ff92015-05-14 16:18:53 -0700288 SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED |
289 SCREENLAYOUT_ROUND_UNDEFINED;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700290
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700291 /**
292 * Special flag we generate to indicate that the screen layout requires
293 * us to use a compatibility mode for apps that are not modern layout
294 * aware.
295 * @hide
296 */
297 public static final int SCREENLAYOUT_COMPAT_NEEDED = 0x10000000;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700298
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700299 /**
Andrii Kulianf12fce12016-05-27 17:30:16 -0700300 * Bit mask of overall layout of the screen. Currently there are four
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700301 * fields:
302 * <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
303 * of the screen. They may be one of
304 * {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
Adam Powell49e7ff92015-05-14 16:18:53 -0700305 * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.</p>
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700306 *
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700307 * <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
308 * is wider/taller than normal. They may be one of
Adam Powell49e7ff92015-05-14 16:18:53 -0700309 * {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.</p>
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700310 *
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700311 * <p>The {@link #SCREENLAYOUT_LAYOUTDIR_MASK} defines whether the screen layout
312 * is either LTR or RTL. They may be one of
Adam Powell49e7ff92015-05-14 16:18:53 -0700313 * {@link #SCREENLAYOUT_LAYOUTDIR_LTR} or {@link #SCREENLAYOUT_LAYOUTDIR_RTL}.</p>
314 *
315 * <p>The {@link #SCREENLAYOUT_ROUND_MASK} defines whether the screen has a rounded
316 * shape. They may be one of {@link #SCREENLAYOUT_ROUND_NO} or {@link #SCREENLAYOUT_ROUND_YES}.
317 * </p>
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700318 *
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700319 * <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
Adam Powell49e7ff92015-05-14 16:18:53 -0700320 * Multiple Screens</a> for more information.</p>
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700321 */
322 public int screenLayout;
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -0700323
Bryce Lee7566d762017-03-30 09:34:15 -0700324 /**
Wale Ogunwale822e5122017-07-26 06:02:24 -0700325 * Configuration relating to the windowing state of the object associated with this
326 * Configuration. Contents of this field are not intended to affect resources, but need to be
327 * communicated and propagated at the same time as the rest of Configuration.
Wale Ogunwale0d5609b2017-09-13 05:55:07 -0700328 * @hide
Bryce Lee7566d762017-03-30 09:34:15 -0700329 */
Wale Ogunwale0d5609b2017-09-13 05:55:07 -0700330 @TestApi
Wale Ogunwale822e5122017-07-26 06:02:24 -0700331 public final WindowConfiguration windowConfiguration = new WindowConfiguration();
Bryce Lee7566d762017-03-30 09:34:15 -0700332
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -0700333 /** @hide */
334 static public int resetScreenLayout(int curLayout) {
335 return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK
336 | SCREENLAYOUT_COMPAT_NEEDED))
337 | (SCREENLAYOUT_LONG_YES | SCREENLAYOUT_SIZE_XLARGE);
338 }
339
340 /** @hide */
341 static public int reduceScreenLayout(int curLayout, int longSizeDp, int shortSizeDp) {
342 int screenLayoutSize;
343 boolean screenLayoutLong;
344 boolean screenLayoutCompatNeeded;
345
346 // These semi-magic numbers define our compatibility modes for
347 // applications with different screens. These are guarantees to
348 // app developers about the space they can expect for a particular
349 // configuration. DO NOT CHANGE!
350 if (longSizeDp < 470) {
351 // This is shorter than an HVGA normal density screen (which
352 // is 480 pixels on its long side).
353 screenLayoutSize = SCREENLAYOUT_SIZE_SMALL;
354 screenLayoutLong = false;
355 screenLayoutCompatNeeded = false;
356 } else {
357 // What size is this screen screen?
358 if (longSizeDp >= 960 && shortSizeDp >= 720) {
359 // 1.5xVGA or larger screens at medium density are the point
360 // at which we consider it to be an extra large screen.
361 screenLayoutSize = SCREENLAYOUT_SIZE_XLARGE;
362 } else if (longSizeDp >= 640 && shortSizeDp >= 480) {
363 // VGA or larger screens at medium density are the point
364 // at which we consider it to be a large screen.
365 screenLayoutSize = SCREENLAYOUT_SIZE_LARGE;
366 } else {
367 screenLayoutSize = SCREENLAYOUT_SIZE_NORMAL;
368 }
369
370 // If this screen is wider than normal HVGA, or taller
371 // than FWVGA, then for old apps we want to run in size
372 // compatibility mode.
373 if (shortSizeDp > 321 || longSizeDp > 570) {
374 screenLayoutCompatNeeded = true;
375 } else {
376 screenLayoutCompatNeeded = false;
377 }
378
379 // Is this a long screen?
380 if (((longSizeDp*3)/5) >= (shortSizeDp-1)) {
381 // Anything wider than WVGA (5:3) is considering to be long.
382 screenLayoutLong = true;
383 } else {
384 screenLayoutLong = false;
385 }
386 }
387
388 // Now reduce the last screenLayout to not be better than what we
389 // have found.
390 if (!screenLayoutLong) {
391 curLayout = (curLayout&~SCREENLAYOUT_LONG_MASK) | SCREENLAYOUT_LONG_NO;
392 }
393 if (screenLayoutCompatNeeded) {
394 curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
395 }
396 int curSize = curLayout&SCREENLAYOUT_SIZE_MASK;
397 if (screenLayoutSize < curSize) {
398 curLayout = (curLayout&~SCREENLAYOUT_SIZE_MASK) | screenLayoutSize;
399 }
400 return curLayout;
401 }
402
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700403 /** @hide */
404 public static String configurationDiffToString(int diff) {
405 ArrayList<String> list = new ArrayList<>();
406 if ((diff & ActivityInfo.CONFIG_MCC) != 0) {
407 list.add("CONFIG_MCC");
408 }
409 if ((diff & ActivityInfo.CONFIG_MNC) != 0) {
410 list.add("CONFIG_MNC");
411 }
412 if ((diff & ActivityInfo.CONFIG_LOCALE) != 0) {
413 list.add("CONFIG_LOCALE");
414 }
415 if ((diff & ActivityInfo.CONFIG_TOUCHSCREEN) != 0) {
416 list.add("CONFIG_TOUCHSCREEN");
417 }
418 if ((diff & ActivityInfo.CONFIG_KEYBOARD) != 0) {
419 list.add("CONFIG_KEYBOARD");
420 }
421 if ((diff & ActivityInfo.CONFIG_KEYBOARD_HIDDEN) != 0) {
422 list.add("CONFIG_KEYBOARD_HIDDEN");
423 }
424 if ((diff & ActivityInfo.CONFIG_NAVIGATION) != 0) {
425 list.add("CONFIG_NAVIGATION");
426 }
427 if ((diff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
428 list.add("CONFIG_ORIENTATION");
429 }
430 if ((diff & ActivityInfo.CONFIG_SCREEN_LAYOUT) != 0) {
431 list.add("CONFIG_SCREEN_LAYOUT");
432 }
Romain Guy48327452017-01-23 17:03:35 -0800433 if ((diff & ActivityInfo.CONFIG_COLOR_MODE) != 0) {
434 list.add("CONFIG_COLOR_MODE");
Romain Guyc9ba5592017-01-18 16:34:42 -0800435 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700436 if ((diff & ActivityInfo.CONFIG_UI_MODE) != 0) {
437 list.add("CONFIG_UI_MODE");
438 }
439 if ((diff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0) {
440 list.add("CONFIG_SCREEN_SIZE");
441 }
442 if ((diff & ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
443 list.add("CONFIG_SMALLEST_SCREEN_SIZE");
444 }
445 if ((diff & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0) {
446 list.add("CONFIG_LAYOUT_DIRECTION");
447 }
448 if ((diff & ActivityInfo.CONFIG_FONT_SCALE) != 0) {
449 list.add("CONFIG_FONT_SCALE");
450 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100451 if ((diff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
452 list.add("CONFIG_ASSETS_PATHS");
453 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700454 StringBuilder builder = new StringBuilder("{");
455 for (int i = 0, n = list.size(); i < n; i++) {
456 builder.append(list.get(i));
457 if (i != n - 1) {
458 builder.append(", ");
459 }
460 }
461 builder.append("}");
462 return builder.toString();
463 }
464
Dianne Hackborn711e62a2010-11-29 16:38:22 -0800465 /**
466 * Check if the Configuration's current {@link #screenLayout} is at
467 * least the given size.
468 *
469 * @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
470 * {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
471 * {@link #SCREENLAYOUT_SIZE_XLARGE}.
472 * @return Returns true if the current screen layout size is at least
473 * the given size.
474 */
475 public boolean isLayoutSizeAtLeast(int size) {
476 int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
477 if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
Dianne Hackborn7d3a5bc2010-11-29 22:52:12 -0800478 return cur >= size;
Dianne Hackborn711e62a2010-11-29 16:38:22 -0800479 }
480
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700481 /** Constant for {@link #touchscreen}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 public static final int TOUCHSCREEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700483 /** Constant for {@link #touchscreen}, value corresponding to the
484 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#TouchscreenQualifier">notouch</a>
485 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 public static final int TOUCHSCREEN_NOTOUCH = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700487 /** @deprecated Not currently supported or used. */
488 @Deprecated public static final int TOUCHSCREEN_STYLUS = 2;
489 /** Constant for {@link #touchscreen}, value corresponding to the
490 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#TouchscreenQualifier">finger</a>
491 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 public static final int TOUCHSCREEN_FINGER = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 /**
495 * The kind of touch screen attached to the device.
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700496 * One of: {@link #TOUCHSCREEN_NOTOUCH}, {@link #TOUCHSCREEN_FINGER}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 */
498 public int touchscreen;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700499
500 /** Constant for {@link #keyboard}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 public static final int KEYBOARD_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700502 /** Constant for {@link #keyboard}, value corresponding to the
503 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">nokeys</a>
504 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 public static final int KEYBOARD_NOKEYS = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700506 /** Constant for {@link #keyboard}, value corresponding to the
507 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">qwerty</a>
508 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 public static final int KEYBOARD_QWERTY = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700510 /** Constant for {@link #keyboard}, value corresponding to the
511 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">12key</a>
512 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 public static final int KEYBOARD_12KEY = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 /**
516 * The kind of keyboard attached to the device.
Kenny Root507f8ed2009-06-09 11:21:11 -0500517 * One of: {@link #KEYBOARD_NOKEYS}, {@link #KEYBOARD_QWERTY},
518 * {@link #KEYBOARD_12KEY}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 */
520 public int keyboard;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700521
522 /** Constant for {@link #keyboardHidden}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700524 /** Constant for {@link #keyboardHidden}, value corresponding to the
525 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keysexposed</a>
526 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 public static final int KEYBOARDHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700528 /** Constant for {@link #keyboardHidden}, value corresponding to the
529 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyshidden</a>
530 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 public static final int KEYBOARDHIDDEN_YES = 2;
532 /** Constant matching actual resource implementation. {@hide} */
533 public static final int KEYBOARDHIDDEN_SOFT = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 /**
536 * A flag indicating whether any keyboard is available. Unlike
537 * {@link #hardKeyboardHidden}, this also takes into account a soft
538 * keyboard, so if the hard keyboard is hidden but there is soft
539 * keyboard available, it will be set to NO. Value is one of:
540 * {@link #KEYBOARDHIDDEN_NO}, {@link #KEYBOARDHIDDEN_YES}.
541 */
542 public int keyboardHidden;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700543
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700544 /** Constant for {@link #hardKeyboardHidden}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700546 /** Constant for {@link #hardKeyboardHidden}, value corresponding to the
547 * physical keyboard being exposed. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 public static final int HARDKEYBOARDHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700549 /** Constant for {@link #hardKeyboardHidden}, value corresponding to the
550 * physical keyboard being hidden. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 public static final int HARDKEYBOARDHIDDEN_YES = 2;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 /**
554 * A flag indicating whether the hard keyboard has been hidden. This will
555 * be set on a device with a mechanism to hide the keyboard from the
556 * user, when that mechanism is closed. One of:
557 * {@link #HARDKEYBOARDHIDDEN_NO}, {@link #HARDKEYBOARDHIDDEN_YES}.
558 */
559 public int hardKeyboardHidden;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700560
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700561 /** Constant for {@link #navigation}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 public static final int NAVIGATION_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700563 /** Constant for {@link #navigation}, value corresponding to the
564 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">nonav</a>
565 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 public static final int NAVIGATION_NONAV = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700567 /** Constant for {@link #navigation}, value corresponding to the
568 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">dpad</a>
569 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 public static final int NAVIGATION_DPAD = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700571 /** Constant for {@link #navigation}, value corresponding to the
572 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">trackball</a>
573 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 public static final int NAVIGATION_TRACKBALL = 3;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700575 /** Constant for {@link #navigation}, value corresponding to the
576 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">wheel</a>
577 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 public static final int NAVIGATION_WHEEL = 4;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 /**
581 * The kind of navigation method available on the device.
Kenny Root507f8ed2009-06-09 11:21:11 -0500582 * One of: {@link #NAVIGATION_NONAV}, {@link #NAVIGATION_DPAD},
583 * {@link #NAVIGATION_TRACKBALL}, {@link #NAVIGATION_WHEEL}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 */
585 public int navigation;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700586
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700587 /** Constant for {@link #navigationHidden}: a value indicating that no value has been set. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700588 public static final int NAVIGATIONHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700589 /** Constant for {@link #navigationHidden}, value corresponding to the
590 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavAvailQualifier">navexposed</a>
591 * resource qualifier. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700592 public static final int NAVIGATIONHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700593 /** Constant for {@link #navigationHidden}, value corresponding to the
594 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavAvailQualifier">navhidden</a>
595 * resource qualifier. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700596 public static final int NAVIGATIONHIDDEN_YES = 2;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700597
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700598 /**
599 * A flag indicating whether any 5-way or DPAD navigation available.
600 * This will be set on a device with a mechanism to hide the navigation
601 * controls from the user, when that mechanism is closed. One of:
602 * {@link #NAVIGATIONHIDDEN_NO}, {@link #NAVIGATIONHIDDEN_YES}.
603 */
604 public int navigationHidden;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700605
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700606 /** Constant for {@link #orientation}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 public static final int ORIENTATION_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700608 /** Constant for {@link #orientation}, value corresponding to the
609 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#OrientationQualifier">port</a>
610 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 public static final int ORIENTATION_PORTRAIT = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700612 /** Constant for {@link #orientation}, value corresponding to the
613 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#OrientationQualifier">land</a>
614 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 public static final int ORIENTATION_LANDSCAPE = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700616 /** @deprecated Not currently supported or used. */
617 @Deprecated public static final int ORIENTATION_SQUARE = 3;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 /**
620 * Overall orientation of the screen. May be one of
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700621 * {@link #ORIENTATION_LANDSCAPE}, {@link #ORIENTATION_PORTRAIT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 */
623 public int orientation;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100624
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700625 /** Constant for {@link #uiMode}: bits that encode the mode type. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100626 public static final int UI_MODE_TYPE_MASK = 0x0f;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700627 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
628 * value indicating that no mode type has been set. */
Dianne Hackbornef05e072010-03-01 17:43:39 -0800629 public static final int UI_MODE_TYPE_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700630 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
631 * value that corresponds to
632 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">no
633 * UI mode</a> resource qualifier specified. */
Dianne Hackbornef05e072010-03-01 17:43:39 -0800634 public static final int UI_MODE_TYPE_NORMAL = 0x01;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700635 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
636 * value that corresponds to the
637 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">desk</a>
638 * resource qualifier. */
Dianne Hackborn7299c412010-03-04 18:41:49 -0800639 public static final int UI_MODE_TYPE_DESK = 0x02;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700640 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
641 * value that corresponds to the
642 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">car</a>
643 * resource qualifier. */
Dianne Hackborn7299c412010-03-04 18:41:49 -0800644 public static final int UI_MODE_TYPE_CAR = 0x03;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700645 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
646 * value that corresponds to the
647 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">television</a>
648 * resource qualifier. */
Dianne Hackborne360bb62011-05-20 16:11:04 -0700649 public static final int UI_MODE_TYPE_TELEVISION = 0x04;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700650 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
651 * value that corresponds to the
652 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">appliance</a>
653 * resource qualifier. */
Joe Onorato44fcb832011-12-14 20:59:30 -0800654 public static final int UI_MODE_TYPE_APPLIANCE = 0x05;
John Spurlock6c191292014-04-03 16:37:27 -0400655 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
656 * value that corresponds to the
657 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">watch</a>
658 * resource qualifier. */
659 public static final int UI_MODE_TYPE_WATCH = 0x06;
Zak Cohen1a6acdb2016-12-12 15:21:21 -0800660 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
661 * value that corresponds to the
662 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">vrheadset</a>
663 * resource qualifier. */
664 public static final int UI_MODE_TYPE_VR_HEADSET = 0x07;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100665
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700666 /** Constant for {@link #uiMode}: bits that encode the night mode. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100667 public static final int UI_MODE_NIGHT_MASK = 0x30;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700668 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
669 * value indicating that no mode type has been set. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100670 public static final int UI_MODE_NIGHT_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700671 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
672 * value that corresponds to the
673 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NightQualifier">notnight</a>
674 * resource qualifier. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100675 public static final int UI_MODE_NIGHT_NO = 0x10;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700676 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
677 * value that corresponds to the
678 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NightQualifier">night</a>
679 * resource qualifier. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100680 public static final int UI_MODE_NIGHT_YES = 0x20;
681
682 /**
683 * Bit mask of the ui mode. Currently there are two fields:
684 * <p>The {@link #UI_MODE_TYPE_MASK} bits define the overall ui mode of the
Dianne Hackborn7299c412010-03-04 18:41:49 -0800685 * device. They may be one of {@link #UI_MODE_TYPE_UNDEFINED},
686 * {@link #UI_MODE_TYPE_NORMAL}, {@link #UI_MODE_TYPE_DESK},
John Spurlock6c191292014-04-03 16:37:27 -0400687 * {@link #UI_MODE_TYPE_CAR}, {@link #UI_MODE_TYPE_TELEVISION},
Zak Cohen1a6acdb2016-12-12 15:21:21 -0800688 * {@link #UI_MODE_TYPE_APPLIANCE}, {@link #UI_MODE_TYPE_WATCH},
689 * or {@link #UI_MODE_TYPE_VR_HEADSET}.
Tobias Haamel27b28b32010-02-09 23:09:17 +0100690 *
691 * <p>The {@link #UI_MODE_NIGHT_MASK} defines whether the screen
Dianne Hackborn7299c412010-03-04 18:41:49 -0800692 * is in a special mode. They may be one of {@link #UI_MODE_NIGHT_UNDEFINED},
Tobias Haamel27b28b32010-02-09 23:09:17 +0100693 * {@link #UI_MODE_NIGHT_NO} or {@link #UI_MODE_NIGHT_YES}.
Tobias Haamel27b28b32010-02-09 23:09:17 +0100694 */
695 public int uiMode;
696
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700697 /**
698 * Default value for {@link #screenWidthDp} indicating that no width
699 * has been specified.
700 */
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700701 public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
702
703 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700704 * The current width of the available screen space, in dp units,
705 * corresponding to
706 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenWidthQualifier">screen
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700707 * width</a> resource qualifier. Set to
708 * {@link #SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700709 */
710 public int screenWidthDp;
711
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700712 /**
713 * Default value for {@link #screenHeightDp} indicating that no width
714 * has been specified.
715 */
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700716 public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
717
718 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700719 * The current height of the available screen space, in dp units,
720 * corresponding to
721 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenHeightQualifier">screen
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700722 * height</a> resource qualifier. Set to
723 * {@link #SCREEN_HEIGHT_DP_UNDEFINED} if no height is specified.
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700724 */
725 public int screenHeightDp;
726
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700727 /**
728 * Default value for {@link #smallestScreenWidthDp} indicating that no width
729 * has been specified.
730 */
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700731 public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0;
732
733 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700734 * The smallest screen size an application will see in normal operation,
735 * corresponding to
736 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">smallest
737 * screen width</a> resource qualifier.
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700738 * This is the smallest value of both screenWidthDp and screenHeightDp
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700739 * in both portrait and landscape. Set to
740 * {@link #SMALLEST_SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700741 */
742 public int smallestScreenWidthDp;
743
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700744 /**
745 * Default value for {@link #densityDpi} indicating that no width
746 * has been specified.
747 */
748 public static final int DENSITY_DPI_UNDEFINED = 0;
749
750 /**
Adam Lesinski31245b42014-08-22 19:10:56 -0700751 * Value for {@link #densityDpi} for resources that scale to any density (vector drawables).
752 * {@hide}
753 */
754 public static final int DENSITY_DPI_ANY = 0xfffe;
755
756 /**
757 * Value for {@link #densityDpi} for resources that are not meant to be scaled.
758 * {@hide}
759 */
760 public static final int DENSITY_DPI_NONE = 0xffff;
761
762 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700763 * The target screen density being rendered to,
764 * corresponding to
765 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#DensityQualifier">density</a>
766 * resource qualifier. Set to
767 * {@link #DENSITY_DPI_UNDEFINED} if no density is specified.
768 */
769 public int densityDpi;
770
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700771 /** @hide Hack to get this information from WM to app running in compat mode. */
772 public int compatScreenWidthDp;
773 /** @hide Hack to get this information from WM to app running in compat mode. */
774 public int compatScreenHeightDp;
775 /** @hide Hack to get this information from WM to app running in compat mode. */
776 public int compatSmallestScreenWidthDp;
777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 /**
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100779 * An undefined assetsSeq. This will not override an existing assetsSeq.
780 * @hide
781 */
782 public static final int ASSETS_SEQ_UNDEFINED = 0;
783
784 /**
785 * Internal counter that allows us to piggyback off the configuration change mechanism to
786 * signal to apps that the the assets for an Application have changed. A difference in these
787 * between two Configurations will yield a diff flag of
788 * {@link ActivityInfo#CONFIG_ASSETS_PATHS}.
789 * @hide
790 */
791 public int assetsSeq;
792
793 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800794 * @hide Internal book-keeping.
795 */
796 public int seq;
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700797
Alan Viveretteac85f902016-03-11 15:15:51 -0500798 /** @hide */
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700799 @IntDef(flag = true, prefix = { "NATIVE_CONFIG_" }, value = {
800 NATIVE_CONFIG_MCC,
801 NATIVE_CONFIG_MNC,
802 NATIVE_CONFIG_LOCALE,
803 NATIVE_CONFIG_TOUCHSCREEN,
804 NATIVE_CONFIG_KEYBOARD,
805 NATIVE_CONFIG_KEYBOARD_HIDDEN,
806 NATIVE_CONFIG_NAVIGATION,
807 NATIVE_CONFIG_ORIENTATION,
808 NATIVE_CONFIG_DENSITY,
809 NATIVE_CONFIG_SCREEN_SIZE,
810 NATIVE_CONFIG_VERSION,
811 NATIVE_CONFIG_SCREEN_LAYOUT,
812 NATIVE_CONFIG_UI_MODE,
813 NATIVE_CONFIG_SMALLEST_SCREEN_SIZE,
814 NATIVE_CONFIG_LAYOUTDIR,
815 NATIVE_CONFIG_COLOR_MODE,
816 })
Alan Viveretteac85f902016-03-11 15:15:51 -0500817 @Retention(RetentionPolicy.SOURCE)
818 public @interface NativeConfig {}
819
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700820 /** @hide Native-specific bit mask for MCC config; DO NOT USE UNLESS YOU ARE SURE. */
821 public static final int NATIVE_CONFIG_MCC = 0x0001;
822 /** @hide Native-specific bit mask for MNC config; DO NOT USE UNLESS YOU ARE SURE. */
823 public static final int NATIVE_CONFIG_MNC = 0x0002;
824 /** @hide Native-specific bit mask for LOCALE config; DO NOT USE UNLESS YOU ARE SURE. */
825 public static final int NATIVE_CONFIG_LOCALE = 0x0004;
826 /** @hide Native-specific bit mask for TOUCHSCREEN config; DO NOT USE UNLESS YOU ARE SURE. */
827 public static final int NATIVE_CONFIG_TOUCHSCREEN = 0x0008;
828 /** @hide Native-specific bit mask for KEYBOARD config; DO NOT USE UNLESS YOU ARE SURE. */
829 public static final int NATIVE_CONFIG_KEYBOARD = 0x0010;
830 /** @hide Native-specific bit mask for KEYBOARD_HIDDEN config; DO NOT USE UNLESS YOU
831 * ARE SURE. */
832 public static final int NATIVE_CONFIG_KEYBOARD_HIDDEN = 0x0020;
833 /** @hide Native-specific bit mask for NAVIGATION config; DO NOT USE UNLESS YOU ARE SURE. */
834 public static final int NATIVE_CONFIG_NAVIGATION = 0x0040;
835 /** @hide Native-specific bit mask for ORIENTATION config; DO NOT USE UNLESS YOU ARE SURE. */
836 public static final int NATIVE_CONFIG_ORIENTATION = 0x0080;
837 /** @hide Native-specific bit mask for DENSITY config; DO NOT USE UNLESS YOU ARE SURE. */
838 public static final int NATIVE_CONFIG_DENSITY = 0x0100;
839 /** @hide Native-specific bit mask for SCREEN_SIZE config; DO NOT USE UNLESS YOU ARE SURE. */
840 public static final int NATIVE_CONFIG_SCREEN_SIZE = 0x0200;
841 /** @hide Native-specific bit mask for VERSION config; DO NOT USE UNLESS YOU ARE SURE. */
842 public static final int NATIVE_CONFIG_VERSION = 0x0400;
843 /** @hide Native-specific bit mask for SCREEN_LAYOUT config; DO NOT USE UNLESS YOU ARE SURE. */
844 public static final int NATIVE_CONFIG_SCREEN_LAYOUT = 0x0800;
845 /** @hide Native-specific bit mask for UI_MODE config; DO NOT USE UNLESS YOU ARE SURE. */
846 public static final int NATIVE_CONFIG_UI_MODE = 0x1000;
847 /** @hide Native-specific bit mask for SMALLEST_SCREEN_SIZE config; DO NOT USE UNLESS YOU
848 * ARE SURE. */
849 public static final int NATIVE_CONFIG_SMALLEST_SCREEN_SIZE = 0x2000;
850 /** @hide Native-specific bit mask for LAYOUTDIR config ; DO NOT USE UNLESS YOU ARE SURE.*/
851 public static final int NATIVE_CONFIG_LAYOUTDIR = 0x4000;
Romain Guy48327452017-01-23 17:03:35 -0800852 /** @hide Native-specific bit mask for COLOR_MODE config ; DO NOT USE UNLESS YOU ARE SURE.*/
853 public static final int NATIVE_CONFIG_COLOR_MODE = 0x10000;
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700854
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800855 /**
Adam Lesinskibad43fc2016-07-19 13:35:01 -0700856 * <p>Construct an invalid Configuration. This state is only suitable for constructing a
857 * Configuration delta that will be applied to some valid Configuration object. In order to
858 * create a valid standalone Configuration, you must call {@link #setToDefaults}. </p>
859 *
860 * <p>Example:</p>
861 * <pre class="prettyprint">
862 * Configuration validConfig = new Configuration();
863 * validConfig.setToDefaults();
864 *
865 * Configuration deltaOnlyConfig = new Configuration();
866 * deltaOnlyConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
867 *
868 * validConfig.updateFrom(deltaOnlyConfig);
869 * </pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 */
871 public Configuration() {
Adam Lesinskibad43fc2016-07-19 13:35:01 -0700872 unset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 }
874
875 /**
876 * Makes a deep copy suitable for modification.
877 */
878 public Configuration(Configuration o) {
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700879 setTo(o);
880 }
881
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700882 /* This brings mLocaleList in sync with locale in case a user of the older API who doesn't know
883 * about setLocales() has changed locale directly. */
884 private void fixUpLocaleList() {
885 if ((locale == null && !mLocaleList.isEmpty()) ||
Roozbeh Pournaderfee44842016-02-04 15:24:24 -0800886 (locale != null && !locale.equals(mLocaleList.get(0)))) {
Raph Levien10ea92a2016-05-02 12:56:01 -0700887 mLocaleList = locale == null ? LocaleList.getEmptyLocaleList() : new LocaleList(locale);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700888 }
889 }
890
Chet Haased30149e2017-01-13 12:55:16 -0800891 /**
892 * Sets the fields in this object to those in the given Configuration.
893 *
894 * @param o The Configuration object used to set the values of this Configuration's fields.
895 */
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700896 public void setTo(Configuration o) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 fontScale = o.fontScale;
898 mcc = o.mcc;
899 mnc = o.mnc;
Roozbeh Pournader8a412e02015-12-02 18:39:50 -0800900 locale = o.locale == null ? null : (Locale) o.locale.clone();
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700901 o.fixUpLocaleList();
902 mLocaleList = o.mLocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 userSetLocale = o.userSetLocale;
904 touchscreen = o.touchscreen;
905 keyboard = o.keyboard;
906 keyboardHidden = o.keyboardHidden;
907 hardKeyboardHidden = o.hardKeyboardHidden;
908 navigation = o.navigation;
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700909 navigationHidden = o.navigationHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 orientation = o.orientation;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700911 screenLayout = o.screenLayout;
Romain Guy48327452017-01-23 17:03:35 -0800912 colorMode = o.colorMode;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100913 uiMode = o.uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700914 screenWidthDp = o.screenWidthDp;
915 screenHeightDp = o.screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700916 smallestScreenWidthDp = o.smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700917 densityDpi = o.densityDpi;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700918 compatScreenWidthDp = o.compatScreenWidthDp;
919 compatScreenHeightDp = o.compatScreenHeightDp;
920 compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +0100921 assetsSeq = o.assetsSeq;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800922 seq = o.seq;
Wale Ogunwale822e5122017-07-26 06:02:24 -0700923 windowConfiguration.setTo(o.windowConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700927 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn29735682011-04-21 17:26:39 -0700928 sb.append("{");
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700929 sb.append(fontScale);
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700930 sb.append(" ");
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700931 if (mcc != 0) {
932 sb.append(mcc);
933 sb.append("mcc");
934 } else {
935 sb.append("?mcc");
936 }
937 if (mnc != 0) {
938 sb.append(mnc);
939 sb.append("mnc");
940 } else {
941 sb.append("?mnc");
942 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700943 fixUpLocaleList();
944 if (!mLocaleList.isEmpty()) {
Dianne Hackborn9a849832011-04-07 15:11:57 -0700945 sb.append(" ");
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700946 sb.append(mLocaleList);
Dianne Hackborn9a849832011-04-07 15:11:57 -0700947 } else {
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -0700948 sb.append(" ?localeList");
Daniel Sandler7d6bddc2010-07-22 16:11:55 -0400949 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700950 int layoutDir = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK);
951 switch (layoutDir) {
952 case SCREENLAYOUT_LAYOUTDIR_UNDEFINED: sb.append(" ?layoutDir"); break;
Fabrice Di Meglio8a802db2012-09-05 13:12:02 -0700953 case SCREENLAYOUT_LAYOUTDIR_LTR: sb.append(" ldltr"); break;
954 case SCREENLAYOUT_LAYOUTDIR_RTL: sb.append(" ldrtl"); break;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700955 default: sb.append(" layoutDir=");
956 sb.append(layoutDir >> SCREENLAYOUT_LAYOUTDIR_SHIFT); break;
Fabrice Di Meglio7a736fb2011-06-09 20:20:36 -0700957 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700958 if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
959 sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
960 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700961 sb.append(" ?swdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700962 }
963 if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
964 sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");
965 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700966 sb.append(" ?wdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700967 }
968 if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
969 sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");
970 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700971 sb.append(" ?hdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700972 }
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700973 if (densityDpi != DENSITY_DPI_UNDEFINED) {
974 sb.append(" "); sb.append(densityDpi); sb.append("dpi");
975 } else {
976 sb.append(" ?density");
977 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700978 switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {
979 case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;
980 case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break;
981 case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break;
982 case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break;
983 case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break;
984 default: sb.append(" layoutSize=");
985 sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break;
986 }
987 switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) {
988 case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break;
989 case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break;
990 case SCREENLAYOUT_LONG_YES: sb.append(" long"); break;
991 default: sb.append(" layoutLong=");
992 sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break;
993 }
Romain Guy48327452017-01-23 17:03:35 -0800994 switch ((colorMode &COLOR_MODE_HDR_MASK)) {
995 case COLOR_MODE_HDR_UNDEFINED: sb.append(" ?ldr"); break; // most likely not HDR
996 case COLOR_MODE_HDR_NO: /* ldr is not interesting to print */ break;
997 case COLOR_MODE_HDR_YES: sb.append(" hdr"); break;
Romain Guyc9ba5592017-01-18 16:34:42 -0800998 default: sb.append(" dynamicRange=");
Romain Guy48327452017-01-23 17:03:35 -0800999 sb.append(colorMode &COLOR_MODE_HDR_MASK); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001000 }
Romain Guy48327452017-01-23 17:03:35 -08001001 switch ((colorMode &COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
1002 case COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED: sb.append(" ?wideColorGamut"); break;
1003 case COLOR_MODE_WIDE_COLOR_GAMUT_NO: /* not wide is not interesting to print */ break;
1004 case COLOR_MODE_WIDE_COLOR_GAMUT_YES: sb.append(" widecg"); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001005 default: sb.append(" wideColorGamut=");
Romain Guy48327452017-01-23 17:03:35 -08001006 sb.append(colorMode &COLOR_MODE_WIDE_COLOR_GAMUT_MASK); break;
Romain Guyc9ba5592017-01-18 16:34:42 -08001007 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001008 switch (orientation) {
1009 case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break;
1010 case ORIENTATION_LANDSCAPE: sb.append(" land"); break;
1011 case ORIENTATION_PORTRAIT: sb.append(" port"); break;
1012 default: sb.append(" orien="); sb.append(orientation); break;
1013 }
1014 switch ((uiMode&UI_MODE_TYPE_MASK)) {
1015 case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
1016 case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
1017 case UI_MODE_TYPE_DESK: sb.append(" desk"); break;
1018 case UI_MODE_TYPE_CAR: sb.append(" car"); break;
Dianne Hackborne360bb62011-05-20 16:11:04 -07001019 case UI_MODE_TYPE_TELEVISION: sb.append(" television"); break;
Joe Onorato44fcb832011-12-14 20:59:30 -08001020 case UI_MODE_TYPE_APPLIANCE: sb.append(" appliance"); break;
John Spurlock6c191292014-04-03 16:37:27 -04001021 case UI_MODE_TYPE_WATCH: sb.append(" watch"); break;
Zak Cohen1a6acdb2016-12-12 15:21:21 -08001022 case UI_MODE_TYPE_VR_HEADSET: sb.append(" vrheadset"); break;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001023 default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break;
1024 }
1025 switch ((uiMode&UI_MODE_NIGHT_MASK)) {
1026 case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break;
1027 case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break;
1028 case UI_MODE_NIGHT_YES: sb.append(" night"); break;
1029 default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break;
1030 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07001031 switch (touchscreen) {
1032 case TOUCHSCREEN_UNDEFINED: sb.append(" ?touch"); break;
1033 case TOUCHSCREEN_NOTOUCH: sb.append(" -touch"); break;
1034 case TOUCHSCREEN_STYLUS: sb.append(" stylus"); break;
1035 case TOUCHSCREEN_FINGER: sb.append(" finger"); break;
1036 default: sb.append(" touch="); sb.append(touchscreen); break;
1037 }
1038 switch (keyboard) {
1039 case KEYBOARD_UNDEFINED: sb.append(" ?keyb"); break;
1040 case KEYBOARD_NOKEYS: sb.append(" -keyb"); break;
1041 case KEYBOARD_QWERTY: sb.append(" qwerty"); break;
1042 case KEYBOARD_12KEY: sb.append(" 12key"); break;
1043 default: sb.append(" keys="); sb.append(keyboard); break;
1044 }
1045 switch (keyboardHidden) {
1046 case KEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;
1047 case KEYBOARDHIDDEN_NO: sb.append("/v"); break;
1048 case KEYBOARDHIDDEN_YES: sb.append("/h"); break;
1049 case KEYBOARDHIDDEN_SOFT: sb.append("/s"); break;
1050 default: sb.append("/"); sb.append(keyboardHidden); break;
1051 }
1052 switch (hardKeyboardHidden) {
1053 case HARDKEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;
1054 case HARDKEYBOARDHIDDEN_NO: sb.append("/v"); break;
1055 case HARDKEYBOARDHIDDEN_YES: sb.append("/h"); break;
1056 default: sb.append("/"); sb.append(hardKeyboardHidden); break;
1057 }
1058 switch (navigation) {
1059 case NAVIGATION_UNDEFINED: sb.append(" ?nav"); break;
1060 case NAVIGATION_NONAV: sb.append(" -nav"); break;
1061 case NAVIGATION_DPAD: sb.append(" dpad"); break;
1062 case NAVIGATION_TRACKBALL: sb.append(" tball"); break;
1063 case NAVIGATION_WHEEL: sb.append(" wheel"); break;
1064 default: sb.append(" nav="); sb.append(navigation); break;
1065 }
1066 switch (navigationHidden) {
1067 case NAVIGATIONHIDDEN_UNDEFINED: sb.append("/?"); break;
1068 case NAVIGATIONHIDDEN_NO: sb.append("/v"); break;
1069 case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
1070 default: sb.append("/"); sb.append(navigationHidden); break;
1071 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07001072 sb.append(" winConfig="); sb.append(windowConfiguration);
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001073 if (assetsSeq != 0) {
1074 sb.append(" as.").append(assetsSeq);
1075 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001076 if (seq != 0) {
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001077 sb.append(" s.").append(seq);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001078 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001079 sb.append('}');
1080 return sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 }
1082
1083 /**
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001084 * Write to a protocol buffer output stream.
1085 * Protocol buffer message definition at {@link android.content.ConfigurationProto}
1086 *
1087 * @param protoOutputStream Stream to write the Configuration object to.
1088 * @param fieldId Field Id of the Configuration as defined in the parent message
1089 * @hide
1090 */
1091 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
1092 final long token = protoOutputStream.start(fieldId);
1093 protoOutputStream.write(FONT_SCALE, fontScale);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001094 protoOutputStream.write(MCC, mcc);
1095 protoOutputStream.write(MNC, mnc);
1096 mLocaleList.writeToProto(protoOutputStream, LOCALES);
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001097 protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001098 protoOutputStream.write(HDR_COLOR_MODE,
1099 (colorMode & Configuration.COLOR_MODE_HDR_MASK) >> COLOR_MODE_HDR_SHIFT);
1100 protoOutputStream.write(WIDE_COLOR_GAMUT,
1101 colorMode & Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_MASK);
1102 protoOutputStream.write(TOUCHSCREEN, touchscreen);
1103 protoOutputStream.write(KEYBOARD_HIDDEN, keyboardHidden);
1104 protoOutputStream.write(HARD_KEYBOARD_HIDDEN, hardKeyboardHidden);
1105 protoOutputStream.write(NAVIGATION, navigation);
1106 protoOutputStream.write(NAVIGATION_HIDDEN, navigationHidden);
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001107 protoOutputStream.write(ORIENTATION, orientation);
1108 protoOutputStream.write(UI_MODE, uiMode);
1109 protoOutputStream.write(SCREEN_WIDTH_DP, screenWidthDp);
1110 protoOutputStream.write(SCREEN_HEIGHT_DP, screenHeightDp);
1111 protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp);
1112 protoOutputStream.write(DENSITY_DPI, densityDpi);
1113 windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
1114 protoOutputStream.end(token);
1115 }
1116
1117 /**
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001118 * Write full {@link android.content.ResourcesConfigurationProto} to protocol buffer output
1119 * stream.
1120 *
1121 * @param protoOutputStream Stream to write the Configuration object to.
1122 * @param fieldId Field Id of the Configuration as defined in the parent message
1123 * @param metrics Current display information
1124 * @hide
1125 */
1126 public void writeResConfigToProto(ProtoOutputStream protoOutputStream, long fieldId,
1127 DisplayMetrics metrics) {
1128 final int width, height;
1129 if (metrics.widthPixels >= metrics.heightPixels) {
1130 width = metrics.widthPixels;
1131 height = metrics.heightPixels;
1132 } else {
1133 //noinspection SuspiciousNameCombination
1134 width = metrics.heightPixels;
1135 //noinspection SuspiciousNameCombination
1136 height = metrics.widthPixels;
1137 }
1138
1139 final long token = protoOutputStream.start(fieldId);
1140 writeToProto(protoOutputStream, CONFIGURATION);
1141 protoOutputStream.write(SDK_VERSION, Build.VERSION.RESOURCES_SDK_INT);
1142 protoOutputStream.write(SCREEN_WIDTH_PX, width);
1143 protoOutputStream.write(SCREEN_HEIGHT_PX, height);
1144 protoOutputStream.end(token);
1145 }
1146
1147 /**
Michael Wright19859762017-09-18 20:57:58 +01001148 * Convert the UI mode to a human readable format.
1149 * @hide
1150 */
1151 public static String uiModeToString(int uiMode) {
1152 switch (uiMode) {
1153 case UI_MODE_TYPE_UNDEFINED:
1154 return "UI_MODE_TYPE_UNDEFINED";
1155 case UI_MODE_TYPE_NORMAL:
1156 return "UI_MODE_TYPE_NORMAL";
1157 case UI_MODE_TYPE_DESK:
1158 return "UI_MODE_TYPE_DESK";
1159 case UI_MODE_TYPE_CAR:
1160 return "UI_MODE_TYPE_CAR";
1161 case UI_MODE_TYPE_TELEVISION:
1162 return "UI_MODE_TYPE_TELEVISION";
1163 case UI_MODE_TYPE_APPLIANCE:
1164 return "UI_MODE_TYPE_APPLIANCE";
1165 case UI_MODE_TYPE_WATCH:
1166 return "UI_MODE_TYPE_WATCH";
1167 case UI_MODE_TYPE_VR_HEADSET:
1168 return "UI_MODE_TYPE_VR_HEADSET";
1169 default:
1170 return Integer.toString(uiMode);
1171 }
1172 }
1173
1174 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 * Set this object to the system defaults.
1176 */
1177 public void setToDefaults() {
1178 fontScale = 1;
1179 mcc = mnc = 0;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001180 mLocaleList = LocaleList.getEmptyLocaleList();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001181 locale = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 userSetLocale = false;
1183 touchscreen = TOUCHSCREEN_UNDEFINED;
1184 keyboard = KEYBOARD_UNDEFINED;
1185 keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
1186 hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
1187 navigation = NAVIGATION_UNDEFINED;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001188 navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 orientation = ORIENTATION_UNDEFINED;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001190 screenLayout = SCREENLAYOUT_UNDEFINED;
Romain Guy48327452017-01-23 17:03:35 -08001191 colorMode = COLOR_MODE_UNDEFINED;
Dianne Hackborn7299c412010-03-04 18:41:49 -08001192 uiMode = UI_MODE_TYPE_UNDEFINED;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001193 screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
1194 screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
1195 smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001196 densityDpi = DENSITY_DPI_UNDEFINED;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001197 assetsSeq = ASSETS_SEQ_UNDEFINED;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001198 seq = 0;
Wale Ogunwale822e5122017-07-26 06:02:24 -07001199 windowConfiguration.setToDefaults();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 }
1201
Adam Lesinskibad43fc2016-07-19 13:35:01 -07001202 /**
1203 * Set this object to completely undefined.
1204 * @hide
1205 */
1206 public void unset() {
1207 setToDefaults();
1208 fontScale = 0;
1209 }
1210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 /** {@hide} */
1212 @Deprecated public void makeDefault() {
1213 setToDefaults();
1214 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 /**
Alan Viveretteac85f902016-03-11 15:15:51 -05001217 * Copies the fields from delta into this Configuration object, keeping
1218 * track of which ones have changed. Any undefined fields in {@code delta}
1219 * are ignored and not copied in to the current Configuration.
1220 *
1221 * @return a bit mask of the changed fields, as per {@link #diff}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001223 public @Config int updateFrom(@NonNull Configuration delta) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 int changed = 0;
1225 if (delta.fontScale > 0 && fontScale != delta.fontScale) {
1226 changed |= ActivityInfo.CONFIG_FONT_SCALE;
1227 fontScale = delta.fontScale;
1228 }
1229 if (delta.mcc != 0 && mcc != delta.mcc) {
1230 changed |= ActivityInfo.CONFIG_MCC;
1231 mcc = delta.mcc;
1232 }
1233 if (delta.mnc != 0 && mnc != delta.mnc) {
1234 changed |= ActivityInfo.CONFIG_MNC;
1235 mnc = delta.mnc;
1236 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001237 fixUpLocaleList();
1238 delta.fixUpLocaleList();
1239 if (!delta.mLocaleList.isEmpty() && !mLocaleList.equals(delta.mLocaleList)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 changed |= ActivityInfo.CONFIG_LOCALE;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001241 mLocaleList = delta.mLocaleList;
1242 // delta.locale can't be null, since delta.mLocaleList is not empty.
1243 if (!delta.locale.equals(locale)) {
1244 locale = (Locale) delta.locale.clone();
1245 // If locale has changed, then layout direction is also changed ...
1246 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
1247 // ... and we need to update the layout direction (represented by the first
1248 // 2 most significant bits in screenLayout).
1249 setLayoutDirection(locale);
1250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 }
Craig Mautner31678b52013-08-12 17:56:34 -07001252 final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
1253 if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
1254 deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
1255 screenLayout = (screenLayout & ~SCREENLAYOUT_LAYOUTDIR_MASK) | deltaScreenLayoutDir;
Amith Yamasanid8415f42013-08-07 20:15:10 -07001256 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
Amith Yamasanid8415f42013-08-07 20:15:10 -07001257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
1259 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 changed |= ActivityInfo.CONFIG_LOCALE;
Amith Yamasanid8415f42013-08-07 20:15:10 -07001261 userSetLocale = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 }
1263 if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
1264 && touchscreen != delta.touchscreen) {
1265 changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
1266 touchscreen = delta.touchscreen;
1267 }
1268 if (delta.keyboard != KEYBOARD_UNDEFINED
1269 && keyboard != delta.keyboard) {
1270 changed |= ActivityInfo.CONFIG_KEYBOARD;
1271 keyboard = delta.keyboard;
1272 }
1273 if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
1274 && keyboardHidden != delta.keyboardHidden) {
1275 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1276 keyboardHidden = delta.keyboardHidden;
1277 }
1278 if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
1279 && hardKeyboardHidden != delta.hardKeyboardHidden) {
1280 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1281 hardKeyboardHidden = delta.hardKeyboardHidden;
1282 }
1283 if (delta.navigation != NAVIGATION_UNDEFINED
1284 && navigation != delta.navigation) {
1285 changed |= ActivityInfo.CONFIG_NAVIGATION;
1286 navigation = delta.navigation;
1287 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001288 if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
1289 && navigationHidden != delta.navigationHidden) {
1290 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1291 navigationHidden = delta.navigationHidden;
1292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 if (delta.orientation != ORIENTATION_UNDEFINED
1294 && orientation != delta.orientation) {
1295 changed |= ActivityInfo.CONFIG_ORIENTATION;
1296 orientation = delta.orientation;
1297 }
Robert Carrdf259d32016-12-05 20:33:10 -08001298 if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
1299 && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
1300 != (screenLayout & SCREENLAYOUT_SIZE_MASK)) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07001301 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
Robert Carrdf259d32016-12-05 20:33:10 -08001302 screenLayout = (screenLayout & ~SCREENLAYOUT_SIZE_MASK)
1303 | (delta.screenLayout & SCREENLAYOUT_SIZE_MASK);
Dianne Hackborn723738c2009-06-25 19:48:04 -07001304 }
Robert Carrdf259d32016-12-05 20:33:10 -08001305 if (((delta.screenLayout & SCREENLAYOUT_LONG_MASK) != SCREENLAYOUT_LONG_UNDEFINED)
1306 && (delta.screenLayout & SCREENLAYOUT_LONG_MASK)
1307 != (screenLayout & SCREENLAYOUT_LONG_MASK)) {
1308 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1309 screenLayout = (screenLayout & ~SCREENLAYOUT_LONG_MASK)
1310 | (delta.screenLayout & SCREENLAYOUT_LONG_MASK);
1311 }
1312 if (((delta.screenLayout & SCREENLAYOUT_ROUND_MASK) != SCREENLAYOUT_ROUND_UNDEFINED)
1313 && (delta.screenLayout & SCREENLAYOUT_ROUND_MASK)
1314 != (screenLayout & SCREENLAYOUT_ROUND_MASK)) {
1315 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1316 screenLayout = (screenLayout & ~SCREENLAYOUT_ROUND_MASK)
1317 | (delta.screenLayout & SCREENLAYOUT_ROUND_MASK);
1318 }
1319 if ((delta.screenLayout & SCREENLAYOUT_COMPAT_NEEDED)
1320 != (screenLayout & SCREENLAYOUT_COMPAT_NEEDED)
1321 && delta.screenLayout != 0) {
1322 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1323 screenLayout = (screenLayout & ~SCREENLAYOUT_COMPAT_NEEDED)
1324 | (delta.screenLayout & SCREENLAYOUT_COMPAT_NEEDED);
1325 }
1326
Romain Guy48327452017-01-23 17:03:35 -08001327 if (((delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
1328 COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED)
1329 && (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)
1330 != (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
1331 changed |= ActivityInfo.CONFIG_COLOR_MODE;
1332 colorMode = (colorMode & ~COLOR_MODE_WIDE_COLOR_GAMUT_MASK)
1333 | (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK);
Romain Guyc9ba5592017-01-18 16:34:42 -08001334 }
1335
Romain Guy48327452017-01-23 17:03:35 -08001336 if (((delta.colorMode & COLOR_MODE_HDR_MASK) != COLOR_MODE_HDR_UNDEFINED)
1337 && (delta.colorMode & COLOR_MODE_HDR_MASK)
1338 != (colorMode & COLOR_MODE_HDR_MASK)) {
1339 changed |= ActivityInfo.CONFIG_COLOR_MODE;
1340 colorMode = (colorMode & ~COLOR_MODE_HDR_MASK)
1341 | (delta.colorMode & COLOR_MODE_HDR_MASK);
Romain Guyc9ba5592017-01-18 16:34:42 -08001342 }
1343
Dianne Hackborn7299c412010-03-04 18:41:49 -08001344 if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
Tobias Haamel27b28b32010-02-09 23:09:17 +01001345 && uiMode != delta.uiMode) {
1346 changed |= ActivityInfo.CONFIG_UI_MODE;
Dianne Hackborn7299c412010-03-04 18:41:49 -08001347 if ((delta.uiMode&UI_MODE_TYPE_MASK) != UI_MODE_TYPE_UNDEFINED) {
1348 uiMode = (uiMode&~UI_MODE_TYPE_MASK)
1349 | (delta.uiMode&UI_MODE_TYPE_MASK);
1350 }
1351 if ((delta.uiMode&UI_MODE_NIGHT_MASK) != UI_MODE_NIGHT_UNDEFINED) {
1352 uiMode = (uiMode&~UI_MODE_NIGHT_MASK)
1353 | (delta.uiMode&UI_MODE_NIGHT_MASK);
1354 }
Tobias Haamel27b28b32010-02-09 23:09:17 +01001355 }
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001356 if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
1357 && screenWidthDp != delta.screenWidthDp) {
1358 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1359 screenWidthDp = delta.screenWidthDp;
1360 }
1361 if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
1362 && screenHeightDp != delta.screenHeightDp) {
1363 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1364 screenHeightDp = delta.screenHeightDp;
1365 }
Danny Baumanne7123a62013-05-15 10:21:40 +02001366 if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
1367 && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
1368 changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001369 smallestScreenWidthDp = delta.smallestScreenWidthDp;
1370 }
Danny Baumanne7123a62013-05-15 10:21:40 +02001371 if (delta.densityDpi != DENSITY_DPI_UNDEFINED &&
1372 densityDpi != delta.densityDpi) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001373 changed |= ActivityInfo.CONFIG_DENSITY;
1374 densityDpi = delta.densityDpi;
1375 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001376 if (delta.compatScreenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
1377 compatScreenWidthDp = delta.compatScreenWidthDp;
1378 }
1379 if (delta.compatScreenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
1380 compatScreenHeightDp = delta.compatScreenHeightDp;
1381 }
1382 if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
1383 compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
1384 }
Adam Lesinski4eb41292017-07-06 12:06:13 -07001385 if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) {
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001386 changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
1387 assetsSeq = delta.assetsSeq;
1388 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001389 if (delta.seq != 0) {
1390 seq = delta.seq;
1391 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07001392 if (windowConfiguration.updateFrom(delta.windowConfiguration) != 0) {
1393 changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
1394 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 return changed;
1397 }
1398
1399 /**
1400 * Return a bit mask of the differences between this Configuration
1401 * object and the given one. Does not change the values of either. Any
1402 * undefined fields in <var>delta</var> are ignored.
1403 * @return Returns a bit mask indicating which configuration
1404 * values has changed, containing any combination of
1405 * {@link android.content.pm.ActivityInfo#CONFIG_FONT_SCALE
1406 * PackageManager.ActivityInfo.CONFIG_FONT_SCALE},
1407 * {@link android.content.pm.ActivityInfo#CONFIG_MCC
1408 * PackageManager.ActivityInfo.CONFIG_MCC},
1409 * {@link android.content.pm.ActivityInfo#CONFIG_MNC
1410 * PackageManager.ActivityInfo.CONFIG_MNC},
1411 * {@link android.content.pm.ActivityInfo#CONFIG_LOCALE
1412 * PackageManager.ActivityInfo.CONFIG_LOCALE},
1413 * {@link android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
1414 * PackageManager.ActivityInfo.CONFIG_TOUCHSCREEN},
1415 * {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
1416 * PackageManager.ActivityInfo.CONFIG_KEYBOARD},
1417 * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
Dianne Hackborn723738c2009-06-25 19:48:04 -07001418 * PackageManager.ActivityInfo.CONFIG_NAVIGATION},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001420 * PackageManager.ActivityInfo.CONFIG_ORIENTATION},
Dianne Hackborn723738c2009-06-25 19:48:04 -07001421 * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001422 * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or
1423 * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001424 * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}, or
1425 * {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
1426 * PackageManager.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001427 * {@link android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
1428 * PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 */
1430 public int diff(Configuration delta) {
Bryce Lee658d9842017-07-28 08:33:36 -07001431 return diff(delta, false /* compareUndefined */, false /* publicOnly */);
1432 }
1433
1434 /**
1435 * Returns the diff against the provided {@link Configuration} excluding values that would
1436 * publicly be equivalent, such as appBounds.
1437 * @param delta {@link Configuration} to compare to.
1438 *
1439 * TODO(b/36812336): Remove once appBounds has been moved out of Configuration.
1440 * {@hide}
1441 */
1442 public int diffPublicOnly(Configuration delta) {
1443 return diff(delta, false /* compareUndefined */, true /* publicOnly */);
Andrii Kulianb10330d2016-09-16 13:51:46 -07001444 }
1445
1446 /**
1447 * Variation of {@link #diff(Configuration)} with an option to skip checks for undefined values.
1448 *
1449 * @hide
1450 */
Bryce Lee658d9842017-07-28 08:33:36 -07001451 public int diff(Configuration delta, boolean compareUndefined, boolean publicOnly) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 int changed = 0;
Andrii Kulianb10330d2016-09-16 13:51:46 -07001453 if ((compareUndefined || delta.fontScale > 0) && fontScale != delta.fontScale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 changed |= ActivityInfo.CONFIG_FONT_SCALE;
1455 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001456 if ((compareUndefined || delta.mcc != 0) && mcc != delta.mcc) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 changed |= ActivityInfo.CONFIG_MCC;
1458 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001459 if ((compareUndefined || delta.mnc != 0) && mnc != delta.mnc) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 changed |= ActivityInfo.CONFIG_MNC;
1461 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001462 fixUpLocaleList();
1463 delta.fixUpLocaleList();
Andrii Kulianb10330d2016-09-16 13:51:46 -07001464 if ((compareUndefined || !delta.mLocaleList.isEmpty())
1465 && !mLocaleList.equals(delta.mLocaleList)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 changed |= ActivityInfo.CONFIG_LOCALE;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001467 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 }
Craig Mautner31678b52013-08-12 17:56:34 -07001469 final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
Andrii Kulianb10330d2016-09-16 13:51:46 -07001470 if ((compareUndefined || deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED)
1471 && deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
Amith Yamasanid8415f42013-08-07 20:15:10 -07001472 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
1473 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001474 if ((compareUndefined || delta.touchscreen != TOUCHSCREEN_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 && touchscreen != delta.touchscreen) {
1476 changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
1477 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001478 if ((compareUndefined || delta.keyboard != KEYBOARD_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 && keyboard != delta.keyboard) {
1480 changed |= ActivityInfo.CONFIG_KEYBOARD;
1481 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001482 if ((compareUndefined || delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 && keyboardHidden != delta.keyboardHidden) {
1484 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1485 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001486 if ((compareUndefined || delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 && hardKeyboardHidden != delta.hardKeyboardHidden) {
1488 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1489 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001490 if ((compareUndefined || delta.navigation != NAVIGATION_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 && navigation != delta.navigation) {
1492 changed |= ActivityInfo.CONFIG_NAVIGATION;
1493 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001494 if ((compareUndefined || delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED)
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001495 && navigationHidden != delta.navigationHidden) {
1496 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1497 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001498 if ((compareUndefined || delta.orientation != ORIENTATION_UNDEFINED)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 && orientation != delta.orientation) {
1500 changed |= ActivityInfo.CONFIG_ORIENTATION;
1501 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001502 if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) !=
1503 (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED))
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001504 && getScreenLayoutNoDirection(screenLayout) !=
Andrii Kulianb10330d2016-09-16 13:51:46 -07001505 getScreenLayoutNoDirection(delta.screenLayout)) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07001506 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1507 }
Romain Guyc9ba5592017-01-18 16:34:42 -08001508 if ((compareUndefined ||
Romain Guy48327452017-01-23 17:03:35 -08001509 (delta.colorMode & COLOR_MODE_HDR_MASK) != COLOR_MODE_HDR_UNDEFINED)
1510 && (colorMode & COLOR_MODE_HDR_MASK) !=
1511 (delta.colorMode & COLOR_MODE_HDR_MASK)) {
1512 changed |= ActivityInfo.CONFIG_COLOR_MODE;
Romain Guyc9ba5592017-01-18 16:34:42 -08001513 }
1514 if ((compareUndefined ||
Romain Guy48327452017-01-23 17:03:35 -08001515 (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
1516 COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED)
1517 && (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
1518 (delta.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
1519 changed |= ActivityInfo.CONFIG_COLOR_MODE;
Romain Guyc9ba5592017-01-18 16:34:42 -08001520 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001521 if ((compareUndefined || delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED))
Tobias Haamel27b28b32010-02-09 23:09:17 +01001522 && uiMode != delta.uiMode) {
1523 changed |= ActivityInfo.CONFIG_UI_MODE;
1524 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001525 if ((compareUndefined || delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED)
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001526 && screenWidthDp != delta.screenWidthDp) {
1527 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1528 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001529 if ((compareUndefined || delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED)
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001530 && screenHeightDp != delta.screenHeightDp) {
1531 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1532 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001533 if ((compareUndefined || delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED)
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001534 && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
1535 changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
1536 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001537 if ((compareUndefined || delta.densityDpi != DENSITY_DPI_UNDEFINED)
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001538 && densityDpi != delta.densityDpi) {
1539 changed |= ActivityInfo.CONFIG_DENSITY;
1540 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001541 if ((compareUndefined || delta.assetsSeq != ASSETS_SEQ_UNDEFINED)
1542 && assetsSeq != delta.assetsSeq) {
1543 changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
1544 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001545
Wale Ogunwale822e5122017-07-26 06:02:24 -07001546 // WindowConfiguration differences aren't considered public...
1547 if (!publicOnly
1548 && windowConfiguration.diff(delta.windowConfiguration, compareUndefined) != 0) {
1549 changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Bryce Lee7566d762017-03-30 09:34:15 -07001550 }
1551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 return changed;
1553 }
1554
1555 /**
Alan Viveretteac85f902016-03-11 15:15:51 -05001556 * Determines if a new resource needs to be loaded from the bit set of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 * configuration changes returned by {@link #updateFrom(Configuration)}.
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001558 *
Alan Viveretteac85f902016-03-11 15:15:51 -05001559 * @param configChanges the mask of changes configurations as returned by
1560 * {@link #updateFrom(Configuration)}
1561 * @param interestingChanges the configuration changes that the resource
1562 * can handle as given in
1563 * {@link android.util.TypedValue#changingConfigurations}
1564 * @return {@code true} if the resource needs to be loaded, {@code false}
1565 * otherwise
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001567 public static boolean needNewResources(@Config int configChanges,
1568 @Config int interestingChanges) {
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001569 // CONFIG_ASSETS_PATHS and CONFIG_FONT_SCALE are higher level configuration changes that
1570 // all resources are subject to change with.
1571 interestingChanges = interestingChanges | ActivityInfo.CONFIG_ASSETS_PATHS
1572 | ActivityInfo.CONFIG_FONT_SCALE;
1573 return (configChanges & interestingChanges) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 }
Amith Yamasanid8415f42013-08-07 20:15:10 -07001575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001577 * @hide Return true if the sequence of 'other' is better than this. Assumes
1578 * that 'this' is your current sequence and 'other' is a new one you have
1579 * received some how and want to compare with what you have.
1580 */
1581 public boolean isOtherSeqNewer(Configuration other) {
1582 if (other == null) {
1583 // Sanity check.
1584 return false;
1585 }
1586 if (other.seq == 0) {
1587 // If the other sequence is not specified, then we must assume
1588 // it is newer since we don't know any better.
1589 return true;
1590 }
1591 if (seq == 0) {
1592 // If this sequence is not specified, then we also consider the
1593 // other is better. Yes we have a preference for other. Sue us.
1594 return true;
1595 }
1596 int diff = other.seq - seq;
1597 if (diff > 0x10000) {
1598 // If there has been a sufficiently large jump, assume the
1599 // sequence has wrapped around.
1600 return false;
1601 }
1602 return diff > 0;
1603 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001604
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001605 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 * Parcelable methods
1607 */
1608 public int describeContents() {
1609 return 0;
1610 }
1611
1612 public void writeToParcel(Parcel dest, int flags) {
1613 dest.writeFloat(fontScale);
1614 dest.writeInt(mcc);
1615 dest.writeInt(mnc);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001616
1617 fixUpLocaleList();
1618 final int localeListSize = mLocaleList.size();
1619 dest.writeInt(localeListSize);
1620 for (int i = 0; i < localeListSize; ++i) {
1621 final Locale l = mLocaleList.get(i);
1622 dest.writeString(l.toLanguageTag());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 if(userSetLocale) {
1626 dest.writeInt(1);
1627 } else {
1628 dest.writeInt(0);
1629 }
1630 dest.writeInt(touchscreen);
1631 dest.writeInt(keyboard);
1632 dest.writeInt(keyboardHidden);
1633 dest.writeInt(hardKeyboardHidden);
1634 dest.writeInt(navigation);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001635 dest.writeInt(navigationHidden);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 dest.writeInt(orientation);
Dianne Hackborn723738c2009-06-25 19:48:04 -07001637 dest.writeInt(screenLayout);
Romain Guy48327452017-01-23 17:03:35 -08001638 dest.writeInt(colorMode);
Tobias Haamel27b28b32010-02-09 23:09:17 +01001639 dest.writeInt(uiMode);
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001640 dest.writeInt(screenWidthDp);
1641 dest.writeInt(screenHeightDp);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001642 dest.writeInt(smallestScreenWidthDp);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001643 dest.writeInt(densityDpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001644 dest.writeInt(compatScreenWidthDp);
1645 dest.writeInt(compatScreenHeightDp);
1646 dest.writeInt(compatSmallestScreenWidthDp);
Wale Ogunwale822e5122017-07-26 06:02:24 -07001647 dest.writeValue(windowConfiguration);
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001648 dest.writeInt(assetsSeq);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001649 dest.writeInt(seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 }
1651
Dianne Hackborn694f79b2010-03-17 19:44:59 -07001652 public void readFromParcel(Parcel source) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 fontScale = source.readFloat();
1654 mcc = source.readInt();
1655 mnc = source.readInt();
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001656
1657 final int localeListSize = source.readInt();
1658 final Locale[] localeArray = new Locale[localeListSize];
1659 for (int i = 0; i < localeListSize; ++i) {
1660 localeArray[i] = Locale.forLanguageTag(source.readString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001662 mLocaleList = new LocaleList(localeArray);
Roozbeh Pournaderfee44842016-02-04 15:24:24 -08001663 locale = mLocaleList.get(0);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 userSetLocale = (source.readInt()==1);
1666 touchscreen = source.readInt();
1667 keyboard = source.readInt();
1668 keyboardHidden = source.readInt();
1669 hardKeyboardHidden = source.readInt();
1670 navigation = source.readInt();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001671 navigationHidden = source.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 orientation = source.readInt();
Dianne Hackborn723738c2009-06-25 19:48:04 -07001673 screenLayout = source.readInt();
Romain Guy48327452017-01-23 17:03:35 -08001674 colorMode = source.readInt();
Tobias Haamel27b28b32010-02-09 23:09:17 +01001675 uiMode = source.readInt();
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001676 screenWidthDp = source.readInt();
1677 screenHeightDp = source.readInt();
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001678 smallestScreenWidthDp = source.readInt();
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001679 densityDpi = source.readInt();
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001680 compatScreenWidthDp = source.readInt();
1681 compatScreenHeightDp = source.readInt();
1682 compatSmallestScreenWidthDp = source.readInt();
Wale Ogunwale822e5122017-07-26 06:02:24 -07001683 windowConfiguration.setTo((WindowConfiguration) source.readValue(null));
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001684 assetsSeq = source.readInt();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001685 seq = source.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 }
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -07001687
Dianne Hackborn694f79b2010-03-17 19:44:59 -07001688 public static final Parcelable.Creator<Configuration> CREATOR
1689 = new Parcelable.Creator<Configuration>() {
1690 public Configuration createFromParcel(Parcel source) {
1691 return new Configuration(source);
1692 }
1693
1694 public Configuration[] newArray(int size) {
1695 return new Configuration[size];
1696 }
1697 };
1698
1699 /**
1700 * Construct this Configuration object, reading from the Parcel.
1701 */
1702 private Configuration(Parcel source) {
1703 readFromParcel(source);
1704 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001705
1706 public int compareTo(Configuration that) {
1707 int n;
1708 float a = this.fontScale;
1709 float b = that.fontScale;
1710 if (a < b) return -1;
1711 if (a > b) return 1;
1712 n = this.mcc - that.mcc;
1713 if (n != 0) return n;
1714 n = this.mnc - that.mnc;
1715 if (n != 0) return n;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001716
1717 fixUpLocaleList();
1718 that.fixUpLocaleList();
1719 // for backward compatibility, we consider an empty locale list to be greater
1720 // than any non-empty locale list.
1721 if (this.mLocaleList.isEmpty()) {
1722 if (!that.mLocaleList.isEmpty()) return 1;
1723 } else if (that.mLocaleList.isEmpty()) {
Dianne Hackborna8397032010-03-12 10:52:22 -08001724 return -1;
1725 } else {
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001726 final int minSize = Math.min(this.mLocaleList.size(), that.mLocaleList.size());
1727 for (int i = 0; i < minSize; ++i) {
1728 final Locale thisLocale = this.mLocaleList.get(i);
1729 final Locale thatLocale = that.mLocaleList.get(i);
1730 n = thisLocale.getLanguage().compareTo(thatLocale.getLanguage());
1731 if (n != 0) return n;
1732 n = thisLocale.getCountry().compareTo(thatLocale.getCountry());
1733 if (n != 0) return n;
1734 n = thisLocale.getVariant().compareTo(thatLocale.getVariant());
1735 if (n != 0) return n;
1736 n = thisLocale.toLanguageTag().compareTo(thatLocale.toLanguageTag());
1737 if (n != 0) return n;
1738 }
1739 n = this.mLocaleList.size() - that.mLocaleList.size();
Dianne Hackborna8397032010-03-12 10:52:22 -08001740 if (n != 0) return n;
1741 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 n = this.touchscreen - that.touchscreen;
1744 if (n != 0) return n;
1745 n = this.keyboard - that.keyboard;
1746 if (n != 0) return n;
1747 n = this.keyboardHidden - that.keyboardHidden;
1748 if (n != 0) return n;
1749 n = this.hardKeyboardHidden - that.hardKeyboardHidden;
1750 if (n != 0) return n;
1751 n = this.navigation - that.navigation;
1752 if (n != 0) return n;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001753 n = this.navigationHidden - that.navigationHidden;
1754 if (n != 0) return n;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 n = this.orientation - that.orientation;
Dianne Hackborn723738c2009-06-25 19:48:04 -07001756 if (n != 0) return n;
Romain Guy48327452017-01-23 17:03:35 -08001757 n = this.colorMode - that.colorMode;
Romain Guyc9ba5592017-01-18 16:34:42 -08001758 if (n != 0) return n;
Dianne Hackborn723738c2009-06-25 19:48:04 -07001759 n = this.screenLayout - that.screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +01001760 if (n != 0) return n;
1761 n = this.uiMode - that.uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001762 if (n != 0) return n;
1763 n = this.screenWidthDp - that.screenWidthDp;
1764 if (n != 0) return n;
1765 n = this.screenHeightDp - that.screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001766 if (n != 0) return n;
1767 n = this.smallestScreenWidthDp - that.smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001768 if (n != 0) return n;
1769 n = this.densityDpi - that.densityDpi;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001770 if (n != 0) return n;
1771 n = this.assetsSeq - that.assetsSeq;
Bryce Leec5fe0ee2017-06-30 09:03:09 -07001772 if (n != 0) return n;
Wale Ogunwale822e5122017-07-26 06:02:24 -07001773 n = windowConfiguration.compareTo(that.windowConfiguration);
1774 if (n != 0) return n;
Bryce Leec5fe0ee2017-06-30 09:03:09 -07001775
1776 // if (n != 0) return n;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 return n;
1778 }
1779
1780 public boolean equals(Configuration that) {
1781 if (that == null) return false;
1782 if (that == this) return true;
1783 return this.compareTo(that) == 0;
1784 }
1785
1786 public boolean equals(Object that) {
1787 try {
1788 return equals((Configuration)that);
1789 } catch (ClassCastException e) {
1790 }
1791 return false;
1792 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 public int hashCode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001795 int result = 17;
1796 result = 31 * result + Float.floatToIntBits(fontScale);
1797 result = 31 * result + mcc;
1798 result = 31 * result + mnc;
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001799 result = 31 * result + mLocaleList.hashCode();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001800 result = 31 * result + touchscreen;
1801 result = 31 * result + keyboard;
1802 result = 31 * result + keyboardHidden;
1803 result = 31 * result + hardKeyboardHidden;
1804 result = 31 * result + navigation;
1805 result = 31 * result + navigationHidden;
1806 result = 31 * result + orientation;
1807 result = 31 * result + screenLayout;
Romain Guy48327452017-01-23 17:03:35 -08001808 result = 31 * result + colorMode;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001809 result = 31 * result + uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001810 result = 31 * result + screenWidthDp;
1811 result = 31 * result + screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001812 result = 31 * result + smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001813 result = 31 * result + densityDpi;
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01001814 result = 31 * result + assetsSeq;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001815 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001817
1818 /**
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001819 * Get the locale list. This is the preferred way for getting the locales (instead of using
1820 * the direct accessor to {@link #locale}, which would only provide the primary locale).
1821 *
1822 * @return The locale list.
1823 */
Adam Lesinskib61e4052016-05-19 18:23:05 -07001824 public @NonNull LocaleList getLocales() {
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001825 fixUpLocaleList();
1826 return mLocaleList;
1827 }
1828
1829 /**
1830 * Set the locale list. This is the preferred way for setting up the locales (instead of using
1831 * the direct accessor or {@link #setLocale(Locale)}). This will also set the layout direction
1832 * according to the first locale in the list.
1833 *
1834 * Note that the layout direction will always come from the first locale in the locale list,
1835 * even if the locale is not supported by the resources (the resources may only support
1836 * another locale further down the list which has a different direction).
1837 *
1838 * @param locales The locale list. If null, an empty LocaleList will be assigned.
1839 */
1840 public void setLocales(@Nullable LocaleList locales) {
1841 mLocaleList = locales == null ? LocaleList.getEmptyLocaleList() : locales;
Roozbeh Pournaderfee44842016-02-04 15:24:24 -08001842 locale = mLocaleList.get(0);
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001843 setLayoutDirection(locale);
1844 }
1845
1846 /**
1847 * Set the locale list to a list of just one locale. This will also set the layout direction
1848 * according to the locale.
1849 *
1850 * Note that after this is run, calling <code>.equals()</code> on the input locale and the
1851 * {@link #locale} attribute would return <code>true</code> if they are not null, but there is
1852 * no guarantee that they would be the same object.
1853 *
1854 * See also the note about layout direction in {@link #setLocales(LocaleList)}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001855 *
1856 * @param loc The locale. Can be null.
1857 */
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001858 public void setLocale(@Nullable Locale loc) {
Raph Levien10ea92a2016-05-02 12:56:01 -07001859 setLocales(loc == null ? LocaleList.getEmptyLocaleList() : new LocaleList(loc));
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001860 }
1861
1862 /**
Seigo Nonakabd5cac62016-05-13 15:11:37 +09001863 * @hide
1864 *
1865 * Clears the locale without changing layout direction.
1866 */
1867 public void clearLocales() {
1868 mLocaleList = LocaleList.getEmptyLocaleList();
1869 locale = null;
1870 }
1871
1872 /**
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001873 * Return the layout direction. Will be either {@link View#LAYOUT_DIRECTION_LTR} or
1874 * {@link View#LAYOUT_DIRECTION_RTL}.
1875 *
Dianne Hackbornf1ae2692013-04-19 14:09:37 -07001876 * @return Returns {@link View#LAYOUT_DIRECTION_RTL} if the configuration
1877 * is {@link #SCREENLAYOUT_LAYOUTDIR_RTL}, otherwise {@link View#LAYOUT_DIRECTION_LTR}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001878 */
1879 public int getLayoutDirection() {
Dianne Hackbornf1ae2692013-04-19 14:09:37 -07001880 return (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == SCREENLAYOUT_LAYOUTDIR_RTL
1881 ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001882 }
1883
1884 /**
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001885 * Set the layout direction from a Locale.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001886 *
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001887 * @param loc The Locale. If null will set the layout direction to
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001888 * {@link View#LAYOUT_DIRECTION_LTR}. If not null will set it to the layout direction
1889 * corresponding to the Locale.
1890 *
John Spurlockbc4cf002015-03-24 21:51:20 -04001891 * @see View#LAYOUT_DIRECTION_LTR
1892 * @see View#LAYOUT_DIRECTION_RTL
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001893 */
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001894 public void setLayoutDirection(Locale loc) {
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001895 // There is a "1" difference between the configuration values for
1896 // layout direction and View constants for layout direction, just add "1".
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07001897 final int layoutDirection = 1 + TextUtils.getLayoutDirectionFromLocale(loc);
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001898 screenLayout = (screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK)|
1899 (layoutDirection << SCREENLAYOUT_LAYOUTDIR_SHIFT);
1900 }
1901
1902 private static int getScreenLayoutNoDirection(int screenLayout) {
1903 return screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK;
1904 }
Adam Lesinski2c749d22014-06-04 13:00:29 -07001905
1906 /**
Adam Powell49e7ff92015-05-14 16:18:53 -07001907 * Return whether the screen has a round shape. Apps may choose to change styling based
1908 * on this property, such as the alignment or layout of text or informational icons.
1909 *
1910 * @return true if the screen is rounded, false otherwise
1911 */
1912 public boolean isScreenRound() {
1913 return (screenLayout & SCREENLAYOUT_ROUND_MASK) == SCREENLAYOUT_ROUND_YES;
1914 }
1915
1916 /**
Romain Guye89d0bb2017-06-20 12:23:42 -07001917 * Return whether the screen has a wide color gamut and wide color gamut rendering
1918 * is supported by this device.
Romain Guyc9ba5592017-01-18 16:34:42 -08001919 *
Romain Guye89d0bb2017-06-20 12:23:42 -07001920 * @return true if the screen has a wide color gamut and wide color gamut rendering
1921 * is supported, false otherwise
Romain Guyc9ba5592017-01-18 16:34:42 -08001922 */
1923 public boolean isScreenWideColorGamut() {
Romain Guy48327452017-01-23 17:03:35 -08001924 return (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) == COLOR_MODE_WIDE_COLOR_GAMUT_YES;
Romain Guyc9ba5592017-01-18 16:34:42 -08001925 }
1926
1927 /**
1928 * Return whether the screen has a high dynamic range.
1929 *
1930 * @return true if the screen has a high dynamic range, false otherwise
1931 */
1932 public boolean isScreenHdr() {
Romain Guy48327452017-01-23 17:03:35 -08001933 return (colorMode & COLOR_MODE_HDR_MASK) == COLOR_MODE_HDR_YES;
Romain Guyc9ba5592017-01-18 16:34:42 -08001934 }
1935
1936 /**
Adam Lesinski2c749d22014-06-04 13:00:29 -07001937 *
1938 * @hide
1939 */
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08001940 public static String localesToResourceQualifier(LocaleList locs) {
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07001941 final StringBuilder sb = new StringBuilder();
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08001942 for (int i = 0; i < locs.size(); i++) {
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07001943 final Locale loc = locs.get(i);
1944 final int l = loc.getLanguage().length();
1945 if (l == 0) {
1946 continue;
1947 }
1948 final int s = loc.getScript().length();
1949 final int c = loc.getCountry().length();
1950 final int v = loc.getVariant().length();
1951 // We ignore locale extensions, since they are not supported by AAPT
1952
1953 if (sb.length() != 0) {
1954 sb.append(",");
1955 }
1956 if (l == 2 && s == 0 && (c == 0 || c == 2) && v == 0) {
1957 // Traditional locale format: xx or xx-rYY
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08001958 sb.append(loc.getLanguage());
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07001959 if (c == 2) {
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08001960 sb.append("-r").append(loc.getCountry());
Roozbeh Pournader309ebd62016-06-17 22:13:12 -07001961 }
1962 } else {
1963 sb.append("b+");
1964 sb.append(loc.getLanguage());
1965 if (s != 0) {
1966 sb.append("+");
1967 sb.append(loc.getScript());
1968 }
1969 if (c != 0) {
1970 sb.append("+");
1971 sb.append(loc.getCountry());
1972 }
1973 if (v != 0) {
1974 sb.append("+");
1975 sb.append(loc.getVariant());
Adam Lesinski2c749d22014-06-04 13:00:29 -07001976 }
1977 }
1978 }
1979 return sb.toString();
1980 }
1981
1982
1983 /**
1984 * Returns a string representation of the configuration that can be parsed
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001985 * by build tools (like AAPT), without display metrics included
Adam Lesinski2c749d22014-06-04 13:00:29 -07001986 *
Adam Lesinski2c749d22014-06-04 13:00:29 -07001987 * @hide
1988 */
1989 public static String resourceQualifierString(Configuration config) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001990 return resourceQualifierString(config, null);
1991 }
1992
1993 /**
1994 * Returns a string representation of the configuration that can be parsed
1995 * by build tools (like AAPT).
1996 *
1997 * @hide
1998 */
1999 public static String resourceQualifierString(Configuration config, DisplayMetrics metrics) {
Adam Lesinski2c749d22014-06-04 13:00:29 -07002000 ArrayList<String> parts = new ArrayList<String>();
2001
2002 if (config.mcc != 0) {
Adam Lesinski90865622014-10-16 18:18:10 -07002003 parts.add("mcc" + config.mcc);
Adam Lesinski2c749d22014-06-04 13:00:29 -07002004 if (config.mnc != 0) {
Adam Lesinski90865622014-10-16 18:18:10 -07002005 parts.add("mnc" + config.mnc);
Adam Lesinski2c749d22014-06-04 13:00:29 -07002006 }
2007 }
2008
Roozbeh Pournader47f71a62015-11-07 11:55:38 -08002009 if (!config.mLocaleList.isEmpty()) {
Roozbeh Pournader417bbe02015-11-09 17:09:15 -08002010 final String resourceQualifier = localesToResourceQualifier(config.mLocaleList);
2011 if (!resourceQualifier.isEmpty()) {
2012 parts.add(resourceQualifier);
2013 }
Adam Lesinski2c749d22014-06-04 13:00:29 -07002014 }
2015
2016 switch (config.screenLayout & Configuration.SCREENLAYOUT_LAYOUTDIR_MASK) {
2017 case Configuration.SCREENLAYOUT_LAYOUTDIR_LTR:
2018 parts.add("ldltr");
2019 break;
2020 case Configuration.SCREENLAYOUT_LAYOUTDIR_RTL:
2021 parts.add("ldrtl");
2022 break;
2023 default:
2024 break;
2025 }
2026
2027 if (config.smallestScreenWidthDp != 0) {
2028 parts.add("sw" + config.smallestScreenWidthDp + "dp");
2029 }
2030
2031 if (config.screenWidthDp != 0) {
2032 parts.add("w" + config.screenWidthDp + "dp");
2033 }
2034
2035 if (config.screenHeightDp != 0) {
2036 parts.add("h" + config.screenHeightDp + "dp");
2037 }
2038
2039 switch (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) {
2040 case Configuration.SCREENLAYOUT_SIZE_SMALL:
2041 parts.add("small");
2042 break;
2043 case Configuration.SCREENLAYOUT_SIZE_NORMAL:
2044 parts.add("normal");
2045 break;
2046 case Configuration.SCREENLAYOUT_SIZE_LARGE:
2047 parts.add("large");
2048 break;
2049 case Configuration.SCREENLAYOUT_SIZE_XLARGE:
2050 parts.add("xlarge");
2051 break;
2052 default:
2053 break;
2054 }
2055
2056 switch (config.screenLayout & Configuration.SCREENLAYOUT_LONG_MASK) {
2057 case Configuration.SCREENLAYOUT_LONG_YES:
2058 parts.add("long");
2059 break;
2060 case Configuration.SCREENLAYOUT_LONG_NO:
2061 parts.add("notlong");
2062 break;
2063 default:
2064 break;
2065 }
2066
Adam Powell49e7ff92015-05-14 16:18:53 -07002067 switch (config.screenLayout & Configuration.SCREENLAYOUT_ROUND_MASK) {
2068 case Configuration.SCREENLAYOUT_ROUND_YES:
2069 parts.add("round");
2070 break;
2071 case Configuration.SCREENLAYOUT_ROUND_NO:
2072 parts.add("notround");
2073 break;
2074 default:
2075 break;
2076 }
2077
Romain Guy48327452017-01-23 17:03:35 -08002078 switch (config.colorMode & Configuration.COLOR_MODE_HDR_MASK) {
2079 case Configuration.COLOR_MODE_HDR_YES:
Romain Guyc9ba5592017-01-18 16:34:42 -08002080 parts.add("highdr");
2081 break;
Romain Guy48327452017-01-23 17:03:35 -08002082 case Configuration.COLOR_MODE_HDR_NO:
Romain Guyc9ba5592017-01-18 16:34:42 -08002083 parts.add("lowdr");
2084 break;
2085 default:
2086 break;
2087 }
2088
Romain Guy48327452017-01-23 17:03:35 -08002089 switch (config.colorMode & Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_MASK) {
2090 case Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES:
Romain Guyc9ba5592017-01-18 16:34:42 -08002091 parts.add("widecg");
2092 break;
Romain Guy48327452017-01-23 17:03:35 -08002093 case Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO:
Romain Guyc9ba5592017-01-18 16:34:42 -08002094 parts.add("nowidecg");
2095 break;
2096 default:
2097 break;
2098 }
2099
Adam Lesinski2c749d22014-06-04 13:00:29 -07002100 switch (config.orientation) {
2101 case Configuration.ORIENTATION_LANDSCAPE:
2102 parts.add("land");
2103 break;
2104 case Configuration.ORIENTATION_PORTRAIT:
2105 parts.add("port");
2106 break;
2107 default:
2108 break;
2109 }
2110
2111 switch (config.uiMode & Configuration.UI_MODE_TYPE_MASK) {
2112 case Configuration.UI_MODE_TYPE_APPLIANCE:
2113 parts.add("appliance");
2114 break;
2115 case Configuration.UI_MODE_TYPE_DESK:
2116 parts.add("desk");
2117 break;
2118 case Configuration.UI_MODE_TYPE_TELEVISION:
2119 parts.add("television");
2120 break;
2121 case Configuration.UI_MODE_TYPE_CAR:
2122 parts.add("car");
2123 break;
2124 case Configuration.UI_MODE_TYPE_WATCH:
2125 parts.add("watch");
2126 break;
Zak Cohen1a6acdb2016-12-12 15:21:21 -08002127 case Configuration.UI_MODE_TYPE_VR_HEADSET:
2128 parts.add("vrheadset");
2129 break;
Adam Lesinski2c749d22014-06-04 13:00:29 -07002130 default:
2131 break;
2132 }
2133
2134 switch (config.uiMode & Configuration.UI_MODE_NIGHT_MASK) {
2135 case Configuration.UI_MODE_NIGHT_YES:
2136 parts.add("night");
2137 break;
2138 case Configuration.UI_MODE_NIGHT_NO:
2139 parts.add("notnight");
2140 break;
2141 default:
2142 break;
2143 }
2144
2145 switch (config.densityDpi) {
Adam Lesinski31245b42014-08-22 19:10:56 -07002146 case DENSITY_DPI_UNDEFINED:
Adam Lesinski2c749d22014-06-04 13:00:29 -07002147 break;
2148 case 120:
2149 parts.add("ldpi");
2150 break;
2151 case 160:
2152 parts.add("mdpi");
2153 break;
2154 case 213:
2155 parts.add("tvdpi");
2156 break;
2157 case 240:
2158 parts.add("hdpi");
2159 break;
2160 case 320:
2161 parts.add("xhdpi");
2162 break;
Adam Lesinskiebc3e4c2014-08-21 12:21:45 -07002163 case 480:
2164 parts.add("xxhdpi");
2165 break;
2166 case 640:
2167 parts.add("xxxhdpi");
2168 break;
Adam Lesinski31245b42014-08-22 19:10:56 -07002169 case DENSITY_DPI_ANY:
2170 parts.add("anydpi");
2171 break;
2172 case DENSITY_DPI_NONE:
2173 parts.add("nodpi");
Christian Williamsb709f3c2017-11-02 17:19:27 -07002174 break;
Adam Lesinski2c749d22014-06-04 13:00:29 -07002175 default:
2176 parts.add(config.densityDpi + "dpi");
2177 break;
2178 }
2179
2180 switch (config.touchscreen) {
2181 case Configuration.TOUCHSCREEN_NOTOUCH:
2182 parts.add("notouch");
2183 break;
2184 case Configuration.TOUCHSCREEN_FINGER:
2185 parts.add("finger");
2186 break;
2187 default:
2188 break;
2189 }
2190
2191 switch (config.keyboardHidden) {
2192 case Configuration.KEYBOARDHIDDEN_NO:
2193 parts.add("keysexposed");
2194 break;
2195 case Configuration.KEYBOARDHIDDEN_YES:
2196 parts.add("keyshidden");
2197 break;
2198 case Configuration.KEYBOARDHIDDEN_SOFT:
2199 parts.add("keyssoft");
2200 break;
2201 default:
2202 break;
2203 }
2204
2205 switch (config.keyboard) {
2206 case Configuration.KEYBOARD_NOKEYS:
2207 parts.add("nokeys");
2208 break;
2209 case Configuration.KEYBOARD_QWERTY:
2210 parts.add("qwerty");
2211 break;
2212 case Configuration.KEYBOARD_12KEY:
2213 parts.add("12key");
2214 break;
2215 default:
2216 break;
2217 }
2218
2219 switch (config.navigationHidden) {
2220 case Configuration.NAVIGATIONHIDDEN_NO:
2221 parts.add("navexposed");
2222 break;
2223 case Configuration.NAVIGATIONHIDDEN_YES:
2224 parts.add("navhidden");
2225 break;
2226 default:
2227 break;
2228 }
2229
2230 switch (config.navigation) {
2231 case Configuration.NAVIGATION_NONAV:
2232 parts.add("nonav");
2233 break;
2234 case Configuration.NAVIGATION_DPAD:
2235 parts.add("dpad");
2236 break;
2237 case Configuration.NAVIGATION_TRACKBALL:
2238 parts.add("trackball");
2239 break;
2240 case Configuration.NAVIGATION_WHEEL:
2241 parts.add("wheel");
2242 break;
2243 default:
2244 break;
2245 }
2246
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002247 if (metrics != null) {
2248 final int width, height;
2249 if (metrics.widthPixels >= metrics.heightPixels) {
2250 width = metrics.widthPixels;
2251 height = metrics.heightPixels;
2252 } else {
2253 //noinspection SuspiciousNameCombination
2254 width = metrics.heightPixels;
2255 //noinspection SuspiciousNameCombination
2256 height = metrics.widthPixels;
2257 }
2258 parts.add(width + "x" + height);
2259 }
2260
Adam Lesinskiebc3e4c2014-08-21 12:21:45 -07002261 parts.add("v" + Build.VERSION.RESOURCES_SDK_INT);
Adam Lesinski2c749d22014-06-04 13:00:29 -07002262 return TextUtils.join("-", parts);
2263 }
Adam Lesinski7f61e962014-09-02 16:43:52 -07002264
2265 /**
2266 * Generate a delta Configuration between <code>base</code> and <code>change</code>. The
2267 * resulting delta can be used with {@link #updateFrom(Configuration)}.
2268 * <p />
2269 * Caveat: If the any of the Configuration's members becomes undefined, then
2270 * {@link #updateFrom(Configuration)} will treat it as a no-op and not update that member.
2271 *
2272 * This is fine for device configurations as no member is ever undefined.
2273 * {@hide}
2274 */
2275 public static Configuration generateDelta(Configuration base, Configuration change) {
2276 final Configuration delta = new Configuration();
2277 if (base.fontScale != change.fontScale) {
2278 delta.fontScale = change.fontScale;
2279 }
2280
2281 if (base.mcc != change.mcc) {
2282 delta.mcc = change.mcc;
2283 }
2284
2285 if (base.mnc != change.mnc) {
2286 delta.mnc = change.mnc;
2287 }
2288
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002289 base.fixUpLocaleList();
2290 change.fixUpLocaleList();
2291 if (!base.mLocaleList.equals(change.mLocaleList)) {
2292 delta.mLocaleList = change.mLocaleList;
Adam Lesinski7f61e962014-09-02 16:43:52 -07002293 delta.locale = change.locale;
2294 }
2295
2296 if (base.touchscreen != change.touchscreen) {
2297 delta.touchscreen = change.touchscreen;
2298 }
2299
2300 if (base.keyboard != change.keyboard) {
2301 delta.keyboard = change.keyboard;
2302 }
2303
2304 if (base.keyboardHidden != change.keyboardHidden) {
2305 delta.keyboardHidden = change.keyboardHidden;
2306 }
2307
2308 if (base.navigation != change.navigation) {
2309 delta.navigation = change.navigation;
2310 }
2311
2312 if (base.navigationHidden != change.navigationHidden) {
2313 delta.navigationHidden = change.navigationHidden;
2314 }
2315
2316 if (base.orientation != change.orientation) {
2317 delta.orientation = change.orientation;
2318 }
2319
2320 if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) !=
2321 (change.screenLayout & SCREENLAYOUT_SIZE_MASK)) {
2322 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK;
2323 }
2324
2325 if ((base.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK) !=
2326 (change.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
2327 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
2328 }
2329
2330 if ((base.screenLayout & SCREENLAYOUT_LONG_MASK) !=
2331 (change.screenLayout & SCREENLAYOUT_LONG_MASK)) {
2332 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_LONG_MASK;
2333 }
2334
Adam Powell49e7ff92015-05-14 16:18:53 -07002335 if ((base.screenLayout & SCREENLAYOUT_ROUND_MASK) !=
2336 (change.screenLayout & SCREENLAYOUT_ROUND_MASK)) {
2337 delta.screenLayout |= change.screenLayout & SCREENLAYOUT_ROUND_MASK;
2338 }
2339
Romain Guy48327452017-01-23 17:03:35 -08002340 if ((base.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) !=
2341 (change.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK)) {
2342 delta.colorMode |= change.colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK;
Romain Guyc9ba5592017-01-18 16:34:42 -08002343 }
2344
Romain Guy48327452017-01-23 17:03:35 -08002345 if ((base.colorMode & COLOR_MODE_HDR_MASK) !=
2346 (change.colorMode & COLOR_MODE_HDR_MASK)) {
2347 delta.colorMode |= change.colorMode & COLOR_MODE_HDR_MASK;
Romain Guyc9ba5592017-01-18 16:34:42 -08002348 }
2349
Adam Lesinski7f61e962014-09-02 16:43:52 -07002350 if ((base.uiMode & UI_MODE_TYPE_MASK) != (change.uiMode & UI_MODE_TYPE_MASK)) {
2351 delta.uiMode |= change.uiMode & UI_MODE_TYPE_MASK;
2352 }
2353
2354 if ((base.uiMode & UI_MODE_NIGHT_MASK) != (change.uiMode & UI_MODE_NIGHT_MASK)) {
2355 delta.uiMode |= change.uiMode & UI_MODE_NIGHT_MASK;
2356 }
2357
2358 if (base.screenWidthDp != change.screenWidthDp) {
2359 delta.screenWidthDp = change.screenWidthDp;
2360 }
2361
2362 if (base.screenHeightDp != change.screenHeightDp) {
2363 delta.screenHeightDp = change.screenHeightDp;
2364 }
2365
2366 if (base.smallestScreenWidthDp != change.smallestScreenWidthDp) {
2367 delta.smallestScreenWidthDp = change.smallestScreenWidthDp;
2368 }
2369
2370 if (base.densityDpi != change.densityDpi) {
2371 delta.densityDpi = change.densityDpi;
2372 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01002373
2374 if (base.assetsSeq != change.assetsSeq) {
2375 delta.assetsSeq = change.assetsSeq;
2376 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07002377
2378 if (!base.windowConfiguration.equals(change.windowConfiguration)) {
2379 delta.windowConfiguration.setTo(change.windowConfiguration);
2380 }
Adam Lesinski7f61e962014-09-02 16:43:52 -07002381 return delta;
2382 }
2383
2384 private static final String XML_ATTR_FONT_SCALE = "fs";
2385 private static final String XML_ATTR_MCC = "mcc";
2386 private static final String XML_ATTR_MNC = "mnc";
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002387 private static final String XML_ATTR_LOCALES = "locales";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002388 private static final String XML_ATTR_TOUCHSCREEN = "touch";
2389 private static final String XML_ATTR_KEYBOARD = "key";
2390 private static final String XML_ATTR_KEYBOARD_HIDDEN = "keyHid";
2391 private static final String XML_ATTR_HARD_KEYBOARD_HIDDEN = "hardKeyHid";
2392 private static final String XML_ATTR_NAVIGATION = "nav";
2393 private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
2394 private static final String XML_ATTR_ORIENTATION = "ori";
Bryce Leec1f2f2a2017-06-22 15:29:42 -07002395 private static final String XML_ATTR_ROTATION = "rot";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002396 private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
Romain Guy48327452017-01-23 17:03:35 -08002397 private static final String XML_ATTR_COLOR_MODE = "clrMod";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002398 private static final String XML_ATTR_UI_MODE = "ui";
2399 private static final String XML_ATTR_SCREEN_WIDTH = "width";
2400 private static final String XML_ATTR_SCREEN_HEIGHT = "height";
2401 private static final String XML_ATTR_SMALLEST_WIDTH = "sw";
2402 private static final String XML_ATTR_DENSITY = "density";
Bryce Lee7566d762017-03-30 09:34:15 -07002403 private static final String XML_ATTR_APP_BOUNDS = "app_bounds";
Adam Lesinski7f61e962014-09-02 16:43:52 -07002404
2405 /**
2406 * Reads the attributes corresponding to Configuration member fields from the Xml parser.
2407 * The parser is expected to be on a tag which has Configuration attributes.
2408 *
2409 * @param parser The Xml parser from which to read attributes.
2410 * @param configOut The Configuration to populate from the Xml attributes.
2411 * {@hide}
2412 */
2413 public static void readXmlAttrs(XmlPullParser parser, Configuration configOut)
2414 throws XmlPullParserException, IOException {
2415 configOut.fontScale = Float.intBitsToFloat(
2416 XmlUtils.readIntAttribute(parser, XML_ATTR_FONT_SCALE, 0));
2417 configOut.mcc = XmlUtils.readIntAttribute(parser, XML_ATTR_MCC, 0);
2418 configOut.mnc = XmlUtils.readIntAttribute(parser, XML_ATTR_MNC, 0);
2419
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002420 final String localesStr = XmlUtils.readStringAttribute(parser, XML_ATTR_LOCALES);
2421 configOut.mLocaleList = LocaleList.forLanguageTags(localesStr);
Roozbeh Pournaderfee44842016-02-04 15:24:24 -08002422 configOut.locale = configOut.mLocaleList.get(0);
Adam Lesinski7f61e962014-09-02 16:43:52 -07002423
2424 configOut.touchscreen = XmlUtils.readIntAttribute(parser, XML_ATTR_TOUCHSCREEN,
2425 TOUCHSCREEN_UNDEFINED);
2426 configOut.keyboard = XmlUtils.readIntAttribute(parser, XML_ATTR_KEYBOARD,
2427 KEYBOARD_UNDEFINED);
2428 configOut.keyboardHidden = XmlUtils.readIntAttribute(parser, XML_ATTR_KEYBOARD_HIDDEN,
2429 KEYBOARDHIDDEN_UNDEFINED);
2430 configOut.hardKeyboardHidden =
2431 XmlUtils.readIntAttribute(parser, XML_ATTR_HARD_KEYBOARD_HIDDEN,
2432 HARDKEYBOARDHIDDEN_UNDEFINED);
2433 configOut.navigation = XmlUtils.readIntAttribute(parser, XML_ATTR_NAVIGATION,
2434 NAVIGATION_UNDEFINED);
2435 configOut.navigationHidden = XmlUtils.readIntAttribute(parser, XML_ATTR_NAVIGATION_HIDDEN,
2436 NAVIGATIONHIDDEN_UNDEFINED);
2437 configOut.orientation = XmlUtils.readIntAttribute(parser, XML_ATTR_ORIENTATION,
2438 ORIENTATION_UNDEFINED);
2439 configOut.screenLayout = XmlUtils.readIntAttribute(parser, XML_ATTR_SCREEN_LAYOUT,
2440 SCREENLAYOUT_UNDEFINED);
Romain Guy48327452017-01-23 17:03:35 -08002441 configOut.colorMode = XmlUtils.readIntAttribute(parser, XML_ATTR_COLOR_MODE,
2442 COLOR_MODE_UNDEFINED);
Adam Lesinski7f61e962014-09-02 16:43:52 -07002443 configOut.uiMode = XmlUtils.readIntAttribute(parser, XML_ATTR_UI_MODE, 0);
2444 configOut.screenWidthDp = XmlUtils.readIntAttribute(parser, XML_ATTR_SCREEN_WIDTH,
2445 SCREEN_WIDTH_DP_UNDEFINED);
2446 configOut.screenHeightDp = XmlUtils.readIntAttribute(parser, XML_ATTR_SCREEN_HEIGHT,
2447 SCREEN_HEIGHT_DP_UNDEFINED);
2448 configOut.smallestScreenWidthDp =
2449 XmlUtils.readIntAttribute(parser, XML_ATTR_SMALLEST_WIDTH,
2450 SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
2451 configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY,
2452 DENSITY_DPI_UNDEFINED);
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01002453
Wale Ogunwale822e5122017-07-26 06:02:24 -07002454 // For persistence, we don't care about assetsSeq and WindowConfiguration, so do not read it
2455 // out.
Adam Lesinski7f61e962014-09-02 16:43:52 -07002456 }
2457
2458
2459 /**
2460 * Writes the Configuration's member fields as attributes into the XmlSerializer.
2461 * The serializer is expected to have already started a tag so that attributes can be
2462 * immediately written.
2463 *
2464 * @param xml The serializer to which to write the attributes.
2465 * @param config The Configuration whose member fields to write.
2466 * {@hide}
2467 */
2468 public static void writeXmlAttrs(XmlSerializer xml, Configuration config) throws IOException {
2469 XmlUtils.writeIntAttribute(xml, XML_ATTR_FONT_SCALE,
2470 Float.floatToIntBits(config.fontScale));
2471 if (config.mcc != 0) {
2472 XmlUtils.writeIntAttribute(xml, XML_ATTR_MCC, config.mcc);
2473 }
2474 if (config.mnc != 0) {
2475 XmlUtils.writeIntAttribute(xml, XML_ATTR_MNC, config.mnc);
2476 }
Roozbeh Pournaderb46fdd42015-08-19 14:56:22 -07002477 config.fixUpLocaleList();
2478 if (!config.mLocaleList.isEmpty()) {
2479 XmlUtils.writeStringAttribute(xml, XML_ATTR_LOCALES, config.mLocaleList.toLanguageTags());
Adam Lesinski7f61e962014-09-02 16:43:52 -07002480 }
2481 if (config.touchscreen != TOUCHSCREEN_UNDEFINED) {
2482 XmlUtils.writeIntAttribute(xml, XML_ATTR_TOUCHSCREEN, config.touchscreen);
2483 }
2484 if (config.keyboard != KEYBOARD_UNDEFINED) {
2485 XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD, config.keyboard);
2486 }
2487 if (config.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED) {
2488 XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD_HIDDEN, config.keyboardHidden);
2489 }
2490 if (config.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED) {
2491 XmlUtils.writeIntAttribute(xml, XML_ATTR_HARD_KEYBOARD_HIDDEN,
2492 config.hardKeyboardHidden);
2493 }
2494 if (config.navigation != NAVIGATION_UNDEFINED) {
2495 XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION, config.navigation);
2496 }
2497 if (config.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED) {
2498 XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION_HIDDEN, config.navigationHidden);
2499 }
2500 if (config.orientation != ORIENTATION_UNDEFINED) {
2501 XmlUtils.writeIntAttribute(xml, XML_ATTR_ORIENTATION, config.orientation);
2502 }
2503 if (config.screenLayout != SCREENLAYOUT_UNDEFINED) {
2504 XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_LAYOUT, config.screenLayout);
2505 }
Romain Guy48327452017-01-23 17:03:35 -08002506 if (config.colorMode != COLOR_MODE_UNDEFINED) {
2507 XmlUtils.writeIntAttribute(xml, XML_ATTR_COLOR_MODE, config.colorMode);
Romain Guyc9ba5592017-01-18 16:34:42 -08002508 }
Adam Lesinski7f61e962014-09-02 16:43:52 -07002509 if (config.uiMode != 0) {
2510 XmlUtils.writeIntAttribute(xml, XML_ATTR_UI_MODE, config.uiMode);
2511 }
2512 if (config.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
2513 XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_WIDTH, config.screenWidthDp);
2514 }
2515 if (config.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
2516 XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_HEIGHT, config.screenHeightDp);
2517 }
2518 if (config.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2519 XmlUtils.writeIntAttribute(xml, XML_ATTR_SMALLEST_WIDTH, config.smallestScreenWidthDp);
2520 }
2521 if (config.densityDpi != DENSITY_DPI_UNDEFINED) {
2522 XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi);
2523 }
Mårten Kongstad49a4a1d2017-01-12 08:36:37 +01002524
Wale Ogunwale822e5122017-07-26 06:02:24 -07002525 // For persistence, we do not care about assetsSeq and window configuration, so do not write
2526 // it out.
Adam Lesinski7f61e962014-09-02 16:43:52 -07002527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528}