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

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

Merge "Introduce WM#LayoutParams mWindowContextToken"

parents ebb01610 3c3b134e
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ClipData;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -2843,6 +2844,16 @@ public interface WindowManager extends ViewManager {
         */
        public IBinder token = null;

        /**
         * The token of {@link android.app.WindowContext}. It is usually a
         * {@link android.app.WindowTokenClient} and is used for updating
         * {@link android.content.res.Resources} from {@link Configuration} propagated from the
         * server side.
         *
         * @hide
         */
        public IBinder mWindowContextToken = null;

        /**
         * Name of the package owning this window.
         */
@@ -3552,6 +3563,7 @@ public interface WindowManager extends ViewManager {
            out.writeFloat(buttonBrightness);
            out.writeInt(rotationAnimation);
            out.writeStrongBinder(token);
            out.writeStrongBinder(mWindowContextToken);
            out.writeString(packageName);
            TextUtils.writeToParcel(mTitle, out, parcelableFlags);
            out.writeInt(screenOrientation);
@@ -3620,6 +3632,7 @@ public interface WindowManager extends ViewManager {
            buttonBrightness = in.readFloat();
            rotationAnimation = in.readInt();
            token = in.readStrongBinder();
            mWindowContextToken = in.readStrongBinder();
            packageName = in.readString();
            mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            screenOrientation = in.readInt();
@@ -3781,6 +3794,11 @@ public interface WindowManager extends ViewManager {
                // already have one.
                token = o.token;
            }
            if (mWindowContextToken == null) {
                // NOTE: token only copied if the recipient doesn't
                // already have one.
                mWindowContextToken = o.mWindowContextToken;
            }
            if (packageName == null) {
                // NOTE: packageName only copied if the recipient doesn't
                // already have one.
+35 −18
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.app.ResourcesManager;
import android.compat.annotation.UnsupportedAppUsage;
@@ -74,23 +75,42 @@ public final class WindowManagerImpl implements WindowManager {
    public final Context mContext;
    private final Window mParentWindow;

    /**
     * If {@link LayoutParams#token} is {@code null} and no parent window is specified, the value
     * of {@link LayoutParams#token} will be overridden to {@code mDefaultToken}.
     */
    private IBinder mDefaultToken;

    /**
     * This token will be set to {@link LayoutParams#mWindowContextToken} and used to receive
     * configuration changes from the server side.
     */
    @Nullable
    private final IBinder mWindowContextToken;

    public WindowManagerImpl(Context context) {
        this(context, null);
        this(context, null /* parentWindow */, null /* clientToken */);
    }

    private WindowManagerImpl(Context context, Window parentWindow) {
    private WindowManagerImpl(Context context, Window parentWindow,
            @Nullable IBinder windowContextToken) {
        mContext = context;
        mParentWindow = parentWindow;
        mWindowContextToken = windowContextToken;
    }

    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
        return new WindowManagerImpl(mContext, parentWindow);
        return new WindowManagerImpl(mContext, parentWindow, mWindowContextToken);
    }

    public WindowManagerImpl createPresentationWindowManager(Context displayContext) {
        return new WindowManagerImpl(displayContext, mParentWindow);
        return new WindowManagerImpl(displayContext, mParentWindow, mWindowContextToken);
    }

    /** Creates a {@link WindowManager} for a {@link android.app.WindowContext}. */
    public static WindowManager createWindowContextWindowManager(Context context) {
        final IBinder clientToken = context.getWindowContextToken();
        return new WindowManagerImpl(context, null /* parentWindow */, clientToken);
    }

    /**
@@ -105,30 +125,27 @@ public final class WindowManagerImpl implements WindowManager {

    @Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        applyTokens(params);
        mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
                mContext.getUserId());
    }

    @Override
    public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        applyTokens(params);
        mGlobal.updateViewLayout(view, params);
    }

    private void applyDefaultToken(@NonNull ViewGroup.LayoutParams params) {
        // Only use the default token if we don't have a parent window.
        if (mDefaultToken != null && mParentWindow == null) {
    private void applyTokens(@NonNull ViewGroup.LayoutParams params) {
        if (!(params instanceof WindowManager.LayoutParams)) {
            throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
        }

            // Only use the default token if we don't already have a token.
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
            if (wparams.token == null) {
        // Only use the default token if we don't have a parent window and a token.
        if (mDefaultToken != null && mParentWindow == null && wparams.token == null) {
            wparams.token = mDefaultToken;
        }
        }
        wparams.mWindowContextToken = mWindowContextToken;
    }

    @Override
+33 −11
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.app;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

@@ -28,7 +29,10 @@ import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
import android.view.IWindowManager;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerImpl;

import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -50,23 +54,41 @@ import org.junit.runner.RunWith;
@SmallTest
@Presubmit
public class WindowContextTest {
    private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
    private final WindowContext mWindowContext = createWindowContext();

    @Test
    public void testWindowContextRelease_doRemoveWindowToken() throws Throwable {
        final Context instContext = InstrumentationRegistry.getInstrumentation()
                .getTargetContext();
        final Display display = instContext.getSystemService(DisplayManager.class)
                .getDisplay(DEFAULT_DISPLAY);
        final Context context = instContext.createDisplayContext(display);
        final WindowContext windowContext = new WindowContext(context, TYPE_APPLICATION_OVERLAY,
                null /* options */);

        final IBinder token = windowContext.getWindowContextToken();

        final IBinder token = mWindowContext.getWindowContextToken();
        final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();

        assertTrue("Token must be registered to WMS", wms.isWindowToken(token));

        windowContext.release();
        mWindowContext.release();

        assertFalse("Token must be unregistered to WMS", wms.isWindowToken(token));
    }

    @Test
    public void testCreateWindowContextWindowManagerAttachClientToken() {
        final WindowManager windowContextWm = WindowManagerImpl
                .createWindowContextWindowManager(mWindowContext);
        final WindowManager.LayoutParams params =
                new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
        mInstrumentation.runOnMainSync(() -> {
            final View view = new View(mWindowContext);
            windowContextWm.addView(view, params);
        });

        assertEquals(mWindowContext.getWindowContextToken(), params.mWindowContextToken);
    }

    private WindowContext createWindowContext() {
        final Context instContext = mInstrumentation.getTargetContext();
        final Display display = instContext.getSystemService(DisplayManager.class)
                .getDisplay(DEFAULT_DISPLAY);
        final Context context = instContext.createDisplayContext(display);
        return new WindowContext(context, TYPE_APPLICATION_OVERLAY,
                null /* options */);
    }
}
+1 −2
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.view.View;
import android.view.ViewGroup;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -46,7 +45,7 @@ import java.util.Objects;
 *     {@link WindowManagerService#registerWindowContextListener(IBinder, int, int, Bundle)}
 *     automatically.</li>
 *   <li>When the {@link android.app.WindowContext} adds the first window to the screen via
 *     {@link android.view.WindowManager#addView(View, ViewGroup.LayoutParams)},
 *     {@link android.view.WindowManager#addView(View, android.view.ViewGroup.LayoutParams)},
 *     {@link WindowManagerService} then updates the {@link WindowContextListenerImpl} to listen
 *     to corresponding {@link WindowToken} via this controller.</li>
 *   <li>When the {@link android.app.WindowContext} is GCed, it unregisters the previously