Fix issue #1943706 (Applying the monkey to GoogleVoice causes SecurityException)
Fiddle around with event dispatching to remove calling permissions when we enter event injection, and prevent callers from going to the PhoneWindowManager's event processing code unless they are allowed at that point.
This commit is contained in:
@@ -3834,7 +3834,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
"dispatchPointer " + ev);
|
||||
|
||||
Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
|
||||
ev, true, false);
|
||||
ev, true, false, pid, uid);
|
||||
|
||||
int action = ev.getAction();
|
||||
|
||||
@@ -4032,7 +4032,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
|
||||
|
||||
Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
|
||||
ev, false, false);
|
||||
ev, false, false, pid, uid);
|
||||
if (focusObj == null) {
|
||||
Log.w(TAG, "No focus window, dropping trackball: " + ev);
|
||||
if (qev != null) {
|
||||
@@ -4103,7 +4103,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
if (DEBUG_INPUT) Log.v(TAG, "Dispatch key: " + event);
|
||||
|
||||
Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
|
||||
null, false, false);
|
||||
null, false, false, pid, uid);
|
||||
if (focusObj == null) {
|
||||
Log.w(TAG, "No focus window, dropping: " + event);
|
||||
return INJECT_FAILED;
|
||||
@@ -4220,10 +4220,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
|
||||
deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
|
||||
|
||||
int result = dispatchKey(newEvent, Binder.getCallingPid(), Binder.getCallingUid());
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
final int result = dispatchKey(newEvent, pid, uid);
|
||||
if (sync) {
|
||||
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
|
||||
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
|
||||
}
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
switch (result) {
|
||||
case INJECT_NO_PERMISSION:
|
||||
throw new SecurityException(
|
||||
@@ -4244,10 +4248,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
* @return Returns true if event was dispatched, false if it was dropped for any reason
|
||||
*/
|
||||
public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
|
||||
int result = dispatchPointer(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
final int result = dispatchPointer(null, ev, pid, uid);
|
||||
if (sync) {
|
||||
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
|
||||
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
|
||||
}
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
switch (result) {
|
||||
case INJECT_NO_PERMISSION:
|
||||
throw new SecurityException(
|
||||
@@ -4268,10 +4276,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
* @return Returns true if event was dispatched, false if it was dropped for any reason
|
||||
*/
|
||||
public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
|
||||
int result = dispatchTrackball(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
final int result = dispatchTrackball(null, ev, pid, uid);
|
||||
if (sync) {
|
||||
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
|
||||
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
|
||||
}
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
switch (result) {
|
||||
case INJECT_NO_PERMISSION:
|
||||
throw new SecurityException(
|
||||
@@ -4380,7 +4392,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
*/
|
||||
Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
|
||||
MotionEvent nextMotion, boolean isPointerEvent,
|
||||
boolean failIfTimeout) {
|
||||
boolean failIfTimeout, int callingPid, int callingUid) {
|
||||
long startTime = SystemClock.uptimeMillis();
|
||||
long keyDispatchingTimeout = 5 * 1000;
|
||||
long waitedFor = 0;
|
||||
@@ -4398,7 +4410,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
", mLastWin=" + mLastWin);
|
||||
if (targetIsNew) {
|
||||
Object target = findTargetWindow(nextKey, qev, nextMotion,
|
||||
isPointerEvent);
|
||||
isPointerEvent, callingPid, callingUid);
|
||||
if (target == SKIP_TARGET_TOKEN) {
|
||||
// The user has pressed a special key, and we are
|
||||
// dropping all pending events before it.
|
||||
@@ -4574,7 +4586,8 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
}
|
||||
|
||||
Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
|
||||
MotionEvent nextMotion, boolean isPointerEvent) {
|
||||
MotionEvent nextMotion, boolean isPointerEvent,
|
||||
int callingPid, int callingUid) {
|
||||
mOutsideTouchTargets = null;
|
||||
|
||||
if (nextKey != null) {
|
||||
@@ -4583,9 +4596,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
final int repeatCount = nextKey.getRepeatCount();
|
||||
final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
|
||||
boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
|
||||
|
||||
if (!dispatch) {
|
||||
mPolicy.interceptKeyTi(null, keycode,
|
||||
nextKey.getMetaState(), down, repeatCount);
|
||||
if (callingUid == 0 ||
|
||||
mContext.checkPermission(
|
||||
android.Manifest.permission.INJECT_EVENTS,
|
||||
callingPid, callingUid)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
mPolicy.interceptKeyTi(null, keycode,
|
||||
nextKey.getMetaState(), down, repeatCount);
|
||||
}
|
||||
Log.w(TAG, "Event timeout during app switch: dropping "
|
||||
+ nextKey);
|
||||
return SKIP_TARGET_TOKEN;
|
||||
@@ -4600,9 +4620,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
||||
|
||||
wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
|
||||
|
||||
if (mPolicy.interceptKeyTi(focus,
|
||||
keycode, nextKey.getMetaState(), down, repeatCount)) {
|
||||
return CONSUMED_EVENT_TOKEN;
|
||||
if (callingUid == 0 ||
|
||||
(focus != null && callingUid == focus.mSession.mUid) ||
|
||||
mContext.checkPermission(
|
||||
android.Manifest.permission.INJECT_EVENTS,
|
||||
callingPid, callingUid)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
if (mPolicy.interceptKeyTi(focus,
|
||||
keycode, nextKey.getMetaState(), down, repeatCount)) {
|
||||
return CONSUMED_EVENT_TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
return focus;
|
||||
|
||||
Reference in New Issue
Block a user