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

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

Introduce #createWindowContext with display

Test: atest ContextIsUiContextTest ContextGetDisplayTest
Test: atest WindowContextPolicyTests
Bug: 174640742
Change-Id: I13bd07fa3a4e79fe44bce34157ee93622cbb431d
parent c1cd3d6f
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -10116,6 +10116,7 @@ package android.content {
    method public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
    method public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
    method public abstract android.content.Context createPackageContext(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.Context createPackageContext(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method @NonNull public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
    method @NonNull public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
    method @NonNull public android.content.Context createWindowContext(@NonNull android.view.Display, int, @Nullable android.os.Bundle);
    method public abstract String[] databaseList();
    method public abstract String[] databaseList();
    method public abstract boolean deleteDatabase(String);
    method public abstract boolean deleteDatabase(String);
    method public abstract boolean deleteFile(String);
    method public abstract boolean deleteFile(String);
+16 −2
Original line number Original line Diff line number Diff line
@@ -2470,8 +2470,9 @@ class ContextImpl extends Context {
        return context;
        return context;
    }
    }


    @NonNull
    @Override
    @Override
    public @NonNull WindowContext createWindowContext(int type, Bundle options) {
    public WindowContext createWindowContext(int type, @NonNull Bundle options) {
        if (getDisplay() == null) {
        if (getDisplay() == null) {
            throw new UnsupportedOperationException("WindowContext can only be created from "
            throw new UnsupportedOperationException("WindowContext can only be created from "
                    + "other visual contexts, such as Activity or one created with "
                    + "other visual contexts, such as Activity or one created with "
@@ -2480,13 +2481,26 @@ class ContextImpl extends Context {
        return new WindowContext(this, type, options);
        return new WindowContext(this, type, options);
    }
    }


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

    ContextImpl createBaseWindowContext(IBinder token, Display display) {
        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag,
        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag,
                mSplitName, token, mUser, mFlags, mClassLoader, null);
                mSplitName, token, mUser, mFlags, mClassLoader, null);
        // Window contexts receive configurations directly from the server and as such do not
        // Window contexts receive configurations directly from the server and as such do not
        // need to override their display in ResourcesManager.
        // need to override their display in ResourcesManager.
        context.mForceDisplayOverrideInResources = false;
        context.mForceDisplayOverrideInResources = false;
        context.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
        context.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
        if (display != null) {
            context.mDisplay = display;
        }
        return context;
        return context;
    }
    }


+19 −3
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.ContextWrapper;
import android.os.Bundle;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.view.Display;
import android.view.IWindowManager;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerImpl;
import android.view.WindowManagerImpl;
@@ -59,13 +60,27 @@ public class WindowContext extends ContextWrapper {
     * @hide
     * @hide
     */
     */
    public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
    public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
        this(base, null /* display */, type, options);
    }

    /**
     * Default constructor. Will generate a {@link WindowTokenClient} and attach this context to
     * the token.
     *
     * @param base Base {@link Context} for this new instance.
     * @param display the {@link Display} to override.
     * @param type Window type to be used with this context.
     * @hide
     */
    public WindowContext(@NonNull Context base, @Nullable Display display, int type,
            @Nullable Bundle options) {
        // Correct base context will be built once the token is resolved, so passing 'null' here.
        // Correct base context will be built once the token is resolved, so passing 'null' here.
        super(null /* base */);
        super(null /* base */);


        mWms = WindowManagerGlobal.getWindowManagerService();
        mWms = WindowManagerGlobal.getWindowManagerService();
        mToken = new WindowTokenClient();
        mToken = new WindowTokenClient();


        final ContextImpl contextImpl = createBaseWindowContext(base, mToken);
        final ContextImpl contextImpl = createBaseWindowContext(base, mToken, display);
        attachBaseContext(contextImpl);
        attachBaseContext(contextImpl);
        contextImpl.setOuterContext(this);
        contextImpl.setOuterContext(this);


@@ -93,9 +108,10 @@ public class WindowContext extends ContextWrapper {
        Reference.reachabilityFence(this);
        Reference.reachabilityFence(this);
    }
    }


    private static ContextImpl createBaseWindowContext(Context outer, IBinder token) {
    private static ContextImpl createBaseWindowContext(Context outer, IBinder token,
            Display display) {
        final ContextImpl contextImpl = ContextImpl.getImpl(outer);
        final ContextImpl contextImpl = ContextImpl.getImpl(outer);
        return contextImpl.createBaseWindowContext(token);
        return contextImpl.createBaseWindowContext(token, display);
    }
    }


    @Override
    @Override
+33 −7
Original line number Original line Diff line number Diff line
@@ -5968,22 +5968,22 @@ public abstract class Context {
     * Creating a window context is an expensive operation. Misuse of this API may lead to a huge
     * Creating a window context is an expensive operation. Misuse of this API may lead to a huge
     * performance drop. The best practice is to use the same window context when possible.
     * performance drop. The best practice is to use the same window context when possible.
     * An approach is to create one window context with specific window type and display and
     * An approach is to create one window context with specific window type and display and
     * use it everywhere it's needed..
     * use it everywhere it's needed.
     * </p>
     * </p>
     *
     *
     * @param type Window type in {@link WindowManager.LayoutParams}
     * @param type Window type in {@link WindowManager.LayoutParams}
     * @param options Bundle used to pass window-related options.
     * @param options A bundle used to pass window-related options
     * @return A {@link Context} that can be used to create windows.
     * @return A {@link Context} that can be used to create
     * @throws UnsupportedOperationException if this is called on a non-UI context, such as
     *         non-{@link android.app.Activity activity} windows.
     *         {@link android.app.Application Application} or {@link android.app.Service Service}.
     *
     *
     * @see #getSystemService(String)
     * @see #getSystemService(String)
     * @see #getSystemService(Class)
     * @see #getSystemService(Class)
     * @see #WINDOW_SERVICE
     * @see #WINDOW_SERVICE
     * @see #LAYOUT_INFLATER_SERVICE
     * @see #LAYOUT_INFLATER_SERVICE
     * @see #WALLPAPER_SERVICE
     * @see #WALLPAPER_SERVICE
     * @throws UnsupportedOperationException if this {@link Context} does not attach to a display or
     * @throws UnsupportedOperationException if this {@link Context} does not attach to a display,
     * the current number of window contexts without adding any view by
     * such as {@link android.app.Application Application} or {@link android.app.Service Service},
     * or the current number of window contexts without adding any view by
     * {@link WindowManager#addView} <b>exceeds five</b>.
     * {@link WindowManager#addView} <b>exceeds five</b>.
     */
     */
    @UiContext
    @UiContext
@@ -5992,6 +5992,32 @@ public abstract class Context {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }
    }


    /**
     * A special version of {@link #createWindowContext(int, Bundle)} which also takes
     * {@link Display}. The only difference between this API and
     * {@link #createWindowContext(int, Bundle)} is that this API can create window context from
     * any context even if the context which is not associated to a {@link Display} instance.
     *
     * @param display The {@link Display} to associate with
     * @param type Window type in {@link WindowManager.LayoutParams}
     * @param options A bundle used to pass window-related options.
     * @return A {@link Context} that can be used to create
     *         non-{@link android.app.Activity activity} windows.
     * @throws IllegalArgumentException if the {@link Display} is {@code null}.
     *
     * @see #getSystemService(String)
     * @see #getSystemService(Class)
     * @see #WINDOW_SERVICE
     * @see #LAYOUT_INFLATER_SERVICE
     * @see #WALLPAPER_SERVICE
     */
    @UiContext
    @NonNull
    public Context createWindowContext(@NonNull Display display, @WindowType int type,
            @Nullable Bundle options) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
    /**
     * Return a new Context object for the current Context but attribute to a different tag.
     * Return a new Context object for the current Context but attribute to a different tag.
     * In complex apps attribution tagging can be used to distinguish between separate logical
     * In complex apps attribution tagging can be used to distinguish between separate logical
+7 −0
Original line number Original line Diff line number Diff line
@@ -987,6 +987,13 @@ public class ContextWrapper extends Context {
        return mBase.createWindowContext(type, options);
        return mBase.createWindowContext(type, options);
    }
    }


    @Override
    @NonNull
    public Context createWindowContext(@NonNull Display display, @WindowType int type,
            @Nullable Bundle options) {
        return mBase.createWindowContext(display, type, options);
    }

    @Override
    @Override
    public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
    public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
        return mBase.createAttributionContext(attributionTag);
        return mBase.createAttributionContext(attributionTag);
Loading