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

Commit 1e76f995 authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Move WindowContext module to window package" into sc-dev

parents c7b83931 f48ece48
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2328,7 +2328,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    final Handler getHandler() {
    public Handler getHandler() {
        return mH;
    }

+108 −31
Original line number Diff line number Diff line
@@ -19,10 +19,12 @@ package android.app;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.StrictMode.vmIncorrectContextUseEnabled;
import static android.view.WindowManager.LayoutParams.WindowType;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
@@ -87,6 +89,8 @@ import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.autofill.AutofillManager.AutofillClient;
import android.window.WindowContext;
import android.window.WindowTokenClient;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -2563,23 +2567,63 @@ class ContextImpl extends Context {

    @NonNull
    @Override
    public WindowContext createWindowContext(int type, @NonNull Bundle options) {
    public WindowContext createWindowContext(@WindowType int type,
            @Nullable Bundle options) {
        if (getDisplay() == null) {
            throw new UnsupportedOperationException("WindowContext can only be created from "
                    + "other visual contexts, such as Activity or one created with "
                    + "Context#createDisplayContext(Display)");
            throw new UnsupportedOperationException("Please call this API with context associated"
                    + " with a display instance, such as Activity or context created via"
                    + " Context#createDisplayContext(Display), or try to invoke"
                    + " Context#createWindowContext(Display, int, Bundle)");
        }
        return new WindowContext(this, type, options);
        return createWindowContextInternal(getDisplay(), type, options);
    }

    @NonNull
    @Override
    public WindowContext createWindowContext(@NonNull Display display, int type,
            @NonNull Bundle options) {
    public WindowContext createWindowContext(@NonNull Display display, @WindowType int type,
            @Nullable Bundle options) {
        if (display == null) {
            throw new IllegalArgumentException("Display must not be null");
        }
        return new WindowContext(this, display, type, options);
        return createWindowContextInternal(display, type, options);
    }

    /**
     * The internal implementation of {@link Context#createWindowContext(int, Bundle)} and
     * {@link Context#createWindowContext(Display, int, Bundle)}.
     *
     * @param display The {@link Display} instance to be associated with.
     *
     * @see Context#createWindowContext(Display, int, Bundle)
     * @see Context#createWindowContext(int, Bundle)
     */
    private WindowContext createWindowContextInternal(@NonNull Display display,
            @WindowType int type, @Nullable Bundle options) {
        // Step 1. Create a WindowTokenClient to associate with the WindowContext's Resources
        //         instance and it will be later used to receive configuration updates from the
        //         server side.
        final WindowTokenClient windowTokenClient = new WindowTokenClient();

        // Step 2. Create the base context of the window context, it will also create a Resources
        //         associated with the WindowTokenClient and set the token to the base context.
        final ContextImpl windowContextBase = createWindowContextBase(windowTokenClient, display);

        // Step 3. Create a WindowContext instance and set it as the outer context of the base
        //         context to make the service obtained by #getSystemService(String) able to query
        //         the WindowContext's WindowManager instead of the default one.
        final WindowContext windowContext = new WindowContext(windowContextBase, type, options);
        windowContextBase.setOuterContext(windowContext);

        // Step 4. Attach the WindowContext to the WindowTokenClient. In this way, when there's a
        //         configuration update from the server side, the update will then apply to
        //         WindowContext's resources.
        windowTokenClient.attachContext(windowContext);

        // Step 5. Register the window context's token to the server side to associate with a
        //         window manager node.
        windowContext.registerWithServer();

        return windowContext;
    }

    @NonNull
@@ -2588,40 +2632,65 @@ class ContextImpl extends Context {
        if (display == null) {
            throw new IllegalArgumentException("Display must not be null");
        }
        final ContextImpl tokenContext = createBaseWindowContext(token, display);
        tokenContext.setResources(createWindowContextResources());
        final ContextImpl tokenContext = createWindowContextBase(token, display);
        tokenContext.setResources(createWindowContextResources(tokenContext));
        return tokenContext;
    }


    ContextImpl createBaseWindowContext(IBinder token, Display display) {
        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
    /**
     * Creates the base {@link Context} for UI context to associate with a non-{@link Activity}
     * window.
     *
     * @param token The token to associate with {@link Resources}
     * @param display The {@link Display} to associate with.
     *
     * @see #createWindowContext(Display, int, Bundle)
     * @see #createTokenContext(IBinder, Display)
     */
    @UiContext
    ContextImpl createWindowContextBase(@NonNull IBinder token, @NonNull Display display) {
        ContextImpl baseContext = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
                mSplitName, token, mUser, mFlags, mClassLoader, null);
        // Window contexts receive configurations directly from the server and as such do not
        // need to override their display in ResourcesManager.
        context.mForceDisplayOverrideInResources = false;
        context.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
        if (display != null) {
            context.mDisplay = display;
        }
        return context;
        baseContext.mForceDisplayOverrideInResources = false;
        baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
        baseContext.mDisplay = display;

        final Resources windowContextResources = createWindowContextResources(baseContext);
        baseContext.setResources(windowContextResources);

        return baseContext;
    }

    Resources createWindowContextResources() {
        final String resDir = mPackageInfo.getResDir();
        final String[] splitResDirs = mPackageInfo.getSplitResDirs();
        final String[] legacyOverlayDirs = mPackageInfo.getOverlayDirs();
        final String[] overlayPaths = mPackageInfo.getOverlayPaths();
        final String[] libDirs = mPackageInfo.getApplicationInfo().sharedLibraryFiles;
        final int displayId = getDisplayId();
    /**
     * Creates the {@link Resources} to associate with the {@link WindowContext}'s token.
     *
     * When there's a {@link Configuration} update, this Resources instance will be updated to match
     * the new configuration.
     *
     * @see WindowTokenClient
     * @see #getWindowContextToken()
     */
    private static Resources createWindowContextResources(@NonNull ContextImpl windowContextBase) {
        final LoadedApk packageInfo = windowContextBase.mPackageInfo;
        final ClassLoader classLoader = windowContextBase.mClassLoader;
        final IBinder token = windowContextBase.getWindowContextToken();

        final String resDir = packageInfo.getResDir();
        final String[] splitResDirs = packageInfo.getSplitResDirs();
        final String[] legacyOverlayDirs = packageInfo.getOverlayDirs();
        final String[] overlayPaths = packageInfo.getOverlayPaths();
        final String[] libDirs = packageInfo.getApplicationInfo().sharedLibraryFiles;
        final int displayId = windowContextBase.getDisplayId();
        final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
                ? mPackageInfo.getCompatibilityInfo()
                ? packageInfo.getCompatibilityInfo()
                : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
        final List<ResourcesLoader> loaders = mResources.getLoaders();
        final List<ResourcesLoader> loaders = windowContextBase.mResources.getLoaders();

        return mResourcesManager.createBaseTokenResources(mToken, resDir, splitResDirs,
                legacyOverlayDirs, overlayPaths, libDirs, displayId, null /* overrideConfig */,
                compatInfo, mClassLoader, loaders);
        return windowContextBase.mResourcesManager.createBaseTokenResources(token, resDir,
                splitResDirs, legacyOverlayDirs, overlayPaths, libDirs, displayId,
                null /* overrideConfig */, compatInfo, classLoader, loaders);
    }

    @NonNull
@@ -3114,6 +3183,14 @@ class ContextImpl extends Context {
        return result;
    }

    @Override
    public void destroy() {
        // The final clean-up is to release BroadcastReceiver registrations. It is called in
        // ActivityThread for Activity and Service. For the context, such as WindowContext,
        // without lifecycle concept, it should be called once the context is released.
        scheduleFinalCleanup(getClass().getName(), getOuterContext().getClass().getSimpleName());
    }

    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
+2 −3
Original line number Diff line number Diff line
@@ -39,13 +39,13 @@ import android.os.IBinder;
import android.os.Process;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.window.WindowContext;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -61,7 +61,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.WeakHashMap;
@@ -168,7 +167,7 @@ public class ResourcesManager {

    /**
     * Class containing the base configuration override and set of resources associated with an
     * Activity or {@link WindowContext}.
     * {@link Activity} or a {@link WindowContext}.
     */
    private static class ActivityResources {
        /**
+12 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ import android.view.WindowManager.LayoutParams.WindowType;
import android.view.autofill.AutofillManager.AutofillClient;
import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.view.textclassifier.TextClassificationManager;
import android.window.WindowContext;

import com.android.internal.compat.IPlatformCompat;
import com.android.internal.compat.IPlatformCompatNative;
@@ -6793,4 +6794,15 @@ public abstract class Context {
    public boolean isUiContext() {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Called when a {@link Context} is going to be released.
     * This method can be overridden to perform the final cleanups, such as release
     * {@link BroadcastReceiver} registrations.
     *
     * @see WindowContext#destroy()
     *
     * @hide
     */
    public void destroy() { }
}
+3 −3
Original line number Diff line number Diff line
@@ -777,11 +777,11 @@ interface IWindowManager
    VerifiedDisplayHash verifyDisplayHash(in DisplayHash displayHash);

    /**
     * Registers a listener for a {@link android.app.WindowContext} to handle configuration changes
     * from the server side.
     * Registers a listener for a {@link android.window.WindowContext} to handle configuration
     * changes from the server side.
     * <p>
     * Note that this API should be invoked after calling
     * {@link android.app.WindowTokenClient#attachContext(WindowContext)}
     * {@link android.window.WindowTokenClient#attachContext(Context)}
     * </p>
     *
     * @param clientToken the window context's token
Loading