diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 11e379523bc2b..5846bb5d38ee7 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -16,6 +16,8 @@ package android.os; +import android.text.TextUtils; + import com.android.internal.telephony.TelephonyProperties; /** @@ -509,7 +511,39 @@ public class Build { public static final String TAGS = getString("ro.build.tags"); /** A string that uniquely identifies this build. Do not attempt to parse this value. */ - public static final String FINGERPRINT = getString("ro.build.fingerprint"); + public static final String FINGERPRINT = deriveFingerprint(); + + /** + * Some devices split the fingerprint components between multiple + * partitions, so we might derive the fingerprint at runtime. + */ + private static String deriveFingerprint() { + String finger = SystemProperties.get("ro.build.fingerprint"); + if (TextUtils.isEmpty(finger)) { + finger = getString("ro.product.brand") + '/' + + getString("ro.product.name") + '/' + + getString("ro.product.device") + ':' + + getString("ro.build.version.release") + '/' + + getString("ro.build.id") + '/' + + getString("ro.build.version.incremental") + ':' + + getString("ro.build.type") + '/' + + getString("ro.build.tags"); + } + return finger; + } + + /** + * Ensure that raw fingerprint system property is defined. If it was derived + * dynamically by {@link #deriveFingerprint()} this is where we push the + * derived value into the property service. + * + * @hide + */ + public static void ensureFingerprintProperty() { + if (TextUtils.isEmpty(SystemProperties.get("ro.build.fingerprint"))) { + SystemProperties.set("ro.build.fingerprint", FINGERPRINT); + } + } // The following properties only make sense for internal engineering builds. public static final long TIME = getLong("ro.build.date.utc") * 1000; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 00d5468c84b90..08b1eba274b7d 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -29,6 +29,7 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.media.AudioService; +import android.os.Build; import android.os.Environment; import android.os.FactoryTest; import android.os.Handler; @@ -201,6 +202,10 @@ public final class SystemServer { // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); + // Some devices rely on runtime fingerprint generation, so make sure + // we've defined it before booting further. + Build.ensureFingerprintProperty(); + // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true);