Merge "Give Divider back its touch-region" into rvc-dev am: 5a61909275

Change-Id: Ifc5c167bc96e44e541299c0b32beb62060dd4efe
This commit is contained in:
Evan Rosky
2020-05-01 00:17:50 +00:00
committed by Automerger Merge Worker
8 changed files with 104 additions and 11 deletions

View File

@@ -342,5 +342,5 @@ interface IWindowSession {
* Update the flags on an input channel associated with a particular surface. * Update the flags on an input channel associated with a particular surface.
*/ */
void updateInputChannel(in IBinder channelToken, int displayId, in SurfaceControl surface, void updateInputChannel(in IBinder channelToken, int displayId, in SurfaceControl surface,
int flags); int flags, in Region region);
} }

View File

@@ -233,6 +233,14 @@ public class SurfaceControlViewHost {
return mViewRoot.mWindow; return mViewRoot.mWindow;
} }
/**
* @return the WindowlessWindowManager instance that this host is attached to.
* @hide
*/
public @NonNull WindowlessWindowManager getWindowlessWM() {
return mWm;
}
/** /**
* @hide * @hide
*/ */

View File

@@ -16,16 +16,19 @@
package android.view; package android.view;
import android.annotation.Nullable;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.util.MergedConfiguration; import android.util.MergedConfiguration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
/** /**
* A simplistic implementation of IWindowSession. Rather than managing Surfaces * A simplistic implementation of IWindowSession. Rather than managing Surfaces
@@ -42,6 +45,7 @@ public class WindowlessWindowManager implements IWindowSession {
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
int mDisplayId; int mDisplayId;
IBinder mInputChannelToken; IBinder mInputChannelToken;
Region mInputRegion;
State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId,
IBinder inputChannelToken) { IBinder inputChannelToken) {
mSurfaceControl = sc; mSurfaceControl = sc;
@@ -95,6 +99,30 @@ public class WindowlessWindowManager implements IWindowSession {
mResizeCompletionForWindow.put(window, callback); mResizeCompletionForWindow.put(window, callback);
} }
protected void setTouchRegion(IBinder window, @Nullable Region region) {
State state;
synchronized (this) {
// Do everything while locked so that we synchronize with relayout. This should be a
// very infrequent operation.
state = mStateForWindow.get(window);
if (state == null) {
return;
}
if (Objects.equals(region, state.mInputRegion)) {
return;
}
state.mInputRegion = region != null ? new Region(region) : null;
if (state.mInputChannelToken != null) {
try {
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
state.mSurfaceControl, state.mParams.flags, state.mInputRegion);
} catch (RemoteException e) {
Log.e(TAG, "Failed to update surface input channel: ", e);
}
}
}
}
/** /**
* IWindowSession implementation. * IWindowSession implementation.
*/ */
@@ -234,7 +262,7 @@ public class WindowlessWindowManager implements IWindowSession {
&& state.mInputChannelToken != null) { && state.mInputChannelToken != null) {
try { try {
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc, mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc,
attrs.flags); attrs.flags, state.mInputRegion);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Failed to update surface input channel: ", e); Log.e(TAG, "Failed to update surface input channel: ", e);
} }
@@ -409,7 +437,7 @@ public class WindowlessWindowManager implements IWindowSession {
@Override @Override
public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
int flags) { int flags, Region region) {
} }
@Override @Override

View File

@@ -29,6 +29,7 @@ import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region.Op; import android.graphics.Region.Op;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.os.Bundle; import android.os.Bundle;
@@ -338,12 +339,12 @@ public class DividerView extends FrameLayout implements OnTouchListener,
@Override @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mFirstLayout) { if (mFirstLayout) {
// Wait for first layout so that the ViewRootImpl surface has been created. // Wait for first layout so that the ViewRootImpl surface has been created.
initializeSurfaceState(); initializeSurfaceState();
mFirstLayout = false; mFirstLayout = false;
} }
super.onLayout(changed, left, top, right, bottom);
int minimizeLeft = 0; int minimizeLeft = 0;
int minimizeTop = 0; int minimizeTop = 0;
if (mDockSide == WindowManager.DOCKED_TOP) { if (mDockSide == WindowManager.DOCKED_TOP) {
@@ -783,6 +784,20 @@ public class DividerView extends FrameLayout implements OnTouchListener,
setResizeDimLayer(t, false /* secondary */, 0.f /* alpha */); setResizeDimLayer(t, false /* secondary */, 0.f /* alpha */);
t.apply(); t.apply();
mTiles.releaseTransaction(t); mTiles.releaseTransaction(t);
// Get the actually-visible bar dimensions (relative to full window). This is a thin
// bar going through the center.
final Rect dividerBar = isHorizontalDivision()
? new Rect(0, mDividerInsets, mSplitLayout.mDisplayLayout.width(),
mDividerInsets + mDividerSize)
: new Rect(mDividerInsets, 0, mDividerInsets + mDividerSize,
mSplitLayout.mDisplayLayout.height());
final Region touchRegion = new Region(dividerBar);
// Add in the "draggable" portion. While not visible, this is an expanded area that the
// user can interact with.
touchRegion.union(new Rect(mHandle.getLeft(), mHandle.getTop(),
mHandle.getRight(), mHandle.getBottom()));
mWindowManager.setTouchRegion(touchRegion);
} }
public void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable) { public void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable) {

View File

@@ -27,6 +27,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Region;
import android.os.Binder; import android.os.Binder;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
@@ -103,4 +104,12 @@ public class DividerWindowManager {
mSystemWindows.updateViewLayout(mView, mLp); mSystemWindows.updateViewLayout(mView, mLp);
} }
} }
/** Sets the touch region to `touchRegion`. Use null to unset.*/
public void setTouchRegion(Region touchRegion) {
if (mView == null) {
return;
}
mSystemWindows.setTouchableRegion(mView, touchRegion);
}
} }

