Add checks to detect wrong conditions when creating Applications Bug: 185177290 Test: Boot + monitor logcat Change-Id: Icd9f5e891c7b7fe32ee4144d95dd26139b87d9cf (cherry picked from commit 9b9ee9dc4b8465b351e58f6804f52379e26cb737) Merged-In:Icd9f5e891c7b7fe32ee4144d95dd26139b87d9cf
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d90010e..7ac4bdd 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java
@@ -4535,6 +4535,12 @@ // we are back active so skip it. unscheduleGcIdler(); + // To investigate "duplciate Application objects" bug (b/185177290) + if (UserHandle.myUserId() != UserHandle.getUserId(data.info.applicationInfo.uid)) { + Slog.wtf(TAG, "handleCreateService called with wrong appinfo UID: myUserId=" + + UserHandle.myUserId() + " appinfo.uid=" + data.info.applicationInfo.uid); + } + LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null;
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 77af474..4e32e9a 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java
@@ -1341,15 +1341,43 @@ return mResources; } + /** + * Used to investigate "duplicate app objects" bug (b/185177290). + * makeApplication() should only be called on the main thread, so no synchronization should + * be needed, but syncing anyway just in case. + */ + @GuardedBy("sApplicationCache") + private static final ArrayMap<String, Application> sApplicationCache = new ArrayMap<>(4); + @UnsupportedAppUsage public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } - Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); + // For b/185177290. + final boolean wrongUser = + UserHandle.myUserId() != UserHandle.getUserId(mApplicationInfo.uid); + if (wrongUser) { + Slog.wtf(TAG, "makeApplication called with wrong appinfo UID: myUserId=" + + UserHandle.myUserId() + " appinfo.uid=" + mApplicationInfo.uid); + } + synchronized (sApplicationCache) { + final Application cached = sApplicationCache.get(mPackageName); + if (cached != null) { + // Looks like this is always happening for the system server, because + // the LoadedApk created in systemMain() -> attach() isn't cached properly? + if (!"android".equals(mPackageName)) { + Slog.wtf(TAG, "App instance already created for package=" + mPackageName + + " instance=" + cached); + } + // TODO Return the cached one, unles it's for the wrong user? + // For now, we just add WTF checks. + } + } + Application app = null; final String myProcessName = Process.myProcessName(); @@ -1397,6 +1425,9 @@ } mActivityThread.mAllApplications.add(app); mApplication = app; + synchronized (sApplicationCache) { + sApplicationCache.put(mPackageName, app); + } if (instrumentation != null) { try {