Device Identifiers

Android 10 changes the permissions for device identifiers so that all device identifiers are now protected by the READ_PRIVILEGED_PHONE_STATE permission. Prior to Android 10, persistent device identifiers (IMEI/MEID, IMSI, SIM, and build serial) were protected behind the READ_PHONE_STATE runtime permission. The READ_PRIVILEGED_PHONE_STATE permission is only granted to apps signed with the platform key and privileged system apps.

More information for the new permission requirements can be found in the Javadoc pages for TelephonyManager.java and Build.java.

This change affects the following APIs:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

Carrier apps in Google Play that don't use carrier privileges no longer have access to device identifiers. Carriers with apps that are preloaded on devices as privileged apps need to use the READ_PRIVILEGED_PHONE_STATE permission to access device identifiers.

Implementation

Update your privileged permission whitelist to grant the READ_PRIVILEGED_PHONE_STATE permission to those privileged apps that require access to device identifiers.

To learn more about whitelisting, refer to Privileged Permission Whitelisting.

To invoke the affected APIs, an app must meet one of the following requirements:

  • If the app is a preloaded privileged application, it needs the READ_PRIVILEGED_PHONE_STATE permission declared in AndroidManifest.xml. The app also needs to whitelist this privileged permission.
  • Apps delivered through Google Play need carrier privileges. Learn more about granting carrier privileges on the UICC Carrier Privileges page.
  • A device or profile owner app that has been granted the READ_PHONE_STATE permission.

An app that doesn't meet any of these requirements has the following behavior:

  • If the app is targeting pre-Q and doesn't have the READ_PHONE_STATE permission granted, SecurityException is triggered. this is the current pre-Q behavior as this permission is required to invoke these APIs.
  • If the app is targeting pre-Q and does have the READ_PHONE_STATE permission granted, it receives a null value for all of the TelephonyManager APIs and Build.UNKNOWN for the Build#getSerial method.
  • If the app is targeting Android 10 or higher and doesn't meet any one of the new requirements then it receives a SecurityException.

Validation and testing

The Compatibility Test Suite (CTS) includes tests to verify the expected device identifier access behavior for apps with carrier privileges, device and profile owners, and those apps that are expected to not have access to device identifiers.

The following CTS tests are specific to this feature.

cts-tradefed run cts -m CtsCarrierApiTestCases -t
    android.carrierapi.cts.CarrierApiTest

cts-tradefed run cts -m CtsTelephonyTestCases -t
    android.telephony.cts.TelephonyManagerTest

cts-tradefed run cts -m CtsTelephony3TestCases

cts-tradefed run cts -m CtsPermissionTestCases -t
    android.permission.cts.TelephonyManagerPermissionTest

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission