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

Commit 57b6ccec authored by Filip Gruszczynski's avatar Filip Gruszczynski
Browse files

Dismissing of docked stack by dragging to the side.

Bug: 24623909
Change-Id: Ic93b169442de1eb4dca9f65a87ae2b813bcef043
parent d316d3d2
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2691,6 +2691,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            reply.writeNoException();
            return true;
        }
        case REMOVE_STACK: {
            data.enforceInterface(IActivityManager.descriptor);
            final int stackId = data.readInt();
            removeStack(stackId);
            reply.writeNoException();
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -6239,5 +6246,17 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    @Override
    public void removeStack(int stackId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(stackId);
        mRemote.transact(REMOVE_STACK, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    private IBinder mRemote;
}
+4 −1
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package android.app;

import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
@@ -538,6 +538,8 @@ public interface IActivityManager extends IInterface {

    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException;

    public void removeStack(int stackId) throws RemoteException;

    /*
     * Private non-Binder interfaces
     */
@@ -895,4 +897,5 @@ public interface IActivityManager extends IInterface {
    int REPORT_SIZE_CONFIGURATIONS = IBinder.FIRST_CALL_TRANSACTION + 345;
    int MOVE_TASK_TO_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 346;
    int SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 347;
    int REMOVE_STACK = IBinder.FIRST_CALL_TRANSACTION + 348;
}
+18 −0
Original line number Diff line number Diff line
@@ -17571,6 +17571,24 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
    }
    @Override
    public void removeStack(int stackId) {
        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                "detahStack()");
        if (stackId == HOME_STACK_ID) {
            throw new IllegalArgumentException("Removing home stack is not allowed.");
        }
        synchronized (this) {
            ActivityStack stack = mStackSupervisor.getStack(stackId);
            if (stack != null) {
                ArrayList<TaskRecord> tasks = stack.getAllTasks();
                for (int i = tasks.size() - 1; i >= 0; i--) {
                    removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */);
                }
            }
        }
    }
    @Override
    public void updatePersistentConfiguration(Configuration values) {
        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
+4 −0
Original line number Diff line number Diff line
@@ -29,6 +29,10 @@ public class DimLayer {
    private static final String TAG = "DimLayer";
    private static final boolean DEBUG = false;

    public static final float RESIZING_HINT_ALPHA = 0.5f;

    public static final int RESIZING_HINT_DURATION_MS = 0;

    /** Actual surface that dims */
    SurfaceControl mDimSurface;

+122 −5
Original line number Diff line number Diff line
@@ -25,16 +25,22 @@ import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static com.android.server.wm.DimLayer.RESIZING_HINT_ALPHA;
import static com.android.server.wm.DimLayer.RESIZING_HINT_DURATION_MS;
import static com.android.server.wm.TaskPositioner.SIDE_MARGIN_DIP;
import static com.android.server.wm.TaskStack.DOCKED_BOTTOM;
import static com.android.server.wm.TaskStack.DOCKED_LEFT;
import static com.android.server.wm.TaskStack.DOCKED_RIGHT;
import static com.android.server.wm.TaskStack.DOCKED_TOP;
import static com.android.server.wm.WindowManagerService.dipToPixel;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -44,11 +50,13 @@ import android.view.WindowManagerGlobal;
/**
 * Controls showing and hiding of a docked stack divider on the display.
 */
public class DockedStackDividerController implements View.OnTouchListener {
public class DockedStackDividerController implements View.OnTouchListener, DimLayer.DimLayerUser {
    private static final String TAG = "DockedStackDivider";
    private final Context mContext;
    private final int mDividerWidth;
    private final DisplayContent mDisplayContent;
    private final int mSideMargin;
    private final DimLayer mDimLayer;
    private View mView;
    private Rect mTmpRect = new Rect();
    private Rect mLastResizeRect = new Rect();
@@ -57,12 +65,15 @@ public class DockedStackDividerController implements View.OnTouchListener {
    private TaskStack mTaskStack;
    private Rect mOriginalRect = new Rect();
    private int mDockSide;
    private boolean mDimLayerVisible;

    DockedStackDividerController(Context context, DisplayContent displayContent) {
        mContext = context;
        mDisplayContent = displayContent;
        mDividerWidth = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.docked_stack_divider_thickness);
        mSideMargin = dipToPixel(SIDE_MARGIN_DIP, mDisplayContent.getDisplayMetrics());
        mDimLayer = new DimLayer(displayContent.mService, this, displayContent.getDisplayId());
    }

    private void addDivider(Configuration configuration) {
@@ -154,11 +165,17 @@ public class DockedStackDividerController implements View.OnTouchListener {
                break;
            case MotionEvent.ACTION_MOVE:
                if (mTaskStack != null) {
                    resizeStack(event);
                    final int x = (int) event.getRawX();
                    final int y = (int) event.getRawY();
                    resizeStack(x, y);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mTaskStack != null) {
                    maybeDismissTaskStack((int) event.getRawX(), (int) event.getRawY());
                }
                setDimLayerVisible(false, -1, -1);
                mTaskStack = null;
                mDockSide = TaskStack.DOCKED_INVALID;
                break;
@@ -166,10 +183,88 @@ public class DockedStackDividerController implements View.OnTouchListener {
        return true;
    }

    private void resizeStack(MotionEvent event) {
    private void maybeDismissTaskStack(int x, int y) {
        final int distance = distanceFromDockSide(mDockSide, mOriginalRect, x, y);
        if (distance == -1) {
            Slog.wtf(TAG, "maybeDismissTaskStack: Unknown dock side=" + mDockSide);
            return;
        }
        if (distance <= mSideMargin) {
            try {
                mDisplayContent.mService.mActivityManager.removeStack(mTaskStack.mStackId);
            } catch (RemoteException e) {
                // This can't happen because we are in the same process.
            }
        }
    }

    private void updateDimLayer(int x, int y) {
        final int distance = distanceFromDockSide(mDockSide, mOriginalRect, x, y);
        if (distance == -1) {
            Slog.wtf(TAG, "updateDimLayer: Unknown dock side=" + mDockSide);
            return;
        }
        setDimLayerVisible(distance <= mSideMargin, x, y);
    }

    /**
     * Provides the distance from the point to the docked side of a rectangle.
     *
     * @return non negative distance or -1 on error
     */
    private static int distanceFromDockSide(int dockSide, Rect bounds, int x, int y) {
        switch (dockSide) {
            case DOCKED_LEFT:
                return x - bounds.left;
            case DOCKED_TOP:
                return y - bounds.top;
            case DOCKED_RIGHT:
                return bounds.right - x;
            case DOCKED_BOTTOM:
                return bounds.bottom - y;
        }
        return -1;
    }

    private void setDimLayerVisible(boolean visible, int x, int y) {
        if (visible) {
            mTmpRect.set(mOriginalRect);
            switch (mDockSide) {
                case DOCKED_LEFT:
                    mTmpRect.right = x;
                    break;
                case DOCKED_TOP:
                    mTmpRect.bottom = y;
                    break;
                case DOCKED_RIGHT:
                    mTmpRect.left = x;
                    break;
                case DOCKED_BOTTOM:
                    mTmpRect.top = y;
                    break;
                default:
                    Slog.wtf(TAG, "setDimLayerVisible: Unknown dock side when setting dim layer="
                            + mDockSide);
                    return;
            }
            mDimLayer.setBounds(mTmpRect);
        }
        if (mDimLayerVisible == visible) {
            return;
        }
        mDimLayerVisible = visible;
        if (mDimLayerVisible) {
            mDimLayer.show(mDisplayContent.mService.getDragLayerLocked(), RESIZING_HINT_ALPHA,
                    RESIZING_HINT_DURATION_MS);
        } else {
            mDimLayer.hide();
        }
    }

    private void resizeStack(int x, int y) {
        mTmpRect.set(mOriginalRect);
        final int deltaX = (int) event.getRawX() - mStartX;
        final int deltaY = (int) event.getRawY() - mStartY;
        final int deltaX = x - mStartX;
        final int deltaY = y - mStartY;
        switch (mDockSide) {
            case DOCKED_LEFT:
                mTmpRect.right += deltaX;
@@ -191,7 +286,9 @@ public class DockedStackDividerController implements View.OnTouchListener {
        try {
            mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect);
        } catch (RemoteException e) {
            // This can't happen because we are in the same process.
        }
        updateDimLayer(x, y);
    }

    boolean isResizing() {
@@ -201,4 +298,24 @@ public class DockedStackDividerController implements View.OnTouchListener {
    int getWidthAdjustment() {
        return getWidth() / 2;
    }

    @Override
    public boolean isFullscreen() {
        return false;
    }

    @Override
    public DisplayInfo getDisplayInfo() {
        return mDisplayContent.getDisplayInfo();
    }

    @Override
    public void getBounds(Rect outBounds) {
        // This dim layer user doesn't need this.
    }

    @Override
    public String toShortString() {
        return TAG;
    }
}
Loading