Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3565962 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Never instatiate App class multiple times

- GMS-core is still sometimes seeing the app class being
instatiated multiple times.

Let's just cache the app instance to avoid such situations.

- Also removed some tentative WTFs, which have never been triggered.
(so they should be unrelated to the dup-app bug)

Bug: 185177290
Test: Boot / treehugger
Change-Id: I4c74a5798264472d1bfbf5604f399a49e5946c64
parent eebb589d
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -4469,12 +4469,6 @@ public final class ActivityThread extends ClientTransactionHandler
        // 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;
+13 −21
Original line number Diff line number Diff line
@@ -160,6 +160,13 @@ public final class LoadedApk {
    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
        = new ArrayMap<>();
    private AppComponentFactory mAppComponentFactory;

    /**
     * We cache the instantiated application object for each package on this process here.
     */
    @GuardedBy("sApplications")
    private static final ArrayMap<String, Application> sApplications = new ArrayMap<>(4);

    private final Object mLock = new Object();

    Application getApplication() {
@@ -1345,14 +1352,6 @@ public final class LoadedApk {
        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) {
@@ -1361,15 +1360,8 @@ public final class LoadedApk {
        }
        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);
        synchronized (sApplications) {
            final Application cached = sApplications.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?
@@ -1377,8 +1369,8 @@ public final class LoadedApk {
                    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.
                mApplication = cached;
                return cached;
            }
        }

@@ -1429,8 +1421,8 @@ public final class LoadedApk {
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
        synchronized (sApplicationCache) {
            sApplicationCache.put(mPackageName, app);
        synchronized (sApplications) {
            sApplications.put(mPackageName, app);
        }

        if (instrumentation != null) {