View File

@@ -23,7 +23,9 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.MergedConfiguration; import android.util.MergedConfiguration;
@@ -138,6 +140,23 @@ public class SystemWindows {
root.relayout((WindowManager.LayoutParams) params); root.relayout((WindowManager.LayoutParams) params);
} }
/**
* Sets the touchable region of a view's window. This will be cropped to the window size.
* @param view
* @param region
*/
public void setTouchableRegion(@NonNull View view, Region region) {
SurfaceControlViewHost root = mViewRoots.get(view);
if (root == null) {
return;
}
WindowlessWindowManager wwm = root.getWindowlessWM();
if (!(wwm instanceof SysUiWindowManager)) {
return;
}
((SysUiWindowManager) wwm).setTouchableRegionForWindow(view, region);
}
/** /**
* Adds a root for system-ui window management with no views. Only useful for IME. * Adds a root for system-ui window management with no views. Only useful for IME.
*/ */
@@ -289,6 +308,14 @@ public class SystemWindows {
SurfaceControl getSurfaceControlForWindow(View rootView) { SurfaceControl getSurfaceControlForWindow(View rootView) {
return getSurfaceControl(rootView); return getSurfaceControl(rootView);
} }
void setTouchableRegionForWindow(View rootView, Region region) {
IBinder token = rootView.getWindowToken();
if (token == null) {
return;
}
setTouchRegion(token, region);
}
} }
class ContainerWindow extends IWindow.Stub { class ContainerWindow extends IWindow.Stub {

View File

@@ -679,10 +679,10 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
@Override @Override
public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
int flags) { int flags, Region region) {
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
mService.updateInputChannel(channelToken, displayId, surface, flags); mService.updateInputChannel(channelToken, displayId, surface, flags, region);
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }

View File

@@ -8030,7 +8030,7 @@ public class WindowManagerService extends IWindowManager.Stub
} }
updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface, updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
name, applicationHandle, flags); name, applicationHandle, flags, null /* region */);
clientChannel.transferTo(outInputChannel); clientChannel.transferTo(outInputChannel);
clientChannel.dispose(); clientChannel.dispose();
@@ -8042,7 +8042,7 @@ public class WindowManagerService extends IWindowManager.Stub
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid, private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
int displayId, SurfaceControl surface, String name, int displayId, SurfaceControl surface, String name,
InputApplicationHandle applicationHandle, int flags) { InputApplicationHandle applicationHandle, int flags, Region region) {
InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId); InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
h.token = channelToken; h.token = channelToken;
h.name = name; h.name = name;
@@ -8062,7 +8062,13 @@ public class WindowManagerService extends IWindowManager.Stub
h.inputFeatures = 0; h.inputFeatures = 0;
h.replaceTouchableRegionWithCrop(null); if (region == null) {
h.replaceTouchableRegionWithCrop(null);
} else {
h.touchableRegion.set(region);
h.replaceTouchableRegionWithCrop = false;
h.setTouchableRegionCrop(surface);
}
SurfaceControl.Transaction t = mTransactionFactory.get(); SurfaceControl.Transaction t = mTransactionFactory.get();
t.setInputWindowInfo(surface, h); t.setInputWindowInfo(surface, h);
@@ -8076,7 +8082,7 @@ public class WindowManagerService extends IWindowManager.Stub
* is undefined. * is undefined.
*/ */
void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
int flags) { int flags, Region region) {
final InputApplicationHandle applicationHandle; final InputApplicationHandle applicationHandle;
final String name; final String name;
final EmbeddedWindowController.EmbeddedWindow win; final EmbeddedWindowController.EmbeddedWindow win;
@@ -8091,7 +8097,7 @@ public class WindowManagerService extends IWindowManager.Stub
} }
updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name, updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
applicationHandle, flags); applicationHandle, flags, region);
} }
/** Return whether layer tracing is enabled */ /** Return whether layer tracing is enabled */