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

Commit a87f032c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implement launch bounds logic in Android (2/3)"

parents dbc63bff b5cc09fe
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1408,5 +1408,13 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
         * @attr ref android.R.styleable#AndroidManifestLayout_minHeight
         */
        public final int minHeight;

        /**
         * Returns if this {@link WindowLayout} has specified bounds.
         * @hide
         */
        public boolean hasSpecifiedSize() {
            return width >= 0 || height >= 0 || widthFraction >= 0 || heightFraction >= 0;
        }
    }
}
+0 −65
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.am;

import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;

import com.android.server.am.LaunchParamsController.LaunchParams;
import com.android.server.am.LaunchParamsController.LaunchParamsModifier;

/**
 * An implementation of {@link LaunchParamsModifier}, which applies the launch bounds specified
 * inside {@link ActivityOptions#getLaunchBounds()}.
 */
public class ActivityLaunchParamsModifier implements LaunchParamsModifier {
    private final ActivityStackSupervisor mSupervisor;

    ActivityLaunchParamsModifier(ActivityStackSupervisor activityStackSupervisor) {
        mSupervisor = activityStackSupervisor;
    }

    @Override
    public int onCalculate(TaskRecord task, ActivityInfo.WindowLayout layout,
            ActivityRecord activity, ActivityRecord source, ActivityOptions options,
            LaunchParams currentParams, LaunchParams outParams) {
        // We only care about figuring out bounds for activities.
        if (activity == null) {
            return RESULT_SKIP;
        }

        // Activity must be resizeable in the specified task.
        if (!(mSupervisor.canUseActivityOptionsLaunchBounds(options)
                && (activity.isResizeable() || (task != null && task.isResizeable())))) {
            return RESULT_SKIP;
        }

        final Rect bounds = options.getLaunchBounds();

        // Bounds weren't valid.
        if (bounds == null || bounds.isEmpty()) {
            return RESULT_SKIP;
        }

        outParams.mBounds.set(bounds);

        // When this is the most explicit position specification so we should not allow further
        // modification of the position.
        return RESULT_DONE;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    }

    @Override
    protected ConfigurationContainer getChildAt(int index) {
    protected TaskRecord getChildAt(int index) {
        return mTaskHistory.get(index);
    }

+25 −40
Original line number Diff line number Diff line
@@ -1606,13 +1606,18 @@ class ActivityStarter {
        mVoiceSession = voiceSession;
        mVoiceInteractor = voiceInteractor;

        mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);

        mLaunchParams.reset();

        mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
                options, mLaunchParams);

        if (mLaunchParams.hasPreferredDisplay()) {
            mPreferredDisplayId = mLaunchParams.mPreferredDisplayId;
        } else {
            mPreferredDisplayId = DEFAULT_DISPLAY;
        }
        ensureValidPreferredDisplayId(r);

        mLaunchMode = r.launchMode;

