blob: a07fc9708b7f8ac93bfc2d681c1724d5be3f8413 [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
19import android.content.pm.ActivityInfo;
20import android.os.Parcel;
21import android.os.Parcelable;
Fabrice Di Megliod3d9f3f2012-09-18 12:55:32 -070022import android.text.TextUtils;
Fabrice Di Meglio3fb824b2012-02-28 17:58:31 -080023import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
25import java.util.Locale;
26
27/**
28 * This class describes all device configuration information that can
29 * impact the resources the application retrieves. This includes both
30 * user-specified configuration options (locale and scaling) as well
Scott Main63848e32011-04-20 22:20:46 -070031 * as device configurations (such as input modes, screen size and screen orientation).
32 * <p>You can acquire this object from {@link Resources}, using {@link
33 * Resources#getConfiguration}. Thus, from an activity, you can get it by chaining the request
34 * with {@link android.app.Activity#getResources}:</p>
35 * <pre>Configuration config = getResources().getConfiguration();</pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036 */
37public final class Configuration implements Parcelable, Comparable<Configuration> {
Dianne Hackborn756220b2012-08-14 16:45:30 -070038 /** @hide */
39 public static final Configuration EMPTY = new Configuration();
40
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 /**
42 * Current user preference for the scaling factor for fonts, relative
43 * to the base density scaling.
44 */
45 public float fontScale;
46
47 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070048 * IMSI MCC (Mobile Country Code), corresponding to
49 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mcc</a>
50 * resource qualifier. 0 if undefined.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 */
52 public int mcc;
53
54 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070055 * IMSI MNC (Mobile Network Code), corresponding to
56 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mnc</a>
Mattias Petersson1d766b52011-10-07 09:33:52 +020057 * resource qualifier. 0 if undefined. Note that the actual MNC may be 0; in order to check
58 * for this use the {@link #MNC_ZERO} symbol.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 */
60 public int mnc;
Mattias Petersson1d766b52011-10-07 09:33:52 +020061
62 /**
63 * Constant used to to represent MNC (Mobile Network Code) zero.
64 * 0 cannot be used, since it is used to represent an undefined MNC.
65 */
66 public static final int MNC_ZERO = 0xffff;
67
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070069 * Current user preference for the locale, corresponding to
70 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
71 * resource qualifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 */
73 public Locale locale;
74
75 /**
Andy Stadlerf8a7cea2009-04-10 16:24:47 -070076 * Locale should persist on setting. This is hidden because it is really
77 * questionable whether this is the right way to expose the functionality.
78 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 */
80 public boolean userSetLocale;
81
Dianne Hackborn2f98f262011-03-28 18:28:35 -070082 /** Constant for {@link #screenLayout}: bits that encode the size. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -070083 public static final int SCREENLAYOUT_SIZE_MASK = 0x0f;
Dianne Hackborn2f98f262011-03-28 18:28:35 -070084 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
85 * value indicating that no size has been set. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -070086 public static final int SCREENLAYOUT_SIZE_UNDEFINED = 0x00;
Dianne Hackborn2f98f262011-03-28 18:28:35 -070087 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070088 * value indicating the screen is at least approximately 320x426 dp units,
89 * corresponds to the
90 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">small</a>
91 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -070092 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
93 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -070094 public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
Dianne Hackborn2f98f262011-03-28 18:28:35 -070095 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -070096 * value indicating the screen is at least approximately 320x470 dp units,
97 * corresponds to the
98 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">normal</a>
99 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700100 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
101 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700102 public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700103 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700104 * value indicating the screen is at least approximately 480x640 dp units,
105 * corresponds to the
106 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">large</a>
107 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700108 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
109 * Multiple Screens</a> for more information. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700110 public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700111 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK}
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700112 * value indicating the screen is at least approximately 720x960 dp units,
113 * corresponds to the
114 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenSizeQualifier">xlarge</a>
115 * resource qualifier.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700116 * See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
117 * Multiple Screens</a> for more information.*/
Dianne Hackborn14cee9f2010-04-23 17:51:26 -0700118 public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700119
120 /** Constant for {@link #screenLayout}: bits that encode the aspect ratio. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700121 public static final int SCREENLAYOUT_LONG_MASK = 0x30;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700122 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
123 * value indicating that no size has been set. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700124 public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700125 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
126 * value that corresponds to the
127 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">notlong</a>
128 * resource qualifier. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700129 public static final int SCREENLAYOUT_LONG_NO = 0x10;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700130 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LONG_MASK}
131 * value that corresponds to the
132 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">long</a>
133 * resource qualifier. */
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700134 public static final int SCREENLAYOUT_LONG_YES = 0x20;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700135
136 /** Constant for {@link #screenLayout}: bits that encode the layout direction. */
137 public static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
138 /** Constant for {@link #screenLayout}: bits shift to get the layout direction. */
139 public static final int SCREENLAYOUT_LAYOUTDIR_SHIFT = 6;
140 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
141 * value indicating that no layout dir has been set. */
142 public static final int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0x00;
143 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
144 * value indicating that a layout dir has been set to LTR. */
145 public static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x01 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
146 /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
147 * value indicating that a layout dir has been set to RTL. */
148 public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x02 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
149
150 /** Constant for {@link #screenLayout}: a value indicating that screenLayout is undefined */
151 public static final int SCREENLAYOUT_UNDEFINED = SCREENLAYOUT_SIZE_UNDEFINED |
152 SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED;
153
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700154 /**
155 * Special flag we generate to indicate that the screen layout requires
156 * us to use a compatibility mode for apps that are not modern layout
157 * aware.
158 * @hide
159 */
160 public static final int SCREENLAYOUT_COMPAT_NEEDED = 0x10000000;
161
162 /**
163 * Bit mask of overall layout of the screen. Currently there are two
164 * fields:
165 * <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
166 * of the screen. They may be one of
167 * {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
Dianne Hackborn14cee9f2010-04-23 17:51:26 -0700168 * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700169 *
170 * <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
171 * is wider/taller than normal. They may be one of
172 * {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700173 *
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700174 * <p>The {@link #SCREENLAYOUT_LAYOUTDIR_MASK} defines whether the screen layout
175 * is either LTR or RTL. They may be one of
176 * {@link #SCREENLAYOUT_LAYOUTDIR_LTR} or {@link #SCREENLAYOUT_LAYOUTDIR_RTL}.
177 *
Dianne Hackborn2f98f262011-03-28 18:28:35 -0700178 * <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
179 * Multiple Screens</a> for more information.
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700180 */
181 public int screenLayout;
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -0700182
183 /** @hide */
184 static public int resetScreenLayout(int curLayout) {
185 return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK
186 | SCREENLAYOUT_COMPAT_NEEDED))
187 | (SCREENLAYOUT_LONG_YES | SCREENLAYOUT_SIZE_XLARGE);
188 }
189
190 /** @hide */
191 static public int reduceScreenLayout(int curLayout, int longSizeDp, int shortSizeDp) {
192 int screenLayoutSize;
193 boolean screenLayoutLong;
194 boolean screenLayoutCompatNeeded;
195
196 // These semi-magic numbers define our compatibility modes for
197 // applications with different screens. These are guarantees to
198 // app developers about the space they can expect for a particular
199 // configuration. DO NOT CHANGE!
200 if (longSizeDp < 470) {
201 // This is shorter than an HVGA normal density screen (which
202 // is 480 pixels on its long side).
203 screenLayoutSize = SCREENLAYOUT_SIZE_SMALL;
204 screenLayoutLong = false;
205 screenLayoutCompatNeeded = false;
206 } else {
207 // What size is this screen screen?
208 if (longSizeDp >= 960 && shortSizeDp >= 720) {
209 // 1.5xVGA or larger screens at medium density are the point
210 // at which we consider it to be an extra large screen.
211 screenLayoutSize = SCREENLAYOUT_SIZE_XLARGE;
212 } else if (longSizeDp >= 640 && shortSizeDp >= 480) {
213 // VGA or larger screens at medium density are the point
214 // at which we consider it to be a large screen.
215 screenLayoutSize = SCREENLAYOUT_SIZE_LARGE;
216 } else {
217 screenLayoutSize = SCREENLAYOUT_SIZE_NORMAL;
218 }
219
220 // If this screen is wider than normal HVGA, or taller
221 // than FWVGA, then for old apps we want to run in size
222 // compatibility mode.
223 if (shortSizeDp > 321 || longSizeDp > 570) {
224 screenLayoutCompatNeeded = true;
225 } else {
226 screenLayoutCompatNeeded = false;
227 }
228
229 // Is this a long screen?
230 if (((longSizeDp*3)/5) >= (shortSizeDp-1)) {
231 // Anything wider than WVGA (5:3) is considering to be long.
232 screenLayoutLong = true;
233 } else {
234 screenLayoutLong = false;
235 }
236 }
237
238 // Now reduce the last screenLayout to not be better than what we
239 // have found.
240 if (!screenLayoutLong) {
241 curLayout = (curLayout&~SCREENLAYOUT_LONG_MASK) | SCREENLAYOUT_LONG_NO;
242 }
243 if (screenLayoutCompatNeeded) {
244 curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
245 }
246 int curSize = curLayout&SCREENLAYOUT_SIZE_MASK;
247 if (screenLayoutSize < curSize) {
248 curLayout = (curLayout&~SCREENLAYOUT_SIZE_MASK) | screenLayoutSize;
249 }
250 return curLayout;
251 }
252
Dianne Hackborn711e62a2010-11-29 16:38:22 -0800253 /**
254 * Check if the Configuration's current {@link #screenLayout} is at
255 * least the given size.
256 *
257 * @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
258 * {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
259 * {@link #SCREENLAYOUT_SIZE_XLARGE}.
260 * @return Returns true if the current screen layout size is at least
261 * the given size.
262 */
263 public boolean isLayoutSizeAtLeast(int size) {
264 int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
265 if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
Dianne Hackborn7d3a5bc2010-11-29 22:52:12 -0800266 return cur >= size;
Dianne Hackborn711e62a2010-11-29 16:38:22 -0800267 }
268
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700269 /** Constant for {@link #touchscreen}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 public static final int TOUCHSCREEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700271 /** Constant for {@link #touchscreen}, value corresponding to the
272 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#TouchscreenQualifier">notouch</a>
273 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 public static final int TOUCHSCREEN_NOTOUCH = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700275 /** @deprecated Not currently supported or used. */
276 @Deprecated public static final int TOUCHSCREEN_STYLUS = 2;
277 /** Constant for {@link #touchscreen}, value corresponding to the
278 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#TouchscreenQualifier">finger</a>
279 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 public static final int TOUCHSCREEN_FINGER = 3;
281
282 /**
283 * The kind of touch screen attached to the device.
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700284 * One of: {@link #TOUCHSCREEN_NOTOUCH}, {@link #TOUCHSCREEN_FINGER}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 */
286 public int touchscreen;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700287
288 /** Constant for {@link #keyboard}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 public static final int KEYBOARD_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700290 /** Constant for {@link #keyboard}, value corresponding to the
291 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">nokeys</a>
292 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 public static final int KEYBOARD_NOKEYS = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700294 /** Constant for {@link #keyboard}, value corresponding to the
295 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">qwerty</a>
296 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 public static final int KEYBOARD_QWERTY = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700298 /** Constant for {@link #keyboard}, value corresponding to the
299 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ImeQualifier">12key</a>
300 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 public static final int KEYBOARD_12KEY = 3;
302
303 /**
304 * The kind of keyboard attached to the device.
Kenny Root507f8ed2009-06-09 11:21:11 -0500305 * One of: {@link #KEYBOARD_NOKEYS}, {@link #KEYBOARD_QWERTY},
306 * {@link #KEYBOARD_12KEY}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 */
308 public int keyboard;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700309
310 /** Constant for {@link #keyboardHidden}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700312 /** Constant for {@link #keyboardHidden}, value corresponding to the
313 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keysexposed</a>
314 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 public static final int KEYBOARDHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700316 /** Constant for {@link #keyboardHidden}, value corresponding to the
317 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyshidden</a>
318 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 public static final int KEYBOARDHIDDEN_YES = 2;
320 /** Constant matching actual resource implementation. {@hide} */
321 public static final int KEYBOARDHIDDEN_SOFT = 3;
322
323 /**
324 * A flag indicating whether any keyboard is available. Unlike
325 * {@link #hardKeyboardHidden}, this also takes into account a soft
326 * keyboard, so if the hard keyboard is hidden but there is soft
327 * keyboard available, it will be set to NO. Value is one of:
328 * {@link #KEYBOARDHIDDEN_NO}, {@link #KEYBOARDHIDDEN_YES}.
329 */
330 public int keyboardHidden;
331
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700332 /** Constant for {@link #hardKeyboardHidden}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700334 /** Constant for {@link #hardKeyboardHidden}, value corresponding to the
335 * physical keyboard being exposed. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 public static final int HARDKEYBOARDHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700337 /** Constant for {@link #hardKeyboardHidden}, value corresponding to the
338 * physical keyboard being hidden. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 public static final int HARDKEYBOARDHIDDEN_YES = 2;
340
341 /**
342 * A flag indicating whether the hard keyboard has been hidden. This will
343 * be set on a device with a mechanism to hide the keyboard from the
344 * user, when that mechanism is closed. One of:
345 * {@link #HARDKEYBOARDHIDDEN_NO}, {@link #HARDKEYBOARDHIDDEN_YES}.
346 */
347 public int hardKeyboardHidden;
348
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700349 /** Constant for {@link #navigation}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 public static final int NAVIGATION_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700351 /** Constant for {@link #navigation}, value corresponding to the
352 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">nonav</a>
353 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 public static final int NAVIGATION_NONAV = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700355 /** Constant for {@link #navigation}, value corresponding to the
356 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">dpad</a>
357 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 public static final int NAVIGATION_DPAD = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700359 /** Constant for {@link #navigation}, value corresponding to the
360 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">trackball</a>
361 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 public static final int NAVIGATION_TRACKBALL = 3;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700363 /** Constant for {@link #navigation}, value corresponding to the
364 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavigationQualifier">wheel</a>
365 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 public static final int NAVIGATION_WHEEL = 4;
367
368 /**
369 * The kind of navigation method available on the device.
Kenny Root507f8ed2009-06-09 11:21:11 -0500370 * One of: {@link #NAVIGATION_NONAV}, {@link #NAVIGATION_DPAD},
371 * {@link #NAVIGATION_TRACKBALL}, {@link #NAVIGATION_WHEEL}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 */
373 public int navigation;
374
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700375 /** Constant for {@link #navigationHidden}: a value indicating that no value has been set. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700376 public static final int NAVIGATIONHIDDEN_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700377 /** Constant for {@link #navigationHidden}, value corresponding to the
378 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavAvailQualifier">navexposed</a>
379 * resource qualifier. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700380 public static final int NAVIGATIONHIDDEN_NO = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700381 /** Constant for {@link #navigationHidden}, value corresponding to the
382 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NavAvailQualifier">navhidden</a>
383 * resource qualifier. */
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700384 public static final int NAVIGATIONHIDDEN_YES = 2;
385
386 /**
387 * A flag indicating whether any 5-way or DPAD navigation available.
388 * This will be set on a device with a mechanism to hide the navigation
389 * controls from the user, when that mechanism is closed. One of:
390 * {@link #NAVIGATIONHIDDEN_NO}, {@link #NAVIGATIONHIDDEN_YES}.
391 */
392 public int navigationHidden;
393
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700394 /** Constant for {@link #orientation}: a value indicating that no value has been set. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 public static final int ORIENTATION_UNDEFINED = 0;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700396 /** Constant for {@link #orientation}, value corresponding to the
397 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#OrientationQualifier">port</a>
398 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 public static final int ORIENTATION_PORTRAIT = 1;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700400 /** Constant for {@link #orientation}, value corresponding to the
401 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#OrientationQualifier">land</a>
402 * resource qualifier. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 public static final int ORIENTATION_LANDSCAPE = 2;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700404 /** @deprecated Not currently supported or used. */
405 @Deprecated public static final int ORIENTATION_SQUARE = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406
407 /**
408 * Overall orientation of the screen. May be one of
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700409 * {@link #ORIENTATION_LANDSCAPE}, {@link #ORIENTATION_PORTRAIT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 */
411 public int orientation;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100412
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700413 /** Constant for {@link #uiMode}: bits that encode the mode type. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100414 public static final int UI_MODE_TYPE_MASK = 0x0f;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700415 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
416 * value indicating that no mode type has been set. */
Dianne Hackbornef05e072010-03-01 17:43:39 -0800417 public static final int UI_MODE_TYPE_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700418 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
419 * value that corresponds to
420 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">no
421 * UI mode</a> resource qualifier specified. */
Dianne Hackbornef05e072010-03-01 17:43:39 -0800422 public static final int UI_MODE_TYPE_NORMAL = 0x01;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700423 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
424 * value that corresponds to the
425 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">desk</a>
426 * resource qualifier. */
Dianne Hackborn7299c412010-03-04 18:41:49 -0800427 public static final int UI_MODE_TYPE_DESK = 0x02;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700428 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
429 * value that corresponds to the
430 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">car</a>
431 * resource qualifier. */
Dianne Hackborn7299c412010-03-04 18:41:49 -0800432 public static final int UI_MODE_TYPE_CAR = 0x03;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700433 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
434 * value that corresponds to the
435 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">television</a>
436 * resource qualifier. */
Dianne Hackborne360bb62011-05-20 16:11:04 -0700437 public static final int UI_MODE_TYPE_TELEVISION = 0x04;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700438 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
439 * value that corresponds to the
440 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">appliance</a>
441 * resource qualifier. */
Joe Onorato44fcb832011-12-14 20:59:30 -0800442 public static final int UI_MODE_TYPE_APPLIANCE = 0x05;
John Spurlock6c191292014-04-03 16:37:27 -0400443 /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
444 * value that corresponds to the
445 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#UiModeQualifier">watch</a>
446 * resource qualifier. */
447 public static final int UI_MODE_TYPE_WATCH = 0x06;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100448
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700449 /** Constant for {@link #uiMode}: bits that encode the night mode. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100450 public static final int UI_MODE_NIGHT_MASK = 0x30;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700451 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
452 * value indicating that no mode type has been set. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100453 public static final int UI_MODE_NIGHT_UNDEFINED = 0x00;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700454 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
455 * value that corresponds to the
456 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NightQualifier">notnight</a>
457 * resource qualifier. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100458 public static final int UI_MODE_NIGHT_NO = 0x10;
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700459 /** Constant for {@link #uiMode}: a {@link #UI_MODE_NIGHT_MASK}
460 * value that corresponds to the
461 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#NightQualifier">night</a>
462 * resource qualifier. */
Tobias Haamel27b28b32010-02-09 23:09:17 +0100463 public static final int UI_MODE_NIGHT_YES = 0x20;
464
465 /**
466 * Bit mask of the ui mode. Currently there are two fields:
467 * <p>The {@link #UI_MODE_TYPE_MASK} bits define the overall ui mode of the
Dianne Hackborn7299c412010-03-04 18:41:49 -0800468 * device. They may be one of {@link #UI_MODE_TYPE_UNDEFINED},
469 * {@link #UI_MODE_TYPE_NORMAL}, {@link #UI_MODE_TYPE_DESK},
John Spurlock6c191292014-04-03 16:37:27 -0400470 * {@link #UI_MODE_TYPE_CAR}, {@link #UI_MODE_TYPE_TELEVISION},
471 * {@link #UI_MODE_TYPE_APPLIANCE}, or {@link #UI_MODE_TYPE_WATCH}.
Tobias Haamel27b28b32010-02-09 23:09:17 +0100472 *
473 * <p>The {@link #UI_MODE_NIGHT_MASK} defines whether the screen
Dianne Hackborn7299c412010-03-04 18:41:49 -0800474 * is in a special mode. They may be one of {@link #UI_MODE_NIGHT_UNDEFINED},
Tobias Haamel27b28b32010-02-09 23:09:17 +0100475 * {@link #UI_MODE_NIGHT_NO} or {@link #UI_MODE_NIGHT_YES}.
Tobias Haamel27b28b32010-02-09 23:09:17 +0100476 */
477 public int uiMode;
478
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700479 /**
480 * Default value for {@link #screenWidthDp} indicating that no width
481 * has been specified.
482 */
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700483 public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
484
485 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700486 * The current width of the available screen space, in dp units,
487 * corresponding to
488 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenWidthQualifier">screen
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700489 * width</a> resource qualifier. Set to
490 * {@link #SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700491 */
492 public int screenWidthDp;
493
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700494 /**
495 * Default value for {@link #screenHeightDp} indicating that no width
496 * has been specified.
497 */
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700498 public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
499
500 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700501 * The current height of the available screen space, in dp units,
502 * corresponding to
503 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenHeightQualifier">screen
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700504 * height</a> resource qualifier. Set to
505 * {@link #SCREEN_HEIGHT_DP_UNDEFINED} if no height is specified.
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700506 */
507 public int screenHeightDp;
508
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700509 /**
510 * Default value for {@link #smallestScreenWidthDp} indicating that no width
511 * has been specified.
512 */
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700513 public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0;
514
515 /**
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700516 * The smallest screen size an application will see in normal operation,
517 * corresponding to
518 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">smallest
519 * screen width</a> resource qualifier.
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700520 * This is the smallest value of both screenWidthDp and screenHeightDp
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700521 * in both portrait and landscape. Set to
522 * {@link #SMALLEST_SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700523 */
524 public int smallestScreenWidthDp;
525
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700526 /**
527 * Default value for {@link #densityDpi} indicating that no width
528 * has been specified.
529 */
530 public static final int DENSITY_DPI_UNDEFINED = 0;
531
532 /**
533 * The target screen density being rendered to,
534 * corresponding to
535 * <a href="{@docRoot}guide/topics/resources/providing-resources.html#DensityQualifier">density</a>
536 * resource qualifier. Set to
537 * {@link #DENSITY_DPI_UNDEFINED} if no density is specified.
538 */
539 public int densityDpi;
540
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700541 /** @hide Hack to get this information from WM to app running in compat mode. */
542 public int compatScreenWidthDp;
543 /** @hide Hack to get this information from WM to app running in compat mode. */
544 public int compatScreenHeightDp;
545 /** @hide Hack to get this information from WM to app running in compat mode. */
546 public int compatSmallestScreenWidthDp;
547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800549 * @hide Internal book-keeping.
550 */
551 public int seq;
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700552
553 /** @hide Native-specific bit mask for MCC config; DO NOT USE UNLESS YOU ARE SURE. */
554 public static final int NATIVE_CONFIG_MCC = 0x0001;
555 /** @hide Native-specific bit mask for MNC config; DO NOT USE UNLESS YOU ARE SURE. */
556 public static final int NATIVE_CONFIG_MNC = 0x0002;
557 /** @hide Native-specific bit mask for LOCALE config; DO NOT USE UNLESS YOU ARE SURE. */
558 public static final int NATIVE_CONFIG_LOCALE = 0x0004;
559 /** @hide Native-specific bit mask for TOUCHSCREEN config; DO NOT USE UNLESS YOU ARE SURE. */
560 public static final int NATIVE_CONFIG_TOUCHSCREEN = 0x0008;
561 /** @hide Native-specific bit mask for KEYBOARD config; DO NOT USE UNLESS YOU ARE SURE. */
562 public static final int NATIVE_CONFIG_KEYBOARD = 0x0010;
563 /** @hide Native-specific bit mask for KEYBOARD_HIDDEN config; DO NOT USE UNLESS YOU
564 * ARE SURE. */
565 public static final int NATIVE_CONFIG_KEYBOARD_HIDDEN = 0x0020;
566 /** @hide Native-specific bit mask for NAVIGATION config; DO NOT USE UNLESS YOU ARE SURE. */
567 public static final int NATIVE_CONFIG_NAVIGATION = 0x0040;
568 /** @hide Native-specific bit mask for ORIENTATION config; DO NOT USE UNLESS YOU ARE SURE. */
569 public static final int NATIVE_CONFIG_ORIENTATION = 0x0080;
570 /** @hide Native-specific bit mask for DENSITY config; DO NOT USE UNLESS YOU ARE SURE. */
571 public static final int NATIVE_CONFIG_DENSITY = 0x0100;
572 /** @hide Native-specific bit mask for SCREEN_SIZE config; DO NOT USE UNLESS YOU ARE SURE. */
573 public static final int NATIVE_CONFIG_SCREEN_SIZE = 0x0200;
574 /** @hide Native-specific bit mask for VERSION config; DO NOT USE UNLESS YOU ARE SURE. */
575 public static final int NATIVE_CONFIG_VERSION = 0x0400;
576 /** @hide Native-specific bit mask for SCREEN_LAYOUT config; DO NOT USE UNLESS YOU ARE SURE. */
577 public static final int NATIVE_CONFIG_SCREEN_LAYOUT = 0x0800;
578 /** @hide Native-specific bit mask for UI_MODE config; DO NOT USE UNLESS YOU ARE SURE. */
579 public static final int NATIVE_CONFIG_UI_MODE = 0x1000;
580 /** @hide Native-specific bit mask for SMALLEST_SCREEN_SIZE config; DO NOT USE UNLESS YOU
581 * ARE SURE. */
582 public static final int NATIVE_CONFIG_SMALLEST_SCREEN_SIZE = 0x2000;
583 /** @hide Native-specific bit mask for LAYOUTDIR config ; DO NOT USE UNLESS YOU ARE SURE.*/
584 public static final int NATIVE_CONFIG_LAYOUTDIR = 0x4000;
585
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800586 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 * Construct an invalid Configuration. You must call {@link #setToDefaults}
588 * for this object to be valid. {@more}
589 */
590 public Configuration() {
591 setToDefaults();
592 }
593
594 /**
595 * Makes a deep copy suitable for modification.
596 */
597 public Configuration(Configuration o) {
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700598 setTo(o);
599 }
600
601 public void setTo(Configuration o) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 fontScale = o.fontScale;
603 mcc = o.mcc;
604 mnc = o.mnc;
605 if (o.locale != null) {
606 locale = (Locale) o.locale.clone();
607 }
608 userSetLocale = o.userSetLocale;
609 touchscreen = o.touchscreen;
610 keyboard = o.keyboard;
611 keyboardHidden = o.keyboardHidden;
612 hardKeyboardHidden = o.hardKeyboardHidden;
613 navigation = o.navigation;
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700614 navigationHidden = o.navigationHidden;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 orientation = o.orientation;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700616 screenLayout = o.screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +0100617 uiMode = o.uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700618 screenWidthDp = o.screenWidthDp;
619 screenHeightDp = o.screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700620 smallestScreenWidthDp = o.smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700621 densityDpi = o.densityDpi;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700622 compatScreenWidthDp = o.compatScreenWidthDp;
623 compatScreenHeightDp = o.compatScreenHeightDp;
624 compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800625 seq = o.seq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700629 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn29735682011-04-21 17:26:39 -0700630 sb.append("{");
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700631 sb.append(fontScale);
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700632 sb.append(" ");
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700633 if (mcc != 0) {
634 sb.append(mcc);
635 sb.append("mcc");
636 } else {
637 sb.append("?mcc");
638 }
639 if (mnc != 0) {
640 sb.append(mnc);
641 sb.append("mnc");
642 } else {
643 sb.append("?mnc");
644 }
Dianne Hackborn9a849832011-04-07 15:11:57 -0700645 if (locale != null) {
646 sb.append(" ");
647 sb.append(locale);
648 } else {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700649 sb.append(" ?locale");
Daniel Sandler7d6bddc2010-07-22 16:11:55 -0400650 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700651 int layoutDir = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK);
652 switch (layoutDir) {
653 case SCREENLAYOUT_LAYOUTDIR_UNDEFINED: sb.append(" ?layoutDir"); break;
Fabrice Di Meglio8a802db2012-09-05 13:12:02 -0700654 case SCREENLAYOUT_LAYOUTDIR_LTR: sb.append(" ldltr"); break;
655 case SCREENLAYOUT_LAYOUTDIR_RTL: sb.append(" ldrtl"); break;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700656 default: sb.append(" layoutDir=");
657 sb.append(layoutDir >> SCREENLAYOUT_LAYOUTDIR_SHIFT); break;
Fabrice Di Meglio7a736fb2011-06-09 20:20:36 -0700658 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700659 if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
660 sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
661 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700662 sb.append(" ?swdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700663 }
664 if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
665 sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");
666 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700667 sb.append(" ?wdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700668 }
669 if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
670 sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");
671 } else {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700672 sb.append(" ?hdp");
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700673 }
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700674 if (densityDpi != DENSITY_DPI_UNDEFINED) {
675 sb.append(" "); sb.append(densityDpi); sb.append("dpi");
676 } else {
677 sb.append(" ?density");
678 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700679 switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {
680 case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;
681 case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break;
682 case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break;
683 case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break;
684 case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break;
685 default: sb.append(" layoutSize=");
686 sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break;
687 }
688 switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) {
689 case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break;
690 case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break;
691 case SCREENLAYOUT_LONG_YES: sb.append(" long"); break;
692 default: sb.append(" layoutLong=");
693 sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break;
694 }
695 switch (orientation) {
696 case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break;
697 case ORIENTATION_LANDSCAPE: sb.append(" land"); break;
698 case ORIENTATION_PORTRAIT: sb.append(" port"); break;
699 default: sb.append(" orien="); sb.append(orientation); break;
700 }
701 switch ((uiMode&UI_MODE_TYPE_MASK)) {
702 case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
703 case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
704 case UI_MODE_TYPE_DESK: sb.append(" desk"); break;
705 case UI_MODE_TYPE_CAR: sb.append(" car"); break;
Dianne Hackborne360bb62011-05-20 16:11:04 -0700706 case UI_MODE_TYPE_TELEVISION: sb.append(" television"); break;
Joe Onorato44fcb832011-12-14 20:59:30 -0800707 case UI_MODE_TYPE_APPLIANCE: sb.append(" appliance"); break;
John Spurlock6c191292014-04-03 16:37:27 -0400708 case UI_MODE_TYPE_WATCH: sb.append(" watch"); break;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700709 default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break;
710 }
711 switch ((uiMode&UI_MODE_NIGHT_MASK)) {
712 case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break;
713 case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break;
714 case UI_MODE_NIGHT_YES: sb.append(" night"); break;
715 default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break;
716 }
Dianne Hackborn9a849832011-04-07 15:11:57 -0700717 switch (touchscreen) {
718 case TOUCHSCREEN_UNDEFINED: sb.append(" ?touch"); break;
719 case TOUCHSCREEN_NOTOUCH: sb.append(" -touch"); break;
720 case TOUCHSCREEN_STYLUS: sb.append(" stylus"); break;
721 case TOUCHSCREEN_FINGER: sb.append(" finger"); break;
722 default: sb.append(" touch="); sb.append(touchscreen); break;
723 }
724 switch (keyboard) {
725 case KEYBOARD_UNDEFINED: sb.append(" ?keyb"); break;
726 case KEYBOARD_NOKEYS: sb.append(" -keyb"); break;
727 case KEYBOARD_QWERTY: sb.append(" qwerty"); break;
728 case KEYBOARD_12KEY: sb.append(" 12key"); break;
729 default: sb.append(" keys="); sb.append(keyboard); break;
730 }
731 switch (keyboardHidden) {
732 case KEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;
733 case KEYBOARDHIDDEN_NO: sb.append("/v"); break;
734 case KEYBOARDHIDDEN_YES: sb.append("/h"); break;
735 case KEYBOARDHIDDEN_SOFT: sb.append("/s"); break;
736 default: sb.append("/"); sb.append(keyboardHidden); break;
737 }
738 switch (hardKeyboardHidden) {
739 case HARDKEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break;
740 case HARDKEYBOARDHIDDEN_NO: sb.append("/v"); break;
741 case HARDKEYBOARDHIDDEN_YES: sb.append("/h"); break;
742 default: sb.append("/"); sb.append(hardKeyboardHidden); break;
743 }
744 switch (navigation) {
745 case NAVIGATION_UNDEFINED: sb.append(" ?nav"); break;
746 case NAVIGATION_NONAV: sb.append(" -nav"); break;
747 case NAVIGATION_DPAD: sb.append(" dpad"); break;
748 case NAVIGATION_TRACKBALL: sb.append(" tball"); break;
749 case NAVIGATION_WHEEL: sb.append(" wheel"); break;
750 default: sb.append(" nav="); sb.append(navigation); break;
751 }
752 switch (navigationHidden) {
753 case NAVIGATIONHIDDEN_UNDEFINED: sb.append("/?"); break;
754 case NAVIGATIONHIDDEN_NO: sb.append("/v"); break;
755 case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
756 default: sb.append("/"); sb.append(navigationHidden); break;
757 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800758 if (seq != 0) {
Dianne Hackborn9a849832011-04-07 15:11:57 -0700759 sb.append(" s.");
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800760 sb.append(seq);
761 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700762 sb.append('}');
763 return sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 }
765
766 /**
767 * Set this object to the system defaults.
768 */
769 public void setToDefaults() {
770 fontScale = 1;
771 mcc = mnc = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800772 locale = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 userSetLocale = false;
774 touchscreen = TOUCHSCREEN_UNDEFINED;
775 keyboard = KEYBOARD_UNDEFINED;
776 keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
777 hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
778 navigation = NAVIGATION_UNDEFINED;
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700779 navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 orientation = ORIENTATION_UNDEFINED;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700781 screenLayout = SCREENLAYOUT_UNDEFINED;
Dianne Hackborn7299c412010-03-04 18:41:49 -0800782 uiMode = UI_MODE_TYPE_UNDEFINED;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700783 screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
784 screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
785 smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700786 densityDpi = DENSITY_DPI_UNDEFINED;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800787 seq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 }
789
790 /** {@hide} */
791 @Deprecated public void makeDefault() {
792 setToDefaults();
793 }
794
795 /**
796 * Copy the fields from delta into this Configuration object, keeping
797 * track of which ones have changed. Any undefined fields in
798 * <var>delta</var> are ignored and not copied in to the current
799 * Configuration.
800 * @return Returns a bit mask of the changed fields, as per
801 * {@link #diff}.
802 */
803 public int updateFrom(Configuration delta) {
804 int changed = 0;
805 if (delta.fontScale > 0 && fontScale != delta.fontScale) {
806 changed |= ActivityInfo.CONFIG_FONT_SCALE;
807 fontScale = delta.fontScale;
808 }
809 if (delta.mcc != 0 && mcc != delta.mcc) {
810 changed |= ActivityInfo.CONFIG_MCC;
811 mcc = delta.mcc;
812 }
813 if (delta.mnc != 0 && mnc != delta.mnc) {
814 changed |= ActivityInfo.CONFIG_MNC;
815 mnc = delta.mnc;
816 }
817 if (delta.locale != null
818 && (locale == null || !locale.equals(delta.locale))) {
819 changed |= ActivityInfo.CONFIG_LOCALE;
820 locale = delta.locale != null
821 ? (Locale) delta.locale.clone() : null;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700822 // If locale has changed, then layout direction is also changed ...
823 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
824 // ... and we need to update the layout direction (represented by the first
825 // 2 most significant bits in screenLayout).
826 setLayoutDirection(locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
Craig Mautner31678b52013-08-12 17:56:34 -0700828 final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
829 if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
830 deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
831 screenLayout = (screenLayout & ~SCREENLAYOUT_LAYOUTDIR_MASK) | deltaScreenLayoutDir;
Amith Yamasanid8415f42013-08-07 20:15:10 -0700832 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
Amith Yamasanid8415f42013-08-07 20:15:10 -0700833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
835 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 changed |= ActivityInfo.CONFIG_LOCALE;
Amith Yamasanid8415f42013-08-07 20:15:10 -0700837 userSetLocale = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 }
839 if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
840 && touchscreen != delta.touchscreen) {
841 changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
842 touchscreen = delta.touchscreen;
843 }
844 if (delta.keyboard != KEYBOARD_UNDEFINED
845 && keyboard != delta.keyboard) {
846 changed |= ActivityInfo.CONFIG_KEYBOARD;
847 keyboard = delta.keyboard;
848 }
849 if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
850 && keyboardHidden != delta.keyboardHidden) {
851 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
852 keyboardHidden = delta.keyboardHidden;
853 }
854 if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
855 && hardKeyboardHidden != delta.hardKeyboardHidden) {
856 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
857 hardKeyboardHidden = delta.hardKeyboardHidden;
858 }
859 if (delta.navigation != NAVIGATION_UNDEFINED
860 && navigation != delta.navigation) {
861 changed |= ActivityInfo.CONFIG_NAVIGATION;
862 navigation = delta.navigation;
863 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700864 if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
865 && navigationHidden != delta.navigationHidden) {
866 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
867 navigationHidden = delta.navigationHidden;
868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 if (delta.orientation != ORIENTATION_UNDEFINED
870 && orientation != delta.orientation) {
871 changed |= ActivityInfo.CONFIG_ORIENTATION;
872 orientation = delta.orientation;
873 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700874 if (getScreenLayoutNoDirection(delta.screenLayout) !=
875 (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)
876 && (getScreenLayoutNoDirection(screenLayout) !=
877 getScreenLayoutNoDirection(delta.screenLayout))) {
Dianne Hackborn723738c2009-06-25 19:48:04 -0700878 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700879 // We need to preserve the previous layout dir bits if they were defined
880 if ((delta.screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == 0) {
881 screenLayout = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK)|delta.screenLayout;
882 } else {
883 screenLayout = delta.screenLayout;
884 }
Dianne Hackborn723738c2009-06-25 19:48:04 -0700885 }
Dianne Hackborn7299c412010-03-04 18:41:49 -0800886 if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
Tobias Haamel27b28b32010-02-09 23:09:17 +0100887 && uiMode != delta.uiMode) {
888 changed |= ActivityInfo.CONFIG_UI_MODE;
Dianne Hackborn7299c412010-03-04 18:41:49 -0800889 if ((delta.uiMode&UI_MODE_TYPE_MASK) != UI_MODE_TYPE_UNDEFINED) {
890 uiMode = (uiMode&~UI_MODE_TYPE_MASK)
891 | (delta.uiMode&UI_MODE_TYPE_MASK);
892 }
893 if ((delta.uiMode&UI_MODE_NIGHT_MASK) != UI_MODE_NIGHT_UNDEFINED) {
894 uiMode = (uiMode&~UI_MODE_NIGHT_MASK)
895 | (delta.uiMode&UI_MODE_NIGHT_MASK);
896 }
Tobias Haamel27b28b32010-02-09 23:09:17 +0100897 }
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700898 if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
899 && screenWidthDp != delta.screenWidthDp) {
900 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
901 screenWidthDp = delta.screenWidthDp;
902 }
903 if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
904 && screenHeightDp != delta.screenHeightDp) {
905 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
906 screenHeightDp = delta.screenHeightDp;
907 }
Danny Baumanne7123a62013-05-15 10:21:40 +0200908 if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
909 && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
910 changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700911 smallestScreenWidthDp = delta.smallestScreenWidthDp;
912 }
Danny Baumanne7123a62013-05-15 10:21:40 +0200913 if (delta.densityDpi != DENSITY_DPI_UNDEFINED &&
914 densityDpi != delta.densityDpi) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700915 changed |= ActivityInfo.CONFIG_DENSITY;
916 densityDpi = delta.densityDpi;
917 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700918 if (delta.compatScreenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
919 compatScreenWidthDp = delta.compatScreenWidthDp;
920 }
921 if (delta.compatScreenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
922 compatScreenHeightDp = delta.compatScreenHeightDp;
923 }
924 if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
925 compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
926 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800927 if (delta.seq != 0) {
928 seq = delta.seq;
929 }
930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 return changed;
932 }
933
934 /**
935 * Return a bit mask of the differences between this Configuration
936 * object and the given one. Does not change the values of either. Any
937 * undefined fields in <var>delta</var> are ignored.
938 * @return Returns a bit mask indicating which configuration
939 * values has changed, containing any combination of
940 * {@link android.content.pm.ActivityInfo#CONFIG_FONT_SCALE
941 * PackageManager.ActivityInfo.CONFIG_FONT_SCALE},
942 * {@link android.content.pm.ActivityInfo#CONFIG_MCC
943 * PackageManager.ActivityInfo.CONFIG_MCC},
944 * {@link android.content.pm.ActivityInfo#CONFIG_MNC
945 * PackageManager.ActivityInfo.CONFIG_MNC},
946 * {@link android.content.pm.ActivityInfo#CONFIG_LOCALE
947 * PackageManager.ActivityInfo.CONFIG_LOCALE},
948 * {@link android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
949 * PackageManager.ActivityInfo.CONFIG_TOUCHSCREEN},
950 * {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
951 * PackageManager.ActivityInfo.CONFIG_KEYBOARD},
952 * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
Dianne Hackborn723738c2009-06-25 19:48:04 -0700953 * PackageManager.ActivityInfo.CONFIG_NAVIGATION},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700955 * PackageManager.ActivityInfo.CONFIG_ORIENTATION},
Dianne Hackborn723738c2009-06-25 19:48:04 -0700956 * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
Dianne Hackbornebff8f92011-05-12 18:07:47 -0700957 * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or
958 * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700959 * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}, or
960 * {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
961 * PackageManager.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700962 * {@link android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
963 * PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 */
965 public int diff(Configuration delta) {
966 int changed = 0;
967 if (delta.fontScale > 0 && fontScale != delta.fontScale) {
968 changed |= ActivityInfo.CONFIG_FONT_SCALE;
969 }
970 if (delta.mcc != 0 && mcc != delta.mcc) {
971 changed |= ActivityInfo.CONFIG_MCC;
972 }
973 if (delta.mnc != 0 && mnc != delta.mnc) {
974 changed |= ActivityInfo.CONFIG_MNC;
975 }
976 if (delta.locale != null
977 && (locale == null || !locale.equals(delta.locale))) {
978 changed |= ActivityInfo.CONFIG_LOCALE;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -0700979 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 }
Craig Mautner31678b52013-08-12 17:56:34 -0700981 final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
982 if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
983 deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
Amith Yamasanid8415f42013-08-07 20:15:10 -0700984 changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
987 && touchscreen != delta.touchscreen) {
988 changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
989 }
990 if (delta.keyboard != KEYBOARD_UNDEFINED
991 && keyboard != delta.keyboard) {
992 changed |= ActivityInfo.CONFIG_KEYBOARD;
993 }
994 if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
995 && keyboardHidden != delta.keyboardHidden) {
996 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
997 }
998 if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
999 && hardKeyboardHidden != delta.hardKeyboardHidden) {
1000 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1001 }
1002 if (delta.navigation != NAVIGATION_UNDEFINED
1003 && navigation != delta.navigation) {
1004 changed |= ActivityInfo.CONFIG_NAVIGATION;
1005 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001006 if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
1007 && navigationHidden != delta.navigationHidden) {
1008 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
1009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 if (delta.orientation != ORIENTATION_UNDEFINED
1011 && orientation != delta.orientation) {
1012 changed |= ActivityInfo.CONFIG_ORIENTATION;
1013 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001014 if (getScreenLayoutNoDirection(delta.screenLayout) !=
1015 (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)
1016 && getScreenLayoutNoDirection(screenLayout) !=
1017 getScreenLayoutNoDirection(delta.screenLayout)) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07001018 changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
1019 }
Dianne Hackborn7299c412010-03-04 18:41:49 -08001020 if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
Tobias Haamel27b28b32010-02-09 23:09:17 +01001021 && uiMode != delta.uiMode) {
1022 changed |= ActivityInfo.CONFIG_UI_MODE;
1023 }
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001024 if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
1025 && screenWidthDp != delta.screenWidthDp) {
1026 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1027 }
1028 if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
1029 && screenHeightDp != delta.screenHeightDp) {
1030 changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
1031 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001032 if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
1033 && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
1034 changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
1035 }
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001036 if (delta.densityDpi != DENSITY_DPI_UNDEFINED
1037 && densityDpi != delta.densityDpi) {
1038 changed |= ActivityInfo.CONFIG_DENSITY;
1039 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 return changed;
1042 }
1043
1044 /**
1045 * Determine if a new resource needs to be loaded from the bit set of
1046 * configuration changes returned by {@link #updateFrom(Configuration)}.
1047 *
1048 * @param configChanges The mask of changes configurations as returned by
1049 * {@link #updateFrom(Configuration)}.
1050 * @param interestingChanges The configuration changes that the resource
1051 * can handled, as given in {@link android.util.TypedValue#changingConfigurations}.
1052 *
1053 * @return Return true if the resource needs to be loaded, else false.
1054 */
1055 public static boolean needNewResources(int configChanges, int interestingChanges) {
1056 return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
1057 }
Amith Yamasanid8415f42013-08-07 20:15:10 -07001058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001060 * @hide Return true if the sequence of 'other' is better than this. Assumes
1061 * that 'this' is your current sequence and 'other' is a new one you have
1062 * received some how and want to compare with what you have.
1063 */
1064 public boolean isOtherSeqNewer(Configuration other) {
1065 if (other == null) {
1066 // Sanity check.
1067 return false;
1068 }
1069 if (other.seq == 0) {
1070 // If the other sequence is not specified, then we must assume
1071 // it is newer since we don't know any better.
1072 return true;
1073 }
1074 if (seq == 0) {
1075 // If this sequence is not specified, then we also consider the
1076 // other is better. Yes we have a preference for other. Sue us.
1077 return true;
1078 }
1079 int diff = other.seq - seq;
1080 if (diff > 0x10000) {
1081 // If there has been a sufficiently large jump, assume the
1082 // sequence has wrapped around.
1083 return false;
1084 }
1085 return diff > 0;
1086 }
1087
1088 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 * Parcelable methods
1090 */
1091 public int describeContents() {
1092 return 0;
1093 }
1094
1095 public void writeToParcel(Parcel dest, int flags) {
1096 dest.writeFloat(fontScale);
1097 dest.writeInt(mcc);
1098 dest.writeInt(mnc);
1099 if (locale == null) {
1100 dest.writeInt(0);
1101 } else {
1102 dest.writeInt(1);
1103 dest.writeString(locale.getLanguage());
1104 dest.writeString(locale.getCountry());
1105 dest.writeString(locale.getVariant());
1106 }
1107 if(userSetLocale) {
1108 dest.writeInt(1);
1109 } else {
1110 dest.writeInt(0);
1111 }
1112 dest.writeInt(touchscreen);
1113 dest.writeInt(keyboard);
1114 dest.writeInt(keyboardHidden);
1115 dest.writeInt(hardKeyboardHidden);
1116 dest.writeInt(navigation);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001117 dest.writeInt(navigationHidden);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 dest.writeInt(orientation);
Dianne Hackborn723738c2009-06-25 19:48:04 -07001119 dest.writeInt(screenLayout);
Tobias Haamel27b28b32010-02-09 23:09:17 +01001120 dest.writeInt(uiMode);
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001121 dest.writeInt(screenWidthDp);
1122 dest.writeInt(screenHeightDp);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001123 dest.writeInt(smallestScreenWidthDp);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001124 dest.writeInt(densityDpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001125 dest.writeInt(compatScreenWidthDp);
1126 dest.writeInt(compatScreenHeightDp);
1127 dest.writeInt(compatSmallestScreenWidthDp);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001128 dest.writeInt(seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 }
1130
Dianne Hackborn694f79b2010-03-17 19:44:59 -07001131 public void readFromParcel(Parcel source) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 fontScale = source.readFloat();
1133 mcc = source.readInt();
1134 mnc = source.readInt();
1135 if (source.readInt() != 0) {
1136 locale = new Locale(source.readString(), source.readString(),
1137 source.readString());
1138 }
1139 userSetLocale = (source.readInt()==1);
1140 touchscreen = source.readInt();
1141 keyboard = source.readInt();
1142 keyboardHidden = source.readInt();
1143 hardKeyboardHidden = source.readInt();
1144 navigation = source.readInt();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001145 navigationHidden = source.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 orientation = source.readInt();
Dianne Hackborn723738c2009-06-25 19:48:04 -07001147 screenLayout = source.readInt();
Tobias Haamel27b28b32010-02-09 23:09:17 +01001148 uiMode = source.readInt();
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001149 screenWidthDp = source.readInt();
1150 screenHeightDp = source.readInt();
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001151 smallestScreenWidthDp = source.readInt();
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001152 densityDpi = source.readInt();
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001153 compatScreenWidthDp = source.readInt();
1154 compatScreenHeightDp = source.readInt();
1155 compatSmallestScreenWidthDp = source.readInt();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001156 seq = source.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07001158
1159 public static final Parcelable.Creator<Configuration> CREATOR
1160 = new Parcelable.Creator<Configuration>() {
1161 public Configuration createFromParcel(Parcel source) {
1162 return new Configuration(source);
1163 }
1164
1165 public Configuration[] newArray(int size) {
1166 return new Configuration[size];
1167 }
1168 };
1169
1170 /**
1171 * Construct this Configuration object, reading from the Parcel.
1172 */
1173 private Configuration(Parcel source) {
1174 readFromParcel(source);
1175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176
1177 public int compareTo(Configuration that) {
1178 int n;
1179 float a = this.fontScale;
1180 float b = that.fontScale;
1181 if (a < b) return -1;
1182 if (a > b) return 1;
1183 n = this.mcc - that.mcc;
1184 if (n != 0) return n;
1185 n = this.mnc - that.mnc;
1186 if (n != 0) return n;
Dianne Hackborna8397032010-03-12 10:52:22 -08001187 if (this.locale == null) {
1188 if (that.locale != null) return 1;
1189 } else if (that.locale == null) {
1190 return -1;
1191 } else {
1192 n = this.locale.getLanguage().compareTo(that.locale.getLanguage());
1193 if (n != 0) return n;
1194 n = this.locale.getCountry().compareTo(that.locale.getCountry());
1195 if (n != 0) return n;
1196 n = this.locale.getVariant().compareTo(that.locale.getVariant());
1197 if (n != 0) return n;
1198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 n = this.touchscreen - that.touchscreen;
1200 if (n != 0) return n;
1201 n = this.keyboard - that.keyboard;
1202 if (n != 0) return n;
1203 n = this.keyboardHidden - that.keyboardHidden;
1204 if (n != 0) return n;
1205 n = this.hardKeyboardHidden - that.hardKeyboardHidden;
1206 if (n != 0) return n;
1207 n = this.navigation - that.navigation;
1208 if (n != 0) return n;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07001209 n = this.navigationHidden - that.navigationHidden;
1210 if (n != 0) return n;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 n = this.orientation - that.orientation;
Dianne Hackborn723738c2009-06-25 19:48:04 -07001212 if (n != 0) return n;
1213 n = this.screenLayout - that.screenLayout;
Tobias Haamel27b28b32010-02-09 23:09:17 +01001214 if (n != 0) return n;
1215 n = this.uiMode - that.uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001216 if (n != 0) return n;
1217 n = this.screenWidthDp - that.screenWidthDp;
1218 if (n != 0) return n;
1219 n = this.screenHeightDp - that.screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001220 if (n != 0) return n;
1221 n = this.smallestScreenWidthDp - that.smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001222 if (n != 0) return n;
1223 n = this.densityDpi - that.densityDpi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 //if (n != 0) return n;
1225 return n;
1226 }
1227
1228 public boolean equals(Configuration that) {
1229 if (that == null) return false;
1230 if (that == this) return true;
1231 return this.compareTo(that) == 0;
1232 }
1233
1234 public boolean equals(Object that) {
1235 try {
1236 return equals((Configuration)that);
1237 } catch (ClassCastException e) {
1238 }
1239 return false;
1240 }
1241
1242 public int hashCode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001243 int result = 17;
1244 result = 31 * result + Float.floatToIntBits(fontScale);
1245 result = 31 * result + mcc;
1246 result = 31 * result + mnc;
1247 result = 31 * result + (locale != null ? locale.hashCode() : 0);
1248 result = 31 * result + touchscreen;
1249 result = 31 * result + keyboard;
1250 result = 31 * result + keyboardHidden;
1251 result = 31 * result + hardKeyboardHidden;
1252 result = 31 * result + navigation;
1253 result = 31 * result + navigationHidden;
1254 result = 31 * result + orientation;
1255 result = 31 * result + screenLayout;
1256 result = 31 * result + uiMode;
Dianne Hackbornebff8f92011-05-12 18:07:47 -07001257 result = 31 * result + screenWidthDp;
1258 result = 31 * result + screenHeightDp;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001259 result = 31 * result + smallestScreenWidthDp;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001260 result = 31 * result + densityDpi;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001261 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 }
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001263
1264 /**
1265 * Set the locale. This is the preferred way for setting up the locale (instead of using the
1266 * direct accessor). This will also set the userLocale and layout direction according to
1267 * the locale.
1268 *
1269 * @param loc The locale. Can be null.
1270 */
1271 public void setLocale(Locale loc) {
1272 locale = loc;
1273 userSetLocale = true;
1274 setLayoutDirection(locale);
1275 }
1276
1277 /**
1278 * Return the layout direction. Will be either {@link View#LAYOUT_DIRECTION_LTR} or
1279 * {@link View#LAYOUT_DIRECTION_RTL}.
1280 *
Dianne Hackbornf1ae2692013-04-19 14:09:37 -07001281 * @return Returns {@link View#LAYOUT_DIRECTION_RTL} if the configuration
1282 * is {@link #SCREENLAYOUT_LAYOUTDIR_RTL}, otherwise {@link View#LAYOUT_DIRECTION_LTR}.
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001283 */
1284 public int getLayoutDirection() {
Dianne Hackbornf1ae2692013-04-19 14:09:37 -07001285 return (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == SCREENLAYOUT_LAYOUTDIR_RTL
1286 ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001287 }
1288
1289 /**
1290 * Set the layout direction from the Locale.
1291 *
1292 * @param locale The Locale. If null will set the layout direction to
1293 * {@link View#LAYOUT_DIRECTION_LTR}. If not null will set it to the layout direction
1294 * corresponding to the Locale.
1295 *
1296 * @see {@link View#LAYOUT_DIRECTION_LTR} and {@link View#LAYOUT_DIRECTION_RTL}
1297 */
1298 public void setLayoutDirection(Locale locale) {
1299 // There is a "1" difference between the configuration values for
1300 // layout direction and View constants for layout direction, just add "1".
Fabrice Di Megliod3d9f3f2012-09-18 12:55:32 -07001301 final int layoutDirection = 1 + TextUtils.getLayoutDirectionFromLocale(locale);
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001302 screenLayout = (screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK)|
1303 (layoutDirection << SCREENLAYOUT_LAYOUTDIR_SHIFT);
1304 }
1305
1306 private static int getScreenLayoutNoDirection(int screenLayout) {
1307 return screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK;
1308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309}