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

Commit 718bc413 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Add focusability into the hierarchy and Container transaction"

parents 9edf72d0 226de137
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -74,6 +74,18 @@ public class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Sets whether a container or any of its children can be focusable. When {@code false}, no
     * child can be focused; however, when {@code true}, it is still possible for children to be
     * non-focusable due to WM policy.
     */
    public WindowContainerTransaction setFocusable(IWindowContainer container, boolean focusable) {
        Change chg = getOrCreateChange(container.asBinder());
        chg.mFocusable = focusable;
        chg.mChangeMask |= Change.CHANGE_FOCUSABLE;
        return this;
    }

    public Map<IBinder, Change> getChanges() {
        return mChanges;
    }
@@ -112,7 +124,11 @@ public class WindowContainerTransaction implements Parcelable {
     * @hide
     */
    public static class Change implements Parcelable {
        public static final int CHANGE_FOCUSABLE = 1;

        private final Configuration mConfiguration = new Configuration();
        private boolean mFocusable = true;
        private int mChangeMask = 0;
        private @ActivityInfo.Config int mConfigSetMask = 0;
        private @WindowConfiguration.WindowConfig int mWindowSetMask = 0;

@@ -123,6 +139,8 @@ public class WindowContainerTransaction implements Parcelable {

        protected Change(Parcel in) {
            mConfiguration.readFromParcel(in);
            mFocusable = in.readBoolean();
            mChangeMask = in.readInt();
            mConfigSetMask = in.readInt();
            mWindowSetMask = in.readInt();
            mSchedulePipCallback = (in.readInt() != 0);
@@ -136,6 +154,18 @@ public class WindowContainerTransaction implements Parcelable {
            return mConfiguration;
        }

        /** Gets the requested focusable value */
        public boolean getFocusable() {
            if ((mChangeMask & CHANGE_FOCUSABLE) == 0) {
                throw new RuntimeException("Focusable not set. check CHANGE_FOCUSABLE first");
            }
            return mFocusable;
        }

        public int getChangeMask() {
            return mChangeMask;
        }

        @ActivityInfo.Config
        public int getConfigSetMask() {
            return mConfigSetMask;
@@ -170,6 +200,9 @@ public class WindowContainerTransaction implements Parcelable {
            if (changesSss) {
                sb.append("ssw:" + mConfiguration.smallestScreenWidthDp + ",");
            }
            if ((mChangeMask & CHANGE_FOCUSABLE) != 0) {
                sb.append("focusable:" + mFocusable + ",");
            }
            sb.append("}");
            return sb.toString();
        }
@@ -177,6 +210,8 @@ public class WindowContainerTransaction implements Parcelable {
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            mConfiguration.writeToParcel(dest, flags);
            dest.writeBoolean(mFocusable);
            dest.writeInt(mChangeMask);
            dest.writeInt(mConfigSetMask);
            dest.writeInt(mWindowSetMask);

+4 −2
Original line number Diff line number Diff line
@@ -2137,8 +2137,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
    }

    @Override
    boolean isFocusable() {
        return mRootWindowContainer.isFocusable(this, isAlwaysFocusable());
        return super.isFocusable()
                && (getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable());
    }

    boolean isResizeable() {
@@ -2489,7 +2491,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            // We are finishing the top focused activity and its stack has nothing to be focused so
            // the next focusable stack should be focused.
            if (mayAdjustTop
                    && (stack.topRunningActivity() == null || !stack.isFocusable())) {
                    && (stack.topRunningActivity() == null || !stack.isTopActivityFocusable())) {
                if (shouldAdjustGlobalFocus) {
                    // Move the entire hierarchy to top with updating global top resumed activity
                    // and focused application if needed.
+10 −3
Original line number Diff line number Diff line
@@ -161,9 +161,9 @@ import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.ITaskOrganizer;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.ITaskOrganizer;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -1248,13 +1248,20 @@ class ActivityStack extends WindowContainer<WindowContainer> implements BoundsAn
        }
    }

    @Override
    boolean isFocusable() {
        return super.isFocusable() && !(inSplitScreenPrimaryWindowingMode()
                && mRootWindowContainer.mIsDockMinimized);
    }

    boolean isTopActivityFocusable() {
        final ActivityRecord r = topRunningActivity();
        return mRootWindowContainer.isFocusable(this, r != null && r.isFocusable());
        return r != null ? r.isFocusable()
                : (isFocusable() && getWindowConfiguration().canReceiveKeys());
    }

    boolean isFocusableAndVisible() {
        return isFocusable() && shouldBeVisible(null /* starting */);
        return isTopActivityFocusable() && shouldBeVisible(null /* starting */);
    }

    @Override
+2 −2
Original line number Diff line number Diff line
@@ -1569,7 +1569,7 @@ class ActivityStarter {
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
            if (!mTargetStack.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                // If the activity is not focusable, we can't resume it, but still would like to
@@ -1588,7 +1588,7 @@ class ActivityStarter {
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable()
                if (mTargetStack.isTopActivityFocusable()
                        && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityInner");
                }
+67 −21
Original line number Diff line number Diff line
@@ -248,7 +248,6 @@ import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -345,6 +344,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** This activity is being relaunched due to a free-resize operation. */
    public static final int RELAUNCH_REASON_FREE_RESIZE = 2;

    /** Flag indicating that an applied transaction may have effected lifecycle */
    private static final int TRANSACT_EFFECTS_CLIENT_CONFIG = 1;
    private static final int TRANSACT_EFFECTS_LIFECYCLE = 1 << 1;

    Context mContext;

    /**
@@ -3300,7 +3303,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
    }

    private void sanitizeAndApplyConfigChange(ConfigurationContainer container,
    private int sanitizeAndApplyChange(ConfigurationContainer container,
            WindowContainerTransaction.Change change) {
        if (!(container instanceof Task || container instanceof ActivityStack)) {
            throw new RuntimeException("Invalid token in task transaction");
@@ -3312,12 +3315,22 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        configMask &= ActivityInfo.CONFIG_WINDOW_CONFIGURATION
                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
        windowMask &= WindowConfiguration.WINDOW_CONFIG_BOUNDS;
        int effects = 0;
        if (configMask != 0) {
            Configuration c = new Configuration(container.getRequestedOverrideConfiguration());
            c.setTo(change.getConfiguration(), configMask, windowMask);
            container.onRequestedOverrideConfigurationChanged(c);
            // TODO(b/145675353): remove the following once we could apply new bounds to the
            // pinned stack together with its children.
            resizePinnedStackIfNeeded(container, configMask, windowMask, c);
            effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
        }
        if ((change.getChangeMask() & WindowContainerTransaction.Change.CHANGE_FOCUSABLE) != 0) {
            if (container.setFocusable(change.getFocusable())) {
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
        }
        return effects;
    }

    private void resizePinnedStackIfNeeded(ConfigurationContainer container, int configMask,
@@ -3334,9 +3347,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
    }

    private void applyWindowContainerChange(ConfigurationContainer cc,
    private int applyWindowContainerChange(ConfigurationContainer cc,
            WindowContainerTransaction.Change c) {
        sanitizeAndApplyConfigChange(cc, c);
        int effects = sanitizeAndApplyChange(cc, c);

        Rect enterPipBounds = c.getEnterPipBounds();
        if (enterPipBounds != null) {
@@ -3344,25 +3357,58 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mStackSupervisor.updatePictureInPictureMode(tr,
                    enterPipBounds, true);
        }
        return effects;
    }

    @Override
    public void applyContainerTransaction(WindowContainerTransaction t) {
        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "applyContainerTransaction()");
        long ident = Binder.clearCallingIdentity();
        try {
        if (t == null) {
            return;
        }
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                int effects = 0;
                deferWindowLayout();
                try {
                    ArraySet<WindowContainer> haveConfigChanges = new ArraySet<>();
                    Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries =
                            t.getChanges().entrySet().iterator();
                    while (entries.hasNext()) {
                        final Map.Entry<IBinder, WindowContainerTransaction.Change> entry =
                                entries.next();
                    final ConfigurationContainer cc = ConfigurationContainer.RemoteToken.fromBinder(
                        final ConfigurationContainer cc =
                                ConfigurationContainer.RemoteToken.fromBinder(
                                        entry.getKey()).getContainer();
                    applyWindowContainerChange(cc, entry.getValue());
                        int containerEffect = applyWindowContainerChange(cc, entry.getValue());
                        effects |= containerEffect;
                        // Lifecycle changes will trigger ensureConfig for everything.
                        if ((effects & TRANSACT_EFFECTS_LIFECYCLE) == 0
                                && (containerEffect & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
                            if (cc instanceof WindowContainer) {
                                haveConfigChanges.add((WindowContainer) cc);
                            }
                        }
                    }
                    if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
                        // Already calls ensureActivityConfig
                        mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
                    } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
                        final PooledConsumer f = PooledLambda.obtainConsumer(
                                ActivityRecord::ensureActivityConfiguration,
                                PooledLambda.__(ActivityRecord.class), 0,
                                false /* preserveWindow */);
                        try {
                            for (int i = haveConfigChanges.size() - 1; i >= 0; --i) {
                                haveConfigChanges.valueAt(i).forAllActivities(f);
                            }
                        } finally {
                            f.recycle();
                        }
                    }
                } finally {
                    continueWindowLayout();
                }
            }
        } finally {
Loading