Understanding Google Play device Compatibility

All communication between Android and Google Play is handled by the hypertext transfer protocol. Every request includes the following two HTTP headers:

  • User-Agent (Standard RFC 2612 Header)
  • X-DFE-Device-Id (Non Standard Header)

Whenever apps are searched or APK files are requested for download, the values of these two headers are checked against the app’s 🗋 AndroidManifest.xml file to determine device compatibility.

In addition to checking whether an app could run on a device, Play will also take the settings in the Play Developer Console into account, where developers can explicitly exclude specific device models or manufacturers.


The X-DFE-Device-Id header takes the GSF ID in hexadecimal notation. Originally, this was intended to be the Android Id (it is still referred to by this name internally). However, letting the device roll its own id upon setup and hoping for no collisions proved to be futile. Custom and Manufacturer ROMS appeared where the Android Id was hard wired to zero either due to bugs or privacy concerns.

Nowadays, the GSF ID is generated server side and requested by the device when an account is added to it (every user gets his own GSF ID). After being assigned a GSF ID, the device will bind the account to it and upload its datasheet. To see A JSON representation of what DummyDroid would upload, first select Edit > Copy datasheet , then paste into a text editor.

Please note that not all values of the datasheet are relevant for determining app/device compatibility. Some fields may have been relevant in the past and are no longer being used (if they were intended to be used for checking app compatibility in the first place).


The Android System was originally designed to run from a ROM image on unmodifiable hardware. From that point of view, it made sense to tie a datasheet to a “unique” 64 bit value and store it server side. However, two developments made it necessary to abandon that design:

  • Security holes became an issue, requiring the OS to be updateable.
  • AndroidMarket became Google Play. That is, what was originally just a glorified download center, turned into a Market Place and the sales people weren’t satisfied with a shopping window that could only be redecorated every 2 years, when the user got a new phone.

As a result, the dynamic aspects of the datasheet (mostly software version numbers) now need to be transmitted on every request, encoded in the user agent string. To see the User-Agent, DummyDroid uses, based on the current datasheet, Select the View Useragent menu entry (the User-Agent is always build from the datasheet, it cannot be changed in the dialog).

Please note, that the User-Agent also contains some static aspects of the device (e.g. the manufacturer). Why this is the case is up to speculation. Nevertheless, both GSF ID and User-Agent are both actively sourced for determining device compatibility.

Why does Google not deprecate the GSF ID and only use the User-Agent?

Early day Android smartphones typically had a 320x480 screen, little RAM and slow CPUs. Browsing the AndroidMarket (now: Google Play) was a chore on that. So Google added a feature, allowing you to access Play from your PC and install apps from the webbrowser. That feature is still supported today and requires a stored hardware profile to determine app compatibility.

When (not) to register a new GSF ID

App compatibility experiments that are limited to the “Versions” tab do not require require you to register a new GSF ID (and upload the datasheet) every time. This information is taken from the User-Agent string.


Most fields in the datasheet have very little or no effect on the set of compatible apps. Some are deal breakers, few have unexpected consequences. The following is an unsorted list of research notes:

  • The OTA checkbox in the Build Tab has no effect (other then getting uploaded). It’s not clear why Google even asks for this because the information is kept in the database of the Google Play App and gets destroyed when the user clears its cache.
  • The Bootloader field has no effect on app compatibility.
  • The “Versions” tab indicates to Play whether it can serve you a Split APK or has to stick to traditional APKs. Sadly, simply bumping up the SDK version, while keeping com.android.vending below 7.x won’t work.
  • Modern smartphones add tons of features to the “Features” Tab. Play doesn’t care for most of them. However, leaving the tab blank altogether means declaring that you do not have a touch screen. This rules out pretty much every app on the compatibility check.
  • Pay close attention to the “Graphics” tab. Some apps, you may not expect it from require Open GL ES 3.0 or later.
  • The “Languages” tab seems to be completely unnecessary.
  • You don’t have to be super accurate. Not everything, Play requests is used for compatibility testing. Some values are just for the statistics.