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

Commit e8e22d79 authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge "Support different multi-window compatibility modes"

parents afa51a0e d26176f3
Loading
Loading
Loading
Loading
+49 −14
Original line number Diff line number Diff line
@@ -155,6 +155,35 @@ public class ActivityInfo extends ComponentInfo
     */
    public String targetActivity;

    /**
     * Activity can not be resized and always occupies the fullscreen area with all windows fully
     * visible.
     * @hide
     */
    public static final int RESIZE_MODE_UNRESIZEABLE = 0;
    /**
     * Activity can not be resized and always occupies the fullscreen area with all windows cropped
     * to either the task or stack bounds.
     * @hide
     */
    public static final int RESIZE_MODE_CROP_WINDOWS = 1;
    /**
     * Activity is resizeable.
     * @hide
     */
    public static final int RESIZE_MODE_RESIZEABLE = 2;
    /**
     * Activity is resizeable and supported picture-in-picture mode.
     * @hide
     */
    public static final int RESIZE_MODE_RESIZEABLE_AND_PIPABLE = 3;
    /**
     * Value indicating if the resizing mode the activity supports.
     * See {@link android.R.attr#resizeableActivity}.
     * @hide
     */
    public int resizeMode;

    /**
     * Bit in {@link #flags} indicating whether this activity is able to
     * run in multiple processes.  If
@@ -282,20 +311,6 @@ public class ActivityInfo extends ComponentInfo
     */
    public static final int FLAG_ENABLE_VR_MODE = 0x8000;

    /**
     * Bit in {@link #flags} indicating if the activity is resizeable to any dimension.
     * See {@link android.R.attr#resizeableActivity}.
     * @hide
     */
    public static final int FLAG_RESIZEABLE = 0x10000;

    /**
     * Bit in {@link #flags} indicating if the activity is supports picture-in-picture form of
     * multi-window mode. See {@link android.R.attr#supportsPictureInPicture}.
     * @hide
     */
    public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x20000;

    /**
     * Bit in {@link #flags} indicating if the activity is always focusable regardless of if it is
     * in a task/stack whose activities are normally not focusable.
@@ -746,6 +761,7 @@ public class ActivityInfo extends ComponentInfo
        maxRecents = orig.maxRecents;
        lockTaskLaunchMode = orig.lockTaskLaunchMode;
        layout = orig.layout;
        resizeMode = orig.resizeMode;
    }

    /**
@@ -768,6 +784,22 @@ public class ActivityInfo extends ComponentInfo
        }
    }

    /** @hide */
    public static final String resizeModeToString(int mode) {
        switch (mode) {
            case RESIZE_MODE_UNRESIZEABLE:
                return "RESIZE_MODE_UNRESIZEABLE";
            case RESIZE_MODE_CROP_WINDOWS:
                return "RESIZE_MODE_CROP_WINDOWS";
            case RESIZE_MODE_RESIZEABLE:
                return "RESIZE_MODE_RESIZEABLE";
            case RESIZE_MODE_RESIZEABLE_AND_PIPABLE:
                return "RESIZE_MODE_RESIZEABLE_AND_PIPABLE";
            default:
                return "unknown=" + mode;
        }
    }

    public void dump(Printer pw, String prefix) {
        dump(pw, prefix, DUMP_FLAG_ALL);
    }
@@ -806,6 +838,7 @@ public class ActivityInfo extends ComponentInfo
                    + layout.widthFraction + ", " + layout.height + "|"
                    + layout.heightFraction + ", " + layout.gravity);
        }
        pw.println(prefix + "resizeMode=" + resizeModeToString(resizeMode));
        super.dumpBack(pw, prefix, flags);
    }

