Home | History | Annotate | Download | only in os
      1 /*
      2  * Copyright (C) 2007 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 
     17 package android.os;
     18 
     19 import android.annotation.SystemApi;
     20 import android.text.TextUtils;
     21 import android.util.Slog;
     22 
     23 import com.android.internal.telephony.TelephonyProperties;
     24 
     25 import dalvik.system.VMRuntime;
     26 
     27 import java.util.Objects;
     28 
     29 /**
     30  * Information about the current build, extracted from system properties.
     31  */
     32 public class Build {
     33     private static final String TAG = "Build";
     34 
     35     /** Value used for when a build property is unknown. */
     36     public static final String UNKNOWN = "unknown";
     37 
     38     /** Either a changelist number, or a label like "M4-rc20". */
     39     public static final String ID = getString("ro.build.id");
     40 
     41     /** A build ID string meant for displaying to the user */
     42     public static final String DISPLAY = getString("ro.build.display.id");
     43 
     44     /** The name of the overall product. */
     45     public static final String PRODUCT = getString("ro.product.name");
     46 
     47     /** The name of the industrial design. */
     48     public static final String DEVICE = getString("ro.product.device");
     49 
     50     /** The name of the underlying board, like "goldfish". */
     51     public static final String BOARD = getString("ro.product.board");
     52 
     53     /**
     54      * The name of the instruction set (CPU type + ABI convention) of native code.
     55      *
     56      * @deprecated Use {@link #SUPPORTED_ABIS} instead.
     57      */
     58     @Deprecated
     59     public static final String CPU_ABI;
     60 
     61     /**
     62      * The name of the second instruction set (CPU type + ABI convention) of native code.
     63      *
     64      * @deprecated Use {@link #SUPPORTED_ABIS} instead.
     65      */
     66     @Deprecated
     67     public static final String CPU_ABI2;
     68 
     69     /** The manufacturer of the product/hardware. */
     70     public static final String MANUFACTURER = getString("ro.product.manufacturer");
     71 
     72     /** The consumer-visible brand with which the product/hardware will be associated, if any. */
     73     public static final String BRAND = getString("ro.product.brand");
     74 
     75     /** The end-user-visible name for the end product. */
     76     public static final String MODEL = getString("ro.product.model");
     77 
     78     /** The system bootloader version number. */
     79     public static final String BOOTLOADER = getString("ro.bootloader");
     80 
     81     /**
     82      * The radio firmware version number.
     83      *
     84      * @deprecated The radio firmware version is frequently not
     85      * available when this class is initialized, leading to a blank or
     86      * "unknown" value for this string.  Use
     87      * {@link #getRadioVersion} instead.
     88      */
     89     @Deprecated
     90     public static final String RADIO = getString(TelephonyProperties.PROPERTY_BASEBAND_VERSION);
     91 
     92     /** The name of the hardware (from the kernel command line or /proc). */
     93     public static final String HARDWARE = getString("ro.hardware");
     94 
     95     /**
     96      * Whether this build was for an emulator device.
     97      * @hide
     98      */
     99     public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");
    100 
    101     /** A hardware serial number, if available.  Alphanumeric only, case-insensitive. */
    102     public static final String SERIAL = getString("ro.serialno");
    103 
    104     /**
    105      * An ordered list of ABIs supported by this device. The most preferred ABI is the first
    106      * element in the list.
    107      *
    108      * See {@link #SUPPORTED_32_BIT_ABIS} and {@link #SUPPORTED_64_BIT_ABIS}.
    109      */
    110     public static final String[] SUPPORTED_ABIS = getStringList("ro.product.cpu.abilist", ",");
    111 
    112     /**
    113      * An ordered list of <b>32 bit</b> ABIs supported by this device. The most preferred ABI
    114      * is the first element in the list.
    115      *
    116      * See {@link #SUPPORTED_ABIS} and {@link #SUPPORTED_64_BIT_ABIS}.
    117      */
    118     public static final String[] SUPPORTED_32_BIT_ABIS =
    119             getStringList("ro.product.cpu.abilist32", ",");
    120 
    121     /**
    122      * An ordered list of <b>64 bit</b> ABIs supported by this device. The most preferred ABI
    123      * is the first element in the list.
    124      *
    125      * See {@link #SUPPORTED_ABIS} and {@link #SUPPORTED_32_BIT_ABIS}.
    126      */
    127     public static final String[] SUPPORTED_64_BIT_ABIS =
    128             getStringList("ro.product.cpu.abilist64", ",");
    129 
    130 
    131     static {
    132         /*
    133          * Adjusts CPU_ABI and CPU_ABI2 depending on whether or not a given process is 64 bit.
    134          * 32 bit processes will always see 32 bit ABIs in these fields for backward
    135          * compatibility.
    136          */
    137         final String[] abiList;
    138         if (VMRuntime.getRuntime().is64Bit()) {
    139             abiList = SUPPORTED_64_BIT_ABIS;
    140         } else {
    141             abiList = SUPPORTED_32_BIT_ABIS;
    142         }
    143 
    144         CPU_ABI = abiList[0];
    145         if (abiList.length > 1) {
    146             CPU_ABI2 = abiList[1];
    147         } else {
    148             CPU_ABI2 = "";
    149         }
    150     }
    151 
    152     /** Various version strings. */
    153     public static class VERSION {
    154         /**
    155          * The internal value used by the underlying source control to
    156          * represent this build.  E.g., a perforce changelist number
    157          * or a git hash.
    158          */
    159         public static final String INCREMENTAL = getString("ro.build.version.incremental");
    160 
    161         /**
    162          * The user-visible version string.  E.g., "1.0" or "3.4b5".
    163          */
    164         public static final String RELEASE = getString("ro.build.version.release");
    165 
    166         /**
    167          * The base OS build the product is based on.
    168          */
    169         public static final String BASE_OS = SystemProperties.get("ro.build.version.base_os", "");
    170 
    171         /**
    172          * The user-visible security patch level.
    173          */
    174         public static final String SECURITY_PATCH = SystemProperties.get(
    175                 "ro.build.version.security_patch", "");
    176 
    177         /**
    178          * The user-visible SDK version of the framework in its raw String
    179          * representation; use {@link #SDK_INT} instead.
    180          *
    181          * @deprecated Use {@link #SDK_INT} to easily get this as an integer.
    182          */
    183         @Deprecated
    184         public static final String SDK = getString("ro.build.version.sdk");
    185 
    186         /**
    187          * The user-visible SDK version of the framework; its possible
    188          * values are defined in {@link Build.VERSION_CODES}.
    189          */
    190         public static final int SDK_INT = SystemProperties.getInt(
    191                 "ro.build.version.sdk", 0);
    192 
    193         /**
    194          * The developer preview revision of a prerelease SDK. This value will always
    195          * be <code>0</code> on production platform builds/devices.
    196          *
    197          * <p>When this value is nonzero, any new API added since the last
    198          * officially published {@link #SDK_INT API level} is only guaranteed to be present
    199          * on that specific preview revision. For example, an API <code>Activity.fooBar()</code>
    200          * might be present in preview revision 1 but renamed or removed entirely in
    201          * preview revision 2, which may cause an app attempting to call it to crash
    202          * at runtime.</p>
    203          *
    204          * <p>Experimental apps targeting preview APIs should check this value for
    205          * equality (<code>==</code>) with the preview SDK revision they were built for
    206          * before using any prerelease platform APIs. Apps that detect a preview SDK revision
    207          * other than the specific one they expect should fall back to using APIs from
    208          * the previously published API level only to avoid unwanted runtime exceptions.
    209          * </p>
    210          */
    211         public static final int PREVIEW_SDK_INT = SystemProperties.getInt(
    212                 "ro.build.version.preview_sdk", 0);
    213 
    214         /**
    215          * The current development codename, or the string "REL" if this is
    216          * a release build.
    217          */
    218         public static final String CODENAME = getString("ro.build.version.codename");
    219 
    220         private static final String[] ALL_CODENAMES
    221                 = getStringList("ro.build.version.all_codenames", ",");
    222 
    223         /**
    224          * @hide
    225          */
    226         public static final String[] ACTIVE_CODENAMES = "REL".equals(ALL_CODENAMES[0])
    227                 ? new String[0] : ALL_CODENAMES;
    228 
    229         /**
    230          * The SDK version to use when accessing resources.
    231          * Use the current SDK version code.  For every active development codename
    232          * we are operating under, we bump the assumed resource platform version by 1.
    233          * @hide
    234          */
    235         public static final int RESOURCES_SDK_INT = SDK_INT + ACTIVE_CODENAMES.length;
    236     }
    237 
    238     /**
    239      * Enumeration of the currently known SDK version codes.  These are the
    240      * values that can be found in {@link VERSION#SDK}.  Version numbers
    241      * increment monotonically with each official platform release.
    242      */
    243     public static class VERSION_CODES {
    244         /**
    245          * Magic version number for a current development build, which has
    246          * not yet turned into an official release.
    247          */
    248         public static final int CUR_DEVELOPMENT = 10000;
    249 
    250         /**
    251          * October 2008: The original, first, version of Android.  Yay!
    252          */
    253         public static final int BASE = 1;
    254 
    255         /**
    256          * February 2009: First Android update, officially called 1.1.
    257          */
    258         public static final int BASE_1_1 = 2;
    259 
    260         /**
    261          * May 2009: Android 1.5.
    262          */
    263         public static final int CUPCAKE = 3;
    264 
    265         /**
    266          * September 2009: Android 1.6.
    267          *
    268          * <p>Applications targeting this or a later release will get these
    269          * new changes in behavior:</p>
    270          * <ul>
    271          * <li> They must explicitly request the
    272          * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission to be
    273          * able to modify the contents of the SD card.  (Apps targeting
    274          * earlier versions will always request the permission.)
    275          * <li> They must explicitly request the
    276          * {@link android.Manifest.permission#READ_PHONE_STATE} permission to be
    277          * able to be able to retrieve phone state info.  (Apps targeting
    278          * earlier versions will always request the permission.)
    279          * <li> They are assumed to support different screen densities and
    280          * sizes.  (Apps targeting earlier versions are assumed to only support
    281          * medium density normal size screens unless otherwise indicated).
    282          * They can still explicitly specify screen support either way with the
    283          * supports-screens manifest tag.
    284          * <li> {@link android.widget.TabHost} will use the new dark tab
    285          * background design.
    286          * </ul>
    287          */
    288         public static final int DONUT = 4;
    289 
    290         /**
    291          * November 2009: Android 2.0
    292          *
    293          * <p>Applications targeting this or a later release will get these
    294          * new changes in behavior:</p>
    295          * <ul>
    296          * <li> The {@link android.app.Service#onStartCommand
    297          * Service.onStartCommand} function will return the new
    298          * {@link android.app.Service#START_STICKY} behavior instead of the
    299          * old compatibility {@link android.app.Service#START_STICKY_COMPATIBILITY}.
    300          * <li> The {@link android.app.Activity} class will now execute back
    301          * key presses on the key up instead of key down, to be able to detect
    302          * canceled presses from virtual keys.
    303          * <li> The {@link android.widget.TabWidget} class will use a new color scheme
    304          * for tabs. In the new scheme, the foreground tab has a medium gray background
    305          * the background tabs have a dark gray background.
    306          * </ul>
    307          */
    308         public static final int ECLAIR = 5;
    309 
    310         /**
    311          * December 2009: Android 2.0.1
    312          */
    313         public static final int ECLAIR_0_1 = 6;
    314 
    315         /**
    316          * January 2010: Android 2.1
    317          */
    318         public static final int ECLAIR_MR1 = 7;
    319 
    320         /**
    321          * June 2010: Android 2.2
    322          */
    323         public static final int FROYO = 8;
    324 
    325         /**
    326          * November 2010: Android 2.3
    327          *
    328          * <p>Applications targeting this or a later release will get these
    329          * new changes in behavior:</p>
    330          * <ul>
    331          * <li> The application's notification icons will be shown on the new
    332          * dark status bar background, so must be visible in this situation.
    333          * </ul>
    334          */
    335         public static final int GINGERBREAD = 9;
    336 
    337         /**
    338          * February 2011: Android 2.3.3.
    339          */
    340         public static final int GINGERBREAD_MR1 = 10;
    341 
    342         /**
    343          * February 2011: Android 3.0.
    344          *
    345          * <p>Applications targeting this or a later release will get these
    346          * new changes in behavior:</p>
    347          * <ul>
    348          * <li> The default theme for applications is now dark holographic:
    349          *      {@link android.R.style#Theme_Holo}.
    350          * <li> On large screen devices that do not have a physical menu
    351          * button, the soft (compatibility) menu is disabled.
    352          * <li> The activity lifecycle has changed slightly as per
    353          * {@link android.app.Activity}.
    354          * <li> An application will crash if it does not call through
    355          * to the super implementation of its
    356          * {@link android.app.Activity#onPause Activity.onPause()} method.
    357          * <li> When an application requires a permission to access one of
    358          * its components (activity, receiver, service, provider), this
    359          * permission is no longer enforced when the application wants to
    360          * access its own component.  This means it can require a permission
    361          * on a component that it does not itself hold and still access that
    362          * component.
    363          * <li> {@link android.content.Context#getSharedPreferences
    364          * Context.getSharedPreferences()} will not automatically reload
    365          * the preferences if they have changed on storage, unless
    366          * {@link android.content.Context#MODE_MULTI_PROCESS} is used.
    367          * <li> {@link android.view.ViewGroup#setMotionEventSplittingEnabled}
    368          * will default to true.
    369          * <li> {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH}
    370          * is enabled by default on windows.
    371          * <li> {@link android.widget.PopupWindow#isSplitTouchEnabled()
    372          * PopupWindow.isSplitTouchEnabled()} will return true by default.
    373          * <li> {@link android.widget.GridView} and {@link android.widget.ListView}
    374          * will use {@link android.view.View#setActivated View.setActivated}
    375          * for selected items if they do not implement {@link android.widget.Checkable}.
    376          * <li> {@link android.widget.Scroller} will be constructed with
    377          * "flywheel" behavior enabled by default.
    378          * </ul>
    379          */
    380         public static final int HONEYCOMB = 11;
    381 
    382         /**
    383          * May 2011: Android 3.1.
    384          */
    385         public static final int HONEYCOMB_MR1 = 12;
    386 
    387         /**
    388          * June 2011: Android 3.2.
    389          *
    390          * <p>Update to Honeycomb MR1 to support 7 inch tablets, improve
    391          * screen compatibility mode, etc.</p>
    392          *
    393          * <p>As of this version, applications that don't say whether they
    394          * support XLARGE screens will be assumed to do so only if they target
    395          * {@link #HONEYCOMB} or later; it had been {@link #GINGERBREAD} or
    396          * later.  Applications that don't support a screen size at least as
    397          * large as the current screen will provide the user with a UI to
    398          * switch them in to screen size compatibility mode.</p>
    399          *
    400          * <p>This version introduces new screen size resource qualifiers
    401          * based on the screen size in dp: see
    402          * {@link android.content.res.Configuration#screenWidthDp},
    403          * {@link android.content.res.Configuration#screenHeightDp}, and
    404          * {@link android.content.res.Configuration#smallestScreenWidthDp}.
    405          * Supplying these in &lt;supports-screens&gt; as per
    406          * {@link android.content.pm.ApplicationInfo#requiresSmallestWidthDp},
    407          * {@link android.content.pm.ApplicationInfo#compatibleWidthLimitDp}, and
    408          * {@link android.content.pm.ApplicationInfo#largestWidthLimitDp} is
    409          * preferred over the older screen size buckets and for older devices
    410          * the appropriate buckets will be inferred from them.</p>
    411          *
    412          * <p>Applications targeting this or a later release will get these
    413          * new changes in behavior:</p>
    414          * <ul>
    415          * <li><p>New {@link android.content.pm.PackageManager#FEATURE_SCREEN_PORTRAIT}
    416          * and {@link android.content.pm.PackageManager#FEATURE_SCREEN_LANDSCAPE}
    417          * features were introduced in this release.  Applications that target
    418          * previous platform versions are assumed to require both portrait and
    419          * landscape support in the device; when targeting Honeycomb MR1 or
    420          * greater the application is responsible for specifying any specific
    421          * orientation it requires.</p>
    422          * <li><p>{@link android.os.AsyncTask} will use the serial executor
    423          * by default when calling {@link android.os.AsyncTask#execute}.</p>
    424          * <li><p>{@link android.content.pm.ActivityInfo#configChanges
    425          * ActivityInfo.configChanges} will have the
    426          * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE} and
    427          * {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE}
    428          * bits set; these need to be cleared for older applications because
    429          * some developers have done absolute comparisons against this value
    430          * instead of correctly masking the bits they are interested in.
    431          * </ul>
    432          */
    433         public static final int HONEYCOMB_MR2 = 13;
    434 
    435         /**
    436          * October 2011: Android 4.0.
    437          *
    438          * <p>Applications targeting this or a later release will get these
    439          * new changes in behavior:</p>
    440          * <ul>
    441          * <li> For devices without a dedicated menu key, the software compatibility
    442          * menu key will not be shown even on phones.  By targeting Ice Cream Sandwich
    443          * or later, your UI must always have its own menu UI affordance if needed,
    444          * on both tablets and phones.  The ActionBar will take care of this for you.
    445          * <li> 2d drawing hardware acceleration is now turned on by default.
    446          * You can use
    447          * {@link android.R.attr#hardwareAccelerated android:hardwareAccelerated}
    448          * to turn it off if needed, although this is strongly discouraged since
    449          * it will result in poor performance on larger screen devices.
    450          * <li> The default theme for applications is now the "device default" theme:
    451          *      {@link android.R.style#Theme_DeviceDefault}. This may be the
    452          *      holo dark theme or a different dark theme defined by the specific device.
    453          *      The {@link android.R.style#Theme_Holo} family must not be modified
    454          *      for a device to be considered compatible. Applications that explicitly
    455          *      request a theme from the Holo family will be guaranteed that these themes
    456          *      will not change character within the same platform version. Applications
    457          *      that wish to blend in with the device should use a theme from the
    458          *      {@link android.R.style#Theme_DeviceDefault} family.
    459          * <li> Managed cursors can now throw an exception if you directly close
    460          * the cursor yourself without stopping the management of it; previously failures
    461          * would be silently ignored.
    462          * <li> The fadingEdge attribute on views will be ignored (fading edges is no
    463          * longer a standard part of the UI).  A new requiresFadingEdge attribute allows
    464          * applications to still force fading edges on for special cases.
    465          * <li> {@link android.content.Context#bindService Context.bindService()}
    466          * will not automatically add in {@link android.content.Context#BIND_WAIVE_PRIORITY}.
    467          * <li> App Widgets will have standard padding automatically added around
    468          * them, rather than relying on the padding being baked into the widget itself.
    469          * <li> An exception will be thrown if you try to change the type of a
    470          * window after it has been added to the window manager.  Previously this
    471          * would result in random incorrect behavior.
    472          * <li> {@link android.view.animation.AnimationSet} will parse out
    473          * the duration, fillBefore, fillAfter, repeatMode, and startOffset
    474          * XML attributes that are defined.
    475          * <li> {@link android.app.ActionBar#setHomeButtonEnabled
    476          * ActionBar.setHomeButtonEnabled()} is false by default.
    477          * </ul>
    478          */
    479         public static final int ICE_CREAM_SANDWICH = 14;
    480 
    481         /**
    482          * December 2011: Android 4.0.3.
    483          */
    484         public static final int ICE_CREAM_SANDWICH_MR1 = 15;
    485 
    486         /**
    487          * June 2012: Android 4.1.
    488          *
    489          * <p>Applications targeting this or a later release will get these
    490          * new changes in behavior:</p>
    491          * <ul>
    492          * <li> You must explicitly request the {@link android.Manifest.permission#READ_CALL_LOG}
    493          * and/or {@link android.Manifest.permission#WRITE_CALL_LOG} permissions;
    494          * access to the call log is no longer implicitly provided through
    495          * {@link android.Manifest.permission#READ_CONTACTS} and
    496          * {@link android.Manifest.permission#WRITE_CONTACTS}.
    497          * <li> {@link android.widget.RemoteViews} will throw an exception if
    498          * setting an onClick handler for views being generated by a
    499          * {@link android.widget.RemoteViewsService} for a collection container;
    500          * previously this just resulted in a warning log message.
    501          * <li> New {@link android.app.ActionBar} policy for embedded tabs:
    502          * embedded tabs are now always stacked in the action bar when in portrait
    503          * mode, regardless of the size of the screen.
    504          * <li> {@link android.webkit.WebSettings#setAllowFileAccessFromFileURLs(boolean)
    505          * WebSettings.setAllowFileAccessFromFileURLs} and
    506          * {@link android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs(boolean)
    507          * WebSettings.setAllowUniversalAccessFromFileURLs} default to false.
    508          * <li> Calls to {@link android.content.pm.PackageManager#setComponentEnabledSetting
    509          * PackageManager.setComponentEnabledSetting} will now throw an
    510          * IllegalArgumentException if the given component class name does not
    511          * exist in the application's manifest.
    512          * <li> {@link android.nfc.NfcAdapter#setNdefPushMessage
    513          * NfcAdapter.setNdefPushMessage},
    514          * {@link android.nfc.NfcAdapter#setNdefPushMessageCallback
    515          * NfcAdapter.setNdefPushMessageCallback} and
    516          * {@link android.nfc.NfcAdapter#setOnNdefPushCompleteCallback
    517          * NfcAdapter.setOnNdefPushCompleteCallback} will throw
    518          * IllegalStateException if called after the Activity has been destroyed.
    519          * <li> Accessibility services must require the new
    520          * {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission or
    521          * they will not be available for use.
    522          * <li> {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
    523          * AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} must be set
    524          * for unimportant views to be included in queries.
    525          * </ul>
    526          */
    527         public static final int JELLY_BEAN = 16;
    528 
    529         /**
    530          * November 2012: Android 4.2, Moar jelly beans!
    531          *
    532          * <p>Applications targeting this or a later release will get these
    533          * new changes in behavior:</p>
    534          * <ul>
    535          * <li>Content Providers: The default value of {@code android:exported} is now
    536          * {@code false}. See
    537          * <a href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
    538          * the android:exported section</a> in the provider documentation for more details.</li>
    539          * <li>{@link android.view.View#getLayoutDirection() View.getLayoutDirection()}
    540          * can return different values than {@link android.view.View#LAYOUT_DIRECTION_LTR}
    541          * based on the locale etc.
    542          * <li> {@link android.webkit.WebView#addJavascriptInterface(Object, String)
    543          * WebView.addJavascriptInterface} requires explicit annotations on methods
    544          * for them to be accessible from Javascript.
    545          * </ul>
    546          */
    547         public static final int JELLY_BEAN_MR1 = 17;
    548 
    549         /**
    550          * July 2013: Android 4.3, the revenge of the beans.
    551          */
    552         public static final int JELLY_BEAN_MR2 = 18;
    553 
    554         /**
    555          * October 2013: Android 4.4, KitKat, another tasty treat.
    556          *
    557          * <p>Applications targeting this or a later release will get these
    558          * new changes in behavior:</p>
    559          * <ul>
    560          * <li> The default result of
    561          * {@link android.preference.PreferenceActivity#isValidFragment(String)
    562          * PreferenceActivity.isValueFragment} becomes false instead of true.</li>
    563          * <li> In {@link android.webkit.WebView}, apps targeting earlier versions will have
    564          * JS URLs evaluated directly and any result of the evaluation will not replace
    565          * the current page content.  Apps targetting KITKAT or later that load a JS URL will
    566          * have the result of that URL replace the content of the current page</li>
    567          * <li> {@link android.app.AlarmManager#set AlarmManager.set} becomes interpreted as
    568          * an inexact value, to give the system more flexibility in scheduling alarms.</li>
    569          * <li> {@link android.content.Context#getSharedPreferences(String, int)
    570          * Context.getSharedPreferences} no longer allows a null name.</li>
    571          * <li> {@link android.widget.RelativeLayout} changes to compute wrapped content
    572          * margins correctly.</li>
    573          * <li> {@link android.app.ActionBar}'s window content overlay is allowed to be
    574          * drawn.</li>
    575          * <li>The {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
    576          * permission is now always enforced.</li>
    577          * <li>Access to package-specific external storage directories belonging
    578          * to the calling app no longer requires the
    579          * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} or
    580          * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
    581          * permissions.</li>
    582          * </ul>
    583          */
    584         public static final int KITKAT = 19;
    585 
    586         /**
    587          * June 2014: Android 4.4W. KitKat for watches, snacks on the run.
    588          *
    589          * <p>Applications targeting this or a later release will get these
    590          * new changes in behavior:</p>
    591          * <ul>
    592          * <li>{@link android.app.AlertDialog} might not have a default background if the theme does
    593          * not specify one.</li>
    594          * </ul>
    595          */
    596         public static final int KITKAT_WATCH = 20;
    597 
    598         /**
    599          * Temporary until we completely switch to {@link #LOLLIPOP}.
    600          * @hide
    601          */
    602         public static final int L = 21;
    603 
    604         /**
    605          * November 2014: Lollipop.  A flat one with beautiful shadows.  But still tasty.
    606          *
    607          * <p>Applications targeting this or a later release will get these
    608          * new changes in behavior:</p>
    609          * <ul>
    610          * <li> {@link android.content.Context#bindService Context.bindService} now
    611          * requires an explicit Intent, and will throw an exception if given an implicit
    612          * Intent.</li>
    613          * <li> {@link android.app.Notification.Builder Notification.Builder} will
    614          * not have the colors of their various notification elements adjusted to better
    615          * match the new material design look.</li>
    616          * <li> {@link android.os.Message} will validate that a message is not currently
    617          * in use when it is recycled.</li>
    618          * <li> Hardware accelerated drawing in windows will be enabled automatically
    619          * in most places.</li>
    620          * <li> {@link android.widget.Spinner} throws an exception if attaching an
    621          * adapter with more than one item type.</li>
    622          * <li> If the app is a launcher, the launcher will be available to the user
    623          * even when they are using corporate profiles (which requires that the app
    624          * use {@link android.content.pm.LauncherApps} to correctly populate its
    625          * apps UI).</li>
    626          * <li> Calling {@link android.app.Service#stopForeground Service.stopForeground}
    627          * with removeNotification false will modify the still posted notification so that
    628          * it is no longer forced to be ongoing.</li>
    629          * <li> A {@link android.service.dreams.DreamService} must require the
    630          * {@link android.Manifest.permission#BIND_DREAM_SERVICE} permission to be usable.</li>
    631          * </ul>
    632          */
    633         public static final int LOLLIPOP = 21;
    634 
    635         /**
    636          * March 2015: Lollipop with an extra sugar coating on the outside!
    637          */
    638         public static final int LOLLIPOP_MR1 = 22;
    639 
    640         /**
    641          * M is for Marshmallow!
    642          *
    643          * <p>Applications targeting this or a later release will get these
    644          * new changes in behavior:</p>
    645          * <ul>
    646          * <li> Runtime permissions.  Dangerous permissions are no longer granted at
    647          * install time, but must be requested by the application at runtime through
    648          * {@link android.app.Activity#requestPermissions}.</li>
    649          * <li> Bluetooth and Wi-Fi scanning now requires holding the location permission.</li>
    650          * <li> {@link android.app.AlarmManager#setTimeZone AlarmManager.setTimeZone} will fail if
    651          * the given timezone is non-Olson.</li>
    652          * <li> Activity transitions will only return shared
    653          * elements mapped in the returned view hierarchy back to the calling activity.</li>
    654          * <li> {@link android.view.View} allows a number of behaviors that may break
    655          * existing apps: Canvas throws an exception if restore() is called too many times,
    656          * widgets may return a hint size when returning UNSPECIFIED measure specs, and it
    657          * will respect the attributes {@link android.R.attr#foreground},
    658          * {@link android.R.attr#foregroundGravity}, {@link android.R.attr#foregroundTint}, and
    659          * {@link android.R.attr#foregroundTintMode}.</li>
    660          * <li> {@link android.view.MotionEvent#getButtonState MotionEvent.getButtonState}
    661          * will no longer report {@link android.view.MotionEvent#BUTTON_PRIMARY}
    662          * and {@link android.view.MotionEvent#BUTTON_SECONDARY} as synonyms for
    663          * {@link android.view.MotionEvent#BUTTON_STYLUS_PRIMARY} and
    664          * {@link android.view.MotionEvent#BUTTON_STYLUS_SECONDARY}.</li>
    665          * <li> {@link android.widget.ScrollView} now respects the layout param margins
    666          * when measuring.</li>
    667          * </ul>
    668          */
    669         public static final int M = 23;
    670 
    671         /**
    672          * N is for \_()_/.
    673          */
    674         public static final int N = 24;
    675     }
    676 
    677     /** The type of build, like "user" or "eng". */
    678     public static final String TYPE = getString("ro.build.type");
    679 
    680     /** Comma-separated tags describing the build, like "unsigned,debug". */
    681     public static final String TAGS = getString("ro.build.tags");
    682 
    683     /** A string that uniquely identifies this build.  Do not attempt to parse this value. */
    684     public static final String FINGERPRINT = deriveFingerprint();
    685 
    686     /**
    687      * Some devices split the fingerprint components between multiple
    688      * partitions, so we might derive the fingerprint at runtime.
    689      */
    690     private static String deriveFingerprint() {
    691         String finger = SystemProperties.get("ro.build.fingerprint");
    692         if (TextUtils.isEmpty(finger)) {
    693             finger = getString("ro.product.brand") + '/' +
    694                     getString("ro.product.name") + '/' +
    695                     getString("ro.product.device") + ':' +
    696                     getString("ro.build.version.release") + '/' +
    697                     getString("ro.build.id") + '/' +
    698                     getString("ro.build.version.incremental") + ':' +
    699                     getString("ro.build.type") + '/' +
    700                     getString("ro.build.tags");
    701         }
    702         return finger;
    703     }
    704 
    705     /**
    706      * Ensure that raw fingerprint system property is defined. If it was derived
    707      * dynamically by {@link #deriveFingerprint()} this is where we push the
    708      * derived value into the property service.
    709      *
    710      * @hide
    711      */
    712     public static void ensureFingerprintProperty() {
    713         if (TextUtils.isEmpty(SystemProperties.get("ro.build.fingerprint"))) {
    714             try {
    715                 SystemProperties.set("ro.build.fingerprint", FINGERPRINT);
    716             } catch (IllegalArgumentException e) {
    717                 Slog.e(TAG, "Failed to set fingerprint property", e);
    718             }
    719         }
    720     }
    721 
    722     /**
    723      * Verifies the the current flash of the device is consistent with what
    724      * was expected at build time.
    725      * 1) Checks that device fingerprint is defined and that it matches across
    726      *    various partitions.
    727      * 2) Verifies radio and bootloader partitions are those expected in the build.
    728      *
    729      * @hide
    730      */
    731     public static boolean isBuildConsistent() {
    732         // Don't care on eng builds.  Incremental build may trigger false negative.
    733         if ("eng".equals(TYPE)) return true;
    734 
    735         final String system = SystemProperties.get("ro.build.fingerprint");
    736         final String vendor = SystemProperties.get("ro.vendor.build.fingerprint");
    737         final String bootimage = SystemProperties.get("ro.bootimage.build.fingerprint");
    738         final String requiredBootloader = SystemProperties.get("ro.build.expect.bootloader");
    739         final String currentBootloader = SystemProperties.get("ro.bootloader");
    740         final String requiredRadio = SystemProperties.get("ro.build.expect.baseband");
    741         final String currentRadio = SystemProperties.get("gsm.version.baseband");
    742 
    743         if (TextUtils.isEmpty(system)) {
    744             Slog.e(TAG, "Required ro.build.fingerprint is empty!");
    745             return false;
    746         }
    747 
    748         if (!TextUtils.isEmpty(vendor)) {
    749             if (!Objects.equals(system, vendor)) {
    750                 Slog.e(TAG, "Mismatched fingerprints; system reported " + system
    751                         + " but vendor reported " + vendor);
    752                 return false;
    753             }
    754         }
    755 
    756         /* TODO: Figure out issue with checks failing
    757         if (!TextUtils.isEmpty(bootimage)) {
    758             if (!Objects.equals(system, bootimage)) {
    759                 Slog.e(TAG, "Mismatched fingerprints; system reported " + system
    760                         + " but bootimage reported " + bootimage);
    761                 return false;
    762             }
    763         }
    764 
    765         if (!TextUtils.isEmpty(requiredBootloader)) {
    766             if (!Objects.equals(currentBootloader, requiredBootloader)) {
    767                 Slog.e(TAG, "Mismatched bootloader version: build requires " + requiredBootloader
    768                         + " but runtime reports " + currentBootloader);
    769                 return false;
    770             }
    771         }
    772 
    773         if (!TextUtils.isEmpty(requiredRadio)) {
    774             if (!Objects.equals(currentRadio, requiredRadio)) {
    775                 Slog.e(TAG, "Mismatched radio version: build requires " + requiredRadio
    776                         + " but runtime reports " + currentRadio);
    777                 return false;
    778             }
    779         }
    780         */
    781 
    782         return true;
    783     }
    784 
    785     // The following properties only make sense for internal engineering builds.
    786     public static final long TIME = getLong("ro.build.date.utc") * 1000;
    787     public static final String USER = getString("ro.build.user");
    788     public static final String HOST = getString("ro.build.host");
    789 
    790     /**
    791      * Returns true if we are running a debug build such as "user-debug" or "eng".
    792      * @hide
    793      */
    794     public static final boolean IS_DEBUGGABLE =
    795             SystemProperties.getInt("ro.debuggable", 0) == 1;
    796 
    797     /**
    798      * Specifies whether the permissions needed by a legacy app should be
    799      * reviewed before any of its components can run. A legacy app is one
    800      * with targetSdkVersion < 23, i.e apps using the old permission model.
    801      * If review is not required, permissions are reviewed before the app
    802      * is installed.
    803      *
    804      * @hide
    805      */
    806     @SystemApi
    807     public static final boolean PERMISSIONS_REVIEW_REQUIRED =
    808             SystemProperties.getInt("ro.permission_review_required", 0) == 1;
    809 
    810     /**
    811      * Returns the version string for the radio firmware.  May return
    812      * null (if, for instance, the radio is not currently on).
    813      */
    814     public static String getRadioVersion() {
    815         return SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION, null);
    816     }
    817 
    818     private static String getString(String property) {
    819         return SystemProperties.get(property, UNKNOWN);
    820     }
    821 
    822     private static String[] getStringList(String property, String separator) {
    823         String value = SystemProperties.get(property);
    824         if (value.isEmpty()) {
    825             return new String[0];
    826         } else {
    827             return value.split(separator);
    828         }
    829     }
    830 
    831     private static long getLong(String property) {
    832         try {
    833             return Long.parseLong(SystemProperties.get(property));
    834         } catch (NumberFormatException e) {
    835             return -1;
    836         }
    837     }
    838 }
    839