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

Commit d3e5d2be authored by Cosmin Băieș's avatar Cosmin Băieș Committed by Android (Google) Code Review
Browse files

Merge "Handle application info change for system context" into main

parents f08e5b3f be73c3a3
Loading
Loading
Loading
Loading
+46 −11
Original line number Diff line number Diff line
@@ -3100,6 +3100,19 @@ public final class ActivityThread extends ClientTransactionHandler
        mResourcesManager = ResourcesManager.getInstance();
    }

    /**
     * Creates and initialize a new system activity thread, to be used for testing. This does not
     * call {@link #attach}, so it does not modify static state.
     */
    @VisibleForTesting
    @NonNull
    public static ActivityThread createSystemActivityThreadForTesting() {
        final var thread = new ActivityThread();
        thread.mSystemThread = true;
        initializeSystemThread(thread);
        return thread;
    }

    @UnsupportedAppUsage
    public ApplicationThread getApplicationThread()
    {
@@ -6806,6 +6819,16 @@ public final class ActivityThread extends ClientTransactionHandler
            LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
            resApk.updateApplicationInfo(ai, oldPaths);
        }
        if (android.content.res.Flags.systemContextHandleAppInfoChanged() && mSystemThread) {
            final var systemContext = getSystemContext();
            if (systemContext.getPackageName().equals(ai.packageName)) {
                // The system package is not tracked directly, but still needs to receive updates to
                // its application info.
                final ArrayList<String> oldPaths = new ArrayList<>();
                LoadedApk.makePaths(this, systemContext.getApplicationInfo(), oldPaths);
                systemContext.mPackageInfo.updateApplicationInfo(ai, oldPaths);
            }
        }

        ResourcesImpl beforeImpl = getApplication().getResources().getImpl();

@@ -8560,17 +8583,7 @@ public final class ActivityThread extends ClientTransactionHandler
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
            initializeSystemThread(this);
        }

        ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> {
@@ -8595,6 +8608,28 @@ public final class ActivityThread extends ClientTransactionHandler
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

    /**
     * Initializes the given system activity thread, setting up its instrumentation and initial
     * application. This only has an effect if the given thread is a {@link #mSystemThread}.
     *
     * @param thread the given system activity thread to initialize.
     */
    private static void initializeSystemThread(@NonNull ActivityThread thread) {
        if (!thread.mSystemThread) {
            return;
        }
        try {
            thread.mInstrumentation = new Instrumentation();
            thread.mInstrumentation.basicInit(thread);
            ContextImpl context = ContextImpl.createAppContext(
                    thread, thread.getSystemContext().mPackageInfo);
            thread.mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
            thread.mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException("Unable to instantiate Application():" + e, e);
        }
    }

    @UnsupportedAppUsage
    public static ActivityThread systemMain() {
        ThreadedRenderer.initForSystemProcess();
+12 −0
Original line number Diff line number Diff line
@@ -83,3 +83,15 @@ flag {
    bug: "364035303"
}

flag {
    name: "system_context_handle_app_info_changed"
    is_exported: true
    namespace: "resource_manager"
    description: "Feature flag for allowing system context to handle application info changes"
    bug: "362420029"
    # This flag is read at boot time.
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+35 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -59,6 +60,7 @@ import android.app.servertransaction.ResumeActivityItem;
import android.app.servertransaction.StopActivityItem;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -67,7 +69,11 @@ import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -129,6 +135,9 @@ public class ActivityThreadTest {
    @Rule(order = 1)
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);

    @Rule
    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();

    private ActivityWindowInfoListener mActivityWindowInfoListener;
    private WindowTokenClientController mOriginalWindowTokenClientController;
    private Configuration mOriginalAppConfig;
@@ -911,6 +920,32 @@ public class ActivityThreadTest {
        });
    }

    /**
     * Verifies that {@link ActivityThread#handleApplicationInfoChanged} does send updates to the
     * system context, when given the system application info.
     */
    @RequiresFlagsEnabled(android.content.res.Flags.FLAG_SYSTEM_CONTEXT_HANDLE_APP_INFO_CHANGED)
    @Test
    public void testHandleApplicationInfoChanged_systemContext() {
        Looper.prepare();
        final var systemThread = ActivityThread.createSystemActivityThreadForTesting();

        final Context systemContext = systemThread.getSystemContext();
        final var appInfo = systemContext.getApplicationInfo();
        // sourceDir must not be null, and contain at least a '/', for handleApplicationInfoChanged.
        appInfo.sourceDir = "/";

        // Create a copy of the application info.
        final var newAppInfo = new ApplicationInfo(appInfo);
        newAppInfo.sourceDir = "/";
        assertWithMessage("New application info is a separate instance")
                .that(systemContext.getApplicationInfo()).isNotSameInstanceAs(newAppInfo);

        systemThread.handleApplicationInfoChanged(newAppInfo);
        assertWithMessage("Application info was updated successfully")
                .that(systemContext.getApplicationInfo()).isSameInstanceAs(newAppInfo);
    }

    /**
     * Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
     * Configuration, int, ActivityWindowInfo)} to try to push activity configuration to the