@@ -847,6 +880,7 @@ public class ActivityInfo extends ComponentInfo
        } else {
            dest.writeInt(0);
        }
        dest.writeInt(resizeMode);
    }

    public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -879,6 +913,7 @@ public class ActivityInfo extends ComponentInfo
        if (source.readInt() == 1) {
            layout = new Layout(source);
        }
        resizeMode = source.readInt();
    }

    public static final class Layout {
+43 −30
Original line number Diff line number Diff line
@@ -16,15 +16,12 @@

package android.content.pm;

import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.ActivityManager;
import android.content.ComponentName;
@@ -55,15 +52,6 @@ import android.util.apk.ApkSignatureSchemeV2Verifier;
import android.util.jar.StrictJarFile;
import android.view.Gravity;

import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;

import libcore.io.IoUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -87,6 +75,25 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.ZipEntry;

import libcore.io.IoUtils;

import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;

/**
 * Parser for package files (APKs) on disk. This supports apps packaged either
 * as a single "monolithic" APK, or apps packaged as a "cluster" of multiple
@@ -3219,24 +3226,29 @@ public class PackageParser {
                a.info.flags |= ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
            }

            if (sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity,
                    owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N)) {
                a.info.flags |= ActivityInfo.FLAG_RESIZEABLE;
            a.info.screenOrientation = sa.getInt(
                    R.styleable.AndroidManifestActivity_screenOrientation,
                    SCREEN_ORIENTATION_UNSPECIFIED);

            a.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
            if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
                if (sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity, true)) {
                    if (sa.getBoolean(R.styleable.AndroidManifestActivity_supportsPictureInPicture,
                            false)) {
                    a.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
                        a.info.resizeMode = RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
                    } else {
                        a.info.resizeMode = RESIZE_MODE_RESIZEABLE;
                    }
                }
            } else if (a.info.screenOrientation == SCREEN_ORIENTATION_UNSPECIFIED
                    && (a.info.flags & FLAG_IMMERSIVE) == 0) {
                a.info.resizeMode = RESIZE_MODE_CROP_WINDOWS;
            }

            if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysFocusable, false)) {
                a.info.flags |= ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
                a.info.flags |= FLAG_ALWAYS_FOCUSABLE;
            }

            a.info.screenOrientation = sa.getInt(
                    R.styleable.AndroidManifestActivity_screenOrientation,
                    ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

            a.info.lockTaskLaunchMode =
                    sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);

@@ -3478,6 +3490,7 @@ public class PackageParser {
        info.parentActivityName = target.info.parentActivityName;
        info.maxRecents = target.info.maxRecents;
        info.layout = target.info.layout;
        info.resizeMode = target.info.resizeMode;

        Activity a = new Activity(mParseActivityAliasArgs, info);
        if (outError[0] != null) {
+13 −4
Original line number Diff line number Diff line
@@ -19,8 +19,9 @@ package com.android.server.am;
import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_RESIZEABLE;
import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
@@ -355,6 +356,9 @@ final class ActivityRecord {
        if (connections != null) {
            pw.print(prefix); pw.print("connections="); pw.println(connections);
        }
        if (info != null) {
            pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
        }
    }

    public boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
@@ -754,11 +758,16 @@ final class ActivityRecord {
    }

    boolean isResizeable() {
        return (info.flags & FLAG_RESIZEABLE) != 0;
        return !isHomeActivity() && (info.resizeMode == RESIZE_MODE_RESIZEABLE
                || info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE);
    }

    boolean supportsPictureInPicture() {
        return (info.flags & FLAG_SUPPORTS_PICTURE_IN_PICTURE) != 0;
        return !isHomeActivity() && info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
    }

    boolean cropAppWindows() {
        return !isHomeActivity() && info.resizeMode == RESIZE_MODE_CROP_WINDOWS;
    }

    boolean isAlwaysFocusable() {
+6 −9
Original line number Diff line number Diff line
@@ -1410,14 +1410,11 @@ final class ActivityStack {
        }

        if (mStackId == DOCKED_STACK_ID) {
            // Docked stack is always visible, except in the case where the home activity
            // is the top running activity in the focused home stack.
            if (focusedStackId != HOME_STACK_ID) {
                return STACK_VISIBLE;
            }
            ActivityRecord topHomeActivity = focusedStack.topRunningActivityLocked();
            return topHomeActivity == null || !topHomeActivity.isHomeActivity() ?
                    STACK_VISIBLE : STACK_INVISIBLE;
            // Docked stack is always visible, except in the case where the top running activity in
            // the focus stack doesn't support any form of resizing.
            final ActivityRecord r = focusedStack.topRunningActivityLocked();
            return r == null || r.isResizeable() || r.cropAppWindows()
                    ? STACK_VISIBLE : STACK_INVISIBLE;
        }

        // Find the first stack below focused stack that actually got something visible.
@@ -4819,7 +4816,7 @@ final class ActivityStack {
                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,
                task.voiceSession != null, r.mLaunchTaskBehind, bounds, task.mOverrideConfig,
                !r.isHomeActivity(), r.isAlwaysFocusable());
                r.cropAppWindows() | r.isResizeable(), r.isAlwaysFocusable());
        mWindowManager.setTaskResizeable(task.taskId, task.mResizeable);
        r.taskConfigOverride = task.mOverrideConfig;
    }
+5 −2
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
import static android.content.pm.ActivityInfo.FLAG_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
@@ -447,7 +448,9 @@ final class TaskRecord {
        } else {
            autoRemoveRecents = false;
        }
        mResizeable = (info.flags & FLAG_RESIZEABLE) != 0 || mService.mForceResizableActivities;
        mResizeable = info.resizeMode == RESIZE_MODE_RESIZEABLE
                || info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE
                || mService.mForceResizableActivities;
        mLockTaskMode = info.lockTaskLaunchMode;
        mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
        setLockTaskAuth();