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

Commit 1603ed1e authored by Charles Chen's avatar Charles Chen
Browse files

Fix the condition to enable registerCleaner

It should only be enabled when both track_system_ui_context_before_wms
and clean_up_window_context_with_cleaner are enabled.

Test: atest WindowContextTest ContextTest
Flag: com.android.window.flags.clean_up_window_context_with_cleaner
Bug: 339727951
Change-Id: Ib60ef5197237854266b138d15bfeb87c7128a28c
parent 1eec3dda
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -3431,9 +3431,7 @@ class ContextImpl extends Context {
        // if this Context is not a WindowContext. WindowContext finalization is handled in
        // WindowContext class.
        try {
            if (!(com.android.window.flags.Flags.cleanUpWindowContextWithCleaner()
                    || com.android.window.flags.Flags.trackSystemUiContextBeforeWms())
                    && mToken instanceof WindowTokenClient && mOwnsToken) {
            if (!isCleanerEnabled() && mToken instanceof WindowTokenClient && mOwnsToken) {
                WindowTokenClientController.getInstance()
                        .detachIfNeeded((WindowTokenClient) mToken);
            }
@@ -3442,6 +3440,15 @@ class ContextImpl extends Context {
        }
    }

    /**
     * Returns {@code true} if {@link WindowContext#registerCleaner} is enabled.
     */
    private static boolean isCleanerEnabled() {
        return com.android.window.flags.Flags.cleanUpWindowContextWithCleaner()
                // Cleaner only works on SystemUiContext or WindowContext.
                && com.android.window.flags.Flags.trackSystemUiContextBeforeWms();
    }

    @UnsupportedAppUsage
    static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
@@ -3482,8 +3489,7 @@ class ContextImpl extends Context {
        WindowTokenClientController.getInstance().attachToDisplayContent(token, displayId);
        context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
        context.mOwnsToken = true;
        if (!com.android.window.flags.Flags.trackSystemUiContextBeforeWms()) {
            // #registerCleaner only support SystemUiContext or WindowContext.
        if (isCleanerEnabled()) {
            registerCleaner(systemUiContext);
        }
        return systemUiContext;
+33 −0
Original line number Diff line number Diff line
@@ -29,6 +29,13 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.app.ActivityThread;
import android.content.res.Configuration;
@@ -46,18 +53,22 @@ import android.platform.test.flag.junit.SetFlagsRule;
import android.platform.test.ravenwood.RavenwoodRule;
import android.view.Display;
import android.window.WindowTokenClient;
import android.window.WindowTokenClientController;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.internal.util.GcUtils;
import com.android.window.flags.Flags;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.ref.WeakReference;

/**
 *  Build/Install/Run:
 *   atest FrameworksCoreTests:ContextTest
@@ -331,4 +342,26 @@ public class ContextTest {
        assertWithMessage("ComponentCallbacks should delegate to SystemUiContext "
                + "if the flag is enabled.").that(callbacks.mConfiguration).isEqualTo(config);
    }

    @Test
    public void testSystemUiContextCleanUp() {
        final WindowTokenClientController origController =
                WindowTokenClientController.getInstance();
        final WindowTokenClientController mockController = mock(WindowTokenClientController.class);
        doReturn(true).when(mockController).attachToDisplayContent(any(), anyInt());
        doNothing().when(mockController).detachIfNeeded(any());
        WindowTokenClientController.overrideForTesting(mockController);

        WeakReference<Context> windowContextRef = new WeakReference<>(
                ActivityThread.currentActivityThread()
                        .createSystemUiContextForTesting(DEFAULT_DISPLAY));
        final WindowTokenClient token =
                (WindowTokenClient) windowContextRef.get().getWindowContextToken();

        GcUtils.runGcAndFinalizersSync();

        verify(mockController).detachIfNeeded(eq(token));

        WindowTokenClientController.overrideForTesting(origController);
    }
}
+12 −10
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -82,6 +84,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.ref.WeakReference;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@@ -527,20 +530,19 @@ public class WindowContextTest {

    @Test
    public void testWindowContextCleanup() {
        final WindowContext windowContext = createWindowContext();
        final WindowTokenClientController mockController = mock(WindowTokenClientController.class);
        doReturn(true).when(mockController).attachToDisplayArea(
                any(), anyInt(), anyInt(), any());
        doNothing().when(mockController).detachIfNeeded(any());
        WindowTokenClientController.overrideForTesting(mockController);

        windowContext.getSystemService(WindowManager.class).getCurrentWindowMetrics();
        WeakReference<WindowContext> windowContextRef = new WeakReference<>(createWindowContext());
        final WindowTokenClient token =
                (WindowTokenClient) windowContextRef.get().getWindowContextToken();

        GcUtils.runGcAndFinalizersSync();

        PollingCheck.waitFor(() -> {
            try {
                return !mWms.isWindowToken(windowContext.getWindowContextToken());
            } catch (RemoteException e) {
                fail("Fail due to " + e);
            }
            return false;
        });
        verify(mockController).detachIfNeeded(eq(token));
    }

    private static class ConfigurationListener implements ComponentCallbacks {