Move device serial behing a permission

Build serial is non-user resettable freely available deivice
identifier. It can be used by ad-netowrks to track the user
across apps which violates the user's privacy.

This change deprecates Build.SERIAL and adds a new Build.getSerial()
API which requires holding the read_phone_state permission.
The Build.SERIAL value is set to "undefined" for apps targeting
high enough SDK and for legacy app the value is still available.

bug:31402365

Change-Id: Iddd13430b2bd1d9ab4966e31038ecabdbdcec06d
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 5b51002..0191589 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -16,7 +16,10 @@
 
 package android.os;
 
+import android.Manifest;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.content.Context;
 import android.text.TextUtils;
 import android.util.Slog;
 
@@ -98,8 +101,35 @@
      */
     public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");
 
-    /** A hardware serial number, if available.  Alphanumeric only, case-insensitive. */
-    public static final String SERIAL = getString("ro.serialno");
+    /**
+     * A hardware serial number, if available. Alphanumeric only, case-insensitive.
+     * For apps targeting SDK higher than {@link Build.VERSION_CODES#N_MR1} this
+     * field is set to {@link Build#UNKNOWN}.
+     *
+     * @deprecated Use {@link #getSerial()} instead.
+     **/
+    @Deprecated
+    // IMPORTANT: This field should be initialized via a function call to
+    // prevent its value being inlined in the app during compilation because
+    // we will later set it to the value based on the app's target SDK.
+    public static final String SERIAL = getString("no.such.thing");
+
+    /**
+     * Gets the hardware serial, if available. Requires holding the {@link
+     * android.Manifest.permission#READ_PHONE_STATE} permission.
+     * @return The serial if specified.
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public static String getSerial() {
+        IDeviceIdentifiersPolicyService service = IDeviceIdentifiersPolicyService.Stub
+                .asInterface(ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE));
+        try {
+            return service.getSerial();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return UNKNOWN;
+    }
 
     /**
      * An ordered list of ABIs supported by this device. The most preferred ABI is the first