summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-03-10 07:50:56 -0800
committerSteve Kondik <shade@chemlab.org>2016-03-10 17:05:55 -0800
commit43ea012408f622f3b4a3812498f5cacf3d77abe3 (patch)
treeadf9b20eeae8c0cdc2aaa71e4bfed2a463c73283 /services/java
parent31a65449114c2fa6e3e7f2d04ab54d862514925b (diff)
downloadframeworks_base-43ea012408f622f3b4a3812498f5cacf3d77abe3.zip
frameworks_base-43ea012408f622f3b4a3812498f5cacf3d77abe3.tar.gz
frameworks_base-43ea012408f622f3b4a3812498f5cacf3d77abe3.tar.bz2
Revert "[2/2] framework/base: Add EdgeGesture service."
* This is shadowing functionality in SystemGesturesPointerEventListener and breaking things. It's also deprecated. Remove it. This reverts commit 7ae073bef3703ed7d6a141e35ae8d2a7c0137fc8. Change-Id: Ia0b547cddd412cdf1b19bad5a08bf1ccd28c3ee5
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/SystemServer.java18
-rw-r--r--services/java/com/android/server/gesture/EdgeGestureInputFilter.java539
-rw-r--r--services/java/com/android/server/gesture/EdgeGestureService.java488
-rw-r--r--services/java/com/android/server/gesture/EdgeGestureTracker.java252
4 files changed, 0 insertions, 1297 deletions
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0ea8a51..17805ea 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -74,7 +74,6 @@ import com.android.server.net.NetworkStatsService;
import com.android.server.notification.NotificationManagerService;
import com.android.server.os.SchedulingPolicyService;
import com.android.server.pm.BackgroundDexOptService;
-import com.android.server.gesture.EdgeGestureService;
import com.android.server.pm.Installer;
import com.android.server.pm.LauncherAppsService;
import com.android.server.pm.PackageManagerService;
@@ -562,7 +561,6 @@ public final class SystemServer {
AssetAtlasService atlas = null;
MediaRouterService mediaRouter = null;
GestureService gestureService = null;
- EdgeGestureService edgeGestureService = null;
// Bring up services needed for UI.
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
@@ -1018,14 +1016,6 @@ public final class SystemServer {
}
mSystemServiceManager.startService(LauncherAppsService.class);
-
- try {
- Slog.i(TAG, "EdgeGesture service");
- edgeGestureService = new EdgeGestureService(context, inputManager);
- ServiceManager.addService("edgegestureservice", edgeGestureService);
- } catch (Throwable e) {
- Slog.e(TAG, "Failure starting EdgeGesture service", e);
- }
}
if (!disableNonCoreServices) {
@@ -1125,14 +1115,6 @@ public final class SystemServer {
reportWtf("making Display Manager Service ready", e);
}
- if (edgeGestureService != null) {
- try {
- edgeGestureService.systemReady();
- } catch (Throwable e) {
- reportWtf("making EdgeGesture service ready", e);
- }
- }
-
if (gestureService != null) {
try {
gestureService.systemReady();
diff --git a/services/java/com/android/server/gesture/EdgeGestureInputFilter.java b/services/java/com/android/server/gesture/EdgeGestureInputFilter.java
deleted file mode 100644
index c42b7d0..0000000
--- a/services/java/com/android/server/gesture/EdgeGestureInputFilter.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod Project (Jens Doll)
- *
- * 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.gesture;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.util.Slog;
-import android.view.Display;
-import android.view.DisplayInfo;
-import android.view.IInputFilter;
-import android.view.IInputFilterHost;
-import android.view.InputDevice;
-import android.view.InputEvent;
-import android.view.MotionEvent;
-import android.view.WindowManagerPolicy;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-
-import com.android.internal.R;
-import com.android.internal.util.gesture.EdgeGesturePosition;
-import com.android.server.gesture.EdgeGestureTracker.OnActivationListener;
-
-import java.io.PrintWriter;
-
-/**
- * A simple input filter, that listens for edge swipe gestures in the motion event input
- * stream.
- * <p>
- * There are 5 distinct states of this filter.
- * 1) LISTEN:
- * mTracker.active == false
- * All motion events are passed through. If a ACTION_DOWN within a gesture trigger area happen
- * switch to DETECTING.
- * 2) DETECTING:
- * mTracker.active == true
- * All events are buffered now, and the gesture is checked by mTracker. If mTracker rejects
- * the gesture (hopefully as fast as possible) all cached events will be flushed out and the
- * filter falls back to LISTEN.
- * If mTracker accepts the gesture, clear all cached events and go to LOCKED.
- * 3) LOCKED:
- * mTracker.active == false
- * All events will be cached until the state changes to SYNTHESIZE through a filter
- * unlock event. If there is a ACTION_UP, _CANCEL or any PointerId differently to the last
- * event seen when mTracker accepted the gesture, we flush all events and go to LISTEN.
- * 4) SYNTHESIZE:
- * The first motion event found will be turned into a ACTION_DOWN event, all previous events
- * will be discarded.
- * 5) POSTSYNTHESIZE:
- * mSyntheticDownTime != -1
- * All following events will have the down time set to the synthesized ACTION_DOWN event time
- * until an ACTION_UP or ACTION_CANCEL is encountered and the state is reset to LISTEN.
- * 6) DROP:
- * All following events will be discarded. If there is an ACTION_UP, _CANCEL
- * we go to LISTEN state.
- * <p>
- * If you are reading this within Java Doc, you are doing something wrong ;)
- */
-public class EdgeGestureInputFilter implements IInputFilter {
- /* WARNING!! The IInputFilter interface is used directly, there is no Binder between this and
- * the InputDispatcher.
- * This is fine, because it prevents unnecessary parceling, but beware:
- * This means we are running on the dispatch or listener thread of the input dispatcher. Every
- * cycle we waste here adds to the overall input latency.
- */
- private static final String TAG = "EdgeGestureInputFilter";
- private static final boolean DEBUG = false;
- private static final boolean DEBUG_INPUT = false;
- // TODO: Should be turned off in final commit
- private static final boolean SYSTRACE = false;
-
- private final Handler mHandler;
-
- private IInputFilterHost mHost = null; // dispatcher thread
-
- private static final class MotionEventInfo {
- private static final int MAX_POOL_SIZE = 16;
-
- private static final Object sLock = new Object();
- private static MotionEventInfo sPool;
- private static int sPoolSize;
-
- private boolean mInPool;
-
- public static MotionEventInfo obtain(MotionEvent event, int policyFlags) {
- synchronized (sLock) {
- MotionEventInfo info;
- if (sPoolSize > 0) {
- sPoolSize--;
- info = sPool;
- sPool = info.next;
- info.next = null;
- info.mInPool = false;
- } else {
- info = new MotionEventInfo();
- }
- info.initialize(event, policyFlags);
- return info;
- }
- }
-
- private void initialize(MotionEvent event, int policyFlags) {
- this.event = MotionEvent.obtain(event);
- this.policyFlags = policyFlags;
- cachedTimeMillis = SystemClock.uptimeMillis();
- }
-
- public void recycle() {
- synchronized (sLock) {
- if (mInPool) {
- throw new IllegalStateException("Already recycled.");
- }
- clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- sPoolSize++;
- next = sPool;
- sPool = this;
- mInPool = true;
- }
- }
- }
-
- private void clear() {
- event.recycle();
- event = null;
- policyFlags = 0;
- }
-
- public MotionEventInfo next;
- public MotionEvent event;
- public int policyFlags;
- public long cachedTimeMillis;
- }
- private final Object mLock = new Object();
- private MotionEventInfo mMotionEventQueue; // guarded by mLock
- private MotionEventInfo mMotionEventQueueTail; // guarded by mLock
- /* DEBUG */
- private int mMotionEventQueueCountDebug; // guarded by mLock
-
- private int mDeviceId; // dispatcher only
- private enum State {
- LISTEN, DETECTING, LOCKED, SYNTHESIZE, POSTSYNTHESIZE, DROP;
- }
- private State mState = State.LISTEN; // guarded by mLock
- private EdgeGestureTracker mTracker; // guarded by mLock
- private volatile int mPositions; // written by handler / read by dispatcher
- private volatile int mSensitivity; // written by handler / read by dispatcher
-
- // only used by dispatcher
- private long mSyntheticDownTime = -1;
- private PointerCoords[] mTempPointerCoords = new PointerCoords[1];
- private PointerProperties[] mTempPointerProperties = new PointerProperties[1];
-
- public EdgeGestureInputFilter(Context context, Handler handler) {
- mHandler = handler;
-
- final Resources res = context.getResources();
- mTracker = new EdgeGestureTracker(res.getDimensionPixelSize(
- R.dimen.edge_gesture_trigger_thickness),
- res.getDimensionPixelSize(R.dimen.edge_gesture_trigger_distance),
- res.getDimensionPixelSize(R.dimen.edge_gesture_perpendicular_distance));
- mTracker.setOnActivationListener(new OnActivationListener() {
- public void onActivation(MotionEvent event, int touchX, int touchY, EdgeGesturePosition position) {
- // mLock is held by #processMotionEvent
- mHandler.obtainMessage(EdgeGestureService.MSG_EDGE_GESTURE_ACTIVATION,
- touchX, touchY, position).sendToTarget();
- mState = State.LOCKED;
- }
- });
- mTempPointerCoords[0] = new PointerCoords();
- mTempPointerProperties[0] = new PointerProperties();
- }
-
- // called from handler thread (lock taken)
- public void updateDisplay(Display display, DisplayInfo displayInfo) {
- synchronized (mLock) {
- mTracker.updateDisplay(display);
- }
- }
-
- // called from handler thread (lock taken)
- public void updatePositions(int positions) {
- mPositions = positions;
- }
-
- // called from handler thread (lock taken)
- public void updateSensitivity(int sensitivity) {
- mSensitivity = sensitivity;
- }
-
- // called from handler thread
- public boolean unlockFilter() {
- synchronized (mLock) {
- if (mState == State.LOCKED) {
- mState = State.SYNTHESIZE;
- return true;
- }
- }
- return false;
- }
-
- public boolean dropSequence() {
- synchronized (mLock) {
- if (mState == State.LOCKED) {
- mState = State.DROP;
- return true;
- }
- }
- return false;
- }
-
- /**
- * Called to enqueue the input event for filtering.
- * The event must be recycled after the input filter processed it.
- * This method is guaranteed to be non-reentrant.
- *
- * @see InputFilter#filterInputEvent(InputEvent, int)
- * @param event The input event to enqueue.
- */
- // called by the input dispatcher thread
- public void filterInputEvent(InputEvent event, int policyFlags) throws RemoteException {
- if (SYSTRACE) {
- Trace.traceBegin(Trace.TRACE_TAG_INPUT, "filterInputEvent");
- }
- try {
- if (((event.getSource() & InputDevice.SOURCE_TOUCHSCREEN)
- != InputDevice.SOURCE_TOUCHSCREEN)
- || !(event instanceof MotionEvent)) {
- sendInputEvent(event, policyFlags);
- return;
- }
- if (DEBUG_INPUT) {
- Slog.d(TAG, "Received event: " + event + ", policyFlags=0x"
- + Integer.toHexString(policyFlags));
- }
- MotionEvent motionEvent = (MotionEvent) event;
- final int deviceId = event.getDeviceId();
- if (deviceId != mDeviceId) {
- processDeviceSwitch(deviceId, motionEvent, policyFlags);
- } else {
- if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) {
- synchronized (mLock) {
- clearAndResetStateLocked(false, true);
- }
- }
- processMotionEvent(motionEvent, policyFlags);
- }
- } finally {
- event.recycle();
- if (SYSTRACE) {
- Trace.traceEnd(Trace.TRACE_TAG_INPUT);
- }
- }
- }
-
- private void processDeviceSwitch(int deviceId, MotionEvent motionEvent, int policyFlags) {
- if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mDeviceId = deviceId;
- synchronized (mLock) {
- clearAndResetStateLocked(true, false);
- processMotionEvent(motionEvent, policyFlags);
- }
- } else {
- sendInputEvent(motionEvent, policyFlags);
- }
- }
-
- private void processMotionEvent(MotionEvent motionEvent, int policyFlags) {
- final int action = motionEvent.getActionMasked();
-
- synchronized (mLock) {
- switch (mState) {
- case LISTEN:
- if (action == MotionEvent.ACTION_DOWN) {
- boolean hit = mPositions != 0
- && mTracker.start(motionEvent, mPositions, mSensitivity);
- if (DEBUG) Slog.d(TAG, "start:" + hit);
- if (hit) {
- // cache the down event
- cacheDelayedMotionEventLocked(motionEvent, policyFlags);
- mState = State.DETECTING;
- return;
- }
- }
- sendInputEvent(motionEvent, policyFlags);
- break;
- case DETECTING:
- cacheDelayedMotionEventLocked(motionEvent, policyFlags);
- if (action == MotionEvent.ACTION_MOVE) {
- if (mTracker.move(motionEvent)) {
- // return: the tracker is either detecting or triggered onActivation
- return;
- }
- }
- if (DEBUG) {
- Slog.d(TAG, "move: reset!");
- }
- clearAndResetStateLocked(false, true);
- break;
- case LOCKED:
- cacheDelayedMotionEventLocked(motionEvent, policyFlags);
- if (action != MotionEvent.ACTION_MOVE) {
- clearAndResetStateLocked(false, true);
- }
- break;
- case SYNTHESIZE:
- if (action == MotionEvent.ACTION_MOVE) {
- clearDelayedMotionEventsLocked();
- sendSynthesizedMotionEventLocked(motionEvent, policyFlags);
- mState = State.POSTSYNTHESIZE;
- } else {
- // This is the case where a race condition caught us: We already
- // returned the handler thread that it is all right to call
- // #gainTouchFocus(), but apparently this was wrong, as the gesture
- // was canceled now.
- clearAndResetStateLocked(false, true);
- }
- break;
- case POSTSYNTHESIZE:
- motionEvent.setDownTime(mSyntheticDownTime);
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- mState = State.LISTEN;
- mSyntheticDownTime = -1;
- }
- sendInputEvent(motionEvent, policyFlags);
- break;
- case DROP:
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- clearDelayedMotionEventsLocked();
- mState = State.LISTEN;
- }
- break;
- }
- }
- }
-
- private void clearAndResetStateLocked(boolean force, boolean shift) {
- // ignore soft reset in POSTSYNTHESIZE, because we need to tamper with
- // the event stream and going to LISTEN after an ACTION_UP anyway
- if (!force && (mState == State.POSTSYNTHESIZE)) {
- return;
- }
- switch (mState) {
- case LISTEN:
- // this is a nop
- break;
- case DETECTING:
- mTracker.reset();
- // intentionally no break here
- case LOCKED:
- case SYNTHESIZE:
- sendDelayedMotionEventsLocked(shift);
- break;
- case POSTSYNTHESIZE:
- // hard reset (this will break the event stream)
- Slog.w(TAG, "Quit POSTSYNTHESIZE without ACTION_UP from ACTION_DOWN at "
- + mSyntheticDownTime);
- mSyntheticDownTime = -1;
- break;
- }
- // if there are future events that need to be tampered with, goto POSTSYNTHESIZE
- mState = mSyntheticDownTime == -1 ? State.LISTEN : State.POSTSYNTHESIZE;
- }
-
- private void sendInputEvent(InputEvent event, int policyFlags) {
- try {
- mHost.sendInputEvent(event, policyFlags);
- } catch (RemoteException e) {
- /* ignore */
- }
- }
-
- private void cacheDelayedMotionEventLocked(MotionEvent event, int policyFlags) {
- MotionEventInfo info = MotionEventInfo.obtain(event, policyFlags);
- if (mMotionEventQueue == null) {
- mMotionEventQueue = info;
- } else {
- mMotionEventQueueTail.next = info;
- }
- mMotionEventQueueTail = info;
- mMotionEventQueueCountDebug++;
- if (SYSTRACE) {
- Trace.traceCounter(Trace.TRACE_TAG_INPUT, "meq", mMotionEventQueueCountDebug);
- }
- }
-
- private void sendDelayedMotionEventsLocked(boolean shift) {
- while (mMotionEventQueue != null) {
- MotionEventInfo info = mMotionEventQueue;
- mMotionEventQueue = info.next;
-
- if (DEBUG) {
- Slog.d(TAG, "Replay event: " + info.event);
- }
- mMotionEventQueueCountDebug--;
- if (SYSTRACE) {
- Trace.traceCounter(Trace.TRACE_TAG_INPUT, "meq", mMotionEventQueueCountDebug);
- }
- if (shift) {
- final long offset = SystemClock.uptimeMillis() - info.cachedTimeMillis;
- if (info.event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mSyntheticDownTime = info.event.getDownTime() + offset;
- }
- sendMotionEventWithOffsetLocked(info.event, info.policyFlags, mSyntheticDownTime, offset);
- if (info.event.getActionMasked() == MotionEvent.ACTION_UP) {
- mSyntheticDownTime = -1;
- }
- } else {
- sendInputEvent(info.event, info.policyFlags);
- }
- info.recycle();
- }
- mMotionEventQueueTail = null;
- }
-
- private void clearDelayedMotionEventsLocked() {
- while (mMotionEventQueue != null) {
- MotionEventInfo next = mMotionEventQueue.next;
- mMotionEventQueue.recycle();
- mMotionEventQueue = next;
- }
- mMotionEventQueueTail = null;
- mMotionEventQueueCountDebug = 0;
- if (SYSTRACE) {
- Trace.traceCounter(Trace.TRACE_TAG_INPUT, "meq", mMotionEventQueueCountDebug);
- }
- }
-
- private void sendMotionEventWithOffsetLocked(MotionEvent event, int policyFlags,
- long downTime, long offset) {
- final int pointerCount = event.getPointerCount();
- PointerCoords[] coords = getTempPointerCoordsWithMinSizeLocked(pointerCount);
- PointerProperties[] properties = getTempPointerPropertiesWithMinSizeLocked(pointerCount);
- for (int i = 0; i < pointerCount; i++) {
- event.getPointerCoords(i, coords[i]);
- event.getPointerProperties(i, properties[i]);
- }
- final long eventTime = event.getEventTime() + offset;
- sendInputEvent(MotionEvent.obtain(downTime, eventTime, event.getAction(), pointerCount,
- properties, coords, event.getMetaState(), event.getButtonState(), 1.0f, 1.0f,
- event.getDeviceId(), event.getEdgeFlags(), event.getSource(), event.getFlags()),
- policyFlags);
- }
-
- private PointerCoords[] getTempPointerCoordsWithMinSizeLocked(int size) {
- final int oldSize = mTempPointerCoords.length;
- if (oldSize < size) {
- PointerCoords[] oldTempPointerCoords = mTempPointerCoords;
- mTempPointerCoords = new PointerCoords[size];
- System.arraycopy(oldTempPointerCoords, 0, mTempPointerCoords, 0, oldSize);
- }
- for (int i = oldSize; i < size; i++) {
- mTempPointerCoords[i] = new PointerCoords();
- }
- return mTempPointerCoords;
- }
-
- private PointerProperties[] getTempPointerPropertiesWithMinSizeLocked(int size) {
- final int oldSize = mTempPointerProperties.length;
- if (oldSize < size) {
- PointerProperties[] oldTempPointerProperties = mTempPointerProperties;
- mTempPointerProperties = new PointerProperties[size];
- System.arraycopy(oldTempPointerProperties, 0, mTempPointerProperties, 0, oldSize);
- }
- for (int i = oldSize; i < size; i++) {
- mTempPointerProperties[i] = new PointerProperties();
- }
- return mTempPointerProperties;
- }
-
- private void sendSynthesizedMotionEventLocked(MotionEvent event, int policyFlags) {
- if (event.getPointerCount() == 1) {
- event.getPointerCoords(0, mTempPointerCoords[0]);
- event.getPointerProperties(0, mTempPointerProperties[0]);
- MotionEvent down = MotionEvent.obtain(event.getEventTime(), event.getEventTime(),
- MotionEvent.ACTION_DOWN, 1, mTempPointerProperties, mTempPointerCoords,
- event.getMetaState(), event.getButtonState(),
- 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(),
- event.getSource(), event.getFlags());
- Slog.d(TAG, "Synthesized event:" + down);
- sendInputEvent(down, policyFlags);
- mSyntheticDownTime = event.getEventTime();
- } else {
- Slog.w(TAG, "Could not synthesize MotionEvent, this will drop all following events!");
- }
- }
-
- // should never be called
- public IBinder asBinder() {
- throw new UnsupportedOperationException();
- }
-
- // called by the input dispatcher thread
- public void install(IInputFilterHost host) throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "EdgeGesture input filter installed.");
- }
- mHost = host;
- synchronized (mLock) {
- clearAndResetStateLocked(true, false);
- }
- }
-
- // called by the input dispatcher thread
- public void uninstall() throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "EdgeGesture input filter uninstalled.");
- }
- }
-
- // called by a Binder thread
- public void dump(PrintWriter pw, String prefix) {
- synchronized (mLock) {
- pw.print(prefix);
- pw.println("mState=" + mState.name());
- pw.print(prefix);
- pw.println("mPositions=0x" + Integer.toHexString(mPositions));
- pw.print(prefix);
- pw.println("mQueue=" + mMotionEventQueueCountDebug + " items");
- }
- }
-}
diff --git a/services/java/com/android/server/gesture/EdgeGestureService.java b/services/java/com/android/server/gesture/EdgeGestureService.java
deleted file mode 100644
index 0581831..0000000
--- a/services/java/com/android/server/gesture/EdgeGestureService.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod Project (Jens Doll)
- *
- * 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.gesture;
-
-import static com.android.internal.util.gesture.EdgeServiceConstants.POSITION_MASK;
-import static com.android.internal.util.gesture.EdgeServiceConstants.SENSITIVITY_DEFAULT;
-import static com.android.internal.util.gesture.EdgeServiceConstants.SENSITIVITY_MASK;
-import static com.android.internal.util.gesture.EdgeServiceConstants.SENSITIVITY_NONE;
-import static com.android.internal.util.gesture.EdgeServiceConstants.SENSITIVITY_SHIFT;
-import static com.android.internal.util.gesture.EdgeServiceConstants.LONG_LIVING;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.service.gesture.IEdgeGestureActivationListener;
-import android.service.gesture.IEdgeGestureHostCallback;
-import android.service.gesture.IEdgeGestureService;
-import android.util.Slog;
-import android.view.Display;
-import android.view.DisplayInfo;
-import android.view.WindowManager;
-
-import com.android.internal.util.gesture.EdgeGesturePosition;
-import com.android.server.gesture.EdgeGestureInputFilter;
-import com.android.server.input.InputManagerService;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A system service to track and handle edge swipe gestures. This service interacts with
- * the {@link InputManagerService} to do all the dirty work for listeners:
- * <li>Installing an input filter and listen for edge swipe gestures</li>
- * <li>Removing those gestures from the input stream</li>
- * <li>Transferring touch focus to new recipient</li>
- */
-public class EdgeGestureService extends IEdgeGestureService.Stub {
- public static final String TAG = "EdgeGestureService";
- public static final boolean DEBUG = false;
- public static final boolean DEBUG_INPUT = false;
-
- public static final int MSG_EDGE_GESTURE_ACTIVATION = 32023;
- public static final int MSG_UPDATE_SERVICE = 32025;
-
- private final Context mContext;
- private final InputManagerService mInputManager;
-
- private final HandlerThread mHandlerThread = new HandlerThread("EdgeGestureHandler");
- private Handler mHandler;
-
- // Lock for mInputFilter, activations and listener related variables
- private final Object mLock = new Object();
- private EdgeGestureInputFilter mInputFilter;
-
- private int mGlobalPositions = 0;
- private int mGlobalSensitivity = 3;
-
- private final class EdgeGestureActivationListenerRecord extends IEdgeGestureHostCallback.Stub implements DeathRecipient {
- private boolean mActive;
-
- public EdgeGestureActivationListenerRecord(IEdgeGestureActivationListener listener) {
- this.listener = listener;
- this.positions = 0;
- }
-
- public void binderDied() {
- removeListenerRecord(this);
- }
-
- private void updateFlags(int flags) {
- this.positions = flags & POSITION_MASK;
- this.sensitivity = (flags & SENSITIVITY_MASK) >> SENSITIVITY_SHIFT;
- this.longLiving = (flags & LONG_LIVING) != 0;
- }
-
- private boolean eligibleForActivation(int positionFlag) {
- return (positions & positionFlag) != 0;
- }
-
- private boolean notifyEdgeGestureActivation(int touchX, int touchY, EdgeGesturePosition position) {
- if ((positions & position.FLAG) != 0) {
- try {
- mActive = true;
- listener.onEdgeGestureActivation(touchX, touchY, position.INDEX, 0);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to notify process, assuming it died.", e);
- mActive = false;
- binderDied();
- }
- }
- return mActive;
- }
-
- // called through Binder
- public boolean gainTouchFocus(IBinder windowToken) {
- if (DEBUG) {
- Slog.d(TAG, "Gain touch focus for " + windowToken);
- }
- if (mActive) {
- return mInputFilter.unlockFilter();
- }
- return false;
- }
-
- public boolean dropEventsUntilLift() {
- if (DEBUG) {
- Slog.d(TAG, "Will drop all next events till touch up");
- }
- if (mActive) {
- return mInputFilter.dropSequence();
- }
- return false;
- }
-
- // called through Binder
- public void restoreListenerState() throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "Restore listener state");
- }
- if (mActive) {
- mInputFilter.unlockFilter();
- mActive = false;
- synchronized (mLock) {
- // restore input filter state by updating
- mHandler.sendEmptyMessage(MSG_UPDATE_SERVICE);
- }
- }
- }
-
- public boolean isActive() {
- return mActive;
- }
-
- public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix);
- pw.print("mPositions=0x" + Integer.toHexString(positions));
- pw.println(" mActive=" + mActive);
- pw.print(prefix);
- pw.println("mBinder=" + listener);
- }
-
- public int positions;
- public int sensitivity;
- public final IEdgeGestureActivationListener listener;
- public boolean longLiving = false;
- }
- private final List<EdgeGestureActivationListenerRecord> mEdgeGestureActivationListener =
- new ArrayList<EdgeGestureActivationListenerRecord>();
- // end of lock guarded variables
-
- private DisplayObserver mDisplayObserver;
-
- // called by system server
- public EdgeGestureService(Context context, InputManagerService inputManager) {
- mContext = context;
- mInputManager = inputManager;
- }
-
- // called by system server
- public void systemReady() {
- if (DEBUG) Slog.d(TAG, "Starting the edge gesture capture thread ...");
-
- synchronized (mLock) {
- mHandlerThread.start();
- mHandler = new H(mHandlerThread.getLooper());
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_FOREGROUND);
- android.os.Process.setCanSelfBackground(false);
- }
- });
- mDisplayObserver = new DisplayObserver(mContext, mHandler);
- // check if anyone registered during startup
- mHandler.sendEmptyMessage(MSG_UPDATE_SERVICE);
- }
- }
-
-
- private void updateMonitoring() {
- synchronized(mLock) {
- mGlobalPositions = 0;
- mGlobalSensitivity = SENSITIVITY_NONE;
- boolean someLongLiving = false;
- int activePositions = 0;
- for (EdgeGestureActivationListenerRecord temp : mEdgeGestureActivationListener) {
- mGlobalPositions |= temp.positions;
- if (temp.isActive()) {
- activePositions |= temp.positions;
- }
- if (temp.sensitivity != SENSITIVITY_NONE) {
- mGlobalSensitivity = Math.max(mGlobalSensitivity, temp.sensitivity);
- }
- someLongLiving |= temp.longLiving;
- }
- boolean havePositions = mGlobalPositions != 0;
- mGlobalPositions &= ~activePositions;
- // if no special sensitivity is requested, we settle on DEFAULT
- if (mGlobalSensitivity == SENSITIVITY_NONE) {
- mGlobalSensitivity = SENSITIVITY_DEFAULT;
- }
-
- if (mInputFilter == null && havePositions) {
- enforceMonitoringLocked();
- } else if (mInputFilter != null && !havePositions && !someLongLiving) {
- shutdownMonitoringLocked();
- }
- }
- }
-
- private void enforceMonitoringLocked() {
- if (DEBUG) {
- Slog.d(TAG, "Attempting to start monitoring input events ...");
- }
- mInputFilter = new EdgeGestureInputFilter(mContext, mHandler);
- mInputManager.registerSecondaryInputFilter(mInputFilter);
- mDisplayObserver.observe();
- }
-
- private void shutdownMonitoringLocked() {
- if (DEBUG) {
- Slog.d(TAG, "Shutting down monitoring input events ...");
- }
- mDisplayObserver.unobserve();
- mInputManager.unregisterSecondaryInputFilter(mInputFilter);
- mInputFilter = null;
- }
-
- // called through Binder
- public IEdgeGestureHostCallback registerEdgeGestureActivationListener(IEdgeGestureActivationListener listener) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.INJECT_EVENTS)
- != PackageManager.PERMISSION_GRANTED) {
- Slog.w(TAG, "Permission Denial: can't register from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return null;
- }
-
- if (listener == null) {
- throw new IllegalArgumentException("listener must not be null");
- }
-
- EdgeGestureActivationListenerRecord record = null;
- synchronized(mLock) {
- record = findListenerRecordLocked(listener.asBinder());
- if (record == null) {
- record = new EdgeGestureActivationListenerRecord(listener);
- try {
- listener.asBinder().linkToDeath(record, 0);
- } catch (RemoteException e) {
- Slog.w(TAG, "Recipient died during registration pid=" + Binder.getCallingPid());
- return null;
- }
- mEdgeGestureActivationListener.add(record);
- }
- }
- return record;
- }
-
- // called through Binder
- public void updateEdgeGestureActivationListener(IBinder listener, int positionFlags) {
- if (listener == null) {
- throw new IllegalArgumentException("listener must not be null");
- }
- synchronized(mLock) {
- EdgeGestureActivationListenerRecord record = findListenerRecordLocked(listener);
- if (record == null) {
- Slog.w(TAG, "Unknown listener on update listener. Register first?");
- throw new IllegalStateException("listener not registered");
- }
- record.updateFlags(positionFlags);
- // update input filter only when #systemReady() was called
- if (mHandler != null) {
- mHandler.sendEmptyMessage(MSG_UPDATE_SERVICE);
- }
- }
- }
-
- private EdgeGestureActivationListenerRecord findListenerRecordLocked(IBinder listener) {
- for (EdgeGestureActivationListenerRecord record : mEdgeGestureActivationListener) {
- if (record.listener.asBinder().equals(listener)) {
- return record;
- }
- }
- return null;
- }
-
- private void removeListenerRecord(EdgeGestureActivationListenerRecord record) {
- synchronized(mLock) {
- mEdgeGestureActivationListener.remove(record);
- // restore input filter state by updating
- mHandler.sendEmptyMessage(MSG_UPDATE_SERVICE);
- }
- }
-
- // called by handler thread
- private boolean propagateActivation(int touchX, int touchY, EdgeGesturePosition position) {
- synchronized(mLock) {
- EdgeGestureActivationListenerRecord target = null;
- for (EdgeGestureActivationListenerRecord record : mEdgeGestureActivationListener) {
- if (record.eligibleForActivation(position.FLAG)) {
- target = record;
- break;
- }
- }
- // NOTE: We can do this here because the #onGestureActivation() is a oneway
- // Binder call. This means we do not block with holding the mListenerLock!!!
- // If this ever change, this needs to be adjusted and if you don't know what
- // this means, you should probably not mess around with this code, anyway.
- if (target != null && !target.notifyEdgeGestureActivation(touchX, touchY, position)) {
- target = null;
- }
- return target != null;
- }
- }
-
- private final class H extends Handler {
- public H(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message m) {
- switch (m.what) {
- case MSG_EDGE_GESTURE_ACTIVATION:
- if (DEBUG) {
- Slog.d(TAG, "Activating edge gesture on " + m.obj.toString());
- }
- // Since input filter runs asynchronously to us, double activation may happen
- // theoretically. Take the safe route here.
- removeMessages(MSG_EDGE_GESTURE_ACTIVATION);
- if (propagateActivation(m.arg1, m.arg2, (EdgeGesturePosition) m.obj)) {
- // switch off activated positions
- updateMonitoring();
- updateServiceHandler(mGlobalPositions, mGlobalSensitivity);
- }
- break;
- case MSG_UPDATE_SERVICE:
- updateMonitoring();
- if (DEBUG) {
- Slog.d(TAG, "Updating positions 0x" + Integer.toHexString(mGlobalPositions)
- + " sensitivity: " + mGlobalSensitivity);
- }
- updateServiceHandler(mGlobalPositions, mGlobalSensitivity);
- break;
- }
- }
-
- private void updateServiceHandler(int positions, int sensitivity) {
- synchronized (mLock) {
- if (mInputFilter != null) {
- mInputFilter.updatePositions(positions);
- mInputFilter.updateSensitivity(sensitivity);
- }
- }
- }
- }
-
- private final class DisplayObserver implements DisplayListener {
- private final Handler mHandler;
- private final DisplayManager mDisplayManager;
-
- private final Display mDefaultDisplay;
- private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
-
- public DisplayObserver(Context context, Handler handler) {
- mHandler = handler;
- mDisplayManager = (DisplayManager) context.getSystemService(
- Context.DISPLAY_SERVICE);
- final WindowManager windowManager = (WindowManager) context.getSystemService(
- Context.WINDOW_SERVICE);
-
- mDefaultDisplay = windowManager.getDefaultDisplay();
- updateDisplayInfo();
- }
-
- private void updateDisplayInfo() {
- if (DEBUG) {
- Slog.d(TAG, "Updating display information ...");
- }
- if (mDefaultDisplay.getDisplayInfo(mDefaultDisplayInfo)) {
- synchronized (mLock) {
- if (mInputFilter != null) {
- mInputFilter.updateDisplay(mDefaultDisplay, mDefaultDisplayInfo);
- }
- }
- } else {
- Slog.e(TAG, "Default display is not valid.");
- }
- }
-
- public void observe() {
- mDisplayManager.registerDisplayListener(this, mHandler);
- updateDisplayInfo();
- }
-
- public void unobserve() {
- mDisplayManager.unregisterDisplayListener(this);
- }
-
- @Override
- public void onDisplayAdded(int displayId) {
- /* do noting */
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- /* do nothing */
- }
-
- @Override
- public void onDisplayChanged(int displayId) {
- updateDisplayInfo();
- }
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- return super.onTransact(code, data, reply, flags);
- } catch (RuntimeException e) {
- // let's log all exceptions we do not know about.
- if (!(e instanceof IllegalArgumentException || e instanceof IllegalStateException)) {
- Slog.e(TAG, "EdgeGestureService crashed: ", e);
- }
- throw e;
- }
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump EdgeGestureService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
- pw.println("EDGE GESTURE SERVICE (dumpsys edgegestureservice)\n");
- synchronized(mLock) {
- pw.println(" mInputFilter=" + mInputFilter);
- if (mInputFilter != null) {
- mInputFilter.dump(pw, " ");
- }
- pw.println(" mGlobalPositions=0x" + Integer.toHexString(mGlobalPositions));
- pw.println(" mGlobalSensitivity=" + mGlobalSensitivity);
- int i = 0;
- for (EdgeGestureActivationListenerRecord record : mEdgeGestureActivationListener) {
- if (record.isActive()) {
- pw.println(" Active record: #" + (i + 1));
- }
- }
- i = 0;
- for (EdgeGestureActivationListenerRecord record : mEdgeGestureActivationListener) {
- pw.println(" Listener #" + i + ":");
- record.dump(pw, " ");
- i++;
- }
- }
- }
-}
diff --git a/services/java/com/android/server/gesture/EdgeGestureTracker.java b/services/java/com/android/server/gesture/EdgeGestureTracker.java
deleted file mode 100644
index 17cd95e..0000000
--- a/services/java/com/android/server/gesture/EdgeGestureTracker.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod Project (Jens Doll)
- *
- * 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.gesture;
-
-import android.graphics.Point;
-import android.os.SystemClock;
-import android.util.Slog;
-import android.view.Display;
-import android.view.MotionEvent;
-
-import com.android.internal.util.gesture.EdgeGesturePosition;
-import com.android.internal.util.gesture.EdgeServiceConstants;
-
-/**
- * A simple {@link MotionEvent} tracker class. The main aim of this tracker is to
- * reject gestures as fast as possible, so there is only a small amount of events
- * that will be delayed.
- */
-public class EdgeGestureTracker {
- public final static String TAG = "EdgeGestureTracker";
- public final static boolean DEBUG = false;
-
- public final static long TRIGGER_TIME_MS = 140;
- public final static int PIXEL_SWIPE_OFFTAKE_SLOP = 2;
-
- private final int mBaseThickness;
- private final int mBaseTriggerDistance;
- private final int mBasePerpendicularDistance;
-
- private int mThickness;
- private int mTriggerDistance;
- private int mPerpendicularDistance;
- private int mGracePeriodDistance;
- private long mTimeOut;
-
- private int mDisplayWidth;
- private int mDisplayHeight;
-
- private boolean mActive;
- private EdgeGesturePosition mPosition;
- private long mDownTime;
- private int mInitialX;
- private int mInitialY;
- private int mOffTake;
- private int mGracePeriod;
-
- public interface OnActivationListener {
- public void onActivation(MotionEvent event, int touchX, int touchY, EdgeGesturePosition position);
- }
- private OnActivationListener mActivationListener;
-
- public EdgeGestureTracker(int thickness, int distance, int perpendicular) {
- if (DEBUG) {
- Slog.d(TAG, "init: " + thickness + "," + distance);
- }
- mBaseThickness = thickness;
- mBaseTriggerDistance = distance;
- mBasePerpendicularDistance = perpendicular;
- setSensitivity(0);
- }
-
- private void setSensitivity(int sensitivity) {
- float factor = 0.0f;
- if (sensitivity >= 1) {
- factor = (sensitivity - 1) / 4.0f;
- }
- if (DEBUG) {
- Slog.d(TAG, "sensitivity: " + sensitivity + " => factor:" + factor);
- }
- // default values (without overlay):
- // 140ms ... 210ms
- mTimeOut = (long) (TRIGGER_TIME_MS * (factor + 1.0f));
- // 12dp ... 18dp
- mThickness = (int) (mBaseThickness * (factor + 1.0f));
- // 12dp ... 6dp
- mTriggerDistance = (int) (mBaseTriggerDistance * (1.0f - factor));
- mPerpendicularDistance = (int) (mBasePerpendicularDistance * (1.0f - factor));
- mGracePeriodDistance = (int) (mThickness / 3.0f);
- }
-
- public void setOnActivationListener(OnActivationListener listener) {
- mActivationListener = listener;
- }
-
- public void reset() {
- mActive = false;
- }
-
- public void updateDisplay(Display display) {
- Point outSize = new Point(0,0);
- display.getRealSize(outSize);
- mDisplayWidth = outSize.x;
- mDisplayHeight = outSize.y;
- if (DEBUG) {
- Slog.d(TAG, "new display: " + mDisplayWidth + "," + mDisplayHeight);
- }
- }
-
- public boolean start(MotionEvent motionEvent, int positions, int sensitivity) {
- final boolean unrestricted = (positions & EdgeServiceConstants.UNRESTRICTED) != 0;
- final int x = (int) motionEvent.getX();
- final float fx = motionEvent.getX() / mDisplayWidth;
- final int y = (int) motionEvent.getY();
- final float fy = motionEvent.getY() / mDisplayHeight;
-
- // calculate trigger geometry based on sensitivity
- setSensitivity(sensitivity);
-
- if ((positions & EdgeGesturePosition.LEFT.FLAG) != 0) {
- if (x < mThickness && (unrestricted || (fy > 0.1f && fy < 0.9f))) {
- startWithPosition(motionEvent, EdgeGesturePosition.LEFT);
- return true;
- }
- }
- if ((positions & EdgeGesturePosition.BOTTOM.FLAG) != 0) {
- if (y > mDisplayHeight - mThickness && (unrestricted || (fx > 0.1f && fx < 0.9f))) {
- startWithPosition(motionEvent, EdgeGesturePosition.BOTTOM);
- return true;
- }
- }
- if ((positions & EdgeGesturePosition.RIGHT.FLAG) != 0) {
- if (x > mDisplayWidth - mThickness && (unrestricted || (fy > 0.1f && fy < 0.9f))) {
- startWithPosition(motionEvent, EdgeGesturePosition.RIGHT);
- return true;
- }
- }
- if ((positions & EdgeGesturePosition.TOP.FLAG) != 0) {
- if (y < mThickness && (unrestricted || (fx > 0.1f && fx < 0.9f))) {
- startWithPosition(motionEvent, EdgeGesturePosition.TOP);
- return true;
- }
- }
- return false;
- }
-
- private void startWithPosition(MotionEvent motionEvent, EdgeGesturePosition position) {
- if (DEBUG) {
- Slog.d(TAG, "start tracking from " + position.name());
- }
-
- mDownTime = motionEvent.getDownTime();
- this.mPosition = position;
- mInitialX = (int) motionEvent.getX();
- mInitialY = (int) motionEvent.getY();
- switch (position) {
- case LEFT:
- mGracePeriod = mGracePeriodDistance;
- mOffTake = mInitialX - PIXEL_SWIPE_OFFTAKE_SLOP;
- break;
- case BOTTOM:
- mOffTake = mInitialY + PIXEL_SWIPE_OFFTAKE_SLOP;
- break;
- case RIGHT:
- mGracePeriod = mDisplayWidth - mGracePeriodDistance;
- mOffTake = mInitialX + PIXEL_SWIPE_OFFTAKE_SLOP;
- break;
- case TOP:
- mOffTake = mInitialY - PIXEL_SWIPE_OFFTAKE_SLOP;
- break;
- }
- mActive = true;
- }
-
- public boolean move(MotionEvent motionEvent) {
- if (!mActive || motionEvent.getEventTime() - mDownTime > mTimeOut) {
- Slog.d(TAG, "edge gesture timeout: " + (motionEvent.getEventTime() - mDownTime));
- mActive = false;
- return false;
- }
-
- final int x = (int) motionEvent.getX();
- final int y = (int) motionEvent.getY();
- final int deltaX = x - mInitialX;
- final int deltaY = y - mInitialY;
-
- if (DEBUG) {
- Slog.d(TAG, "move at " + x + "," + y + " " + deltaX + "," + deltaY);
- }
-
- boolean loaded = false;
- switch (mPosition) {
- case LEFT:
- if (x < mGracePeriod) {
- mInitialY = y;
- }
- if (deltaY < mPerpendicularDistance && deltaY > -mPerpendicularDistance
- && x >= mOffTake) {
- if (deltaX < mTriggerDistance) {
- mOffTake = x - PIXEL_SWIPE_OFFTAKE_SLOP;
- return true;
- }
- loaded = true;
- }
- break;
- case BOTTOM:
- if (deltaX < mPerpendicularDistance && deltaX > -mPerpendicularDistance
- && y <= mOffTake) {
- if (deltaY > -mTriggerDistance) {
- mOffTake = y + PIXEL_SWIPE_OFFTAKE_SLOP;
- return true;
- }
- loaded = true;
- }
- break;
- case RIGHT:
- if (x > mGracePeriod) {
- mInitialY = y;
- }
- if (deltaY < mPerpendicularDistance && deltaY > -mPerpendicularDistance
- && x <= mOffTake) {
- if (deltaX > -mTriggerDistance) {
- mOffTake = x + PIXEL_SWIPE_OFFTAKE_SLOP;
- return true;
- }
- loaded = true;
- }
- break;
- case TOP:
- if (deltaX < mPerpendicularDistance && deltaX > -mPerpendicularDistance
- && y >= mOffTake) {
- if (deltaY < mTriggerDistance) {
- mOffTake = y - PIXEL_SWIPE_OFFTAKE_SLOP;
- return true;
- }
- loaded = true;
- }
- break;
- }
- mActive = false;
- if (loaded && mActivationListener != null) {
- if (DEBUG) {
- Slog.d(TAG, "activate at " + x + "," + y + " " + mPosition + " within "
- + (SystemClock.uptimeMillis() - mDownTime) + "ms");
- }
- mActivationListener.onActivation(motionEvent, x, y, mPosition);
- }
- return loaded;
- }
-} \ No newline at end of file