diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index f361695b2fbd7..4b0cef6e5a120 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -20,8 +20,11 @@ import android.text.TextUtils;
import android.util.Slog;
import com.android.internal.telephony.TelephonyProperties;
+
import dalvik.system.VMRuntime;
+import java.util.Objects;
+
/**
* Information about the current build, extracted from system properties.
*/
@@ -640,6 +643,32 @@ public class Build {
}
}
+ /**
+ * Check that device fingerprint is defined and that it matches across
+ * various partitions.
+ *
+ * @hide
+ */
+ public static boolean isFingerprintConsistent() {
+ final String system = SystemProperties.get("ro.build.fingerprint");
+ final String vendor = SystemProperties.get("ro.vendor.build.fingerprint");
+
+ if (TextUtils.isEmpty(system)) {
+ Slog.e(TAG, "Required ro.build.fingerprint is empty!");
+ return false;
+ }
+
+ if (!TextUtils.isEmpty(vendor)) {
+ if (!Objects.equals(system, vendor)) {
+ Slog.e(TAG, "Mismatched fingerprints; system reported " + system
+ + " but vendor reported " + vendor);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
// The following properties only make sense for internal engineering builds.
public static final long TIME = getLong("ro.build.date.utc") * 1000;
public static final String USER = getString("ro.build.user");
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 981c57652b4d9..c4b9c5f916c16 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5121,4 +5121,10 @@
Muted by %1$s
+
+
+ There\'s an internal problem with your device, and it may be unstable until you factory data reset.
+
+ There\'s an internal problem with your device. Contact your manufacturer for details.
+
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c592f4962ac9a..f6d08363b2499 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2105,4 +2105,9 @@
+
+
+
+
+
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d311ad9d5c7e9..6d9f0c5e5403c 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1183,7 +1183,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int SERVICE_TIMEOUT_MSG = 12;
static final int UPDATE_TIME_ZONE = 13;
static final int SHOW_UID_ERROR_MSG = 14;
- static final int IM_FEELING_LUCKY_MSG = 15;
+ static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
static final int PROC_START_TIMEOUT_MSG = 20;
static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
static final int KILL_APPLICATION_MSG = 22;
@@ -1212,13 +1212,13 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int FINISH_BOOTING_MSG = 45;
static final int START_USER_SWITCH_MSG = 46;
static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
+ static final int DISMISS_DIALOG_MSG = 48;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
static final int FIRST_COMPAT_MODE_MSG = 300;
static final int FIRST_SUPERVISOR_STACK_MSG = 100;
- AlertDialog mUidAlert;
CompatModeDialog mCompatModeDialog;
long mLastMemUsageReportTime = 0;
@@ -1447,27 +1447,27 @@ public final class ActivityManagerService extends ActivityManagerNative
}
} break;
case SHOW_UID_ERROR_MSG: {
- String title = "System UIDs Inconsistent";
- String text = "UIDs on the system are inconsistent, you need to wipe your"
- + " data partition or your device will be unstable.";
- Log.e(TAG, title + ": " + text);
if (mShowDialogs) {
- // XXX This is a temporary dialog, no need to localize.
AlertDialog d = new BaseErrorDialog(mContext);
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
d.setCancelable(false);
- d.setTitle(title);
- d.setMessage(text);
- d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
- mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
- mUidAlert = d;
+ d.setTitle(mContext.getText(R.string.android_system_label));
+ d.setMessage(mContext.getText(R.string.system_error_wipe_data));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+ mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
d.show();
}
} break;
- case IM_FEELING_LUCKY_MSG: {
- if (mUidAlert != null) {
- mUidAlert.dismiss();
- mUidAlert = null;
+ case SHOW_FINGERPRINT_ERROR_MSG: {
+ if (mShowDialogs) {
+ AlertDialog d = new BaseErrorDialog(mContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setCancelable(false);
+ d.setTitle(mContext.getText(R.string.android_system_label));
+ d.setMessage(mContext.getText(R.string.system_error_manufacturer));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+ mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
+ d.show();
}
} break;
case PROC_START_TIMEOUT_MSG: {
@@ -1727,6 +1727,11 @@ public final class ActivityManagerService extends ActivityManagerNative
}
break;
}
+ case DISMISS_DIALOG_MSG: {
+ final Dialog d = (Dialog) msg.obj;
+ d.dismiss();
+ break;
+ }
}
}
};
@@ -1776,7 +1781,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- int i=0, num=0;
+ int i = 0;
+ int num = 0;
long[] tmp = new long[1];
do {
ProcessRecord proc;
@@ -11250,13 +11256,18 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
- Message msg = Message.obtain();
- msg.what = SHOW_UID_ERROR_MSG;
- mHandler.sendMessage(msg);
+ Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
+ + " data partition or your device will be unstable.");
+ mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
}
} catch (RemoteException e) {
}
+ if (!Build.isFingerprintConsistent()) {
+ Slog.e(TAG, "Build fingerprint is not consistent, warning user");
+ mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
+ }
+
long ident = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
@@ -13962,7 +13973,9 @@ public final class ActivityManagerService extends ActivityManagerNative
ArrayList procMems = new ArrayList();
final SparseArray procMemsMap = new SparseArray();
- long nativePss=0, dalvikPss=0, otherPss=0;
+ long nativePss = 0;
+ long dalvikPss = 0;
+ long otherPss = 0;
long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 0cf2249396c06..db0f53bf2f680 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1298,7 +1298,12 @@ public class UserManagerService extends IUserManager.Stub {
if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
return false;
}
+
+ // We remember deleted user IDs to prevent them from being
+ // reused during the current boot; they can still be reused
+ // after a reboot.
mRemovingUserIds.put(userHandle, true);
+
try {
mAppOpsService.removeUser(userHandle);
} catch (RemoteException e) {
@@ -1387,18 +1392,6 @@ public class UserManagerService extends IUserManager.Stub {
// Remove this user from the list
mUsers.remove(userHandle);
- // Have user ID linger for several seconds to let external storage VFS
- // cache entries expire. This must be greater than the 'entry_valid'
- // timeout used by the FUSE daemon.
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- synchronized (mPackagesLock) {
- mRemovingUserIds.delete(userHandle);
- }
- }
- }, MINUTE_IN_MILLIS);
-
mRestrictionsPinStates.remove(userHandle);
// Remove user file
AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));