summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanny Baumann <dannybaumann@web.de>2016-11-23 10:12:35 +0100
committerDan Pasanen <invisiblek@cyanogenmod.org>2016-11-25 22:00:39 -0600
commit512122a016488f71ca3f2868c5950229f8634648 (patch)
treeb7e88d82988db613f2b77d194fdd23896d7c79fb
parent7a9c884f482fed0a105a61e61c4881dfd5657985 (diff)
downloadframeworks_base-512122a016488f71ca3f2868c5950229f8634648.zip
frameworks_base-512122a016488f71ca3f2868c5950229f8634648.tar.gz
frameworks_base-512122a016488f71ca3f2868c5950229f8634648.tar.bz2
Make Build.TYPE and Build.FINGERPRINT consistent for apps.
Some apps (namely Android Wear) like to do comparisons between TYPE and FINGERPRINT and throw errors on inconsistencies. As our fingerprints are almost always taken from stock ROMs, they don't really match our builds, causing said comparisons to fail. Avoid those failures by taking build type out of fingerprint for apps. Change-Id: I8e8db64de7ea224572ecb3695c85abea91e0e29f
-rw-r--r--core/java/android/os/Build.java41
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java2
2 files changed, 43 insertions, 0 deletions
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 862f4c4..883977f 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -23,7 +23,11 @@ import com.android.internal.telephony.TelephonyProperties;
import dalvik.system.VMRuntime;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Information about the current build, extracted from system properties.
@@ -664,6 +668,7 @@ public class Build {
/** The type of build, like "user" or "eng". */
public static final String TYPE = getString("ro.build.type");
+ private static String TYPE_FOR_APPS = parseBuildTypeFromFingerprint();
/** Comma-separated tags describing the build, like "unsigned,debug". */
public static final String TAGS = getString("ro.build.tags");
@@ -690,6 +695,42 @@ public class Build {
return finger;
}
+ // Some apps like to compare the build type embedded in fingerprint
+ // to the actual build type. As the fingerprint in our case is almost
+ // always hardcoded to the stock ROM fingerprint, provide that instead
+ // of the actual one if possible.
+ private static String parseBuildTypeFromFingerprint() {
+ final String fingerprint = SystemProperties.get("ro.build.fingerprint");
+ if (TextUtils.isEmpty(fingerprint)) {
+ return null;
+ }
+ Pattern fingerprintPattern =
+ Pattern.compile("(.*)\\/(.*)\\/(.*):(.*)\\/(.*)\\/(.*):(.*)\\/(.*)");
+ Matcher matcher = fingerprintPattern.matcher(fingerprint);
+ return matcher.matches() ? matcher.group(7) : null;
+ }
+
+ /** @hide */
+ public static void adjustBuildTypeIfNeeded() {
+ if (Process.isApplicationUid(Process.myUid()) && !TextUtils.isEmpty(TYPE_FOR_APPS)) {
+ try {
+ // This is sick. TYPE is final (which can't be changed because it's an API
+ // guarantee), but we have to reassign it. Resort to reflection to unset the
+ // final modifier, change the value and restore the final modifier afterwards.
+ Field typeField = Build.class.getField("TYPE");
+ Field accessFlagsField = Field.class.getDeclaredField("accessFlags");
+ accessFlagsField.setAccessible(true);
+ int currentFlags = accessFlagsField.getInt(typeField);
+ accessFlagsField.setInt(typeField, currentFlags & ~Modifier.FINAL);
+ typeField.set(null, TYPE_FOR_APPS);
+ accessFlagsField.setInt(typeField, currentFlags);
+ accessFlagsField.setAccessible(false);
+ } catch (Exception e) {
+ // shouldn't happen, but we don't want to crash the app even if it does happen
+ }
+ }
+ }
+
/**
* Ensure that raw fingerprint system property is defined. If it was derived
* dynamically by {@link #deriveFingerprint()} this is where we push the
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 3377189..45dac2f 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -114,6 +114,8 @@ public class RuntimeInit {
/* set default handler; this applies to all threads in the VM */
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
+ Build.adjustBuildTypeIfNeeded();
+
/*
* Install a TimezoneGetter subclass for ZoneInfo.db
*/