Configuration.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1package android.content.res; 2 3import android.content.pm.ActivityInfo; 4import android.os.Parcel; 5import android.os.Parcelable; 6 7import java.util.Locale; 8 9/** 10 * This class describes all device configuration information that can 11 * impact the resources the application retrieves. This includes both 12 * user-specified configuration options (locale and scaling) as well 13 * as dynamic device configuration (various types of input devices). 14 */ 15public final class Configuration implements Parcelable, Comparable<Configuration> { 16 /** 17 * Current user preference for the scaling factor for fonts, relative 18 * to the base density scaling. 19 */ 20 public float fontScale; 21 22 /** 23 * IMSI MCC (Mobile Country Code). 0 if undefined. 24 */ 25 public int mcc; 26 27 /** 28 * IMSI MNC (Mobile Network Code). 0 if undefined. 29 */ 30 public int mnc; 31 32 /** 33 * Current user preference for the locale. 34 */ 35 public Locale locale; 36 37 /** 38 * Locale should persist on setting 39 * @hide pending API council approval 40 */ 41 public boolean userSetLocale; 42 43 public static final int TOUCHSCREEN_UNDEFINED = 0; 44 public static final int TOUCHSCREEN_NOTOUCH = 1; 45 public static final int TOUCHSCREEN_STYLUS = 2; 46 public static final int TOUCHSCREEN_FINGER = 3; 47 48 /** 49 * The kind of touch screen attached to the device. 50 * One of: {@link #TOUCHSCREEN_NOTOUCH}, {@link #TOUCHSCREEN_STYLUS}, 51 * {@link #TOUCHSCREEN_FINGER}. 52 */ 53 public int touchscreen; 54 55 public static final int KEYBOARD_UNDEFINED = 0; 56 public static final int KEYBOARD_NOKEYS = 1; 57 public static final int KEYBOARD_QWERTY = 2; 58 public static final int KEYBOARD_12KEY = 3; 59 60 /** 61 * The kind of keyboard attached to the device. 62 * One of: {@link #KEYBOARD_QWERTY}, {@link #KEYBOARD_12KEY}. 63 */ 64 public int keyboard; 65 66 public static final int KEYBOARDHIDDEN_UNDEFINED = 0; 67 public static final int KEYBOARDHIDDEN_NO = 1; 68 public static final int KEYBOARDHIDDEN_YES = 2; 69 /** Constant matching actual resource implementation. {@hide} */ 70 public static final int KEYBOARDHIDDEN_SOFT = 3; 71 72 /** 73 * A flag indicating whether any keyboard is available. Unlike 74 * {@link #hardKeyboardHidden}, this also takes into account a soft 75 * keyboard, so if the hard keyboard is hidden but there is soft 76 * keyboard available, it will be set to NO. Value is one of: 77 * {@link #KEYBOARDHIDDEN_NO}, {@link #KEYBOARDHIDDEN_YES}. 78 */ 79 public int keyboardHidden; 80 81 public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0; 82 public static final int HARDKEYBOARDHIDDEN_NO = 1; 83 public static final int HARDKEYBOARDHIDDEN_YES = 2; 84 85 /** 86 * A flag indicating whether the hard keyboard has been hidden. This will 87 * be set on a device with a mechanism to hide the keyboard from the 88 * user, when that mechanism is closed. One of: 89 * {@link #HARDKEYBOARDHIDDEN_NO}, {@link #HARDKEYBOARDHIDDEN_YES}. 90 */ 91 public int hardKeyboardHidden; 92 93 public static final int NAVIGATION_UNDEFINED = 0; 94 public static final int NAVIGATION_NONAV = 1; 95 public static final int NAVIGATION_DPAD = 2; 96 public static final int NAVIGATION_TRACKBALL = 3; 97 public static final int NAVIGATION_WHEEL = 4; 98 99 /** 100 * The kind of navigation method available on the device. 101 * One of: {@link #NAVIGATION_DPAD}, {@link #NAVIGATION_TRACKBALL}, 102 * {@link #NAVIGATION_WHEEL}. 103 */ 104 public int navigation; 105 106 public static final int ORIENTATION_UNDEFINED = 0; 107 public static final int ORIENTATION_PORTRAIT = 1; 108 public static final int ORIENTATION_LANDSCAPE = 2; 109 public static final int ORIENTATION_SQUARE = 3; 110 111 /** 112 * Overall orientation of the screen. May be one of 113 * {@link #ORIENTATION_LANDSCAPE}, {@link #ORIENTATION_PORTRAIT}, 114 * or {@link #ORIENTATION_SQUARE}. 115 */ 116 public int orientation; 117 118 /** 119 * Construct an invalid Configuration. You must call {@link #setToDefaults} 120 * for this object to be valid. {@more} 121 */ 122 public Configuration() { 123 setToDefaults(); 124 } 125 126 /** 127 * Makes a deep copy suitable for modification. 128 */ 129 public Configuration(Configuration o) { 130 fontScale = o.fontScale; 131 mcc = o.mcc; 132 mnc = o.mnc; 133 if (o.locale != null) { 134 locale = (Locale) o.locale.clone(); 135 } 136 userSetLocale = o.userSetLocale; 137 touchscreen = o.touchscreen; 138 keyboard = o.keyboard; 139 keyboardHidden = o.keyboardHidden; 140 hardKeyboardHidden = o.hardKeyboardHidden; 141 navigation = o.navigation; 142 orientation = o.orientation; 143 } 144 145 public String toString() { 146 return "{ scale=" + fontScale + " imsi=" + mcc + "/" + mnc 147 + " locale=" + locale 148 + " touch=" + touchscreen + " key=" + keyboard + "/" 149 + keyboardHidden + "/" + hardKeyboardHidden 150 + " nav=" + navigation + " orien=" + orientation + " }"; 151 } 152 153 /** 154 * Set this object to the system defaults. 155 */ 156 public void setToDefaults() { 157 fontScale = 1; 158 mcc = mnc = 0; 159 locale = Locale.getDefault(); 160 userSetLocale = false; 161 touchscreen = TOUCHSCREEN_UNDEFINED; 162 keyboard = KEYBOARD_UNDEFINED; 163 keyboardHidden = KEYBOARDHIDDEN_UNDEFINED; 164 hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED; 165 navigation = NAVIGATION_UNDEFINED; 166 orientation = ORIENTATION_UNDEFINED; 167 } 168 169 /** {@hide} */ 170 @Deprecated public void makeDefault() { 171 setToDefaults(); 172 } 173 174 /** 175 * Copy the fields from delta into this Configuration object, keeping 176 * track of which ones have changed. Any undefined fields in 177 * <var>delta</var> are ignored and not copied in to the current 178 * Configuration. 179 * @return Returns a bit mask of the changed fields, as per 180 * {@link #diff}. 181 */ 182 public int updateFrom(Configuration delta) { 183 int changed = 0; 184 if (delta.fontScale > 0 && fontScale != delta.fontScale) { 185 changed |= ActivityInfo.CONFIG_FONT_SCALE; 186 fontScale = delta.fontScale; 187 } 188 if (delta.mcc != 0 && mcc != delta.mcc) { 189 changed |= ActivityInfo.CONFIG_MCC; 190 mcc = delta.mcc; 191 } 192 if (delta.mnc != 0 && mnc != delta.mnc) { 193 changed |= ActivityInfo.CONFIG_MNC; 194 mnc = delta.mnc; 195 } 196 if (delta.locale != null 197 && (locale == null || !locale.equals(delta.locale))) { 198 changed |= ActivityInfo.CONFIG_LOCALE; 199 locale = delta.locale != null 200 ? (Locale) delta.locale.clone() : null; 201 } 202 if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0))) 203 { 204 userSetLocale = true; 205 changed |= ActivityInfo.CONFIG_LOCALE; 206 } 207 if (delta.touchscreen != TOUCHSCREEN_UNDEFINED 208 && touchscreen != delta.touchscreen) { 209 changed |= ActivityInfo.CONFIG_TOUCHSCREEN; 210 touchscreen = delta.touchscreen; 211 } 212 if (delta.keyboard != KEYBOARD_UNDEFINED 213 && keyboard != delta.keyboard) { 214 changed |= ActivityInfo.CONFIG_KEYBOARD; 215 keyboard = delta.keyboard; 216 } 217 if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED 218 && keyboardHidden != delta.keyboardHidden) { 219 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 220 keyboardHidden = delta.keyboardHidden; 221 } 222 if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED 223 && hardKeyboardHidden != delta.hardKeyboardHidden) { 224 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 225 hardKeyboardHidden = delta.hardKeyboardHidden; 226 } 227 if (delta.navigation != NAVIGATION_UNDEFINED 228 && navigation != delta.navigation) { 229 changed |= ActivityInfo.CONFIG_NAVIGATION; 230 navigation = delta.navigation; 231 } 232 if (delta.orientation != ORIENTATION_UNDEFINED 233 && orientation != delta.orientation) { 234 changed |= ActivityInfo.CONFIG_ORIENTATION; 235 orientation = delta.orientation; 236 } 237 238 return changed; 239 } 240 241 /** 242 * Return a bit mask of the differences between this Configuration 243 * object and the given one. Does not change the values of either. Any 244 * undefined fields in <var>delta</var> are ignored. 245 * @return Returns a bit mask indicating which configuration 246 * values has changed, containing any combination of 247 * {@link android.content.pm.ActivityInfo#CONFIG_FONT_SCALE 248 * PackageManager.ActivityInfo.CONFIG_FONT_SCALE}, 249 * {@link android.content.pm.ActivityInfo#CONFIG_MCC 250 * PackageManager.ActivityInfo.CONFIG_MCC}, 251 * {@link android.content.pm.ActivityInfo#CONFIG_MNC 252 * PackageManager.ActivityInfo.CONFIG_MNC}, 253 * {@link android.content.pm.ActivityInfo#CONFIG_LOCALE 254 * PackageManager.ActivityInfo.CONFIG_LOCALE}, 255 * {@link android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN 256 * PackageManager.ActivityInfo.CONFIG_TOUCHSCREEN}, 257 * {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD 258 * PackageManager.ActivityInfo.CONFIG_KEYBOARD}, 259 * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION 260 * PackageManager.ActivityInfo.CONFIG_NAVIGATION}, or 261 * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION 262 * PackageManager.ActivityInfo.CONFIG_ORIENTATION}. 263 */ 264 public int diff(Configuration delta) { 265 int changed = 0; 266 if (delta.fontScale > 0 && fontScale != delta.fontScale) { 267 changed |= ActivityInfo.CONFIG_FONT_SCALE; 268 } 269 if (delta.mcc != 0 && mcc != delta.mcc) { 270 changed |= ActivityInfo.CONFIG_MCC; 271 } 272 if (delta.mnc != 0 && mnc != delta.mnc) { 273 changed |= ActivityInfo.CONFIG_MNC; 274 } 275 if (delta.locale != null 276 && (locale == null || !locale.equals(delta.locale))) { 277 changed |= ActivityInfo.CONFIG_LOCALE; 278 } 279 if (delta.touchscreen != TOUCHSCREEN_UNDEFINED 280 && touchscreen != delta.touchscreen) { 281 changed |= ActivityInfo.CONFIG_TOUCHSCREEN; 282 } 283 if (delta.keyboard != KEYBOARD_UNDEFINED 284 && keyboard != delta.keyboard) { 285 changed |= ActivityInfo.CONFIG_KEYBOARD; 286 } 287 if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED 288 && keyboardHidden != delta.keyboardHidden) { 289 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 290 } 291 if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED 292 && hardKeyboardHidden != delta.hardKeyboardHidden) { 293 changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 294 } 295 if (delta.navigation != NAVIGATION_UNDEFINED 296 && navigation != delta.navigation) { 297 changed |= ActivityInfo.CONFIG_NAVIGATION; 298 } 299 if (delta.orientation != ORIENTATION_UNDEFINED 300 && orientation != delta.orientation) { 301 changed |= ActivityInfo.CONFIG_ORIENTATION; 302 } 303 304 return changed; 305 } 306 307 /** 308 * Determine if a new resource needs to be loaded from the bit set of 309 * configuration changes returned by {@link #updateFrom(Configuration)}. 310 * 311 * @param configChanges The mask of changes configurations as returned by 312 * {@link #updateFrom(Configuration)}. 313 * @param interestingChanges The configuration changes that the resource 314 * can handled, as given in {@link android.util.TypedValue#changingConfigurations}. 315 * 316 * @return Return true if the resource needs to be loaded, else false. 317 */ 318 public static boolean needNewResources(int configChanges, int interestingChanges) { 319 return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0; 320 } 321 322 /** 323 * Parcelable methods 324 */ 325 public int describeContents() { 326 return 0; 327 } 328 329 public void writeToParcel(Parcel dest, int flags) { 330 dest.writeFloat(fontScale); 331 dest.writeInt(mcc); 332 dest.writeInt(mnc); 333 if (locale == null) { 334 dest.writeInt(0); 335 } else { 336 dest.writeInt(1); 337 dest.writeString(locale.getLanguage()); 338 dest.writeString(locale.getCountry()); 339 dest.writeString(locale.getVariant()); 340 } 341 if(userSetLocale) { 342 dest.writeInt(1); 343 } else { 344 dest.writeInt(0); 345 } 346 dest.writeInt(touchscreen); 347 dest.writeInt(keyboard); 348 dest.writeInt(keyboardHidden); 349 dest.writeInt(hardKeyboardHidden); 350 dest.writeInt(navigation); 351 dest.writeInt(orientation); 352 } 353 354 public static final Parcelable.Creator<Configuration> CREATOR 355 = new Parcelable.Creator<Configuration>() { 356 public Configuration createFromParcel(Parcel source) { 357 return new Configuration(source); 358 } 359 360 public Configuration[] newArray(int size) { 361 return new Configuration[size]; 362 } 363 }; 364 365 /** 366 * Construct this Configuration object, reading from the Parcel. 367 */ 368 private Configuration(Parcel source) { 369 fontScale = source.readFloat(); 370 mcc = source.readInt(); 371 mnc = source.readInt(); 372 if (source.readInt() != 0) { 373 locale = new Locale(source.readString(), source.readString(), 374 source.readString()); 375 } 376 userSetLocale = (source.readInt()==1); 377 touchscreen = source.readInt(); 378 keyboard = source.readInt(); 379 keyboardHidden = source.readInt(); 380 hardKeyboardHidden = source.readInt(); 381 navigation = source.readInt(); 382 orientation = source.readInt(); 383 } 384 385 public int compareTo(Configuration that) { 386 int n; 387 float a = this.fontScale; 388 float b = that.fontScale; 389 if (a < b) return -1; 390 if (a > b) return 1; 391 n = this.mcc - that.mcc; 392 if (n != 0) return n; 393 n = this.mnc - that.mnc; 394 if (n != 0) return n; 395 n = this.locale.getLanguage().compareTo(that.locale.getLanguage()); 396 if (n != 0) return n; 397 n = this.locale.getCountry().compareTo(that.locale.getCountry()); 398 if (n != 0) return n; 399 n = this.locale.getVariant().compareTo(that.locale.getVariant()); 400 if (n != 0) return n; 401 n = this.touchscreen - that.touchscreen; 402 if (n != 0) return n; 403 n = this.keyboard - that.keyboard; 404 if (n != 0) return n; 405 n = this.keyboardHidden - that.keyboardHidden; 406 if (n != 0) return n; 407 n = this.hardKeyboardHidden - that.hardKeyboardHidden; 408 if (n != 0) return n; 409 n = this.navigation - that.navigation; 410 if (n != 0) return n; 411 n = this.orientation - that.orientation; 412 //if (n != 0) return n; 413 return n; 414 } 415 416 public boolean equals(Configuration that) { 417 if (that == null) return false; 418 if (that == this) return true; 419 return this.compareTo(that) == 0; 420 } 421 422 public boolean equals(Object that) { 423 try { 424 return equals((Configuration)that); 425 } catch (ClassCastException e) { 426 } 427 return false; 428 } 429 430 public int hashCode() { 431 return ((int)this.fontScale) + this.mcc + this.mnc 432 + this.locale.hashCode() + this.touchscreen 433 + this.keyboard + this.keyboardHidden + this.hardKeyboardHidden 434 + this.navigation + this.orientation; 435 } 436} 437