`

当界面全屏时,在顶部下拉时会显示statusbar的实现原理

 
阅读更多
当界面全屏时,在顶部下拉时会显示statusbar的实现原理:
/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);
                    }
                });


其中requestTransientBars(mStatusBar);就是要求显示statusbar.
我们看看/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

在PhoneWindowManager会将SystemGesturesPointerEventListener进行
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);

mWindowManagerFuncs是WindowManagerService实现
/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);
    }
//这里建立了window manager的input channel
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));

mPointerEventDispatcher为
/frameworks/base/services/core/java/com/android/server/wm/PointerEventDispatcher.java

应用也有自己的input channel,在WindowManagerService的addWindow
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);


那底层事件是怎么传递到input channel,那就得看
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 这里对应的就是应用的input channel, 
addMonitoringTargetsLocked这个对应的就是window manager的input channel.
通过这段我们就知道产生事件的时候既会派发给应用window也会派发给window manager,window manager主要是处理system 的事件,比如显示statusbar,navigationbar.
关于input channel还有很多细节问题,要自己慢慢研读代码,这里只记录一个大概的代码流程
分享到:
评论

相关推荐

    ActionBar and StatusBar

    例如,在全屏模式下,可以隐藏StatusBar以获得更大的显示空间,但仍然需要保留ActionBar供用户操作。通过`SYSTEM_UI_FLAG_FULLSCREEN`标志可以实现StatusBar的隐藏和显示。 在实际开发中,我们还需要注意不同...

    android状态栏和主界面融为了一体

    5. **Notification Bar和StatusBar的区别**:状态栏(StatusBar)展示系统通知和图标,而通知栏(Notification Bar)是用户下拉状态栏时显示更详细的通知信息的区域。在某些情况下,可能需要隐藏通知栏以达到全屏...

    iOS- 解决App上下黑边

    在iOS开发过程中,有时会遇到应用在运行时无法全屏显示的问题,表现为屏幕四周出现黑边,这无疑会影响用户体验。本篇文章将详细讲解如何解决这一问题,让你的应用完美适应各种设备的屏幕尺寸。 首先,我们需要了解...

    低版本兼容的ActionBar下拉导航+悬浮透明样式

    在Android应用开发中,`ActionBar`是Android 3.0(API级别11)引入的一个重要组件,它提供了一个统一的界面,用于显示应用程序的标识、操作和当前上下文。然而,为了支持低版本Android系统,开发者需要进行一些适配...

    控制状态栏和导航栏显示隐藏接口

    在移动应用开发中,用户界面(UI)的设计与交互是至关重要的部分,而状态栏和导航栏作为用户界面的关键元素,对于用户体验有着显著的影响。本文将深入探讨如何使用"控制状态栏和导航栏显示隐藏接口"来优化应用程序的...

    原生android SystemUI源码

    1. **StatusBar**: 状态栏是Android手机屏幕顶部的一条横条,显示时间、电池状态、网络信号等信息,并提供滑动打开通知中心的入口。状态栏的源码中包含了对各种图标、指示器以及下拉菜单的管理。 2. **...

    SAP_SD_课程1[1]

    - **状态栏(Status Bar)**:显示系统的相关信息,如登录用户、当前时间、系统状态等。 - **命令字段(Command Field)**:允许用户直接输入业务代码或其他指令,快速访问系统功能。 **1.2 用户登录** - **客户...

Global site tag (gtag.js) - Google Analytics