        mLaunchFlags = adjustLaunchFlagsToDocumentMode(
@@ -1704,6 +1709,24 @@ class ActivityStarter {
        mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
    }

    /**
     * Ensure preferred display ID matches the starting activity.
     */
    private void ensureValidPreferredDisplayId(ActivityRecord startingActivity) {
        // Check if the Activity is a VR activity. If so, the activity should be launched in
        // main display.
        if (startingActivity != null && startingActivity.requestedVrComponent != null) {
            mPreferredDisplayId = DEFAULT_DISPLAY;
        }

        // Get the virtual display ID from ActivityStackManagerService. If that's set we should
        // always use that.
        final int displayId = mService.mVr2dDisplayId;
        if (displayId != INVALID_DISPLAY) {
            mPreferredDisplayId = displayId;
        }
    }

    private void sendNewTaskResultRequestIfNeeded() {
        final ActivityStack sourceStack = mStartActivity.resultTo != null
                ? mStartActivity.resultTo.getStack() : null;
@@ -1882,44 +1905,6 @@ class ActivityStarter {
        return intentActivity;
    }

    /**
     * Returns the ID of the display to use for a new activity. If the device is in VR mode,
     * then return the Vr mode's virtual display ID. If not,  if the activity was started with
     * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
     * set, use that to launch the activity.
     */
    private int getPreferedDisplayId(
            ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
        // Check if the Activity is a VR activity. If so, the activity should be launched in
        // main display.
        if (startingActivity != null && startingActivity.requestedVrComponent != null) {
            return DEFAULT_DISPLAY;
        }

        // Get the virtual display id from ActivityManagerService.
        int displayId = mService.mVr2dDisplayId;
        if (displayId != INVALID_DISPLAY) {
            if (DEBUG_STACK) {
                Slog.d(TAG, "getSourceDisplayId :" + displayId);
            }
            return displayId;
        }

        // If the caller requested a display, prefer that display.
        final int launchDisplayId =
                (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
        if (launchDisplayId != INVALID_DISPLAY) {
            return launchDisplayId;
        }

        displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
        // If the activity has a displayId set explicitly, launch it on the same displayId.
        if (displayId != INVALID_DISPLAY) {
            return displayId;
        }
        return DEFAULT_DISPLAY;
    }

    /**
     * Figure out which task and activity to bring to front when we have found an existing matching
     * activity record in history. May also clear the task if needed.
+38 −28
Original line number Diff line number Diff line
@@ -16,6 +16,13 @@

package com.android.server.am;

import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;

import android.annotation.IntDef;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo.WindowLayout;
@@ -26,13 +33,6 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;

/**
 * {@link LaunchParamsController} calculates the {@link LaunchParams} by coordinating between
 * registered {@link LaunchParamsModifier}s.
@@ -58,11 +58,7 @@ class LaunchParamsController {
     */
    void registerDefaultModifiers(ActivityStackSupervisor supervisor) {
        // {@link TaskLaunchParamsModifier} handles window layout preferences.
        registerModifier(new TaskLaunchParamsModifier());

        // {@link ActivityLaunchParamsModifier} is the most specific modifier and thus should be
        // registered last (applied first) out of the defaults.
        registerModifier(new ActivityLaunchParamsModifier(supervisor));
        registerModifier(new TaskLaunchParamsModifier(supervisor));
    }

    /**
@@ -226,27 +222,41 @@ class LaunchParamsController {
        @IntDef({RESULT_SKIP, RESULT_DONE, RESULT_CONTINUE})
        @interface Result {}

        // Returned when the modifier does not want to influence the bounds calculation
        /** Returned when the modifier does not want to influence the bounds calculation */
        int RESULT_SKIP = 0;
        // Returned when the modifier has changed the bounds and would like its results to be the
        // final bounds applied.
        /**
         * Returned when the modifier has changed the bounds and would like its results to be the
         * final bounds applied.
         */
        int RESULT_DONE = 1;
        // Returned when the modifier has changed the bounds but is okay with other modifiers
        // influencing the bounds.
        /**
         * Returned when the modifier has changed the bounds but is okay with other modifiers
         * influencing the bounds.
         */
        int RESULT_CONTINUE = 2;

        /**
         * Called when asked to calculate {@link LaunchParams}.
         * @param task            The {@link TaskRecord} currently being positioned.
         * @param layout          The specified {@link WindowLayout}.
         * @param activity        The {@link ActivityRecord} currently being positioned.
         * @param source          The {@link ActivityRecord} activity was started from.
         * @param options         The {@link ActivityOptions} specified for the activity.
         * @param currentParams   The current {@link LaunchParams}. This can differ from the initial
         *                        params as it represents the modified params up to this point.
         * @param outParams       The resulting {@link LaunchParams} after all calculations.
         * @return                A {@link Result} representing the result of the
         *                        {@link LaunchParams} calculation.
         * Returns the launch params that the provided activity launch params should be overridden
         * to. {@link LaunchParamsModifier} can use this for various purposes, including: 1)
         * Providing default bounds if the launch bounds have not been provided. 2) Repositioning
         * the task so it doesn't get placed over an existing task. 3) Resizing the task so that its
         * dimensions match the activity's requested orientation.
         *
         * @param task          Can be: 1) the target task in which the source activity wants to
         *                      launch the target activity; 2) a newly created task that Android
         *                      gives a chance to override its launching bounds; 3) {@code null} if
         *                      this is called to override an activity's launching bounds.
         * @param layout        Desired layout when activity is first launched.
         * @param activity      Activity that is being started. This can be {@code null} on
         *                      re-parenting an activity to a new task (e.g. for
         *                      Picture-In-Picture). Tasks being created because an activity was
         *                      launched should have this be non-null.
         * @param source        the Activity that launched a new task. Could be {@code null}.
         * @param options       {@link ActivityOptions} used to start the activity with.
         * @param currentParams launching params after the process of last {@link
         *                      LaunchParamsModifier}.
         * @param outParams     the result params to be set.
         * @return see {@link LaunchParamsModifier.Result}
         */
        @Result
        int onCalculate(TaskRecord task, WindowLayout layout, ActivityRecord activity,
Loading