Chris Hall bio photo

Chris Hall

Principal Technical Consultant

PolarCloudsUK Chris LinkedIn Github
Chris Hall Nutanix Certified Master - Multicloud Infrastructure 6 Chris Hall VMware vExpert 2024 Nutanix Certified Professional - Cloud Integration Chris Hall Nutanix Certified Professional - Multicloud Infrastructure 6 Chris Hall Nutanix Certified Professional - Unified Storage 6 Chris Hall VMware vExpert 2023 Chris Hall VMware vExpert 2022
Like it or not smartphone applications ("apps") are here to stay.

Lets face it, we all like to have that "wizzy" app that allows us to do this or that, or displays certain data in a certain way.

 - iPhone has App Store
 - Android has Android Market
    Both have tens of thousands apps available to download.  But how do you ensure that your patrons are installing apps that are not going to adversely affect their end user experience?

    Say hello to the Android build fingerprint.

    It is this build fingerprint that ultimately governs the exact number of apps available to the end user via the Android market.

    However, the Android fingerprint system is not without it's faults.  The most common fault being that apps appear to be "missing" from the market, meaning that they are not available to install.  These issues are typically seen when either (a) a new handset is released or (b) when an existing handset receives an android version upgrade.  

    It just so happens that my T-Mobile Pulse - aka Huawei U8220 - recently received an Android 2.1 upgrade released by T-Mobile in Hungary (yeah I know.  Hungary?!? what the.....?) here.

    It was after installing this update that my personal dealings with "missing" market applications started.

    It turns out that the Android Fingerprint included in the Hungarian update was not as it should have been.

    So, lets look at the Android fingerprint closer.  Namely:
    1. How Android fingerprints are derived
    2. What makes a good fingerprint with lots of market apps available to the user

    Fingerprint Location, Editing and An Example Fingerprint
    Fingerprints live in the /system/build.prop file on any Android phone.

    There are several to look at and modify your build.prop file.  Perhaps the easiest is to use an app like Estrongs File Explorer to open and edit build.prop.  An alternative way is to use Android Debug Bridge or adb as it is known.

    Here is an example fingerprint:
    ro.build.fingerprint=htc_wwe/htc_legend/legend/legend:2.1/ERD79/139791:user/release-keys

    How are fingerprints derived?
    Being that Android is open, the information on deriving fingerprints is out there, the killer is finding it!

    After some searching I eventually stumbled on this PDF which states:

    android.os.Build.FINGERPRINT:
    A string that uniquely identifies this build. It SHOULD be reasonably human-readable. It MUST follow this template:

    $(BRAND)/$(PRODUCT)/$(DEVICE)/$(BOARD):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS)

    For example:
    acme/mydevice/generic/generic:2.1-update1/ERC77/3359:userdebug/test-keys

    The fingerprint MUST NOT include spaces. If other fields included in the template above have spaces, they SHOULD be replaced with the ASCII underscore ("_") character in the fingerprint.

    Breaking this down then:
    (BRAND)
    A value chosen by the device implementer identifying the name of the company, organization, individual, etc. who produced the device, in human-readable format. A possible use of this field is to indicate the OEM and/or carrier who sold the device. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").

    (PRODUCT)
    A value chosen by the device implementer containing the development name or code name of the device. MUST be human-readable, but is not necessarily intended for view by end users. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").

    (DEVICE)
    A value chosen by the device implementer identifying the specific configuration or revision of the body (sometimes called "industrial design")of the device. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").

    (BOARD)
    A value chosen by the device implementer identifying the specific internal hardware used by the device, in human-readable format. A possible use of this field is to indicate the specific revision of the board powering the device. There are no requirements on the specific format of this field, except
    that it MUST NOT be null or the empty string ("").

    (VERSION.RELEASE)
    The version of the currently-executing Android system, in human-readable format. This field MUST have one of the string values defined in Android 2.1 allowed version strings: http://source.android.com/compatibility/2.1/versions.html

    (ID)
    An identifier chosen by the device implementer to refer to a specific release, in human readable format. This field can be the same as android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently meaningful for end users to distinguish between software builds. There are no requirements on the specific format of this field, except that it MUST NOT be
    null or the empty string ("").

    (VERSION.INCREMENTAL)
    A value chosen by the device implementer designating the specific build of the currently-executing Android system, in human-readable format. This value MUST NOT be re-used for different builds shipped to end users. A typical use of this field is to indicate which build number or source-control change identifier was used to generate the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").

    (TAGS)
    A comma-separated list of tags chosen by the device implementer that further distinguish the build. For example, "unsigned,debug". This field MUST NOT be null or the empty string (""), but a single tag (such as "release") is fine.

    Phew!

    To understand this better, lets say:
    • I go into business called CHPhones and produce a nice shiny handset called a CH1, running Android 2.1 update 1.
    • My CH1 is based on the ZZZ chipset
    • I've singed an exclusivity contract with BTCellnet for the CH1
    • I'm creating the android 2.1 build version 0001 today - 29/June/2010
    Using the template from the PDF,
    $(BRAND)/$(PRODUCT)/$(DEVICE)/$(BOARD):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS)

    my build fingerprint would be:
    BTCellnet/CHPhones/CH1/ZZZ:2.1-update1/0001/09062010:user/release-keys

    And there you go, a nice specific fingerprint for use on the market.

    My next step would be to register this brand new fingerprint 'behind the scenes' with Google - possibly through Open Hand Set Alliance, maybe a bit of testing and there we go, one live fingerprint.

    There is no smoke & mirror "magic code" embedded in the fingerprint. The fingerprint really is he sum of the total of it's parts; it only works as a whole. Make any changes to any part of the registered fingerprint and it stops working.  End of.

    As the fingerprint can quite literally be anything you want, the killer is that the whole fingerprint needs to be registered with Google / Open Handset Alliance to ensure that the end user indeed has a compatible handset with those additional applications that potentially need it.

    And there in lies the rub.

    Yes we can use a different fingerprint to "trick the market" into allowing us to install additional applications that have not been specifically tested against our fingerprint (and hence our hardware and specific Android build) but we are potentially opening ourselves up to issues because of this.

    Food for thought, next time you get an Android force close / crash / reboot.

    - Chris