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

Commit 6801b363 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8084085 from 785ee1a5 to sc-v2-release

Change-Id: If9982c1586e37bf5863c0777d2cbba45a0437b43
parents 186b81dc 785ee1a5
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -311,6 +311,14 @@ class ContextImpl extends Context {
    @ContextType
    private int mContextType;

    /**
     * {@code true} to indicate that the {@link Context} owns the {@link #getWindowContextToken()}
     * and is responsible for detaching the token when the Context is released.
     *
     * @see #finalize()
     */
    private boolean mOwnsToken = false;

    @GuardedBy("mSync")
    private File mDatabasesDir;
    @GuardedBy("mSync")
@@ -2979,7 +2987,7 @@ class ContextImpl extends Context {
        // WindowContainer. We should detach from WindowContainer when the Context is finalized
        // if this Context is not a WindowContext. WindowContext finalization is handled in
        // WindowContext class.
        if (mToken instanceof WindowTokenClient && mContextType != CONTEXT_TYPE_WINDOW_CONTEXT) {
        if (mToken instanceof WindowTokenClient && mOwnsToken) {
            ((WindowTokenClient) mToken).detachFromWindowContainerIfNeeded();
        }
        super.finalize();
@@ -3010,6 +3018,7 @@ class ContextImpl extends Context {
        token.attachContext(context);
        token.attachToDisplayContent(displayId);
        context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
        context.mOwnsToken = true;

        return context;
    }
+22 −12
Original line number Diff line number Diff line
@@ -19,9 +19,10 @@ import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
import static android.window.ConfigurationHelper.isDifferentDisplay;
import static android.window.ConfigurationHelper.shouldUpdateResources;

import android.annotation.BinderThread;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.app.IWindowToken;
import android.app.ResourcesManager;
import android.content.Context;
@@ -30,7 +31,9 @@ import android.inputmethodservice.AbstractInputMethodService;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.IWindowManager;
@@ -71,6 +74,8 @@ public class WindowTokenClient extends IWindowToken.Stub {

    private boolean mAttachToWindowContainer;

    private final Handler mHandler = new Handler(Looper.getMainLooper());

    /**
     * Attaches {@code context} to this {@link WindowTokenClient}. Each {@link WindowTokenClient}
     * can only attach one {@link Context}.
@@ -132,7 +137,8 @@ public class WindowTokenClient extends IWindowToken.Stub {
            if (configuration == null) {
                return false;
            }
            onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */);
            mHandler.post(() -> onConfigurationChanged(configuration, displayId,
                    false /* shouldReportConfigChange */));
            mAttachToWindowContainer = true;
            return true;
        } catch (RemoteException e) {
@@ -179,9 +185,11 @@ public class WindowTokenClient extends IWindowToken.Stub {
     * @param newConfig the updated {@link Configuration}
     * @param newDisplayId the updated {@link android.view.Display} ID
     */
    @BinderThread
    @Override
    public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
        onConfigurationChanged(newConfig, newDisplayId, true /* shouldReportConfigChange */);
        mHandler.post(() -> onConfigurationChanged(newConfig, newDisplayId,
                true /* shouldReportConfigChange */));
    }

    // TODO(b/192048581): rewrite this method based on WindowContext and WindowProviderService
@@ -192,6 +200,7 @@ public class WindowTokenClient extends IWindowToken.Stub {
     * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control
     * whether to dispatch configuration update or not.
     */
    @MainThread
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public void onConfigurationChanged(Configuration newConfig, int newDisplayId,
            boolean shouldReportConfigChange) {
@@ -217,16 +226,14 @@ public class WindowTokenClient extends IWindowToken.Stub {

            if (shouldReportConfigChange && context instanceof WindowContext) {
                final WindowContext windowContext = (WindowContext) context;
                ActivityThread.currentActivityThread().getHandler().post(
                        () -> windowContext.dispatchConfigurationChanged(newConfig));
                windowContext.dispatchConfigurationChanged(newConfig);
            }

            final int diff = mConfiguration.diffPublicOnly(newConfig);
            if (shouldReportConfigChange && diff != 0
                    && context instanceof WindowProviderService) {
                final WindowProviderService windowProviderService = (WindowProviderService) context;
                ActivityThread.currentActivityThread().getHandler().post(
                        () -> windowProviderService.onConfigurationChanged(newConfig));
                windowProviderService.onConfigurationChanged(newConfig);
            }
            freeTextLayoutCachesIfNeeded(diff);
            if (mShouldDumpConfigForIme) {
@@ -248,12 +255,15 @@ public class WindowTokenClient extends IWindowToken.Stub {
        }
    }

    @BinderThread
    @Override
    public void onWindowTokenRemoved() {
        mHandler.post(() -> {
            final Context context = mContextRef.get();
            if (context != null) {
                context.destroy();
                mContextRef.clear();
            }
        });
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -783,7 +783,7 @@ public class ZygoteInit {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011,3012",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
+20 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANI
import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -497,6 +498,23 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        return null;
    }

    private boolean shouldSendEventWhenTaskInvisible(@NonNull Task task,
            @NonNull PendingTaskFragmentEvent event) {
        final TaskFragmentOrganizerState state =
                mTaskFragmentOrganizerState.get(event.mTaskFragmentOrg.asBinder());
        final TaskFragmentInfo lastInfo = state.mLastSentTaskFragmentInfos.get(event.mTaskFragment);
        final TaskFragmentInfo info = event.mTaskFragment.getTaskFragmentInfo();
        // Send an info changed callback if this event is for the last activities to finish in a
        // Task so that the {@link TaskFragmentOrganizer} can delete this TaskFragment. Otherwise,
        // the Task may be removed before it becomes visible again to send this event because it no
        // longer has activities. As a result, the organizer will never get this info changed event
        // and will not delete the TaskFragment because the organizer thinks the TaskFragment still
        // has running activities.
        return event.mEventType == PendingTaskFragmentEvent.EVENT_INFO_CHANGED
                && task.topRunningActivity() == null && lastInfo != null
                && lastInfo.getRunningActivityCount() > 0 && info.getRunningActivityCount() == 0;
    }

    void dispatchPendingEvents() {
        if (mAtmService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()
                || mPendingTaskFragmentEvents.isEmpty()) {
@@ -510,7 +528,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
            final PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i);
            final Task task = event.mTaskFragment != null ? event.mTaskFragment.getTask() : null;
            if (task != null && (task.lastActiveTime <= event.mDeferTime
                    || !isTaskVisible(task, visibleTasks, invisibleTasks))) {
                    || !(isTaskVisible(task, visibleTasks, invisibleTasks)
                    || shouldSendEventWhenTaskInvisible(task, event)))) {
                // Defer sending events to the TaskFragment until the host task is active again.
                event.mDeferTime = task.lastActiveTime;
                continue;
+38 −0
Original line number Diff line number Diff line
@@ -21,14 +21,17 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.testing.Assert.assertThrows;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;

import android.content.Intent;
@@ -471,6 +474,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
                .setParentTask(task)
                .setOrganizer(mOrganizer)
                .setFragmentToken(mFragmentToken)
                .build();

        // Mock the task to invisible
@@ -485,4 +489,38 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
        // Verifies that event was not sent
        verify(mOrganizer, never()).onTaskFragmentInfoChanged(any());
    }

    /**
     * Tests that a task fragment info changed event is still sent if the task is invisible only
     * when the info changed event is because of the last activity in a task finishing.
     */
    @Test
    public void testLastPendingTaskFragmentInfoChangedEventOfInvisibleTaskSent() {
        // Create a TaskFragment with an activity, all within a parent task
        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
                .setOrganizer(mOrganizer)
                .setFragmentToken(mFragmentToken)
                .setCreateParentTask()
                .createActivityCount(1)
                .build();
        final Task parentTask = taskFragment.getTask();
        final ActivityRecord activity = taskFragment.getTopNonFinishingActivity();
        assertTrue(parentTask.shouldBeVisible(null));

        // Dispatch pending info changed event from creating the activity
        mController.registerOrganizer(mIOrganizer);
        taskFragment.mTaskFragmentAppearedSent = true;
        mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
        mController.dispatchPendingEvents();

        // Finish the activity and verify that the task is invisible
        activity.finishing = true;
        assertFalse(parentTask.shouldBeVisible(null));

        // Verify the info changed callback still occurred despite the task being invisible
        reset(mOrganizer);
        mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
        mController.dispatchPendingEvents();
        verify(mOrganizer).onTaskFragmentInfoChanged(any());
    }
}