Refactor input dispatcher use of window/app handles.
This change moves the cached window and application input state into the handle objects themselves. It simplifies the dispatcher somewhat because it no longer needs to fix up references to transient InputWindow objects each time the window list is updated. This change will also make it easier to optimize setInputWindows to avoid doing a lot of redundant data copying. In principle, only the modified fields need to be updated. However, for now we continue to update all fields in unison as before. It turns out that the input dispatcher was inappropriately retaining pointers to InputWindow objects within the mWindows InputWindow vector. This vector is copy-on-write so it is possible and the item pointers to change if an editing operation is performed on the vector when it does not exclusively own the underlying SharedBuffer. This bug was uncovered by a previous change that replaced calls to clear() and appendVector() with a simple use of operator= which caused the buffer to be shared. Consequently after editItemAt was called (which it shouldn't have, actually) the buffer was copied and the cached InputWindow pointers became invalid. Oops. This change fixes the problem. Change-Id: I0a259339a6015fcf9113dc4081a6875e047fd425
This commit is contained in:
@@ -26,26 +26,32 @@
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* A handle to an application that can receive input.
|
||||
* Used by the native input dispatcher to indirectly refer to the window manager objects
|
||||
* Describes the properties of an application that can receive input.
|
||||
*
|
||||
* Used by the native input dispatcher as a handle for the window manager objects
|
||||
* that describe an application.
|
||||
*/
|
||||
class InputApplicationHandle : public RefBase {
|
||||
public:
|
||||
String8 name;
|
||||
nsecs_t dispatchingTimeout;
|
||||
|
||||
/**
|
||||
* Requests that the state of this object be updated to reflect
|
||||
* the most current available information about the application.
|
||||
*
|
||||
* This method should only be called from within the input dispatcher's
|
||||
* critical section.
|
||||
*
|
||||
* Returns true on success, or false if the handle is no longer valid.
|
||||
*/
|
||||
virtual bool update() = 0;
|
||||
|
||||
protected:
|
||||
InputApplicationHandle() { }
|
||||
virtual ~InputApplicationHandle() { }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An input application describes properties of an application that can receive input.
|
||||
*/
|
||||
struct InputApplication {
|
||||
sp<InputApplicationHandle> inputApplicationHandle;
|
||||
String8 name;
|
||||
nsecs_t dispatchingTimeout;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_INPUT_APPLICATION_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -321,13 +321,14 @@ public:
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual void setInputWindows(const Vector<InputWindow>& inputWindows) = 0;
|
||||
virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) = 0;
|
||||
|
||||
/* Sets the focused application.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual void setFocusedApplication(const InputApplication* inputApplication) = 0;
|
||||
virtual void setFocusedApplication(
|
||||
const sp<InputApplicationHandle>& inputApplicationHandle) = 0;
|
||||
|
||||
/* Sets the input dispatching mode.
|
||||
*
|
||||
@@ -406,8 +407,8 @@ public:
|
||||
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
|
||||
uint32_t policyFlags);
|
||||
|
||||
virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
|
||||
virtual void setFocusedApplication(const InputApplication* inputApplication);
|
||||
virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
|
||||
virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
|
||||
virtual void setInputDispatchMode(bool enabled, bool frozen);
|
||||
virtual void setInputFilterEnabled(bool enabled);
|
||||
|
||||
@@ -578,7 +579,6 @@ private:
|
||||
sp<Connection> connection;
|
||||
nsecs_t eventTime;
|
||||
KeyEntry* keyEntry;
|
||||
sp<InputChannel> inputChannel;
|
||||
sp<InputApplicationHandle> inputApplicationHandle;
|
||||
sp<InputWindowHandle> inputWindowHandle;
|
||||
int32_t userActivityEventType;
|
||||
@@ -894,7 +894,7 @@ private:
|
||||
// to transfer focus to a new application.
|
||||
EventEntry* mNextUnblockedEvent;
|
||||
|
||||
const InputWindow* findTouchedWindowAtLocked(int32_t x, int32_t y);
|
||||
sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t x, int32_t y);
|
||||
|
||||
// All registered connections mapped by receive pipe file descriptor.
|
||||
KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
|
||||
@@ -953,19 +953,19 @@ private:
|
||||
bool mDispatchFrozen;
|
||||
bool mInputFilterEnabled;
|
||||
|
||||
Vector<InputWindow> mWindows;
|
||||
Vector<sp<InputWindowHandle> > mWindowHandles;
|
||||
|
||||
const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel);
|
||||
sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
|
||||
bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
|
||||
|
||||
// Focus tracking for keys, trackball, etc.
|
||||
const InputWindow* mFocusedWindow;
|
||||
sp<InputWindowHandle> mFocusedWindowHandle;
|
||||
|
||||
// Focus tracking for touch.
|
||||
struct TouchedWindow {
|
||||
const InputWindow* window;
|
||||
sp<InputWindowHandle> windowHandle;
|
||||
int32_t targetFlags;
|
||||
BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
|
||||
sp<InputChannel> channel;
|
||||
};
|
||||
struct TouchState {
|
||||
bool down;
|
||||
@@ -978,9 +978,10 @@ private:
|
||||
~TouchState();
|
||||
void reset();
|
||||
void copyFrom(const TouchState& other);
|
||||
void addOrUpdateWindow(const InputWindow* window,int32_t targetFlags, BitSet32 pointerIds);
|
||||
void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
|
||||
int32_t targetFlags, BitSet32 pointerIds);
|
||||
void filterNonAsIsTouchWindows();
|
||||
const InputWindow* getFirstForegroundWindow() const;
|
||||
sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
|
||||
bool isSlippery() const;
|
||||
};
|
||||
|
||||
@@ -988,9 +989,7 @@ private:
|
||||
TouchState mTempTouchState;
|
||||
|
||||
// Focused application.
|
||||
InputApplication* mFocusedApplication;
|
||||
InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication
|
||||
void releaseFocusedApplicationLocked();
|
||||
sp<InputApplicationHandle> mFocusedApplicationHandle;
|
||||
|
||||
// Dispatch inbound events.
|
||||
bool dispatchConfigurationChangedLocked(
|
||||
@@ -1021,16 +1020,17 @@ private:
|
||||
nsecs_t mInputTargetWaitStartTime;
|
||||
nsecs_t mInputTargetWaitTimeoutTime;
|
||||
bool mInputTargetWaitTimeoutExpired;
|
||||
sp<InputApplicationHandle> mInputTargetWaitApplication;
|
||||
sp<InputApplicationHandle> mInputTargetWaitApplicationHandle;
|
||||
|
||||
// Contains the last window which received a hover event.
|
||||
const InputWindow* mLastHoverWindow;
|
||||
sp<InputWindowHandle> mLastHoverWindowHandle;
|
||||
|
||||
// Finding targets for input events.
|
||||
void resetTargetsLocked();
|
||||
void commitTargetsLocked();
|
||||
int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
|
||||
const InputApplication* application, const InputWindow* window,
|
||||
const sp<InputApplicationHandle>& applicationHandle,
|
||||
const sp<InputWindowHandle>& windowHandle,
|
||||
nsecs_t* nextWakeupTime);
|
||||
void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
|
||||
const sp<InputChannel>& inputChannel);
|
||||
@@ -1043,15 +1043,17 @@ private:
|
||||
nsecs_t* nextWakeupTime, bool* outConflictingPointerActions,
|
||||
const MotionSample** outSplitBatchAfterSample);
|
||||
|
||||
void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
|
||||
BitSet32 pointerIds);
|
||||
void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
|
||||
int32_t targetFlags, BitSet32 pointerIds);
|
||||
void addMonitoringTargetsLocked();
|
||||
void pokeUserActivityLocked(const EventEntry* eventEntry);
|
||||
bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
|
||||
bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const;
|
||||
bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
|
||||
String8 getApplicationWindowLabelLocked(const InputApplication* application,
|
||||
const InputWindow* window);
|
||||
bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
|
||||
const InjectionState* injectionState);
|
||||
bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
|
||||
int32_t x, int32_t y) const;
|
||||
bool isWindowFinishedWithPreviousInputLocked(const sp<InputWindowHandle>& windowHandle);
|
||||
String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
|
||||
const sp<InputWindowHandle>& windowHandle);
|
||||
|
||||
// Manage the dispatch cycle for a single connection.
|
||||
// These methods are deliberately not Interruptible because doing all of the work
|
||||
@@ -1100,7 +1102,8 @@ private:
|
||||
void onDispatchCycleBrokenLocked(
|
||||
nsecs_t currentTime, const sp<Connection>& connection);
|
||||
void onANRLocked(
|
||||
nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
|
||||
nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
|
||||
const sp<InputWindowHandle>& windowHandle,
|
||||
nsecs_t eventTime, nsecs_t waitStartTime);
|
||||
|
||||
// Outbound policy interactions.
|
||||
|
||||
@@ -22,25 +22,25 @@
|
||||
|
||||
namespace android {
|
||||
|
||||
// --- InputWindow ---
|
||||
// --- InputWindowHandle ---
|
||||
|
||||
bool InputWindow::touchableRegionContainsPoint(int32_t x, int32_t y) const {
|
||||
bool InputWindowHandle::touchableRegionContainsPoint(int32_t x, int32_t y) const {
|
||||
return touchableRegion.contains(x, y);
|
||||
}
|
||||
|
||||
bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
|
||||
bool InputWindowHandle::frameContainsPoint(int32_t x, int32_t y) const {
|
||||
return x >= frameLeft && x <= frameRight
|
||||
&& y >= frameTop && y <= frameBottom;
|
||||
}
|
||||
|
||||
bool InputWindow::isTrustedOverlay() const {
|
||||
bool InputWindowHandle::isTrustedOverlay() const {
|
||||
return layoutParamsType == TYPE_INPUT_METHOD
|
||||
|| layoutParamsType == TYPE_INPUT_METHOD_DIALOG
|
||||
|| layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
|
||||
}
|
||||
|
||||
bool InputWindow::supportsSplitTouch() const {
|
||||
return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH;
|
||||
bool InputWindowHandle::supportsSplitTouch() const {
|
||||
return layoutParamsFlags & FLAG_SPLIT_TOUCH;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -31,29 +31,14 @@ namespace android {
|
||||
|
||||
/*
|
||||
* A handle to a window that can receive input.
|
||||
*
|
||||
* Used by the native input dispatcher to indirectly refer to the window manager objects
|
||||
* that describe a window.
|
||||
*/
|
||||
class InputWindowHandle : public RefBase {
|
||||
protected:
|
||||
InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
|
||||
mInputApplicationHandle(inputApplicationHandle) { }
|
||||
virtual ~InputWindowHandle() { }
|
||||
|
||||
public:
|
||||
inline sp<InputApplicationHandle> getInputApplicationHandle() {
|
||||
return mInputApplicationHandle;
|
||||
}
|
||||
const sp<InputApplicationHandle> inputApplicationHandle;
|
||||
|
||||
private:
|
||||
sp<InputApplicationHandle> mInputApplicationHandle;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An input window describes the bounds of a window that can receive input.
|
||||
*/
|
||||
struct InputWindow {
|
||||
// Window flags from WindowManager.LayoutParams
|
||||
enum {
|
||||
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,
|
||||
@@ -164,6 +149,22 @@ struct InputWindow {
|
||||
bool isTrustedOverlay() const;
|
||||
|
||||
bool supportsSplitTouch() const;
|
||||
|
||||
/**
|
||||
* Requests that the state of this object be updated to reflect
|
||||
* the most current available information about the application.
|
||||
*
|
||||
* This method should only be called from within the input dispatcher's
|
||||
* critical section.
|
||||
*
|
||||
* Returns true on success, or false if the handle is no longer valid.
|
||||
*/
|
||||
virtual bool update() = 0;
|
||||
|
||||
protected:
|
||||
InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
|
||||
inputApplicationHandle(inputApplicationHandle) { }
|
||||
virtual ~InputWindowHandle() { }
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -369,11 +369,12 @@ private:
|
||||
return INPUT_EVENT_INJECTION_FAILED;
|
||||
}
|
||||
|
||||
virtual void setInputWindows(const Vector<InputWindow>& inputWindows) {
|
||||
virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
|
||||
ADD_FAILURE() << "Should never be called by input reader.";
|
||||
}
|
||||
|
||||
virtual void setFocusedApplication(const InputApplication* inputApplication) {
|
||||
virtual void setFocusedApplication(
|
||||
const sp<InputApplicationHandle>& inputApplicationHandle) {
|
||||
ADD_FAILURE() << "Should never be called by input reader.";
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ class AppWindowToken extends WindowToken {
|
||||
boolean firstWindowDrawn;
|
||||
|
||||
// Input application handle used by the input dispatcher.
|
||||
InputApplicationHandle mInputApplicationHandle;
|
||||
final InputApplicationHandle mInputApplicationHandle;
|
||||
|
||||
AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
|
||||
super(_service, _token.asBinder(),
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
|
||||
/**
|
||||
* Describes input-related application properties for use by the input dispatcher.
|
||||
* @hide
|
||||
*/
|
||||
public final class InputApplication {
|
||||
// Application handle.
|
||||
public InputApplicationHandle inputApplicationHandle;
|
||||
|
||||
// Application name.
|
||||
public String name;
|
||||
|
||||
// Dispatching timeout.
|
||||
public long dispatchingTimeoutNanos;
|
||||
|
||||
public void recycle() {
|
||||
inputApplicationHandle = null;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,12 @@ public final class InputApplicationHandle {
|
||||
// The window manager's application window token.
|
||||
public final AppWindowToken appWindowToken;
|
||||
|
||||
// Application name.
|
||||
public String name;
|
||||
|
||||
// Dispatching timeout.
|
||||
public long dispatchingTimeoutNanos;
|
||||
|
||||
private native void nativeDispose();
|
||||
|
||||
public InputApplicationHandle(AppWindowToken appWindowToken) {
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.os.SystemProperties;
|
||||
@@ -83,10 +82,10 @@ public class InputManager {
|
||||
private static native int nativeInjectInputEvent(InputEvent event,
|
||||
int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
|
||||
int policyFlags);
|
||||
private static native void nativeSetInputWindows(InputWindow[] windows);
|
||||
private static native void nativeSetInputWindows(InputWindowHandle[] windowHandles);
|
||||
private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
|
||||
private static native void nativeSetSystemUiVisibility(int visibility);
|
||||
private static native void nativeSetFocusedApplication(InputApplication application);
|
||||
private static native void nativeSetFocusedApplication(InputApplicationHandle application);
|
||||
private static native InputDevice nativeGetInputDevice(int deviceId);
|
||||
private static native void nativeGetInputConfiguration(Configuration configuration);
|
||||
private static native int[] nativeGetInputDeviceIds();
|
||||
@@ -372,11 +371,11 @@ public class InputManager {
|
||||
return nativeGetInputDeviceIds();
|
||||
}
|
||||
|
||||
public void setInputWindows(InputWindow[] windows) {
|
||||
nativeSetInputWindows(windows);
|
||||
public void setInputWindows(InputWindowHandle[] windowHandles) {
|
||||
nativeSetInputWindows(windowHandles);
|
||||
}
|
||||
|
||||
public void setFocusedApplication(InputApplication application) {
|
||||
public void setFocusedApplication(InputApplicationHandle application) {
|
||||
nativeSetFocusedApplication(application);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
@@ -26,6 +25,7 @@ import android.view.KeyEvent;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
final class InputMonitor {
|
||||
private final WindowManagerService mService;
|
||||
@@ -42,12 +42,14 @@ final class InputMonitor {
|
||||
// When true, need to call updateInputWindowsLw().
|
||||
private boolean mUpdateInputWindowsNeeded = true;
|
||||
|
||||
// Temporary list of windows information to provide to the input dispatcher.
|
||||
private InputWindowList mTempInputWindows = new InputWindowList();
|
||||
|
||||
// Temporary input application object to provide to the input dispatcher.
|
||||
private InputApplication mTempInputApplication = new InputApplication();
|
||||
|
||||
// Fake handles for the drag surface, lazily initialized.
|
||||
private InputApplicationHandle mDragApplicationHandle;
|
||||
private InputWindowHandle mDragWindowHandle;
|
||||
|
||||
// Array of window handles to provide to the input dispatcher.
|
||||
private InputWindowHandle[] mInputWindowHandles;
|
||||
private int mInputWindowHandleCount;
|
||||
|
||||
// Set to true when the first input device configuration change notification
|
||||
// is received to indicate that the input devices are ready.
|
||||
private final Object mInputDevicesReadyMonitor = new Object();
|
||||
@@ -68,8 +70,10 @@ final class InputMonitor {
|
||||
|
||||
synchronized (mService.mWindowMap) {
|
||||
WindowState windowState = (WindowState) inputWindowHandle.windowState;
|
||||
Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
|
||||
mService.removeWindowLocked(windowState.mSession, windowState);
|
||||
if (windowState != null) {
|
||||
Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
|
||||
mService.removeWindowLocked(windowState.mSession, windowState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +98,11 @@ final class InputMonitor {
|
||||
|
||||
if (appWindowToken == null && inputApplicationHandle != null) {
|
||||
appWindowToken = inputApplicationHandle.appWindowToken;
|
||||
Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to application "
|
||||
+ appWindowToken.stringName);
|
||||
if (appWindowToken != null) {
|
||||
Slog.i(WindowManagerService.TAG,
|
||||
"Input event dispatching timed out sending to application "
|
||||
+ appWindowToken.stringName);
|
||||
}
|
||||
}
|
||||
|
||||
if (appWindowToken != null && appWindowToken.appToken != null) {
|
||||
@@ -114,32 +121,59 @@ final class InputMonitor {
|
||||
return 0; // abort dispatching
|
||||
}
|
||||
|
||||
private void addDragInputWindowLw(InputWindowList windowList) {
|
||||
final InputWindow inputWindow = windowList.add();
|
||||
inputWindow.inputChannel = mService.mDragState.mServerChannel;
|
||||
inputWindow.name = "drag";
|
||||
inputWindow.layoutParamsFlags = 0;
|
||||
inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
|
||||
inputWindow.dispatchingTimeoutNanos = WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
|
||||
inputWindow.visible = true;
|
||||
inputWindow.canReceiveKeys = false;
|
||||
inputWindow.hasFocus = true;
|
||||
inputWindow.hasWallpaper = false;
|
||||
inputWindow.paused = false;
|
||||
inputWindow.layer = mService.mDragState.getDragLayerLw();
|
||||
inputWindow.ownerPid = Process.myPid();
|
||||
inputWindow.ownerUid = Process.myUid();
|
||||
inputWindow.inputFeatures = 0;
|
||||
inputWindow.scaleFactor = 1.0f;
|
||||
private void addDragInputWindowLw() {
|
||||
if (mDragWindowHandle == null) {
|
||||
mDragApplicationHandle = new InputApplicationHandle(null);
|
||||
mDragApplicationHandle.name = "drag";
|
||||
mDragApplicationHandle.dispatchingTimeoutNanos =
|
||||
WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
|
||||
|
||||
mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null);
|
||||
mDragWindowHandle.name = "drag";
|
||||
mDragWindowHandle.layoutParamsFlags = 0;
|
||||
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
|
||||
mDragWindowHandle.dispatchingTimeoutNanos =
|
||||
WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
|
||||
mDragWindowHandle.visible = true;
|
||||
mDragWindowHandle.canReceiveKeys = false;
|
||||
mDragWindowHandle.hasFocus = true;
|
||||
mDragWindowHandle.hasWallpaper = false;
|
||||
mDragWindowHandle.paused = false;
|
||||
mDragWindowHandle.ownerPid = Process.myPid();
|
||||
mDragWindowHandle.ownerUid = Process.myUid();
|
||||
mDragWindowHandle.inputFeatures = 0;
|
||||
mDragWindowHandle.scaleFactor = 1.0f;
|
||||
|
||||
// The drag window cannot receive new touches.
|
||||
mDragWindowHandle.touchableRegion.setEmpty();
|
||||
}
|
||||
|
||||
mDragWindowHandle.layer = mService.mDragState.getDragLayerLw();
|
||||
|
||||
// The drag window covers the entire display
|
||||
inputWindow.frameLeft = 0;
|
||||
inputWindow.frameTop = 0;
|
||||
inputWindow.frameRight = mService.mDisplay.getRealWidth();
|
||||
inputWindow.frameBottom = mService.mDisplay.getRealHeight();
|
||||
mDragWindowHandle.frameLeft = 0;
|
||||
mDragWindowHandle.frameTop = 0;
|
||||
mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth();
|
||||
mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight();
|
||||
|
||||
// The drag window cannot receive new touches.
|
||||
inputWindow.touchableRegion.setEmpty();
|
||||
addInputWindowHandleLw(mDragWindowHandle);
|
||||
}
|
||||
|
||||
private void addInputWindowHandleLw(InputWindowHandle windowHandle) {
|
||||
if (mInputWindowHandles == null) {
|
||||
mInputWindowHandles = new InputWindowHandle[16];
|
||||
}
|
||||
if (mInputWindowHandleCount >= mInputWindowHandles.length) {
|
||||
mInputWindowHandles = Arrays.copyOf(mInputWindowHandles,
|
||||
mInputWindowHandleCount * 2);
|
||||
}
|
||||
mInputWindowHandles[mInputWindowHandleCount++] = windowHandle;
|
||||
}
|
||||
|
||||
private void clearInputWindowHandlesLw() {
|
||||
while (mInputWindowHandleCount != 0) {
|
||||
mInputWindowHandles[--mInputWindowHandleCount] = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setUpdateInputWindowsNeededLw() {
|
||||
@@ -154,7 +188,7 @@ final class InputMonitor {
|
||||
mUpdateInputWindowsNeeded = false;
|
||||
|
||||
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED updateInputWindowsLw");
|
||||
|
||||
|
||||
// Populate the input window list with information about all of the windows that
|
||||
// could potentially receive input.
|
||||
// As an optimization, we could try to prune the list of windows but this turns
|
||||
@@ -168,7 +202,7 @@ final class InputMonitor {
|
||||
if (WindowManagerService.DEBUG_DRAG) {
|
||||
Log.d(WindowManagerService.TAG, "Inserting drag window");
|
||||
}
|
||||
addDragInputWindowLw(mTempInputWindows);
|
||||
addDragInputWindowLw();
|
||||
}
|
||||
|
||||
final int N = windows.size();
|
||||
@@ -194,48 +228,48 @@ final class InputMonitor {
|
||||
}
|
||||
|
||||
// Add a window to our list of input windows.
|
||||
final InputWindow inputWindow = mTempInputWindows.add();
|
||||
inputWindow.inputWindowHandle = child.mInputWindowHandle;
|
||||
inputWindow.inputChannel = child.mInputChannel;
|
||||
inputWindow.name = child.toString();
|
||||
inputWindow.layoutParamsFlags = flags;
|
||||
inputWindow.layoutParamsType = type;
|
||||
inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
|
||||
inputWindow.visible = isVisible;
|
||||
inputWindow.canReceiveKeys = child.canReceiveKeys();
|
||||
inputWindow.hasFocus = hasFocus;
|
||||
inputWindow.hasWallpaper = hasWallpaper;
|
||||
inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
|
||||
inputWindow.layer = child.mLayer;
|
||||
inputWindow.ownerPid = child.mSession.mPid;
|
||||
inputWindow.ownerUid = child.mSession.mUid;
|
||||
inputWindow.inputFeatures = child.mAttrs.inputFeatures;
|
||||
final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
|
||||
inputWindowHandle.inputChannel = child.mInputChannel;
|
||||
inputWindowHandle.name = child.toString();
|
||||
inputWindowHandle.layoutParamsFlags = flags;
|
||||
inputWindowHandle.layoutParamsType = type;
|
||||
inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
|
||||
inputWindowHandle.visible = isVisible;
|
||||
inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
|
||||
inputWindowHandle.hasFocus = hasFocus;
|
||||
inputWindowHandle.hasWallpaper = hasWallpaper;
|
||||
inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
|
||||
inputWindowHandle.layer = child.mLayer;
|
||||
inputWindowHandle.ownerPid = child.mSession.mPid;
|
||||
inputWindowHandle.ownerUid = child.mSession.mUid;
|
||||
inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
|
||||
|
||||
final Rect frame = child.mFrame;
|
||||
inputWindow.frameLeft = frame.left;
|
||||
inputWindow.frameTop = frame.top;
|
||||
inputWindow.frameRight = frame.right;
|
||||
inputWindow.frameBottom = frame.bottom;
|
||||
inputWindowHandle.frameLeft = frame.left;
|
||||
inputWindowHandle.frameTop = frame.top;
|
||||
inputWindowHandle.frameRight = frame.right;
|
||||
inputWindowHandle.frameBottom = frame.bottom;
|
||||
|
||||
if (child.mGlobalScale != 1) {
|
||||
// If we are scaling the window, input coordinates need
|
||||
// to be inversely scaled to map from what is on screen
|
||||
// to what is actually being touched in the UI.
|
||||
inputWindow.scaleFactor = 1.0f/child.mGlobalScale;
|
||||
inputWindowHandle.scaleFactor = 1.0f/child.mGlobalScale;
|
||||
} else {
|
||||
inputWindow.scaleFactor = 1;
|
||||
inputWindowHandle.scaleFactor = 1;
|
||||
}
|
||||
|
||||
child.getTouchableRegion(inputWindow.touchableRegion);
|
||||
child.getTouchableRegion(inputWindowHandle.touchableRegion);
|
||||
|
||||
addInputWindowHandleLw(inputWindowHandle);
|
||||
}
|
||||
|
||||
// Send windows to native code.
|
||||
mService.mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
|
||||
|
||||
mService.mInputManager.setInputWindows(mInputWindowHandles);
|
||||
|
||||
// Clear the list in preparation for the next round.
|
||||
// Also avoids keeping InputChannel objects referenced unnecessarily.
|
||||
mTempInputWindows.clear();
|
||||
|
||||
clearInputWindowHandlesLw();
|
||||
|
||||
if (false) Slog.d(WindowManagerService.TAG, "<<<<<<< EXITED updateInputWindowsLw");
|
||||
}
|
||||
|
||||
@@ -329,14 +363,11 @@ final class InputMonitor {
|
||||
if (newApp == null) {
|
||||
mService.mInputManager.setFocusedApplication(null);
|
||||
} else {
|
||||
mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
|
||||
mTempInputApplication.name = newApp.toString();
|
||||
mTempInputApplication.dispatchingTimeoutNanos =
|
||||
newApp.inputDispatchingTimeoutNanos;
|
||||
final InputApplicationHandle handle = newApp.mInputApplicationHandle;
|
||||
handle.name = newApp.toString();
|
||||
handle.dispatchingTimeoutNanos = newApp.inputDispatchingTimeoutNanos;
|
||||
|
||||
mService.mInputManager.setFocusedApplication(mTempInputApplication);
|
||||
|
||||
mTempInputApplication.recycle();
|
||||
mService.mInputManager.setFocusedApplication(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import android.graphics.Region;
|
||||
import android.view.InputChannel;
|
||||
|
||||
/**
|
||||
* Describes input-related window properties for use by the input dispatcher.
|
||||
* @hide
|
||||
*/
|
||||
public final class InputWindow {
|
||||
// The window handle.
|
||||
public InputWindowHandle inputWindowHandle;
|
||||
|
||||
// The input channel associated with the window.
|
||||
public InputChannel inputChannel;
|
||||
|
||||
// The window name.
|
||||
public String name;
|
||||
|
||||
// Window layout params attributes. (WindowManager.LayoutParams)
|
||||
public int layoutParamsFlags;
|
||||
public int layoutParamsType;
|
||||
|
||||
// Dispatching timeout.
|
||||
public long dispatchingTimeoutNanos;
|
||||
|
||||
// Window frame.
|
||||
public int frameLeft;
|
||||
public int frameTop;
|
||||
public int frameRight;
|
||||
public int frameBottom;
|
||||
|
||||
// Global scaling factor applied to touch events when they are dispatched
|
||||
// to the window
|
||||
public float scaleFactor;
|
||||
|
||||
// Window touchable region.
|
||||
public final Region touchableRegion = new Region();
|
||||
|
||||
// Window is visible.
|
||||
public boolean visible;
|
||||
|
||||
// Window can receive keys.
|
||||
public boolean canReceiveKeys;
|
||||
|
||||
// Window has focus.
|
||||
public boolean hasFocus;
|
||||
|
||||
// Window has wallpaper. (window is the current wallpaper target)
|
||||
public boolean hasWallpaper;
|
||||
|
||||
// Input event dispatching is paused.
|
||||
public boolean paused;
|
||||
|
||||
// Window layer.
|
||||
public int layer;
|
||||
|
||||
// Id of process and user that owns the window.
|
||||
public int ownerPid;
|
||||
public int ownerUid;
|
||||
|
||||
// Window input features.
|
||||
public int inputFeatures;
|
||||
|
||||
public void recycle() {
|
||||
inputWindowHandle = null;
|
||||
inputChannel = null;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import android.graphics.Region;
|
||||
import android.view.InputChannel;
|
||||
import android.view.WindowManagerPolicy;
|
||||
|
||||
/**
|
||||
@@ -35,6 +37,57 @@ public final class InputWindowHandle {
|
||||
// The window manager's window state.
|
||||
public final WindowManagerPolicy.WindowState windowState;
|
||||
|
||||
// The input channel associated with the window.
|
||||
public InputChannel inputChannel;
|
||||
|
||||
// The window name.
|
||||
public String name;
|
||||
|
||||
// Window layout params attributes. (WindowManager.LayoutParams)
|
||||
public int layoutParamsFlags;
|
||||
public int layoutParamsType;
|
||||
|
||||
// Dispatching timeout.
|
||||
public long dispatchingTimeoutNanos;
|
||||
|
||||
// Window frame.
|
||||
public int frameLeft;
|
||||
public int frameTop;
|
||||
public int frameRight;
|
||||
public int frameBottom;
|
||||
|
||||
// Global scaling factor applied to touch events when they are dispatched
|
||||
// to the window
|
||||
public float scaleFactor;
|
||||
|
||||
// Window touchable region.
|
||||
public final Region touchableRegion = new Region();
|
||||
|
||||
// Window is visible.
|
||||
public boolean visible;
|
||||
|
||||
// Window can receive keys.
|
||||
public boolean canReceiveKeys;
|
||||
|
||||
// Window has focus.
|
||||
public boolean hasFocus;
|
||||
|
||||
// Window has wallpaper. (window is the current wallpaper target)
|
||||
public boolean hasWallpaper;
|
||||
|
||||
// Input event dispatching is paused.
|
||||
public boolean paused;
|
||||
|
||||
// Window layer.
|
||||
public int layer;
|
||||
|
||||
// Id of process and user that owns the window.
|
||||
public int ownerPid;
|
||||
public int ownerUid;
|
||||
|
||||
// Window input features.
|
||||
public int inputFeatures;
|
||||
|
||||
private native void nativeDispose();
|
||||
|
||||
public InputWindowHandle(InputApplicationHandle inputApplicationHandle,
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
|
||||
/**
|
||||
* A specialized list of window information objects backed by an array.
|
||||
*
|
||||
* This class is part of an InputManager optimization to avoid allocating objects and arrays
|
||||
* unnecessarily. Internally, it keeps an array full of demand-allocated objects that it
|
||||
* recycles each time the list is cleared. The used portion of the array is padded with a null.
|
||||
*
|
||||
* The contents of the list are intended to be Z-ordered from top to bottom.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class InputWindowList {
|
||||
private InputWindow[] mArray;
|
||||
private int mCount;
|
||||
|
||||
/**
|
||||
* Creates an empty list.
|
||||
*/
|
||||
public InputWindowList() {
|
||||
mArray = new InputWindow[8];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the list.
|
||||
*/
|
||||
public void clear() {
|
||||
if (mCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = mCount;
|
||||
mCount = 0;
|
||||
mArray[count] = mArray[0];
|
||||
while (count > 0) {
|
||||
count -= 1;
|
||||
mArray[count].recycle();
|
||||
}
|
||||
mArray[0] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an uninitialized input window object to the list and returns it.
|
||||
*/
|
||||
public InputWindow add() {
|
||||
if (mCount + 1 == mArray.length) {
|
||||
InputWindow[] oldArray = mArray;
|
||||
mArray = new InputWindow[oldArray.length * 2];
|
||||
System.arraycopy(oldArray, 0, mArray, 0, mCount);
|
||||
}
|
||||
|
||||
// Grab object from tail (after used section) if available.
|
||||
InputWindow item = mArray[mCount + 1];
|
||||
if (item == null) {
|
||||
item = new InputWindow();
|
||||
}
|
||||
|
||||
mArray[mCount] = item;
|
||||
mCount += 1;
|
||||
mArray[mCount] = null;
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input window objects as a null-terminated array.
|
||||
* @return The input window array.
|
||||
*/
|
||||
public InputWindow[] toNullTerminatedArray() {
|
||||
return mArray;
|
||||
}
|
||||
}
|
||||
@@ -272,7 +272,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
float mSurfaceAlpha;
|
||||
|
||||
// Input channel and input window handle used by the input dispatcher.
|
||||
InputWindowHandle mInputWindowHandle;
|
||||
final InputWindowHandle mInputWindowHandle;
|
||||
InputChannel mInputChannel;
|
||||
|
||||
// Used to improve performance of toString()
|
||||
@@ -306,6 +306,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
mIsFloatingLayer = false;
|
||||
mBaseLayer = 0;
|
||||
mSubLayer = 0;
|
||||
mInputWindowHandle = null;
|
||||
return;
|
||||
}
|
||||
mDeathRecipient = deathRecipient;
|
||||
|
||||
@@ -4,10 +4,8 @@ include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES:= \
|
||||
com_android_server_AlarmManagerService.cpp \
|
||||
com_android_server_BatteryService.cpp \
|
||||
com_android_server_InputApplication.cpp \
|
||||
com_android_server_InputApplicationHandle.cpp \
|
||||
com_android_server_InputManager.cpp \
|
||||
com_android_server_InputWindow.cpp \
|
||||
com_android_server_InputWindowHandle.cpp \
|
||||
com_android_server_LightsService.cpp \
|
||||
com_android_server_PowerManagerService.cpp \
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "InputApplication"
|
||||
|
||||
#include "JNIHelp.h"
|
||||
#include "jni.h"
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include "com_android_server_InputApplication.h"
|
||||
#include "com_android_server_InputApplicationHandle.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static struct {
|
||||
jfieldID inputApplicationHandle;
|
||||
jfieldID name;
|
||||
jfieldID dispatchingTimeoutNanos;
|
||||
} gInputApplicationClassInfo;
|
||||
|
||||
|
||||
// --- Global functions ---
|
||||
|
||||
void android_server_InputApplication_toNative(
|
||||
JNIEnv* env, jobject inputApplicationObj, InputApplication* outInputApplication) {
|
||||
jobject inputApplicationHandleObj = env->GetObjectField(inputApplicationObj,
|
||||
gInputApplicationClassInfo.inputApplicationHandle);
|
||||
if (inputApplicationHandleObj) {
|
||||
outInputApplication->inputApplicationHandle =
|
||||
android_server_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
|
||||
env->DeleteLocalRef(inputApplicationHandleObj);
|
||||
} else {
|
||||
outInputApplication->inputApplicationHandle = NULL;
|
||||
}
|
||||
|
||||
jstring nameObj = jstring(env->GetObjectField(inputApplicationObj,
|
||||
gInputApplicationClassInfo.name));
|
||||
if (nameObj) {
|
||||
const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
|
||||
outInputApplication->name.setTo(nameStr);
|
||||
env->ReleaseStringUTFChars(nameObj, nameStr);
|
||||
env->DeleteLocalRef(nameObj);
|
||||
} else {
|
||||
LOGE("InputApplication.name should not be null.");
|
||||
outInputApplication->name.setTo("unknown");
|
||||
}
|
||||
|
||||
outInputApplication->dispatchingTimeout = env->GetLongField(inputApplicationObj,
|
||||
gInputApplicationClassInfo.dispatchingTimeoutNanos);
|
||||
}
|
||||
|
||||
|
||||
// --- JNI ---
|
||||
|
||||
#define FIND_CLASS(var, className) \
|
||||
var = env->FindClass(className); \
|
||||
LOG_FATAL_IF(! var, "Unable to find class " className);
|
||||
|
||||
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
|
||||
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
|
||||
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
|
||||
|
||||
int register_android_server_InputApplication(JNIEnv* env) {
|
||||
jclass clazz;
|
||||
FIND_CLASS(clazz, "com/android/server/wm/InputApplication");
|
||||
|
||||
GET_FIELD_ID(gInputApplicationClassInfo.inputApplicationHandle,
|
||||
clazz,
|
||||
"inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
|
||||
|
||||
GET_FIELD_ID(gInputApplicationClassInfo.name, clazz,
|
||||
"name", "Ljava/lang/String;");
|
||||
|
||||
GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
|
||||
clazz,
|
||||
"dispatchingTimeoutNanos", "J");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace android */
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_SERVER_INPUT_APPLICATION_H
|
||||
#define _ANDROID_SERVER_INPUT_APPLICATION_H
|
||||
|
||||
#include <input/InputApplication.h>
|
||||
|
||||
#include "JNIHelp.h"
|
||||
#include "jni.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
extern void android_server_InputApplication_toNative(
|
||||
JNIEnv* env, jobject inputApplicationObj, InputApplication* outInputApplication);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _ANDROID_SERVER_INPUT_APPLICATION_H
|
||||
@@ -27,6 +27,8 @@ namespace android {
|
||||
|
||||
static struct {
|
||||
jfieldID ptr;
|
||||
jfieldID name;
|
||||
jfieldID dispatchingTimeoutNanos;
|
||||
} gInputApplicationHandleClassInfo;
|
||||
|
||||
static Mutex gHandleMutex;
|
||||
@@ -47,6 +49,31 @@ jobject NativeInputApplicationHandle::getInputApplicationHandleObjLocalRef(JNIEn
|
||||
return env->NewLocalRef(mObjWeak);
|
||||
}
|
||||
|
||||
bool NativeInputApplicationHandle::update() {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
jobject obj = env->NewLocalRef(mObjWeak);
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jstring nameObj = jstring(env->GetObjectField(obj,
|
||||
gInputApplicationHandleClassInfo.name));
|
||||
if (nameObj) {
|
||||
const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
|
||||
name.setTo(nameStr);
|
||||
env->ReleaseStringUTFChars(nameObj, nameStr);
|
||||
env->DeleteLocalRef(nameObj);
|
||||
} else {
|
||||
name.setTo("<null>");
|
||||
}
|
||||
|
||||
dispatchingTimeout = env->GetLongField(obj,
|
||||
gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
|
||||
|
||||
env->DeleteLocalRef(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// --- Global functions ---
|
||||
|
||||
@@ -113,6 +140,13 @@ int register_android_server_InputApplicationHandle(JNIEnv* env) {
|
||||
GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
|
||||
"ptr", "I");
|
||||
|
||||
GET_FIELD_ID(gInputApplicationHandleClassInfo.name, clazz,
|
||||
"name", "Ljava/lang/String;");
|
||||
|
||||
GET_FIELD_ID(gInputApplicationHandleClassInfo.dispatchingTimeoutNanos,
|
||||
clazz,
|
||||
"dispatchingTimeoutNanos", "J");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ public:
|
||||
|
||||
jobject getInputApplicationHandleObjLocalRef(JNIEnv* env);
|
||||
|
||||
virtual bool update();
|
||||
|
||||
private:
|
||||
jweak mObjWeak;
|
||||
};
|
||||
|
||||
@@ -46,9 +46,7 @@
|
||||
#include <android/graphics/GraphicsJNI.h>
|
||||
|
||||
#include "com_android_server_PowerManagerService.h"
|
||||
#include "com_android_server_InputApplication.h"
|
||||
#include "com_android_server_InputApplicationHandle.h"
|
||||
#include "com_android_server_InputWindow.h"
|
||||
#include "com_android_server_InputWindowHandle.h"
|
||||
|
||||
namespace android {
|
||||
@@ -175,8 +173,8 @@ public:
|
||||
const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
|
||||
status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
|
||||
|
||||
void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
|
||||
void setFocusedApplication(JNIEnv* env, jobject applicationObj);
|
||||
void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray);
|
||||
void setFocusedApplication(JNIEnv* env, jobject applicationHandleObj);
|
||||
void setInputDispatchMode(bool enabled, bool frozen);
|
||||
void setSystemUiVisibility(int32_t visibility);
|
||||
void setPointerSpeed(int32_t speed);
|
||||
@@ -582,31 +580,38 @@ bool NativeInputManager::isKeyRepeatEnabled() {
|
||||
return isScreenOn();
|
||||
}
|
||||
|
||||
void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
|
||||
Vector<InputWindow> windows;
|
||||
void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray) {
|
||||
Vector<sp<InputWindowHandle> > windowHandles;
|
||||
|
||||
bool newPointerGesturesEnabled = true;
|
||||
jsize length = env->GetArrayLength(windowObjArray);
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
|
||||
if (! windowObj) {
|
||||
break; // found null element indicating end of used portion of the array
|
||||
}
|
||||
|
||||
windows.push();
|
||||
InputWindow& window = windows.editTop();
|
||||
android_server_InputWindow_toNative(env, windowObj, &window);
|
||||
if (window.inputChannel == NULL) {
|
||||
windows.pop();
|
||||
} else if (window.hasFocus) {
|
||||
if (window.inputFeatures & InputWindow::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES) {
|
||||
newPointerGesturesEnabled = false;
|
||||
if (windowHandleObjArray) {
|
||||
jsize length = env->GetArrayLength(windowHandleObjArray);
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
|
||||
if (! windowHandleObj) {
|
||||
break; // found null element indicating end of used portion of the array
|
||||
}
|
||||
|
||||
sp<InputWindowHandle> windowHandle =
|
||||
android_server_InputWindowHandle_getHandle(env, windowHandleObj);
|
||||
if (windowHandle != NULL) {
|
||||
windowHandles.push(windowHandle);
|
||||
}
|
||||
env->DeleteLocalRef(windowHandleObj);
|
||||
}
|
||||
env->DeleteLocalRef(windowObj);
|
||||
}
|
||||
|
||||
mInputManager->getDispatcher()->setInputWindows(windows);
|
||||
mInputManager->getDispatcher()->setInputWindows(windowHandles);
|
||||
|
||||
// Do this after the dispatcher has updated the window handle state.
|
||||
bool newPointerGesturesEnabled = true;
|
||||
size_t numWindows = windowHandles.size();
|
||||
for (size_t i = 0; i < numWindows; i++) {
|
||||
const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
|
||||
if (windowHandle->hasFocus && (windowHandle->inputFeatures
|
||||
& InputWindowHandle::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
|
||||
newPointerGesturesEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t changes = 0;
|
||||
{ // acquire lock
|
||||
@@ -623,16 +628,10 @@ void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArra
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
|
||||
if (applicationObj) {
|
||||
InputApplication application;
|
||||
android_server_InputApplication_toNative(env, applicationObj, &application);
|
||||
if (application.inputApplicationHandle != NULL) {
|
||||
mInputManager->getDispatcher()->setFocusedApplication(&application);
|
||||
return;
|
||||
}
|
||||
}
|
||||
mInputManager->getDispatcher()->setFocusedApplication(NULL);
|
||||
void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) {
|
||||
sp<InputApplicationHandle> applicationHandle =
|
||||
android_server_InputApplicationHandle_getHandle(env, applicationHandleObj);
|
||||
mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
|
||||
}
|
||||
|
||||
void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
|
||||
@@ -1137,21 +1136,21 @@ static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jcla
|
||||
}
|
||||
|
||||
static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
|
||||
jobjectArray windowObjArray) {
|
||||
jobjectArray windowHandleObjArray) {
|
||||
if (checkInputManagerUnitialized(env)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gNativeInputManager->setInputWindows(env, windowObjArray);
|
||||
gNativeInputManager->setInputWindows(env, windowHandleObjArray);
|
||||
}
|
||||
|
||||
static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
|
||||
jobject applicationObj) {
|
||||
jobject applicationHandleObj) {
|
||||
if (checkInputManagerUnitialized(env)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gNativeInputManager->setFocusedApplication(env, applicationObj);
|
||||
gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
|
||||
}
|
||||
|
||||
static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
|
||||
@@ -1313,9 +1312,9 @@ static JNINativeMethod gInputManagerMethods[] = {
|
||||
(void*) android_server_InputManager_nativeSetInputFilterEnabled },
|
||||
{ "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
|
||||
(void*) android_server_InputManager_nativeInjectInputEvent },
|
||||
{ "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
|
||||
{ "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
|
||||
(void*) android_server_InputManager_nativeSetInputWindows },
|
||||
{ "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
|
||||
{ "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
|
||||
(void*) android_server_InputManager_nativeSetFocusedApplication },
|
||||
{ "nativeSetInputDispatchMode", "(ZZ)V",
|
||||
(void*) android_server_InputManager_nativeSetInputDispatchMode },
|
||||
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "InputWindow"
|
||||
|
||||
#include "JNIHelp.h"
|
||||
#include "jni.h"
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include <android_view_InputChannel.h>
|
||||
#include <android/graphics/Region.h>
|
||||
#include "com_android_server_InputWindow.h"
|
||||
#include "com_android_server_InputWindowHandle.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static struct {
|
||||
jfieldID inputWindowHandle;
|
||||
jfieldID inputChannel;
|
||||
jfieldID name;
|
||||
jfieldID layoutParamsFlags;
|
||||
jfieldID layoutParamsType;
|
||||
jfieldID dispatchingTimeoutNanos;
|
||||
jfieldID frameLeft;
|
||||
jfieldID frameTop;
|
||||
jfieldID frameRight;
|
||||
jfieldID frameBottom;
|
||||
jfieldID scaleFactor;
|
||||
jfieldID touchableRegion;
|
||||
jfieldID visible;
|
||||
jfieldID canReceiveKeys;
|
||||
jfieldID hasFocus;
|
||||
jfieldID hasWallpaper;
|
||||
jfieldID paused;
|
||||
jfieldID layer;
|
||||
jfieldID ownerPid;
|
||||
jfieldID ownerUid;
|
||||
jfieldID inputFeatures;
|
||||
} gInputWindowClassInfo;
|
||||
|
||||
|
||||
// --- Global functions ---
|
||||
|
||||
void android_server_InputWindow_toNative(
|
||||
JNIEnv* env, jobject inputWindowObj, InputWindow* outInputWindow) {
|
||||
jobject inputWindowHandleObj = env->GetObjectField(inputWindowObj,
|
||||
gInputWindowClassInfo.inputWindowHandle);
|
||||
if (inputWindowHandleObj) {
|
||||
outInputWindow->inputWindowHandle =
|
||||
android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
|
||||
env->DeleteLocalRef(inputWindowHandleObj);
|
||||
} else {
|
||||
outInputWindow->inputWindowHandle = NULL;
|
||||
}
|
||||
|
||||
jobject inputChannelObj = env->GetObjectField(inputWindowObj,
|
||||
gInputWindowClassInfo.inputChannel);
|
||||
if (inputChannelObj) {
|
||||
outInputWindow->inputChannel =
|
||||
android_view_InputChannel_getInputChannel(env, inputChannelObj);
|
||||
env->DeleteLocalRef(inputChannelObj);
|
||||
} else {
|
||||
outInputWindow->inputChannel = NULL;
|
||||
}
|
||||
|
||||
jstring nameObj = jstring(env->GetObjectField(inputWindowObj,
|
||||
gInputWindowClassInfo.name));
|
||||
if (nameObj) {
|
||||
const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
|
||||
outInputWindow->name.setTo(nameStr);
|
||||
env->ReleaseStringUTFChars(nameObj, nameStr);
|
||||
env->DeleteLocalRef(nameObj);
|
||||
} else {
|
||||
LOGE("InputWindow.name should not be null.");
|
||||
outInputWindow->name.setTo("unknown");
|
||||
}
|
||||
|
||||
outInputWindow->layoutParamsFlags = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.layoutParamsFlags);
|
||||
outInputWindow->layoutParamsType = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.layoutParamsType);
|
||||
outInputWindow->dispatchingTimeout = env->GetLongField(inputWindowObj,
|
||||
gInputWindowClassInfo.dispatchingTimeoutNanos);
|
||||
outInputWindow->frameLeft = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.frameLeft);
|
||||
outInputWindow->frameTop = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.frameTop);
|
||||
outInputWindow->frameRight = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.frameRight);
|
||||
outInputWindow->frameBottom = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.frameBottom);
|
||||
outInputWindow->scaleFactor = env->GetFloatField(inputWindowObj,
|
||||
gInputWindowClassInfo.scaleFactor);
|
||||
|
||||
jobject regionObj = env->GetObjectField(inputWindowObj,
|
||||
gInputWindowClassInfo.touchableRegion);
|
||||
if (regionObj) {
|
||||
SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
|
||||
outInputWindow->touchableRegion.set(*region);
|
||||
env->DeleteLocalRef(regionObj);
|
||||
} else {
|
||||
outInputWindow->touchableRegion.setEmpty();
|
||||
}
|
||||
|
||||
outInputWindow->visible = env->GetBooleanField(inputWindowObj,
|
||||
gInputWindowClassInfo.visible);
|
||||
outInputWindow->canReceiveKeys = env->GetBooleanField(inputWindowObj,
|
||||
gInputWindowClassInfo.canReceiveKeys);
|
||||
outInputWindow->hasFocus = env->GetBooleanField(inputWindowObj,
|
||||
gInputWindowClassInfo.hasFocus);
|
||||
outInputWindow->hasWallpaper = env->GetBooleanField(inputWindowObj,
|
||||
gInputWindowClassInfo.hasWallpaper);
|
||||
outInputWindow->paused = env->GetBooleanField(inputWindowObj,
|
||||
gInputWindowClassInfo.paused);
|
||||
outInputWindow->layer = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.layer);
|
||||
outInputWindow->ownerPid = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.ownerPid);
|
||||
outInputWindow->ownerUid = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.ownerUid);
|
||||
outInputWindow->inputFeatures = env->GetIntField(inputWindowObj,
|
||||
gInputWindowClassInfo.inputFeatures);
|
||||
}
|
||||
|
||||
|
||||
// --- JNI ---
|
||||
|
||||
#define FIND_CLASS(var, className) \
|
||||
var = env->FindClass(className); \
|
||||
LOG_FATAL_IF(! var, "Unable to find class " className);
|
||||
|
||||
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
|
||||
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
|
||||
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
|
||||
|
||||
int register_android_server_InputWindow(JNIEnv* env) {
|
||||
jclass clazz;
|
||||
FIND_CLASS(clazz, "com/android/server/wm/InputWindow");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.inputWindowHandle, clazz,
|
||||
"inputWindowHandle", "Lcom/android/server/wm/InputWindowHandle;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.inputChannel, clazz,
|
||||
"inputChannel", "Landroid/view/InputChannel;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.name, clazz,
|
||||
"name", "Ljava/lang/String;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, clazz,
|
||||
"layoutParamsFlags", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, clazz,
|
||||
"layoutParamsType", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, clazz,
|
||||
"dispatchingTimeoutNanos", "J");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.frameLeft, clazz,
|
||||
"frameLeft", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.frameTop, clazz,
|
||||
"frameTop", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.frameRight, clazz,
|
||||
"frameRight", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.frameBottom, clazz,
|
||||
"frameBottom", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.scaleFactor, clazz,
|
||||
"scaleFactor", "F");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.touchableRegion, clazz,
|
||||
"touchableRegion", "Landroid/graphics/Region;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.visible, clazz,
|
||||
"visible", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, clazz,
|
||||
"canReceiveKeys", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.hasFocus, clazz,
|
||||
"hasFocus", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, clazz,
|
||||
"hasWallpaper", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.paused, clazz,
|
||||
"paused", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.layer, clazz,
|
||||
"layer", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.ownerPid, clazz,
|
||||
"ownerPid", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.ownerUid, clazz,
|
||||
"ownerUid", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowClassInfo.inputFeatures, clazz,
|
||||
"inputFeatures", "I");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace android */
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_SERVER_INPUT_WINDOW_H
|
||||
#define _ANDROID_SERVER_INPUT_WINDOW_H
|
||||
|
||||
#include <input/InputWindow.h>
|
||||
|
||||
#include "JNIHelp.h"
|
||||
#include "jni.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
extern void android_server_InputWindow_toNative(
|
||||
JNIEnv* env, jobject inputWindowObj, InputWindow* outInputWindow);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _ANDROID_SERVER_INPUT_WINDOW_H
|
||||
@@ -21,6 +21,9 @@
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
#include <android_view_InputChannel.h>
|
||||
#include <android/graphics/Region.h>
|
||||
|
||||
#include "com_android_server_InputWindowHandle.h"
|
||||
#include "com_android_server_InputApplicationHandle.h"
|
||||
|
||||
@@ -29,6 +32,26 @@ namespace android {
|
||||
static struct {
|
||||
jfieldID ptr;
|
||||
jfieldID inputApplicationHandle;
|
||||
jfieldID inputChannel;
|
||||
jfieldID name;
|
||||
jfieldID layoutParamsFlags;
|
||||
jfieldID layoutParamsType;
|
||||
jfieldID dispatchingTimeoutNanos;
|
||||
jfieldID frameLeft;
|
||||
jfieldID frameTop;
|
||||
jfieldID frameRight;
|
||||
jfieldID frameBottom;
|
||||
jfieldID scaleFactor;
|
||||
jfieldID touchableRegion;
|
||||
jfieldID visible;
|
||||
jfieldID canReceiveKeys;
|
||||
jfieldID hasFocus;
|
||||
jfieldID hasWallpaper;
|
||||
jfieldID paused;
|
||||
jfieldID layer;
|
||||
jfieldID ownerPid;
|
||||
jfieldID ownerUid;
|
||||
jfieldID inputFeatures;
|
||||
} gInputWindowHandleClassInfo;
|
||||
|
||||
static Mutex gHandleMutex;
|
||||
@@ -51,6 +74,83 @@ jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
|
||||
return env->NewLocalRef(mObjWeak);
|
||||
}
|
||||
|
||||
bool NativeInputWindowHandle::update() {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
jobject obj = env->NewLocalRef(mObjWeak);
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jobject inputChannelObj = env->GetObjectField(obj,
|
||||
gInputWindowHandleClassInfo.inputChannel);
|
||||
if (inputChannelObj) {
|
||||
inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj);
|
||||
env->DeleteLocalRef(inputChannelObj);
|
||||
} else {
|
||||
inputChannel = NULL;
|
||||
}
|
||||
|
||||
jstring nameObj = jstring(env->GetObjectField(obj,
|
||||
gInputWindowHandleClassInfo.name));
|
||||
if (nameObj) {
|
||||
const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
|
||||
name.setTo(nameStr);
|
||||
env->ReleaseStringUTFChars(nameObj, nameStr);
|
||||
env->DeleteLocalRef(nameObj);
|
||||
} else {
|
||||
name.setTo("<null>");
|
||||
}
|
||||
|
||||
layoutParamsFlags = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.layoutParamsFlags);
|
||||
layoutParamsType = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.layoutParamsType);
|
||||
dispatchingTimeout = env->GetLongField(obj,
|
||||
gInputWindowHandleClassInfo.dispatchingTimeoutNanos);
|
||||
frameLeft = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.frameLeft);
|
||||
frameTop = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.frameTop);
|
||||
frameRight = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.frameRight);
|
||||
frameBottom = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.frameBottom);
|
||||
scaleFactor = env->GetFloatField(obj,
|
||||
gInputWindowHandleClassInfo.scaleFactor);
|
||||
|
||||
jobject regionObj = env->GetObjectField(obj,
|
||||
gInputWindowHandleClassInfo.touchableRegion);
|
||||
if (regionObj) {
|
||||
SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
|
||||
touchableRegion.set(*region);
|
||||
env->DeleteLocalRef(regionObj);
|
||||
} else {
|
||||
touchableRegion.setEmpty();
|
||||
}
|
||||
|
||||
visible = env->GetBooleanField(obj,
|
||||
gInputWindowHandleClassInfo.visible);
|
||||
canReceiveKeys = env->GetBooleanField(obj,
|
||||
gInputWindowHandleClassInfo.canReceiveKeys);
|
||||
hasFocus = env->GetBooleanField(obj,
|
||||
gInputWindowHandleClassInfo.hasFocus);
|
||||
hasWallpaper = env->GetBooleanField(obj,
|
||||
gInputWindowHandleClassInfo.hasWallpaper);
|
||||
paused = env->GetBooleanField(obj,
|
||||
gInputWindowHandleClassInfo.paused);
|
||||
layer = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.layer);
|
||||
ownerPid = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.ownerPid);
|
||||
ownerUid = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.ownerUid);
|
||||
inputFeatures = env->GetIntField(obj,
|
||||
gInputWindowHandleClassInfo.inputFeatures);
|
||||
|
||||
env->DeleteLocalRef(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// --- Global functions ---
|
||||
|
||||
@@ -127,6 +227,65 @@ int register_android_server_InputWindowHandle(JNIEnv* env) {
|
||||
clazz,
|
||||
"inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
|
||||
"inputChannel", "Landroid/view/InputChannel;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.name, clazz,
|
||||
"name", "Ljava/lang/String;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz,
|
||||
"layoutParamsFlags", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz,
|
||||
"layoutParamsType", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.dispatchingTimeoutNanos, clazz,
|
||||
"dispatchingTimeoutNanos", "J");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.frameLeft, clazz,
|
||||
"frameLeft", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.frameTop, clazz,
|
||||
"frameTop", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.frameRight, clazz,
|
||||
"frameRight", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.frameBottom, clazz,
|
||||
"frameBottom", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.scaleFactor, clazz,
|
||||
"scaleFactor", "F");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
|
||||
"touchableRegion", "Landroid/graphics/Region;");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
|
||||
"visible", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.canReceiveKeys, clazz,
|
||||
"canReceiveKeys", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.hasFocus, clazz,
|
||||
"hasFocus", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
|
||||
"hasWallpaper", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
|
||||
"paused", "Z");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.layer, clazz,
|
||||
"layer", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
|
||||
"ownerPid", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz,
|
||||
"ownerUid", "I");
|
||||
|
||||
GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
|
||||
"inputFeatures", "I");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
|
||||
jobject getInputWindowHandleObjLocalRef(JNIEnv* env);
|
||||
|
||||
virtual bool update();
|
||||
|
||||
private:
|
||||
jweak mObjWeak;
|
||||
};
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
namespace android {
|
||||
int register_android_server_AlarmManagerService(JNIEnv* env);
|
||||
int register_android_server_BatteryService(JNIEnv* env);
|
||||
int register_android_server_InputApplication(JNIEnv* env);
|
||||
int register_android_server_InputApplicationHandle(JNIEnv* env);
|
||||
int register_android_server_InputWindow(JNIEnv* env);
|
||||
int register_android_server_InputWindowHandle(JNIEnv* env);
|
||||
int register_android_server_InputManager(JNIEnv* env);
|
||||
int register_android_server_LightsService(JNIEnv* env);
|
||||
@@ -51,9 +49,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
LOG_ASSERT(env, "Could not retrieve the env!");
|
||||
|
||||
register_android_server_PowerManagerService(env);
|
||||
register_android_server_InputApplication(env);
|
||||
register_android_server_InputApplicationHandle(env);
|
||||
register_android_server_InputWindow(env);
|
||||
register_android_server_InputWindowHandle(env);
|
||||
register_android_server_InputManager(env);
|
||||
register_android_server_LightsService(env);
|
||||
|
||||
Reference in New Issue
Block a user