/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
// monitor for system gestures mSystemGestures = new SystemGesturesPointerEventListener(context, new SystemGesturesPointerEventListener.Callbacks() { @Override public void onSwipeFromTop() { if (mStatusBar != null) { requestTransientBars(mStatusBar); } } @Override public void onSwipeFromBottom() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromRight() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromLeft() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) { requestTransientBars(mNavigationBar); } } @Override public void onFling(int duration) { if (mPowerManagerInternal != null) { mPowerManagerInternal.powerHint( PowerManagerInternal.POWER_HINT_INTERACTION, duration); } } @Override public void onDebug() { // no-op } @Override public void onDown() { mOrientationListener.onTouchStart(); } @Override public void onUpOrCancel() { mOrientationListener.onTouchEnd(); } @Override public void onMouseHoverAtTop() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS; mHandler.sendMessageDelayed(msg, 500); } @Override public void onMouseHoverAtBottom() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION; mHandler.sendMessageDelayed(msg, 500); } @Override public void onMouseLeaveFromEdge() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); } });
Among them requestTransientBars(mStatusBar); is to ask to display statusbar.
Let's look at /frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
/* * Listens for system-wide input gestures, firing callbacks when detected. * @hide */ public class SystemGesturesPointerEventListener implements PointerEventListener
The PhoneWindowManager will make the SystemGesturesPointerEventListener
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
mWindowManagerFuncs is the WindowManagerService implementation
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs @Override public void registerPointerEventListener(PointerEventListener listener) { mPointerEventDispatcher.registerInputEventListener(listener); } //Here establishes the input channel of the window manager mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));
mPointerEventDispatcher is
/frameworks/base/services/core/java/com/android/server/wm/PointerEventDispatcher.java
application also has its own input channel, in addWindow of WindowManagerService
final boolean openInputChannels = (outInputChannel != null && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0); if (openInputChannels) { win.openInputChannel(outInputChannel); }
/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void openInputChannel(InputChannel outInputChannel) { if (mInputChannel != null) { throw new IllegalStateException("Window already has an input channel."); } String name = makeInputChannelName(); InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); mInputChannel = inputChannels[0]; mClientChannel = inputChannels[1]; mInputWindowHandle.inputChannel = inputChannels[0]; if (outInputChannel != null) { mClientChannel.transferTo(outInputChannel); mClientChannel.dispose(); mClientChannel = null; } else { // If the window died visible, we setup a dummy input channel, so that taps // can still detected by input monitor channel, and we can relaunch the app. // Create dummy event receiver that simply reports all events as handled. mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); } mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle);
How the underlying event is passed to the input channel depends on
frameworks/native/services/inputflinger/InputDispatcher.cpp
dispatchMotionLocked{ .... if (isPointerEvent) { // Pointer event. (eg. touchscreen) injectionResult = findTouchedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime, &conflictingPointerActions); } else { // Non touch event. (eg. trackball) injectionResult = findFocusedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime); } .... if (isMainDisplay(entry->displayId)) { addMonitoringTargetsLocked(inputTargets); }
findTouchedWindowTargetsLocked here corresponds to the input channel of the application, and
addMonitoringTargetsLocked corresponds to the input channel of the window manager.
Through this section, we know that when an event is generated, it will be dispatched to the application window as well as to the window manager. The window manager mainly deals with the system. events, such as displaying statusbar, navigationbar.
There are still many details about the input channel. You should study the code slowly by yourself. Only a general code flow is recorded here.