Merge "Support mouse pointer on external displays (2/2)"
This commit is contained in:
committed by
Android (Google) Code Review
commit
b42f9c93cb
@@ -89,10 +89,6 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>&
|
||||
|
||||
mLocked.animationPending = false;
|
||||
|
||||
mLocked.displayWidth = -1;
|
||||
mLocked.displayHeight = -1;
|
||||
mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
|
||||
|
||||
mLocked.presentation = PRESENTATION_POINTER;
|
||||
mLocked.presentationChanged = false;
|
||||
|
||||
@@ -110,15 +106,6 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>&
|
||||
mLocked.lastFrameUpdatedTime = 0;
|
||||
|
||||
mLocked.buttonState = 0;
|
||||
|
||||
mPolicy->loadPointerIcon(&mLocked.pointerIcon);
|
||||
|
||||
loadResources();
|
||||
|
||||
if (mLocked.pointerIcon.isValid()) {
|
||||
mLocked.pointerIconChanged = true;
|
||||
updatePointerLocked();
|
||||
}
|
||||
}
|
||||
|
||||
PointerController::~PointerController() {
|
||||
@@ -144,23 +131,15 @@ bool PointerController::getBounds(float* outMinX, float* outMinY,
|
||||
|
||||
bool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
|
||||
float* outMaxX, float* outMaxY) const {
|
||||
if (mLocked.displayWidth <= 0 || mLocked.displayHeight <= 0) {
|
||||
|
||||
if (!mLocked.viewport.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outMinX = 0;
|
||||
*outMinY = 0;
|
||||
switch (mLocked.displayOrientation) {
|
||||
case DISPLAY_ORIENTATION_90:
|
||||
case DISPLAY_ORIENTATION_270:
|
||||
*outMaxX = mLocked.displayHeight - 1;
|
||||
*outMaxY = mLocked.displayWidth - 1;
|
||||
break;
|
||||
default:
|
||||
*outMaxX = mLocked.displayWidth - 1;
|
||||
*outMaxY = mLocked.displayHeight - 1;
|
||||
break;
|
||||
}
|
||||
*outMinX = mLocked.viewport.logicalLeft;
|
||||
*outMinY = mLocked.viewport.logicalTop;
|
||||
*outMaxX = mLocked.viewport.logicalRight - 1;
|
||||
*outMaxY = mLocked.viewport.logicalBottom - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,6 +210,12 @@ void PointerController::getPosition(float* outX, float* outY) const {
|
||||
*outY = mLocked.pointerY;
|
||||
}
|
||||
|
||||
int32_t PointerController::getDisplayId() const {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
return mLocked.viewport.displayId;
|
||||
}
|
||||
|
||||
void PointerController::fade(Transition transition) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
@@ -355,48 +340,56 @@ void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout
|
||||
void PointerController::reloadPointerResources() {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
loadResources();
|
||||
|
||||
if (mLocked.presentation == PRESENTATION_POINTER) {
|
||||
mLocked.additionalMouseResources.clear();
|
||||
mLocked.animationResources.clear();
|
||||
mPolicy->loadPointerIcon(&mLocked.pointerIcon);
|
||||
mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
|
||||
&mLocked.animationResources);
|
||||
}
|
||||
|
||||
mLocked.presentationChanged = true;
|
||||
loadResourcesLocked();
|
||||
updatePointerLocked();
|
||||
}
|
||||
|
||||
void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_t orientation) {
|
||||
AutoMutex _l(mLock);
|
||||
/**
|
||||
* The viewport values for deviceHeight and deviceWidth have already been adjusted for rotation,
|
||||
* so here we are getting the dimensions in the original, unrotated orientation (orientation 0).
|
||||
*/
|
||||
static void getNonRotatedSize(const DisplayViewport& viewport, int32_t& width, int32_t& height) {
|
||||
width = viewport.deviceWidth;
|
||||
height = viewport.deviceHeight;
|
||||
|
||||
// Adjust to use the display's unrotated coordinate frame.
|
||||
if (orientation == DISPLAY_ORIENTATION_90
|
||||
|| orientation == DISPLAY_ORIENTATION_270) {
|
||||
int32_t temp = height;
|
||||
height = width;
|
||||
width = temp;
|
||||
if (viewport.orientation == DISPLAY_ORIENTATION_90
|
||||
|| viewport.orientation == DISPLAY_ORIENTATION_270) {
|
||||
std::swap(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
|
||||
AutoMutex _l(mLock);
|
||||
if (viewport == mLocked.viewport) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
|
||||
mLocked.displayWidth = width;
|
||||
mLocked.displayHeight = height;
|
||||
const DisplayViewport oldViewport = mLocked.viewport;
|
||||
mLocked.viewport = viewport;
|
||||
|
||||
int32_t oldDisplayWidth, oldDisplayHeight;
|
||||
getNonRotatedSize(oldViewport, oldDisplayWidth, oldDisplayHeight);
|
||||
int32_t newDisplayWidth, newDisplayHeight;
|
||||
getNonRotatedSize(viewport, newDisplayWidth, newDisplayHeight);
|
||||
|
||||
// Reset cursor position to center if size or display changed.
|
||||
if (oldViewport.displayId != viewport.displayId
|
||||
|| oldDisplayWidth != newDisplayWidth
|
||||
|| oldDisplayHeight != newDisplayHeight) {
|
||||
|
||||
float minX, minY, maxX, maxY;
|
||||
if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
|
||||
mLocked.pointerX = (minX + maxX) * 0.5f;
|
||||
mLocked.pointerY = (minY + maxY) * 0.5f;
|
||||
// Reload icon resources for density may be changed.
|
||||
loadResourcesLocked();
|
||||
} else {
|
||||
mLocked.pointerX = 0;
|
||||
mLocked.pointerY = 0;
|
||||
}
|
||||
|
||||
fadeOutAndReleaseAllSpotsLocked();
|
||||
}
|
||||
|
||||
if (mLocked.displayOrientation != orientation) {
|
||||
} else if (oldViewport.orientation != viewport.orientation) {
|
||||
// Apply offsets to convert from the pixel top-left corner position to the pixel center.
|
||||
// This creates an invariant frame of reference that we can easily rotate when
|
||||
// taking into account that the pointer may be located at fractional pixel offsets.
|
||||
@@ -405,37 +398,37 @@ void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_
|
||||
float temp;
|
||||
|
||||
// Undo the previous rotation.
|
||||
switch (mLocked.displayOrientation) {
|
||||
switch (oldViewport.orientation) {
|
||||
case DISPLAY_ORIENTATION_90:
|
||||
temp = x;
|
||||
x = mLocked.displayWidth - y;
|
||||
x = oldViewport.deviceHeight - y;
|
||||
y = temp;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_180:
|
||||
x = mLocked.displayWidth - x;
|
||||
y = mLocked.displayHeight - y;
|
||||
x = oldViewport.deviceWidth - x;
|
||||
y = oldViewport.deviceHeight - y;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_270:
|
||||
temp = x;
|
||||
x = y;
|
||||
y = mLocked.displayHeight - temp;
|
||||
y = oldViewport.deviceWidth - temp;
|
||||
break;
|
||||
}
|
||||
|
||||
// Perform the new rotation.
|
||||
switch (orientation) {
|
||||
switch (viewport.orientation) {
|
||||
case DISPLAY_ORIENTATION_90:
|
||||
temp = x;
|
||||
x = y;
|
||||
y = mLocked.displayWidth - temp;
|
||||
y = viewport.deviceHeight - temp;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_180:
|
||||
x = mLocked.displayWidth - x;
|
||||
y = mLocked.displayHeight - y;
|
||||
x = viewport.deviceWidth - x;
|
||||
y = viewport.deviceHeight - y;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_270:
|
||||
temp = x;
|
||||
x = mLocked.displayHeight - y;
|
||||
x = viewport.deviceWidth - y;
|
||||
y = temp;
|
||||
break;
|
||||
}
|
||||
@@ -444,7 +437,6 @@ void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_
|
||||
// and save the results.
|
||||
mLocked.pointerX = x - 0.5f;
|
||||
mLocked.pointerY = y - 0.5f;
|
||||
mLocked.displayOrientation = orientation;
|
||||
}
|
||||
|
||||
updatePointerLocked();
|
||||
@@ -614,11 +606,16 @@ void PointerController::removeInactivityTimeoutLocked() {
|
||||
mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
|
||||
}
|
||||
|
||||
void PointerController::updatePointerLocked() {
|
||||
void PointerController::updatePointerLocked() REQUIRES(mLock) {
|
||||
if (!mLocked.viewport.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSpriteController->openTransaction();
|
||||
|
||||
mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
|
||||
mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
|
||||
mLocked.pointerSprite->setDisplayId(mLocked.viewport.displayId);
|
||||
|
||||
if (mLocked.pointerAlpha > 0) {
|
||||
mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
|
||||
@@ -729,8 +726,18 @@ void PointerController::fadeOutAndReleaseAllSpotsLocked() {
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::loadResources() {
|
||||
void PointerController::loadResourcesLocked() REQUIRES(mLock) {
|
||||
mPolicy->loadPointerResources(&mResources);
|
||||
|
||||
if (mLocked.presentation == PRESENTATION_POINTER) {
|
||||
mLocked.additionalMouseResources.clear();
|
||||
mLocked.animationResources.clear();
|
||||
mPolicy->loadPointerIcon(&mLocked.pointerIcon);
|
||||
mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
|
||||
&mLocked.animationResources);
|
||||
}
|
||||
|
||||
mLocked.pointerIconChanged = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <ui/DisplayInfo.h>
|
||||
#include <input/DisplayViewport.h>
|
||||
#include <input/Input.h>
|
||||
#include <PointerControllerInterface.h>
|
||||
#include <utils/BitSet.h>
|
||||
@@ -96,6 +97,7 @@ public:
|
||||
virtual int32_t getButtonState() const;
|
||||
virtual void setPosition(float x, float y);
|
||||
virtual void getPosition(float* outX, float* outY) const;
|
||||
virtual int32_t getDisplayId() const;
|
||||
virtual void fade(Transition transition);
|
||||
virtual void unfade(Transition transition);
|
||||
|
||||
@@ -106,7 +108,7 @@ public:
|
||||
|
||||
void updatePointerIcon(int32_t iconId);
|
||||
void setCustomPointerIcon(const SpriteIcon& icon);
|
||||
void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
|
||||
void setDisplayViewport(const DisplayViewport& viewport);
|
||||
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
||||
void reloadPointerResources();
|
||||
|
||||
@@ -156,9 +158,7 @@ private:
|
||||
size_t animationFrameIndex;
|
||||
nsecs_t lastFrameUpdatedTime;
|
||||
|
||||
int32_t displayWidth;
|
||||
int32_t displayHeight;
|
||||
int32_t displayOrientation;
|
||||
DisplayViewport viewport;
|
||||
|
||||
InactivityTimeout inactivityTimeout;
|
||||
|
||||
@@ -182,7 +182,7 @@ private:
|
||||
|
||||
Vector<Spot*> spots;
|
||||
Vector<sp<Sprite> > recycledSprites;
|
||||
} mLocked;
|
||||
} mLocked GUARDED_BY(mLock);
|
||||
|
||||
bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
|
||||
void setPositionLocked(float x, float y);
|
||||
@@ -207,7 +207,7 @@ private:
|
||||
void fadeOutAndReleaseSpotLocked(Spot* spot);
|
||||
void fadeOutAndReleaseAllSpotsLocked();
|
||||
|
||||
void loadResources();
|
||||
void loadResourcesLocked();
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -144,13 +144,16 @@ void SpriteController::doUpdateSprites() {
|
||||
}
|
||||
}
|
||||
|
||||
// Resize sprites if needed.
|
||||
// Resize and/or reparent sprites if needed.
|
||||
SurfaceComposerClient::Transaction t;
|
||||
bool needApplyTransaction = false;
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
SpriteUpdate& update = updates.editItemAt(i);
|
||||
if (update.state.surfaceControl == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {
|
||||
if (update.state.wantSurfaceVisible()) {
|
||||
int32_t desiredWidth = update.state.icon.bitmap.width();
|
||||
int32_t desiredHeight = update.state.icon.bitmap.height();
|
||||
if (update.state.surfaceWidth < desiredWidth
|
||||
@@ -170,6 +173,12 @@ 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, update.state.displayId);
|
||||
needApplyTransaction = true;
|
||||
}
|
||||
}
|
||||
if (needApplyTransaction) {
|
||||
t.apply();
|
||||
@@ -236,7 +245,7 @@ void SpriteController::doUpdateSprites() {
|
||||
if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden
|
||||
|| (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
|
||||
| DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
|
||||
| DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
|
||||
| DIRTY_VISIBILITY | DIRTY_HOTSPOT | DIRTY_DISPLAY_ID))))) {
|
||||
needApplyTransaction = true;
|
||||
|
||||
if (wantSurfaceVisibleAndDrawn
|
||||
@@ -445,6 +454,15 @@ void SpriteController::SpriteImpl::setTransformationMatrix(
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setDisplayId(int32_t displayId) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
if (mLocked.state.displayId != displayId) {
|
||||
mLocked.state.displayId = displayId;
|
||||
invalidateLocked(DIRTY_DISPLAY_ID);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) {
|
||||
bool wasDirty = mLocked.state.dirty;
|
||||
mLocked.state.dirty |= dirty;
|
||||
|
||||
@@ -125,6 +125,9 @@ public:
|
||||
|
||||
/* Sets the sprite transformation matrix. */
|
||||
virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
|
||||
|
||||
/* Sets the id of the display where the sprite should be shown. */
|
||||
virtual void setDisplayId(int32_t displayId) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -170,6 +173,7 @@ private:
|
||||
DIRTY_LAYER = 1 << 4,
|
||||
DIRTY_VISIBILITY = 1 << 5,
|
||||
DIRTY_HOTSPOT = 1 << 6,
|
||||
DIRTY_DISPLAY_ID = 1 << 7,
|
||||
};
|
||||
|
||||
/* Describes the state of a sprite.
|
||||
@@ -180,7 +184,7 @@ private:
|
||||
struct SpriteState {
|
||||
inline SpriteState() :
|
||||
dirty(0), visible(false),
|
||||
positionX(0), positionY(0), layer(0), alpha(1.0f),
|
||||
positionX(0), positionY(0), layer(0), alpha(1.0f), displayId(ADISPLAY_ID_DEFAULT),
|
||||
surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
|
||||
}
|
||||
|
||||
@@ -193,6 +197,7 @@ private:
|
||||
int32_t layer;
|
||||
float alpha;
|
||||
SpriteTransformationMatrix transformationMatrix;
|
||||
int32_t displayId;
|
||||
|
||||
sp<SurfaceControl> surfaceControl;
|
||||
int32_t surfaceWidth;
|
||||
@@ -225,6 +230,7 @@ private:
|
||||
virtual void setLayer(int32_t layer);
|
||||
virtual void setAlpha(float alpha);
|
||||
virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
|
||||
virtual void setDisplayId(int32_t displayId);
|
||||
|
||||
inline const SpriteState& getStateLocked() const {
|
||||
return mLocked.state;
|
||||
|
||||
@@ -1950,6 +1950,11 @@ public class InputManagerService extends IInputManager.Stub
|
||||
return PointerIcon.getDefaultIcon(mContext);
|
||||
}
|
||||
|
||||
// Native callback.
|
||||
private int getPointerDisplayId() {
|
||||
return mWindowManagerCallbacks.getPointerDisplayId();
|
||||
}
|
||||
|
||||
// Native callback.
|
||||
private String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier) {
|
||||
if (!mSystemReady) {
|
||||
@@ -2017,6 +2022,8 @@ public class InputManagerService extends IInputManager.Stub
|
||||
KeyEvent event, int policyFlags);
|
||||
|
||||
public int getPointerLayer();
|
||||
|
||||
public int getPointerDisplayId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
|
||||
@@ -9,7 +10,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
import android.os.Debug;
|
||||
import android.os.IBinder;
|
||||
import android.util.Slog;
|
||||
import android.view.InputApplicationHandle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.WindowManager;
|
||||
|
||||
@@ -204,6 +204,37 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
|
||||
+ WindowManagerService.TYPE_LAYER_OFFSET;
|
||||
}
|
||||
|
||||
/** Callback to get pointer display id. */
|
||||
@Override
|
||||
public int getPointerDisplayId() {
|
||||
synchronized (mService.mGlobalLock) {
|
||||
// If desktop mode is not enabled, show on the default display.
|
||||
if (!mService.mForceDesktopModeOnExternalDisplays) {
|
||||
return DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
// Look for the topmost freeform display.
|
||||
int firstExternalDisplayId = DEFAULT_DISPLAY;
|
||||
for (int i = mService.mRoot.mChildren.size() - 1; i >= 0; --i) {
|
||||
final DisplayContent displayContent = mService.mRoot.mChildren.get(i);
|
||||
// Heuristic solution here. Currently when "Freeform windows" developer option is
|
||||
// enabled we automatically put secondary displays in freeform mode and emulating
|
||||
// "desktop mode". It also makes sense to show the pointer on the same display.
|
||||
if (displayContent.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
|
||||
return displayContent.getDisplayId();
|
||||
}
|
||||
|
||||
if (firstExternalDisplayId == DEFAULT_DISPLAY
|
||||
&& displayContent.getDisplayId() != DEFAULT_DISPLAY) {
|
||||
firstExternalDisplayId = displayContent.getDisplayId();
|
||||
}
|
||||
}
|
||||
|
||||
// Look for the topmost non-default display
|
||||
return firstExternalDisplayId;
|
||||
}
|
||||
}
|
||||
|
||||
/** Waits until the built-in input devices have been configured. */
|
||||
public boolean waitForInputDevicesReady(long timeoutMillis) {
|
||||
synchronized (mInputDevicesReadyMonitor) {
|
||||
|
||||
@@ -107,6 +107,7 @@ static struct {
|
||||
jmethodID getLongPressTimeout;
|
||||
jmethodID getPointerLayer;
|
||||
jmethodID getPointerIcon;
|
||||
jmethodID getPointerDisplayId;
|
||||
jmethodID getKeyboardLayoutOverlay;
|
||||
jmethodID getDeviceAlias;
|
||||
jmethodID getTouchCalibrationForInputDevice;
|
||||
@@ -174,15 +175,6 @@ static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t styl
|
||||
loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
|
||||
}
|
||||
|
||||
static void updatePointerControllerFromViewport(
|
||||
sp<PointerController> controller, const DisplayViewport* const viewport) {
|
||||
if (controller != nullptr && viewport != nullptr) {
|
||||
const int32_t width = viewport->logicalRight - viewport->logicalLeft;
|
||||
const int32_t height = viewport->logicalBottom - viewport->logicalTop;
|
||||
controller->setDisplayViewport(width, height, viewport->orientation);
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
WM_ACTION_PASS_TO_USER = 1,
|
||||
};
|
||||
@@ -310,14 +302,19 @@ private:
|
||||
|
||||
// Input devices to be disabled
|
||||
SortedVector<int32_t> disabledInputDevices;
|
||||
|
||||
// Associated Pointer controller display.
|
||||
int32_t pointerDisplayId;
|
||||
} mLocked GUARDED_BY(mLock);
|
||||
|
||||
std::atomic<bool> mInteractive;
|
||||
|
||||
void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
|
||||
void updateInactivityTimeoutLocked();
|
||||
void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
|
||||
void ensureSpriteControllerLocked();
|
||||
|
||||
const DisplayViewport* findDisplayViewportLocked(int32_t displayId);
|
||||
int32_t getPointerDisplayId();
|
||||
void updatePointerDisplayLocked();
|
||||
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
|
||||
|
||||
static inline JNIEnv* jniEnv() {
|
||||
@@ -342,6 +339,7 @@ NativeInputManager::NativeInputManager(jobject contextObj,
|
||||
mLocked.pointerGesturesEnabled = true;
|
||||
mLocked.showTouches = false;
|
||||
mLocked.pointerCapture = false;
|
||||
mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
|
||||
}
|
||||
mInteractive = true;
|
||||
|
||||
@@ -391,9 +389,10 @@ bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const c
|
||||
return false;
|
||||
}
|
||||
|
||||
static const DisplayViewport* findInternalViewport(const std::vector<DisplayViewport>& viewports) {
|
||||
for (const DisplayViewport& v : viewports) {
|
||||
if (v.type == ViewportType::VIEWPORT_INTERNAL) {
|
||||
const DisplayViewport* NativeInputManager::findDisplayViewportLocked(int32_t displayId)
|
||||
REQUIRES(mLock) {
|
||||
for (const DisplayViewport& v : mLocked.viewports) {
|
||||
if (v.displayId == displayId) {
|
||||
return &v;
|
||||
}
|
||||
}
|
||||
@@ -420,20 +419,14 @@ void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportO
|
||||
}
|
||||
}
|
||||
|
||||
const DisplayViewport* newInternalViewport = findInternalViewport(viewports);
|
||||
{
|
||||
// Get the preferred pointer controller displayId.
|
||||
int32_t pointerDisplayId = getPointerDisplayId();
|
||||
|
||||
{ // acquire lock
|
||||
AutoMutex _l(mLock);
|
||||
const DisplayViewport* oldInternalViewport = findInternalViewport(mLocked.viewports);
|
||||
// Internal viewport has changed if there wasn't one earlier, and there is one now, or,
|
||||
// if they are different.
|
||||
const bool internalViewportChanged = (newInternalViewport != nullptr) &&
|
||||
(oldInternalViewport == nullptr || (*oldInternalViewport != *newInternalViewport));
|
||||
if (internalViewportChanged) {
|
||||
sp<PointerController> controller = mLocked.pointerController.promote();
|
||||
updatePointerControllerFromViewport(controller, newInternalViewport);
|
||||
}
|
||||
mLocked.viewports = viewports;
|
||||
}
|
||||
mLocked.pointerDisplayId = pointerDisplayId;
|
||||
} // release lock
|
||||
|
||||
mInputManager->getReader()->requestRefreshConfiguration(
|
||||
InputReaderConfiguration::CHANGE_DISPLAY_INFO);
|
||||
@@ -556,15 +549,42 @@ sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32
|
||||
|
||||
controller = new PointerController(this, mLooper, mLocked.spriteController);
|
||||
mLocked.pointerController = controller;
|
||||
|
||||
const DisplayViewport* internalViewport = findInternalViewport(mLocked.viewports);
|
||||
updatePointerControllerFromViewport(controller, internalViewport);
|
||||
|
||||
updateInactivityTimeoutLocked(controller);
|
||||
updateInactivityTimeoutLocked();
|
||||
}
|
||||
|
||||
updatePointerDisplayLocked();
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
int32_t NativeInputManager::getPointerDisplayId() {
|
||||
JNIEnv* env = jniEnv();
|
||||
jint pointerDisplayId = env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.getPointerDisplayId);
|
||||
if (checkAndClearExceptionFromCallback(env, "getPointerDisplayId")) {
|
||||
pointerDisplayId = ADISPLAY_ID_DEFAULT;
|
||||
}
|
||||
|
||||
return pointerDisplayId;
|
||||
}
|
||||
|
||||
void NativeInputManager::updatePointerDisplayLocked() REQUIRES(mLock) {
|
||||
ATRACE_CALL();
|
||||
|
||||
sp<PointerController> controller = mLocked.pointerController.promote();
|
||||
if (controller != nullptr) {
|
||||
const DisplayViewport* viewport = findDisplayViewportLocked(mLocked.pointerDisplayId);
|
||||
if (viewport == nullptr) {
|
||||
ALOGW("Can't find pointer display viewport, fallback to default display.");
|
||||
viewport = findDisplayViewportLocked(ADISPLAY_ID_DEFAULT);
|
||||
}
|
||||
|
||||
if (viewport != nullptr) {
|
||||
controller->setDisplayViewport(*viewport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
|
||||
if (mLocked.spriteController == nullptr) {
|
||||
JNIEnv* env = jniEnv();
|
||||
@@ -821,16 +841,16 @@ void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
|
||||
|
||||
if (mLocked.systemUiVisibility != visibility) {
|
||||
mLocked.systemUiVisibility = visibility;
|
||||
|
||||
sp<PointerController> controller = mLocked.pointerController.promote();
|
||||
if (controller != nullptr) {
|
||||
updateInactivityTimeoutLocked(controller);
|
||||
}
|
||||
updateInactivityTimeoutLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller)
|
||||
REQUIRES(mLock) {
|
||||
void NativeInputManager::updateInactivityTimeoutLocked() REQUIRES(mLock) {
|
||||
sp<PointerController> controller = mLocked.pointerController.promote();
|
||||
if (controller == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
|
||||
controller->setInactivityTimeout(lightsOut
|
||||
? PointerController::INACTIVITY_TIMEOUT_SHORT
|
||||
@@ -1824,6 +1844,9 @@ int register_android_server_InputManager(JNIEnv* env) {
|
||||
GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
|
||||
"getPointerIcon", "()Landroid/view/PointerIcon;");
|
||||
|
||||
GET_METHOD_ID(gServiceClassInfo.getPointerDisplayId, clazz,
|
||||
"getPointerDisplayId", "()I");
|
||||
|
||||
GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
|
||||
"getKeyboardLayoutOverlay",
|
||||
"(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;");
|
||||
|
||||
Reference in New Issue
Block a user