Merge "SpriteController: Reparent pointer surfaces under DisplayContent"
This commit is contained in:
committed by
Android (Google) Code Review
commit
0cb2de5700
@@ -27,10 +27,12 @@ namespace android {
|
||||
|
||||
// --- SpriteController ---
|
||||
|
||||
SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) :
|
||||
mLooper(looper), mOverlayLayer(overlayLayer) {
|
||||
SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer,
|
||||
ParentSurfaceProvider parentSurfaceProvider)
|
||||
: mLooper(looper),
|
||||
mOverlayLayer(overlayLayer),
|
||||
mParentSurfaceProvider(std::move(parentSurfaceProvider)) {
|
||||
mHandler = new WeakMessageHandler(this);
|
||||
|
||||
mLocked.transactionNestingCount = 0;
|
||||
mLocked.deferredSpriteUpdate = false;
|
||||
}
|
||||
@@ -168,8 +170,7 @@ void SpriteController::doUpdateSprites() {
|
||||
|
||||
// If surface is a new one, we have to set right layer stack.
|
||||
if (update.surfaceChanged || update.state.dirty & DIRTY_DISPLAY_ID) {
|
||||
t.setLayerStack(update.state.surfaceControl,
|
||||
ui::LayerStack::fromValue(update.state.displayId));
|
||||
t.reparent(update.state.surfaceControl, mParentSurfaceProvider(update.state.displayId));
|
||||
needApplyTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,8 @@ protected:
|
||||
virtual ~SpriteController();
|
||||
|
||||
public:
|
||||
SpriteController(const sp<Looper>& looper, int32_t overlayLayer);
|
||||
using ParentSurfaceProvider = std::function<sp<SurfaceControl>(int /*displayId*/)>;
|
||||
SpriteController(const sp<Looper>& looper, int32_t overlayLayer, ParentSurfaceProvider parent);
|
||||
|
||||
/* Creates a new sprite, initially invisible. */
|
||||
virtual sp<Sprite> createSprite();
|
||||
@@ -245,6 +246,7 @@ private:
|
||||
sp<Looper> mLooper;
|
||||
const int32_t mOverlayLayer;
|
||||
sp<WeakMessageHandler> mHandler;
|
||||
ParentSurfaceProvider mParentSurfaceProvider;
|
||||
|
||||
sp<SurfaceComposerClient> mSurfaceComposerClient;
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ namespace android {
|
||||
class MockSpriteController : public SpriteController {
|
||||
|
||||
public:
|
||||
MockSpriteController(sp<Looper> looper) : SpriteController(looper, 0) {}
|
||||
MockSpriteController(sp<Looper> looper)
|
||||
: SpriteController(looper, 0, [](int) { return nullptr; }) {}
|
||||
~MockSpriteController() {}
|
||||
|
||||
MOCK_METHOD(sp<Sprite>, createSprite, (), (override));
|
||||
|
||||
@@ -98,6 +98,7 @@ import android.view.InputMonitor;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.VerifiedInputEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.Toast;
|
||||
@@ -2906,6 +2907,15 @@ public class InputManagerService extends IInputManager.Stub
|
||||
return PointerIcon.getDefaultIcon(getContextForPointerIcon(displayId));
|
||||
}
|
||||
|
||||
// Native callback.
|
||||
private long getParentSurfaceForPointers(int displayId) {
|
||||
final SurfaceControl sc = mWindowManagerCallbacks.getParentSurfaceForPointers(displayId);
|
||||
if (sc == null) {
|
||||
return 0;
|
||||
}
|
||||
return sc.mNativeObject;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Context getContextForPointerIcon(int displayId) {
|
||||
if (mPointerIconDisplayContext != null
|
||||
@@ -3105,6 +3115,12 @@ public class InputManagerService extends IInputManager.Stub
|
||||
* Called when the drag over window has changed.
|
||||
*/
|
||||
void notifyDropWindow(IBinder token, float x, float y);
|
||||
|
||||
/**
|
||||
* Get the {@link SurfaceControl} that should be the parent for the surfaces created for
|
||||
* pointers such as the mouse cursor and touch spots for the given display.
|
||||
*/
|
||||
SurfaceControl getParentSurfaceForPointers(int displayId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.os.IBinder;
|
||||
import android.util.Slog;
|
||||
import android.view.InputApplicationHandle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerPolicyConstants;
|
||||
|
||||
@@ -234,6 +235,19 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
|
||||
mService.mDragDropController::reportDropWindow, token, x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceControl getParentSurfaceForPointers(int displayId) {
|
||||
synchronized (mService.mGlobalLock) {
|
||||
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
|
||||
if (dc == null) {
|
||||
Slog.e(TAG, "Failed to get parent surface for pointers on display " + displayId
|
||||
+ " - DisplayContent not found.");
|
||||
return null;
|
||||
}
|
||||
return dc.getOverlayLayer();
|
||||
}
|
||||
}
|
||||
|
||||
/** Waits until the built-in input devices have been configured. */
|
||||
public boolean waitForInputDevicesReady(long timeoutMillis) {
|
||||
synchronized (mInputDevicesReadyMonitor) {
|
||||
|
||||
@@ -128,6 +128,7 @@ static struct {
|
||||
jmethodID getTouchCalibrationForInputDevice;
|
||||
jmethodID getContextForDisplay;
|
||||
jmethodID notifyDropWindow;
|
||||
jmethodID getParentSurfaceForPointers;
|
||||
} gServiceClassInfo;
|
||||
|
||||
static struct {
|
||||
@@ -389,7 +390,7 @@ private:
|
||||
void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
|
||||
void ensureSpriteControllerLocked();
|
||||
int32_t getPointerDisplayId();
|
||||
void updatePointerDisplayLocked();
|
||||
sp<SurfaceControl> getParentSurfaceForPointers(int displayId);
|
||||
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
|
||||
|
||||
static inline JNIEnv* jniEnv() {
|
||||
@@ -668,6 +669,18 @@ int32_t NativeInputManager::getPointerDisplayId() {
|
||||
return pointerDisplayId;
|
||||
}
|
||||
|
||||
sp<SurfaceControl> NativeInputManager::getParentSurfaceForPointers(int displayId) {
|
||||
JNIEnv* env = jniEnv();
|
||||
jlong nativeSurfaceControlPtr =
|
||||
env->CallLongMethod(mServiceObj, gServiceClassInfo.getParentSurfaceForPointers,
|
||||
displayId);
|
||||
if (checkAndClearExceptionFromCallback(env, "getParentSurfaceForPointers")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<SurfaceControl*>(nativeSurfaceControlPtr);
|
||||
}
|
||||
|
||||
void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
|
||||
if (mLocked.spriteController == nullptr) {
|
||||
JNIEnv* env = jniEnv();
|
||||
@@ -675,7 +688,9 @@ void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
|
||||
if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
|
||||
layer = -1;
|
||||
}
|
||||
mLocked.spriteController = new SpriteController(mLooper, layer);
|
||||
mLocked.spriteController = new SpriteController(mLooper, layer, [this](int displayId) {
|
||||
return getParentSurfaceForPointers(displayId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2500,9 +2515,11 @@ int register_android_server_InputManager(JNIEnv* env) {
|
||||
"getTouchCalibrationForInputDevice",
|
||||
"(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;");
|
||||
|
||||
GET_METHOD_ID(gServiceClassInfo.getContextForDisplay, clazz,
|
||||
"getContextForDisplay",
|
||||
"(I)Landroid/content/Context;")
|
||||
GET_METHOD_ID(gServiceClassInfo.getContextForDisplay, clazz, "getContextForDisplay",
|
||||
"(I)Landroid/content/Context;");
|
||||
|
||||
GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz,
|
||||
"getParentSurfaceForPointers", "(I)J");
|
||||
|
||||
// InputDevice
|
||||
|
||||
|
||||
Reference in New Issue
Block a user