Loading core/java/android/app/ActivityManagerNative.java +19 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } core/java/android/app/IActivityManager.java +4 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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; } services/core/java/com/android/server/am/ActivityManagerService.java +18 −0 Original line number Diff line number Diff line Loading @@ -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, services/core/java/com/android/server/wm/DimLayer.java +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading services/core/java/com/android/server/wm/DockedStackDividerController.java +122 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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; Loading @@ -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() { Loading @@ -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
core/java/android/app/ActivityManagerNative.java +19 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; }
core/java/android/app/IActivityManager.java +4 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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; }
services/core/java/com/android/server/am/ActivityManagerService.java +18 −0 Original line number Diff line number Diff line Loading @@ -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,
services/core/java/com/android/server/wm/DimLayer.java +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
services/core/java/com/android/server/wm/DockedStackDividerController.java +122 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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; Loading @@ -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() { Loading @@ -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; } }