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

Commit e678d95e authored by Charles Chen's avatar Charles Chen
Browse files

Enable to track SystemUiContext config changes

Then we can track the config update in WMS.

Bug: 384428048
Test: atest FrameworksCoreTests:ContextTest
Flag: com.android.window.flags.track_system_ui_context_before_wms

Change-Id: I0b24f30010eb94e2344e68417a2b0faa3a3b6d9b
parent f23ceff6
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ public final class ActivityThread extends ClientTransactionHandler
    @UnsupportedAppUsage
    private ContextImpl mSystemContext;
    @GuardedBy("this")
    private ArrayList<WeakReference<ContextImpl>> mDisplaySystemUiContexts;
    private ArrayList<WeakReference<Context>> mDisplaySystemUiContexts;

    @UnsupportedAppUsage
    static volatile IPackageManager sPackageManager;
@@ -3203,7 +3203,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @NonNull
    public ContextImpl getSystemUiContext() {
    public Context getSystemUiContext() {
        return getSystemUiContext(DEFAULT_DISPLAY);
    }

@@ -3213,7 +3213,7 @@ public final class ActivityThread extends ClientTransactionHandler
     * @see ContextImpl#createSystemUiContext(ContextImpl, int)
     */
    @NonNull
    public ContextImpl getSystemUiContext(int displayId) {
    public Context getSystemUiContext(int displayId) {
        synchronized (this) {
            if (mDisplaySystemUiContexts == null) {
                mDisplaySystemUiContexts = new ArrayList<>();
@@ -3221,7 +3221,7 @@ public final class ActivityThread extends ClientTransactionHandler

            mDisplaySystemUiContexts.removeIf(contextRef -> contextRef.refersTo(null));

            ContextImpl context = getSystemUiContextNoCreateLocked(displayId);
            Context context = getSystemUiContextNoCreateLocked(displayId);
            if (context != null) {
                return context;
            }
@@ -3232,9 +3232,20 @@ public final class ActivityThread extends ClientTransactionHandler
        }
    }

    /**
     * Creates a {@code SystemUiContext} for testing.
     * <p>
     * DO NOT use it in production code.
     */
    @VisibleForTesting
    @NonNull
    public Context createSystemUiContextForTesting(int displayId) {
        return ContextImpl.createSystemUiContext(getSystemContext(), displayId);
    }

    @Nullable
    @Override
    public ContextImpl getSystemUiContextNoCreate() {
    public Context getSystemUiContextNoCreate() {
        synchronized (this) {
            if (mDisplaySystemUiContexts == null) {
                return null;
@@ -3245,9 +3256,9 @@ public final class ActivityThread extends ClientTransactionHandler

    @GuardedBy("this")
    @Nullable
    private ContextImpl getSystemUiContextNoCreateLocked(int displayId) {
    private Context getSystemUiContextNoCreateLocked(int displayId) {
        for (int i = 0; i < mDisplaySystemUiContexts.size(); i++) {
            ContextImpl context = mDisplaySystemUiContexts.get(i).get();
            Context context = mDisplaySystemUiContexts.get(i).get();
            if (context != null && context.getDisplayId() == displayId) {
                return context;
            }
@@ -3266,7 +3277,8 @@ public final class ActivityThread extends ClientTransactionHandler
    public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
        synchronized (this) {
            getSystemContext().installSystemApplicationInfo(info, classLoader);
            getSystemUiContext().installSystemApplicationInfo(info, classLoader);
            final ContextImpl sysUiContextImpl = ContextImpl.getImpl(getSystemUiContext());
            sysUiContextImpl.installSystemApplicationInfo(info, classLoader);

            // give ourselves a default profiler
            mProfiler = new Profiler();
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;

import android.content.ComponentCallbacks2;
import android.content.Context;

import java.util.ArrayList;

@@ -28,7 +29,7 @@ import java.util.ArrayList;
interface ActivityThreadInternal {
    ContextImpl getSystemContext();

    ContextImpl getSystemUiContextNoCreate();
    Context getSystemUiContextNoCreate();

    boolean isInDensityCompatMode();

+1 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ class ConfigurationController {

        // Get theme outside of synchronization to avoid nested lock.
        final Resources.Theme systemTheme = mActivityThread.getSystemContext().getTheme();
        final ContextImpl systemUiContext = mActivityThread.getSystemUiContextNoCreate();
        final Context systemUiContext = mActivityThread.getSystemUiContextNoCreate();
        final Resources.Theme systemUiTheme =
                systemUiContext != null ? systemUiContext.getTheme() : null;
        synchronized (mResourcesManager) {
+17 −3
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.autofill.AutofillManager.AutofillClient;
import android.window.SystemUiContext;
import android.window.WindowContext;
import android.window.WindowTokenClient;
import android.window.WindowTokenClientController;
@@ -3477,15 +3478,28 @@ class ContextImpl extends Context {
     *                      {@link #createSystemContext(ActivityThread)}.
     * @param displayId The ID of the display where the UI is shown.
     */
    static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
    static Context createSystemUiContext(ContextImpl systemContext, int displayId) {
        // Step 1. Create a ContextImpl associated with its own resources.
        final WindowTokenClient token = new WindowTokenClient();
        final ContextImpl context = systemContext.createWindowContextBase(token, displayId);
        token.attachContext(context);

        // Step 2. Create a SystemUiContext to wrap the ContextImpl, which enables to listen to
        // its config updates.
        final Context systemUiContext;
        if (com.android.window.flags.Flags.trackSystemUiContextBeforeWms()) {
            systemUiContext = new SystemUiContext(context);
            context.setOuterContext(systemUiContext);
        } else {
            systemUiContext = context;
        }
        token.attachContext(systemUiContext);

        // Step 3. Associate the SystemUiContext with the display specified with ID.
        WindowTokenClientController.getInstance().attachToDisplayContent(token, displayId);
        context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
        context.mOwnsToken = true;

        return context;
        return systemUiContext;
    }

    @UnsupportedAppUsage
+69 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.window;

import android.annotation.NonNull;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacksController;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;

import com.android.window.flags.Flags;

/**
 * System Context to be used for UI. This Context has resources that can be themed.
 *
 * @see android.app.ActivityThread#getSystemUiContext(int)
 *
 * @hide
 */
public class SystemUiContext extends ContextWrapper implements ConfigurationDispatcher {

    private final ComponentCallbacksController mCallbacksController =
            new ComponentCallbacksController();

    public SystemUiContext(Context base) {
        super(base);
        if (!Flags.trackSystemUiContextBeforeWms()) {
            throw new UnsupportedOperationException("SystemUiContext can only be used after"
                    + " flag is enabled.");
        }
    }

    @Override
    public void registerComponentCallbacks(@NonNull ComponentCallbacks callback) {
        mCallbacksController.registerCallbacks(callback);
    }

    @Override
    public void unregisterComponentCallbacks(@NonNull ComponentCallbacks callback) {
        mCallbacksController.unregisterCallbacks(callback);
    }

    /** Dispatch {@link Configuration} to each {@link ComponentCallbacks}. */
    @Override
    public void dispatchConfigurationChanged(@NonNull Configuration newConfig) {
        mCallbacksController.dispatchConfigurationChanged(newConfig);
    }

    @Override
    public boolean shouldReportPrivateChanges() {
        // We should report all config changes to update fields obtained from resources.
        return true;
    }
}
Loading