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

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

Merge "Expose methods to invoke split screen."

parents 9b569684 42ce900d
Loading
Loading
Loading
Loading
+25 −18
Original line number Diff line number Diff line
@@ -319,30 +319,37 @@ public class ActivityManagerWrapper {
        mBackgroundExecutor.submit(new Runnable() {
            @Override
            public void run() {
                boolean result = false;
                try {
                    ActivityManager.getService().startActivityFromRecents(taskKey.id,
                            finalOptions == null ? null : finalOptions.toBundle());
                    result = startActivityFromRecents(taskKey.id, finalOptions);
                } catch (Exception e) {
                    // Fall through
                }
                final boolean finalResult = result;
                if (resultCallback != null) {
                    resultCallbackHandler.post(new Runnable() {
                        @Override
                        public void run() {
                                resultCallback.accept(true);
                            resultCallback.accept(finalResult);
                        }
                    });
                }
                } catch (Exception e) {
                    if (resultCallback != null) {
                        resultCallbackHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                resultCallback.accept(false);
            }
        });
    }

    /**
     * Starts a task from Recents synchronously.
     */
    public boolean startActivityFromRecents(int taskId, ActivityOptions options) {
        try {
            Bundle optsBundle = options == null ? null : options.toBundle();
            ActivityManager.getService().startActivityFromRecents(taskId, optsBundle);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
        });
    }

    /**
     * Registers a task stack listener with the system.
+41 −0
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.systemui.shared.system;

import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;

import android.app.ActivityOptions;

/**
 * Wrapper around internal ActivityOptions creation.
 */
public abstract class ActivityOptionsCompat {

    /**
     * @return ActivityOptions for starting a task in split screen.
     */
    public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft) {
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        options.setSplitScreenCreateMode(dockTopLeft
                ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
                : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
        return options;
    }
}
+25 −2
Original line number Diff line number Diff line
@@ -19,8 +19,15 @@ package com.android.systemui.shared.system;
import static android.view.Display.DEFAULT_DISPLAY;

import android.graphics.Rect;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.view.WindowManagerGlobal;

import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
import com.android.systemui.shared.recents.view.RecentsTransition;

public class WindowManagerWrapper {

    private static final String TAG = "WindowManagerWrapper";
@@ -38,8 +45,24 @@ public class WindowManagerWrapper {
        try {
            WindowManagerGlobal.getWindowManagerService().getStableInsets(DEFAULT_DISPLAY,
                    outStableInsets);
        } catch (Exception e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to get stable insets", e);
        }
    }

    /**
     * Overrides a pending app transition.
     */
    public void overridePendingAppTransitionMultiThumbFuture(
            AppTransitionAnimationSpecsFuture animationSpecFuture,
            Runnable animStartedCallback, Handler animStartedCallbackHandler, boolean scaleUp) {
        try {
            WindowManagerGlobal.getWindowManagerService()
                    .overridePendingAppTransitionMultiThumbFuture(animationSpecFuture.getFuture(),
                            RecentsTransition.wrapStartedListener(animStartedCallbackHandler,
                                    animStartedCallback), scaleUp);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to override pending app transition (multi-thumbnail future): ", e);
        }
    }
}
+0 −35
Original line number Diff line number Diff line
@@ -21,12 +21,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityOptions;
@@ -49,9 +47,6 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -63,7 +58,6 @@ import android.service.dreams.IDreamManager;
import android.util.Log;
import android.util.MutableBoolean;
import android.view.Display;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IDockedStackListener;
import android.view.IWindowManager;
import android.view.WindowManager;
@@ -78,12 +72,9 @@ import com.android.systemui.R;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.policy.UserInfoController;

import java.util.List;
import java.util.function.Consumer;

/**
 * Acts as a shim around the real system services that we need to access data from, and provides
@@ -268,22 +259,6 @@ public class SystemServicesProxy {
        return mIsSafeMode;
    }

    /** Docks a task to the side of the screen and starts it. */
    public boolean startTaskInDockedMode(int taskId, int createMode) {
        if (mIam == null) return false;

        try {
            final ActivityOptions options = ActivityOptions.makeBasic();
            options.setSplitScreenCreateMode(createMode);
            options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
            mIam.startActivityFromRecents(taskId, options.toBundle());
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Failed to dock task: " + taskId + " with createMode: " + createMode, e);
        }
        return false;
    }

    /** Moves an already resumed task to the side of the screen to initiate split screen. */
    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
            Rect initialBounds) {
@@ -540,16 +515,6 @@ public class SystemServicesProxy {
        }
    }

    public void overridePendingAppTransitionMultiThumbFuture(
            IAppTransitionAnimationSpecsFuture future, IRemoteCallback animStartedListener,
            boolean scaleUp) {
        try {
            mIwm.overridePendingAppTransitionMultiThumbFuture(future, animStartedListener, scaleUp);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to override transition: " + e);
        }
    }

    /**
     * Updates the visibility of recents.
     */
+17 −17
Original line number Diff line number Diff line
@@ -16,13 +16,14 @@

package com.android.systemui.recents.views;

import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;

import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;

import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.ActivityOptions.OnAnimationStartedListener;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
@@ -33,11 +34,11 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.view.AppTransitionAnimationSpec;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -86,13 +87,15 @@ import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.TaskStack;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
import com.android.systemui.shared.recents.view.RecentsTransition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -608,16 +611,17 @@ public class RecentsView extends FrameLayout {
            // rect to its final layout-space rect
            Utilities.setViewFrameFromTranslation(event.taskView);

            // Dock the task and launch it
            SystemServicesProxy ssp = Recents.getSystemServices();
            if (ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode)) {
            final ActivityOptions options = ActivityOptionsCompat.makeSplitScreenOptions(
                    dockState.createMode == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
            if (ActivityManagerWrapper.getInstance().startActivityFromRecents(event.task.key.id,
                    options)) {
                final Runnable animStartedListener = () -> {
                    EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
                    // Remove the task and don't bother relaying out, as all the tasks will be
                    // relaid out when the stack changes on the multiwindow change event
                    // Remove the task and don't bother relaying out, as all the tasks
                    // will be relaid out when the stack changes on the multiwindow
                    // change event
                    getStack().removeTask(event.task, null, true /* fromDockGesture */);
                };

                final Rect taskRect = getTaskRect(event.taskView);
                AppTransitionAnimationSpecsFuture future = new AppTransitionAnimationSpecsFuture(
                        getHandler()) {
@@ -626,10 +630,8 @@ public class RecentsView extends FrameLayout {
                        return mTransitionHelper.composeDockAnimationSpec(event.taskView, taskRect);
                    }
                };
                ssp.overridePendingAppTransitionMultiThumbFuture(future.getFuture(),
                        RecentsTransition.wrapStartedListener(getHandler(), animStartedListener),
                        true /* scaleUp */);

                WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
                        future, animStartedListener, getHandler(), true /* scaleUp */);
                MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
                        event.task.getTopComponent().flattenToShortString());
            } else {
@@ -1032,11 +1034,9 @@ public class RecentsView extends FrameLayout {
                if (taskIndex > -1) {
                    taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
                }
                EventBus.getDefault().send(new LaunchTaskSucceededEvent(
                        taskIndexFromFront));
                EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
            } else {
                Log.e(TAG, mContext.getString(R.string.recents_launch_error_message,
                        task.title));
                Log.e(TAG, mContext.getString(R.string.recents_launch_error_message, task.title));

                // Dismiss the task if we fail to launch it
                if (taskView != null) {
Loading