Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java +58 −42 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi private Context mContext; private PieManager mPieManager; private PieView mPieContainer; private boolean mIsDetaching = false; /** * This is only needed for #toggleRecentApps() and #showSearchPanel() */ Loading Loading @@ -143,12 +144,12 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi // restore listener state immediately (after the bookkeeping), and since the // search panel is a single gesture we will not trigger again mHandler.obtainMessage(MSG_PIE_RESTORE_LISTENER_STATE).sendToTarget(); } else if (mPieContainer != null) { // set the snap points depending on current trigger and mask mPieContainer.setSnapPoints(mPieTriggerMask & ~mPieTriggerSlots); activateFromListener(touchX, touchY, position); } else if (mPieContainer != null && activateFromListener(touchX, touchY, position)) { // give the main thread some time to do the bookkeeping mHandler.obtainMessage(MSG_PIE_GAIN_FOCUS).sendToTarget(); } else { // if anything goes wrong, just quit the ongoing activation mPieActivationListener.restoreListenerState(); } } }; Loading @@ -166,9 +167,13 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); break; case MSG_PIE_GAIN_FOCUS: if (mPieContainer != null) { if (!mPieActivationListener.gainTouchFocus(mPieContainer.getWindowToken())) { mPieContainer.exit(); } } else { mPieActivationListener.restoreListenerState(); } break; case MSG_PIE_RESTORE_LISTENER_STATE: mPieActivationListener.restoreListenerState(); Loading Loading @@ -235,8 +240,11 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi setupContainer(); setupNavigationItems(); setupListener(); } else { } else if (!isShowing()) { detachContainer(); } else { // delay detach to #onExit() mIsDetaching = true; } } } Loading Loading @@ -292,23 +300,6 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi mSettingsObserver.onChange(true); } private void detachContainer() { if (mPieContainer == null) { return; } mPieManager.updatePieActivationListener(mPieActivationListener, 0); if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } mContext.unregisterReceiver(mBroadcastReceiver); mPieContainer.clearSlices(); mPieContainer = null; } public void attachStatusBar(BaseStatusBar statusBar) { mStatusBar = statusBar; } Loading Loading @@ -349,6 +340,33 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi mPieContainer.addSlice(mSysInfo); } @Override public void onExit() { mWindowManager.removeView(mPieContainer); mPieActivationListener.restoreListenerState(); if (mIsDetaching) { detachContainer(); mIsDetaching = false; } } private void detachContainer() { if (mPieContainer == null) { return; } mPieManager.updatePieActivationListener(mPieActivationListener, 0); if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } mContext.unregisterReceiver(mBroadcastReceiver); mPieContainer.clearSlices(); mPieContainer = null; } private void setupListener() { ContentResolver resolver = mContext.getContentResolver(); Loading Loading @@ -424,7 +442,6 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi return item; } } return null; } Loading @@ -435,15 +452,20 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi } } public void activateFromListener(int touchX, int touchY, PiePosition position) { if (!isShowing()) { public boolean activateFromListener(int touchX, int touchY, PiePosition position) { if (isShowing()) { return false; } doHapticTriggerFeedback(); mPosition = position; Point center = new Point(touchX, touchY); mPieContainer.setSnapPoints(mPieTriggerMask & ~mPieTriggerSlots); mPieContainer.activate(center, position); mWindowManager.addView(mPieContainer, generateLayoutParam()); } return true; } private WindowManager.LayoutParams generateLayoutParam() { Loading @@ -464,18 +486,12 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi return lp; } @Override public void onExit() { mWindowManager.removeView(mPieContainer); mPieActivationListener.restoreListenerState(); } public void updatePieTriggerMask(int newMask) { int oldState = mPieTriggerSlots & mPieTriggerMask; mPieTriggerMask = newMask; // first we check, if it would make a change if ((mPieTriggerSlots & mPieTriggerMask) != oldState) { // check if we are active and if it would make a change at all if (mPieContainer != null && ((mPieTriggerSlots & mPieTriggerMask) != oldState)) { setupListener(); } } Loading Loading @@ -669,7 +685,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi } public boolean isShowing() { return mPieContainer.isShowing(); return mPieContainer != null && mPieContainer.isShowing(); } public boolean isSearchLightEnabled() { Loading services/java/com/android/server/pie/PieInputFilter.java +12 −11 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ import java.io.PrintWriter; * 5) POSTSYNTHESIZE: * mSyntheticDownTime != -1 * All following events will have the down time set to the synthesized ACTION_DOWN event time * until an ACTION_UP is encountered and the state is reset to LISTEN. * until an ACTION_UP or ACTION_CANCEL is encountered and the state is reset to LISTEN. * <p> * If you are reading this within Java Doc, you are doing something wrong ;) */ Loading @@ -81,7 +81,7 @@ public class PieInputFilter implements IInputFilter { 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 = true; private static final boolean SYSTRACE = false; private final Handler mHandler; Loading Loading @@ -174,6 +174,7 @@ public class PieInputFilter implements IInputFilter { res.getDimensionPixelSize(R.dimen.pie_perpendicular_distance)); mTracker.setOnActivationListener(new OnActivationListener() { public void onActivation(MotionEvent event, int touchX, int touchY, PiePosition position) { // mLock is held by #processMotionEvent mHandler.obtainMessage(PieService.MSG_PIE_ACTIVATION, touchX, touchY, position).sendToTarget(); mState = State.LOCKED; Loading Loading @@ -307,7 +308,7 @@ public class PieInputFilter implements IInputFilter { case SYNTHESIZE: if (action == MotionEvent.ACTION_MOVE) { clearDelayedMotionEventsLocked(); sendSynthesizedMotionEvent(motionEvent, policyFlags); sendSynthesizedMotionEventLocked(motionEvent, policyFlags); mState = State.POSTSYNTHESIZE; } else { // This is the case where a race condition caught us: We already Loading @@ -319,7 +320,7 @@ public class PieInputFilter implements IInputFilter { break; case POSTSYNTHESIZE: motionEvent.setDownTime(mSyntheticDownTime); if (action == MotionEvent.ACTION_UP) { if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { mState = State.LISTEN; mSyntheticDownTime = -1; } Loading Loading @@ -396,7 +397,7 @@ public class PieInputFilter implements IInputFilter { if (info.event.getActionMasked() == MotionEvent.ACTION_DOWN) { mSyntheticDownTime = info.event.getDownTime() + offset; } sendMotionEventWithOffset(info.event, info.policyFlags, mSyntheticDownTime, offset); sendMotionEventWithOffsetLocked(info.event, info.policyFlags, mSyntheticDownTime, offset); if (info.event.getActionMasked() == MotionEvent.ACTION_UP) { mSyntheticDownTime = -1; } Loading @@ -421,11 +422,11 @@ public class PieInputFilter implements IInputFilter { } } private void sendMotionEventWithOffset(MotionEvent event, int policyFlags, private void sendMotionEventWithOffsetLocked(MotionEvent event, int policyFlags, long downTime, long offset) { final int pointerCount = event.getPointerCount(); PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount); PointerProperties[] properties = getTempPointerPropertiesWithMinSize(pointerCount); 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]); Loading @@ -437,7 +438,7 @@ public class PieInputFilter implements IInputFilter { policyFlags); } private PointerCoords[] getTempPointerCoordsWithMinSize(int size) { private PointerCoords[] getTempPointerCoordsWithMinSizeLocked(int size) { final int oldSize = mTempPointerCoords.length; if (oldSize < size) { PointerCoords[] oldTempPointerCoords = mTempPointerCoords; Loading @@ -450,7 +451,7 @@ public class PieInputFilter implements IInputFilter { return mTempPointerCoords; } private PointerProperties[] getTempPointerPropertiesWithMinSize(int size) { private PointerProperties[] getTempPointerPropertiesWithMinSizeLocked(int size) { final int oldSize = mTempPointerProperties.length; if (oldSize < size) { PointerProperties[] oldTempPointerProperties = mTempPointerProperties; Loading @@ -463,7 +464,7 @@ public class PieInputFilter implements IInputFilter { return mTempPointerProperties; } private void sendSynthesizedMotionEvent(MotionEvent event, int policyFlags) { private void sendSynthesizedMotionEventLocked(MotionEvent event, int policyFlags) { if (event.getPointerCount() == 1) { event.getPointerCoords(0, mTempPointerCoords[0]); event.getPointerProperties(0, mTempPointerProperties[0]); Loading services/java/com/android/server/pie/PieService.java +93 −103 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import android.service.pie.IPieService; import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; import android.view.View; import android.view.WindowManager; import com.android.internal.util.pie.PiePosition; Loading Loading @@ -69,18 +68,16 @@ public class PieService extends IPieService.Stub { private final Context mContext; private final InputManagerService mInputManager; private final WindowManagerService mWindowManager; private HandlerThread mHandlerThread = new HandlerThread("Pie"); private final HandlerThread mHandlerThread = new HandlerThread("Pie"); private Handler mHandler; // Lock for thread, handler, mInputFilter, activations and listener related variables // Lock for mInputFilter, activations and listener related variables private final Object mLock = new Object(); private Handler mHandler; private PieInputFilter mInputFilter; private int mGlobalPositions = 0; private int mGlobalSensitivity = 3; private boolean mIsMonitoring = false; private final class PieActivationListenerRecord extends IPieHostCallback.Stub implements DeathRecipient { private boolean mActive; Loading @@ -94,16 +91,16 @@ public class PieService extends IPieService.Stub { removeListenerRecord(this); } public void updateFlags(int flags) { private void updateFlags(int flags) { this.positions = flags & POSITION_MASK; this.sensitivity = (flags & SENSITIVITY_MASK) >> SENSITIVITY_SHIFT; } public boolean eligibleForActivation(int positionFlag) { private boolean eligibleForActivation(int positionFlag) { return (positions & positionFlag) != 0; } public boolean notifyPieActivation(int touchX, int touchY, PiePosition position) { private boolean notifyPieActivation(int touchX, int touchY, PiePosition position) { if ((positions & position.FLAG) != 0) { try { listener.onPieActivation(touchX, touchY, position.INDEX, 0); Loading Loading @@ -167,7 +164,6 @@ public class PieService extends IPieService.Stub { public PieService(Context context, WindowManagerService windowManager, InputManagerService inputManager) { mContext = context; mInputManager = inputManager; mWindowManager = windowManager; } // called by system server Loading @@ -186,19 +182,41 @@ public class PieService extends IPieService.Stub { }); mDisplayObserver = new DisplayObserver(mContext, mHandler); // check if anyone registered during startup updateMonitoring(); mHandler.obtainMessage(MSG_UPDATE_SERVICE, mGlobalPositions, mGlobalSensitivity).sendToTarget(); updateMonitoring(); } private void updateMonitoring() { synchronized(mLock) { mGlobalPositions = 0; mGlobalSensitivity = SENSITIVITY_NONE; for (PieActivationListenerRecord temp : mPieActivationListener) { mGlobalPositions |= temp.positions; if (temp.sensitivity != SENSITIVITY_NONE) { mGlobalSensitivity = Math.max(mGlobalSensitivity, temp.sensitivity); } } // if no special sensitivity is requested, we settle on DEFAULT if (mGlobalSensitivity == SENSITIVITY_NONE) { mGlobalSensitivity = SENSITIVITY_DEFAULT; } if (mInputFilter == null && mGlobalPositions != 0) { enforceMonitoringLocked(); } else if (mInputFilter != null && mGlobalPositions == 0) { shutdownMonitoringLocked(); } } } private void enforceMonitoringLocked() { if (DEBUG) { Slog.d(TAG, "Attempting to start monitoring input events ..."); } if (mInputFilter == null) { mInputFilter = new PieInputFilter(mContext, mHandler); mInputManager.registerSecondaryInputFilter(mInputFilter); } mDisplayObserver.observe(); } Loading @@ -207,22 +225,9 @@ public class PieService extends IPieService.Stub { Slog.d(TAG, "Shutting down monitoring input events ..."); } mDisplayObserver.unobserve(); if (mInputFilter != null) { mInputManager.unregisterSecondaryInputFilter(mInputFilter); mInputFilter = null; } } private void updateMonitoring() { synchronized(mLock) { if (!mIsMonitoring && mGlobalPositions != 0) { enforceMonitoringLocked(); } else if (mIsMonitoring && mGlobalPositions == 0) { shutdownMonitoringLocked(); } mIsMonitoring = mGlobalPositions != 0; } } // called through Binder public IPieHostCallback registerPieActivationListener(IPieActivationListener listener) { Loading @@ -242,6 +247,12 @@ public class PieService extends IPieService.Stub { record = findListenerRecordLocked(listener.asBinder()); if (record == null) { record = new PieActivationListenerRecord(listener); try { listener.asBinder().linkToDeath(record, 0); } catch (RemoteException e) { Slog.w(TAG, "Recipient died during registration pid=" + Binder.getCallingPid()); return null; } mPieActivationListener.add(record); } } Loading @@ -260,14 +271,13 @@ public class PieService extends IPieService.Stub { throw new IllegalStateException("listener not registered"); } record.updateFlags(positionFlags); updatePositionsLocked(); updateSensitivityLocked(); updateMonitoring(); // update input filter only when not being active and #systemReady() was called if (mActiveRecord == null && mHandler != null) { mHandler.obtainMessage(MSG_UPDATE_SERVICE, mGlobalPositions, mGlobalSensitivity).sendToTarget(); } } updateMonitoring(); } private PieActivationListenerRecord findListenerRecordLocked(IBinder listener) { Loading @@ -279,38 +289,18 @@ public class PieService extends IPieService.Stub { return null; } private void updatePositionsLocked() { mGlobalPositions = 0; for (PieActivationListenerRecord temp : mPieActivationListener) { mGlobalPositions |= temp.positions; } } private void updateSensitivityLocked() { mGlobalSensitivity = SENSITIVITY_NONE; for (PieActivationListenerRecord temp : mPieActivationListener) { if (temp.sensitivity != SENSITIVITY_NONE) { mGlobalSensitivity = Math.max(mGlobalSensitivity, temp.sensitivity); } } // if no special sensitivity is requested, we settle on DEFAULT if (mGlobalSensitivity == SENSITIVITY_NONE) { mGlobalSensitivity = SENSITIVITY_DEFAULT; } } private void removeListenerRecord(PieActivationListenerRecord record) { synchronized(mLock) { mPieActivationListener.remove(record); updatePositionsLocked(); updateMonitoring(); // check if the record was the active one if (record == mActiveRecord) { // restore input filter state by updating mHandler.obtainMessage(MSG_UPDATE_SERVICE, mGlobalPositions, mGlobalSensitivity).sendToTarget(); mActiveRecord = null; } } updateMonitoring(); } // called by handler thread Loading @@ -333,55 +323,8 @@ public class PieService extends IPieService.Stub { if (target != null && target.notifyPieActivation(touchX, touchY, position)) { mActiveRecord = target; } } return mActiveRecord != null; } @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, "PieService 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 PieService from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); return; } pw.println("PIE SERVICE (dumpsys pieservice)\n"); synchronized(mLock) { pw.println(" mIsMonitoring=" + mIsMonitoring); pw.println(" mInputFilter=" + mInputFilter); if (mInputFilter != null) { mInputFilter.dump(pw, " "); } pw.println(" mGlobalPositions=0x" + Integer.toHexString(mGlobalPositions)); int i = 0; for (PieActivationListenerRecord record : mPieActivationListener) { if (record == mActiveRecord) break; i++; } pw.println(" mActiveRecord=" + (mActiveRecord != null ? ("#" + i) : "null")); i = 0; for (PieActivationListenerRecord record : mPieActivationListener) { pw.println(" Listener #" + i + ":"); record.dump(pw, " "); i++; } } } private final class H extends Handler { Loading Loading @@ -481,4 +424,51 @@ public class PieService extends IPieService.Stub { 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, "PieService 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 PieService from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); return; } pw.println("PIE SERVICE (dumpsys pieservice)\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 (PieActivationListenerRecord record : mPieActivationListener) { if (record == mActiveRecord) break; i++; } pw.println(" mActiveRecord=" + (mActiveRecord != null ? ("#" + i) : "null")); i = 0; for (PieActivationListenerRecord record : mPieActivationListener) { pw.println(" Listener #" + i + ":"); record.dump(pw, " "); i++; } } } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java +58 −42 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi private Context mContext; private PieManager mPieManager; private PieView mPieContainer; private boolean mIsDetaching = false; /** * This is only needed for #toggleRecentApps() and #showSearchPanel() */ Loading Loading @@ -143,12 +144,12 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi // restore listener state immediately (after the bookkeeping), and since the // search panel is a single gesture we will not trigger again mHandler.obtainMessage(MSG_PIE_RESTORE_LISTENER_STATE).sendToTarget(); } else if (mPieContainer != null) { // set the snap points depending on current trigger and mask mPieContainer.setSnapPoints(mPieTriggerMask & ~mPieTriggerSlots); activateFromListener(touchX, touchY, position); } else if (mPieContainer != null && activateFromListener(touchX, touchY, position)) { // give the main thread some time to do the bookkeeping mHandler.obtainMessage(MSG_PIE_GAIN_FOCUS).sendToTarget(); } else { // if anything goes wrong, just quit the ongoing activation mPieActivationListener.restoreListenerState(); } } }; Loading @@ -166,9 +167,13 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); break; case MSG_PIE_GAIN_FOCUS: if (mPieContainer != null) { if (!mPieActivationListener.gainTouchFocus(mPieContainer.getWindowToken())) { mPieContainer.exit(); } } else { mPieActivationListener.restoreListenerState(); } break; case MSG_PIE_RESTORE_LISTENER_STATE: mPieActivationListener.restoreListenerState(); Loading Loading @@ -235,8 +240,11 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi setupContainer(); setupNavigationItems(); setupListener(); } else { } else if (!isShowing()) { detachContainer(); } else { // delay detach to #onExit() mIsDetaching = true; } } } Loading Loading @@ -292,23 +300,6 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi mSettingsObserver.onChange(true); } private void detachContainer() { if (mPieContainer == null) { return; } mPieManager.updatePieActivationListener(mPieActivationListener, 0); if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } mContext.unregisterReceiver(mBroadcastReceiver); mPieContainer.clearSlices(); mPieContainer = null; } public void attachStatusBar(BaseStatusBar statusBar) { mStatusBar = statusBar; } Loading Loading @@ -349,6 +340,33 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi mPieContainer.addSlice(mSysInfo); } @Override public void onExit() { mWindowManager.removeView(mPieContainer); mPieActivationListener.restoreListenerState(); if (mIsDetaching) { detachContainer(); mIsDetaching = false; } } private void detachContainer() { if (mPieContainer == null) { return; } mPieManager.updatePieActivationListener(mPieActivationListener, 0); if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } mContext.unregisterReceiver(mBroadcastReceiver); mPieContainer.clearSlices(); mPieContainer = null; } private void setupListener() { ContentResolver resolver = mContext.getContentResolver(); Loading Loading @@ -424,7 +442,6 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi return item; } } return null; } Loading @@ -435,15 +452,20 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi } } public void activateFromListener(int touchX, int touchY, PiePosition position) { if (!isShowing()) { public boolean activateFromListener(int touchX, int touchY, PiePosition position) { if (isShowing()) { return false; } doHapticTriggerFeedback(); mPosition = position; Point center = new Point(touchX, touchY); mPieContainer.setSnapPoints(mPieTriggerMask & ~mPieTriggerSlots); mPieContainer.activate(center, position); mWindowManager.addView(mPieContainer, generateLayoutParam()); } return true; } private WindowManager.LayoutParams generateLayoutParam() { Loading @@ -464,18 +486,12 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi return lp; } @Override public void onExit() { mWindowManager.removeView(mPieContainer); mPieActivationListener.restoreListenerState(); } public void updatePieTriggerMask(int newMask) { int oldState = mPieTriggerSlots & mPieTriggerMask; mPieTriggerMask = newMask; // first we check, if it would make a change if ((mPieTriggerSlots & mPieTriggerMask) != oldState) { // check if we are active and if it would make a change at all if (mPieContainer != null && ((mPieTriggerSlots & mPieTriggerMask) != oldState)) { setupListener(); } } Loading Loading @@ -669,7 +685,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, PieVi } public boolean isShowing() { return mPieContainer.isShowing(); return mPieContainer != null && mPieContainer.isShowing(); } public boolean isSearchLightEnabled() { Loading
services/java/com/android/server/pie/PieInputFilter.java +12 −11 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ import java.io.PrintWriter; * 5) POSTSYNTHESIZE: * mSyntheticDownTime != -1 * All following events will have the down time set to the synthesized ACTION_DOWN event time * until an ACTION_UP is encountered and the state is reset to LISTEN. * until an ACTION_UP or ACTION_CANCEL is encountered and the state is reset to LISTEN. * <p> * If you are reading this within Java Doc, you are doing something wrong ;) */ Loading @@ -81,7 +81,7 @@ public class PieInputFilter implements IInputFilter { 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 = true; private static final boolean SYSTRACE = false; private final Handler mHandler; Loading Loading @@ -174,6 +174,7 @@ public class PieInputFilter implements IInputFilter { res.getDimensionPixelSize(R.dimen.pie_perpendicular_distance)); mTracker.setOnActivationListener(new OnActivationListener() { public void onActivation(MotionEvent event, int touchX, int touchY, PiePosition position) { // mLock is held by #processMotionEvent mHandler.obtainMessage(PieService.MSG_PIE_ACTIVATION, touchX, touchY, position).sendToTarget(); mState = State.LOCKED; Loading Loading @@ -307,7 +308,7 @@ public class PieInputFilter implements IInputFilter { case SYNTHESIZE: if (action == MotionEvent.ACTION_MOVE) { clearDelayedMotionEventsLocked(); sendSynthesizedMotionEvent(motionEvent, policyFlags); sendSynthesizedMotionEventLocked(motionEvent, policyFlags); mState = State.POSTSYNTHESIZE; } else { // This is the case where a race condition caught us: We already Loading @@ -319,7 +320,7 @@ public class PieInputFilter implements IInputFilter { break; case POSTSYNTHESIZE: motionEvent.setDownTime(mSyntheticDownTime); if (action == MotionEvent.ACTION_UP) { if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { mState = State.LISTEN; mSyntheticDownTime = -1; } Loading Loading @@ -396,7 +397,7 @@ public class PieInputFilter implements IInputFilter { if (info.event.getActionMasked() == MotionEvent.ACTION_DOWN) { mSyntheticDownTime = info.event.getDownTime() + offset; } sendMotionEventWithOffset(info.event, info.policyFlags, mSyntheticDownTime, offset); sendMotionEventWithOffsetLocked(info.event, info.policyFlags, mSyntheticDownTime, offset); if (info.event.getActionMasked() == MotionEvent.ACTION_UP) { mSyntheticDownTime = -1; } Loading @@ -421,11 +422,11 @@ public class PieInputFilter implements IInputFilter { } } private void sendMotionEventWithOffset(MotionEvent event, int policyFlags, private void sendMotionEventWithOffsetLocked(MotionEvent event, int policyFlags, long downTime, long offset) { final int pointerCount = event.getPointerCount(); PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount); PointerProperties[] properties = getTempPointerPropertiesWithMinSize(pointerCount); 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]); Loading @@ -437,7 +438,7 @@ public class PieInputFilter implements IInputFilter { policyFlags); } private PointerCoords[] getTempPointerCoordsWithMinSize(int size) { private PointerCoords[] getTempPointerCoordsWithMinSizeLocked(int size) { final int oldSize = mTempPointerCoords.length; if (oldSize < size) { PointerCoords[] oldTempPointerCoords = mTempPointerCoords; Loading @@ -450,7 +451,7 @@ public class PieInputFilter implements IInputFilter { return mTempPointerCoords; } private PointerProperties[] getTempPointerPropertiesWithMinSize(int size) { private PointerProperties[] getTempPointerPropertiesWithMinSizeLocked(int size) { final int oldSize = mTempPointerProperties.length; if (oldSize < size) { PointerProperties[] oldTempPointerProperties = mTempPointerProperties; Loading @@ -463,7 +464,7 @@ public class PieInputFilter implements IInputFilter { return mTempPointerProperties; } private void sendSynthesizedMotionEvent(MotionEvent event, int policyFlags) { private void sendSynthesizedMotionEventLocked(MotionEvent event, int policyFlags) { if (event.getPointerCount() == 1) { event.getPointerCoords(0, mTempPointerCoords[0]); event.getPointerProperties(0, mTempPointerProperties[0]); Loading
services/java/com/android/server/pie/PieService.java +93 −103 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import android.service.pie.IPieService; import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; import android.view.View; import android.view.WindowManager; import com.android.internal.util.pie.PiePosition; Loading Loading @@ -69,18 +68,16 @@ public class PieService extends IPieService.Stub { private final Context mContext; private final InputManagerService mInputManager; private final WindowManagerService mWindowManager; private HandlerThread mHandlerThread = new HandlerThread("Pie"); private final HandlerThread mHandlerThread = new HandlerThread("Pie"); private Handler mHandler; // Lock for thread, handler, mInputFilter, activations and listener related variables // Lock for mInputFilter, activations and listener related variables private final Object mLock = new Object(); private Handler mHandler; private PieInputFilter mInputFilter; private int mGlobalPositions = 0; private int mGlobalSensitivity = 3; private boolean mIsMonitoring = false; private final class PieActivationListenerRecord extends IPieHostCallback.Stub implements DeathRecipient { private boolean mActive; Loading @@ -94,16 +91,16 @@ public class PieService extends IPieService.Stub { removeListenerRecord(this); } public void updateFlags(int flags) { private void updateFlags(int flags) { this.positions = flags & POSITION_MASK; this.sensitivity = (flags & SENSITIVITY_MASK) >> SENSITIVITY_SHIFT; } public boolean eligibleForActivation(int positionFlag) { private boolean eligibleForActivation(int positionFlag) { return (positions & positionFlag) != 0; } public boolean notifyPieActivation(int touchX, int touchY, PiePosition position) { private boolean notifyPieActivation(int touchX, int touchY, PiePosition position) { if ((positions & position.FLAG) != 0) { try { listener.onPieActivation(touchX, touchY, position.INDEX, 0); Loading Loading @@ -167,7 +164,6 @@ public class PieService extends IPieService.Stub { public PieService(Context context, WindowManagerService windowManager, InputManagerService inputManager) { mContext = context; mInputManager = inputManager; mWindowManager = windowManager; } // called by system server Loading @@ -186,19 +182,41 @@ public class PieService extends IPieService.Stub { }); mDisplayObserver = new DisplayObserver(mContext, mHandler); // check if anyone registered during startup updateMonitoring(); mHandler.obtainMessage(MSG_UPDATE_SERVICE, mGlobalPositions, mGlobalSensitivity).sendToTarget(); updateMonitoring(); } private void updateMonitoring() { synchronized(mLock) { mGlobalPositions = 0; mGlobalSensitivity = SENSITIVITY_NONE; for (PieActivationListenerRecord temp : mPieActivationListener) { mGlobalPositions |= temp.positions; if (temp.sensitivity != SENSITIVITY_NONE) { mGlobalSensitivity = Math.max(mGlobalSensitivity, temp.sensitivity); } } // if no special sensitivity is requested, we settle on DEFAULT if (mGlobalSensitivity == SENSITIVITY_NONE) { mGlobalSensitivity = SENSITIVITY_DEFAULT; } if (mInputFilter == null && mGlobalPositions != 0) { enforceMonitoringLocked(); } else if (mInputFilter != null && mGlobalPositions == 0) { shutdownMonitoringLocked(); } } } private void enforceMonitoringLocked() { if (DEBUG) { Slog.d(TAG, "Attempting to start monitoring input events ..."); } if (mInputFilter == null) { mInputFilter = new PieInputFilter(mContext, mHandler); mInputManager.registerSecondaryInputFilter(mInputFilter); } mDisplayObserver.observe(); } Loading @@ -207,22 +225,9 @@ public class PieService extends IPieService.Stub { Slog.d(TAG, "Shutting down monitoring input events ..."); } mDisplayObserver.unobserve(); if (mInputFilter != null) { mInputManager.unregisterSecondaryInputFilter(mInputFilter); mInputFilter = null; } } private void updateMonitoring() { synchronized(mLock) { if (!mIsMonitoring && mGlobalPositions != 0) { enforceMonitoringLocked(); } else if (mIsMonitoring && mGlobalPositions == 0) { shutdownMonitoringLocked(); } mIsMonitoring = mGlobalPositions != 0; } } // called through Binder public IPieHostCallback registerPieActivationListener(IPieActivationListener listener) { Loading @@ -242,6 +247,12 @@ public class PieService extends IPieService.Stub { record = findListenerRecordLocked(listener.asBinder()); if (record == null) { record = new PieActivationListenerRecord(listener); try { listener.asBinder().linkToDeath(record, 0); } catch (RemoteException e) { Slog.w(TAG, "Recipient died during registration pid=" + Binder.getCallingPid()); return null; } mPieActivationListener.add(record); } } Loading @@ -260,14 +271,13 @@ public class PieService extends IPieService.Stub { throw new IllegalStateException("listener not registered"); } record.updateFlags(positionFlags); updatePositionsLocked(); updateSensitivityLocked(); updateMonitoring(); // update input filter only when not being active and #systemReady() was called if (mActiveRecord == null && mHandler != null) { mHandler.obtainMessage(MSG_UPDATE_SERVICE, mGlobalPositions, mGlobalSensitivity).sendToTarget(); } } updateMonitoring(); } private PieActivationListenerRecord findListenerRecordLocked(IBinder listener) { Loading @@ -279,38 +289,18 @@ public class PieService extends IPieService.Stub { return null; } private void updatePositionsLocked() { mGlobalPositions = 0; for (PieActivationListenerRecord temp : mPieActivationListener) { mGlobalPositions |= temp.positions; } } private void updateSensitivityLocked() { mGlobalSensitivity = SENSITIVITY_NONE; for (PieActivationListenerRecord temp : mPieActivationListener) { if (temp.sensitivity != SENSITIVITY_NONE) { mGlobalSensitivity = Math.max(mGlobalSensitivity, temp.sensitivity); } } // if no special sensitivity is requested, we settle on DEFAULT if (mGlobalSensitivity == SENSITIVITY_NONE) { mGlobalSensitivity = SENSITIVITY_DEFAULT; } } private void removeListenerRecord(PieActivationListenerRecord record) { synchronized(mLock) { mPieActivationListener.remove(record); updatePositionsLocked(); updateMonitoring(); // check if the record was the active one if (record == mActiveRecord) { // restore input filter state by updating mHandler.obtainMessage(MSG_UPDATE_SERVICE, mGlobalPositions, mGlobalSensitivity).sendToTarget(); mActiveRecord = null; } } updateMonitoring(); } // called by handler thread Loading @@ -333,55 +323,8 @@ public class PieService extends IPieService.Stub { if (target != null && target.notifyPieActivation(touchX, touchY, position)) { mActiveRecord = target; } } return mActiveRecord != null; } @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, "PieService 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 PieService from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); return; } pw.println("PIE SERVICE (dumpsys pieservice)\n"); synchronized(mLock) { pw.println(" mIsMonitoring=" + mIsMonitoring); pw.println(" mInputFilter=" + mInputFilter); if (mInputFilter != null) { mInputFilter.dump(pw, " "); } pw.println(" mGlobalPositions=0x" + Integer.toHexString(mGlobalPositions)); int i = 0; for (PieActivationListenerRecord record : mPieActivationListener) { if (record == mActiveRecord) break; i++; } pw.println(" mActiveRecord=" + (mActiveRecord != null ? ("#" + i) : "null")); i = 0; for (PieActivationListenerRecord record : mPieActivationListener) { pw.println(" Listener #" + i + ":"); record.dump(pw, " "); i++; } } } private final class H extends Handler { Loading Loading @@ -481,4 +424,51 @@ public class PieService extends IPieService.Stub { 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, "PieService 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 PieService from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); return; } pw.println("PIE SERVICE (dumpsys pieservice)\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 (PieActivationListenerRecord record : mPieActivationListener) { if (record == mActiveRecord) break; i++; } pw.println(" mActiveRecord=" + (mActiveRecord != null ? ("#" + i) : "null")); i = 0; for (PieActivationListenerRecord record : mPieActivationListener) { pw.println(" Listener #" + i + ":"); record.dump(pw, " "); i++; } } } }