原生全局手势在systemui模块,提供了滑动手势功能,如果不能修改framework代码,只能自己手撸了

1、监听系统全局触摸事件

private fun startGlobalInputMonitoring() {
        try {
            val obj = getSystemService(INPUT_SERVICE) as? InputManager ?: return
            inputManager = obj

            val monitorMethod = InputManager::class.java.getMethod(
                "monitorGestureInput",
                String::class.java,
                Int::class.javaPrimitiveType
            )
            mInputMonitor = monitorMethod.invoke(
                inputManager,
                "SystemUI-Global-Gesture",
                Display.DEFAULT_DISPLAY
            )

            if (mInputMonitor == null) {
                Log.w(TAG, "Failed to get InputMonitor instance.")
                return
            }

            val getInputChannelMethod = mInputMonitor?.javaClass?.getMethod("getInputChannel")
            val inputChannel = getInputChannelMethod?.invoke(mInputMonitor) as? InputChannel

            mInputThread =
                HandlerThread("Input-Thread", Process.THREAD_PRIORITY_FOREGROUND).apply {
                    start()
                }
            mInputHandler = Handler(mInputThread!!.looper)
            handleReceiver(inputChannel)
        } catch (e: Exception) {
        }
    }

fun handleReceiver(inputChannel: InputChannel?) {
        if (mInputThread?.looper == null) return
        mInputEventReceiver = object : InputEventReceiver(inputChannel, mInputThread!!.looper) {
            override fun onInputEvent(event: InputEvent) {
                if (event !is MotionEvent) {
                    finishInputEvent(event, true)
                    return
                }
                val copiedEvent = MotionEvent.obtain(event)
                finishInputEvent(event, true)
                try {
                    if (isSkipInputEvent(copiedEvent)) return
                    touch(copiedEvent)
                } catch (e: Exception) {
                    Log.w(TAG, "handleReceiver:", e)
                } finally {
                    copiedEvent.recycle()
                }
            }
        }
    }
View Code

2、判断手势方向

const val EDGE_ZONE_WIDTH_PX = 60 // 左右边缘触发触控宽度

/** 手势处理 */
    private fun touch(event: MotionEvent) {
        val isTouchEvent = (event.source and android.view.InputDevice.SOURCE_TOUCHSCREEN) != 0
        val action = event.actionMasked
        if (isTouchEvent &&
            action != MotionEvent.ACTION_HOVER_ENTER &&
            action != MotionEvent.ACTION_HOVER_MOVE &&
            action != MotionEvent.ACTION_HOVER_EXIT
        ) {
            if (action == MotionEvent.ACTION_DOWN) {
                mPendingThreeFingerGesture = GlobalGestureManager.VSwipeDirection.NONE
                mPendingSingleGesture = GlobalGestureManager.VSwipeDirection.NONE
                mIsThreeFingerTracking = false
                mThreeFingerDispatched = false
            }

            val threeFingerHandled = checkThreeFingerGesture(event)

            if (!threeFingerHandled && !mIsThreeFingerTracking) {
                mGestureDetector?.onTouchEvent(event)
            }

            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                if (action == MotionEvent.ACTION_UP && !threeFingerHandled) {
                    when (mPendingSingleGesture) {
                        GlobalGestureManager.VSwipeDirection.UP -> {
                            onSwipeUp()
                        }

                        GlobalGestureManager.VSwipeDirection.DOWN -> {
                            onSwipeDown()
                        }

                        GlobalGestureManager.VSwipeDirection.LEFT -> {
                            onSwipeLeft()
                        }

                        GlobalGestureManager.VSwipeDirection.RIGHT -> {
                            onSwipeRight()
                        }

                        else -> {}
                    }
                }
                mPendingThreeFingerGesture = GlobalGestureManager.VSwipeDirection.NONE
                mPendingSingleGesture = GlobalGestureManager.VSwipeDirection.NONE
                mIsThreeFingerTracking = false
                mThreeFingerDispatched = false
                mIsMoving = false
            }
        }
    }

private fun isInEdgeZone(x: Float, y: Float): Boolean {
        if (y < statusHeight) return true
        if (y > mScreenHeight - barHeight) return true
        val inMiddleVertical = y > statusHeight && y < mScreenHeight - barHeight
        if (inMiddleVertical && x < GlobalGestureManager.EDGE_ZONE_WIDTH_PX) return true
        if (inMiddleVertical && x > mScreenWidth - GlobalGestureManager.EDGE_ZONE_WIDTH_PX) return true
        return false
    }
touch

如果是上下滑,希望起点在systembar,否则不响应,如果是左右滑,希望起点从屏幕边缘开始,否则不响应
3、手势拦截

/** 拦截手势 */
    private fun isSkipInputEvent(event: MotionEvent): Boolean {
        val action = event.actionMasked
        log("isSkipInputEvent action=$action, x=${event.x} y=${event.y}")
        if (mIsInterceptActive) {
            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                mIsInterceptActive = false
                isFullScreenSkip = false
                log("isSkipInputEvent: intercept session end")
            }
            return true
        }
        when (action) {
            MotionEvent.ACTION_DOWN -> {
                isForbidGlobalGesture = InteractionAPIManager.isGlobalGestureDisabled()
                mInterceptDownX = event.x
                mInterceptDownY = event.y
                isFullScreenSkip = !SystemBarManager.isShowSystemBar()
                log("isSkipInputEvent isFullScreenSkip=$isFullScreenSkip, isForbidGlobalGesture=$isForbidGlobalGesture")
                if ((isForbidGlobalGesture || isFullScreenSkip) &&
                    isInEdgeZone(mInterceptDownX, mInterceptDownY)
                ) {
                    mIsInterceptActive = true
                    log("isSkipInputEvent: activate intercept session")
                    return true
                }
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                mIsInterceptActive = false
                isFullScreenSkip = false
            }
        }
        return false
    }
isSkipInputEvent

根据条件拦截手势响应

4、事件拦截

private fun pilferThreeFingerPointers() {
        try {
            if (!isSplit()) {
                Log.w(TAG, "pilferThreeFingerPointers: isSplit is false")
                return
            }
            val monitor = mInputMonitor ?: run {
                Log.w(TAG, "pilferThreeFingerPointers: mInputMonitor is null")
                return
            }
            val pilferMethod = monitor.javaClass.getMethod("pilferPointers")
            pilferMethod.invoke(monitor)
        } catch (e: Exception) {
            Log.w(TAG, "pilferThreeFingerPointers: ", e)
        }
    }

if (pointerCount >= 3 && action == MotionEvent.ACTION_POINTER_DOWN) {
            pilferThreeFingerPointers()
            return true
        }
pilferThreeFingerPointers

屏幕需要所有app都禁止响应三指操作,所以需要根据条件判断,在触摸时调用 mInputMonitor.pilferPointers()

package com.test.systemui.gesture

import android.app.Service
import android.content.Intent
import android.hardware.input.InputManager
import android.os.Handler
import android.os.HandlerThread
import android.os.IBinder
import android.os.Process
import android.os.RemoteCallbackList
import android.provider.Settings
import android.util.Log
import android.view.Display
import android.view.GestureDetector
import android.view.InputChannel
import android.view.InputEvent
import android.view.InputEventReceiver
import android.view.MotionEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlin.math.abs

class GlobalGestureService : Service() {

    companion object {
        private const val TAG = "GlobalGestureService"
        private const val GLOBAL_LAUNCHER_SPLIT_STATE = "global_launcher_split_state"
    }

    private var mInputMonitor: Any? = null
    private var mInputEventReceiver: InputEventReceiver? = null
    private var mInputThread: HandlerThread? = null
    lateinit var inputManager: InputManager
    private var mInputHandler: Handler? = null
    private var mGestureDetector: GestureDetector? = null
    private var mIsMoving = false

    private var mScreenWidth = 0
    private var mScreenHeight = 0

    // --- 三指手势追踪变量 ---
    private var mIsThreeFingerTracking = false
    private val mThreeFingerStartX = FloatArray(3)
    private val mThreeFingerStartY = FloatArray(3)
    private var mPendingSingleGesture = GlobalGestureManager.VSwipeDirection.NONE
    private var mPendingThreeFingerGesture = GlobalGestureManager.VSwipeDirection.NONE

    private var mThreeFingerDispatched = false

    private var barHeight = 0
    private var statusHeight = 0
    private var isForbidGlobalGesture = false
    private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private var mJob: Job? = null

    private val callbackList = RemoteCallbackList<ISystemGestureCallBack>()
    private var mInterceptDownX = 0f
    private var mInterceptDownY = 0f
    private var mIsInterceptActive = false
    private var isFullScreenSkip = false
    private val isMainProcess by lazy {
        Process.myUserHandle().hashCode() == 0
    }

    override fun onCreate() {
        super.onCreate()
        log("GlobalGestureService 启动!${Process.myUserHandle()}")
        if (!isMainProcess) {
            log("GlobalGestureService stopSelf")
            stopSelf()
            return
        }
        barHeight = resources.getDimensionPixelSize(R.dimen.bottom_nav_bar_total_height)
        statusHeight = resources.getDimensionPixelSize(R.dimen.status_bar_height)
     
        resources.displayMetrics.let {
            mScreenWidth = it.widthPixels
            mScreenHeight = it.heightPixels
        }
        try {
            initGestureDetector()
            startGlobalInputMonitoring()
        } catch (e: Exception) {
            Log.w(TAG, "手势服务初始化失败", e)
        }
        try {
            InteractionAPIManager.setGlobalGestureDisabled(false)
        } catch (e: Exception) {
            Log.w(TAG, "InteractionAPI.setGlobalGestureDisabled(false) error: ${e.message}")
        }
    }

    override fun onStartCommand(
        intent: Intent?,
        flags: Int,
        startId: Int
    ): Int {
        log("GlobalGestureService onStartCommand")
        return START_STICKY
    }

    private fun initGestureDetector() {
        mGestureDetector =
            GestureDetector(
                this,
                object : GestureDetector.SimpleOnGestureListener() {
                    override fun onScroll(
                        eventStart: MotionEvent?, 
                        eventMove: MotionEvent, 
                        distanceX: Float,
                        distanceY: Float
                    ): Boolean {
                        if (eventStart == null) return false

                        val deltaX = eventMove.x - eventStart.x
                        val deltaY = eventMove.y - eventStart.y
                        if (abs(deltaX) > abs(deltaY)) {
                            // 横向滑动判定
                            if (abs(deltaX) > GlobalGestureManager.GESTURE_THRESHOLD_PX) {
                                if (deltaX > 0) {
                                    // 从左边缘往内滑动
                                    if (eventStart.x < GlobalGestureManager.EDGE_ZONE_WIDTH_PX &&
                                        (eventStart.y > statusHeight && eventStart.y < (mScreenHeight - barHeight))
                                    ) { // 在状态栏导航栏内滑动
                                        mPendingSingleGesture =
                                            GlobalGestureManager.VSwipeDirection.RIGHT
                                        return true
                                    }
                                } else {
                                    // 从右边缘往内滑动
                                    if (eventStart.x > (mScreenWidth - GlobalGestureManager.EDGE_ZONE_WIDTH_PX) &&
                                        (eventStart.y > statusHeight && eventStart.y < (mScreenHeight - barHeight))
                                    ) { // 在状态栏导航栏内滑动
                                        mPendingSingleGesture =
                                            GlobalGestureManager.VSwipeDirection.LEFT
                                        return true
                                    }
                                }
                            }
                        } else {
                            // 纵向滑动判定
                            if (abs(deltaY) > GlobalGestureManager.GESTURE_THRESHOLD_PX) {
                                if (deltaY < 0) {
                                    if (eventStart.y < (mScreenHeight) &&
                                        eventStart.y > (mScreenHeight - barHeight)
                                    ) {
                                        mPendingSingleGesture =
                                            GlobalGestureManager.VSwipeDirection.UP
                                        return true
                                    }
                                } else {
                                    if (eventStart.y < statusHeight
                                    ) {
                                        mPendingSingleGesture =
                                            GlobalGestureManager.VSwipeDirection.DOWN
                                        return true
                                    }
                                }
                            }
                        }
                        return false
                    }

                    override fun onSingleTapConfirmed(e: MotionEvent): Boolean = false
                }
            )
    }

    /**
     * 三指左右滑
     */
    private fun checkThreeFingerGesture(event: MotionEvent): Boolean {
        val action = event.actionMasked
        val pointerCount = event.pointerCount

        if (pointerCount >= 3 && action == MotionEvent.ACTION_POINTER_DOWN) {
            if (!mIsThreeFingerTracking) {
                mIsThreeFingerTracking = true
                for (i in 0 until 3) {
                    mThreeFingerStartX[i] = event.getX(i)
                    mThreeFingerStartY[i] = event.getY(i)
                }
                pilferThreeFingerPointers()
            }
            return true
        }

        if (mIsThreeFingerTracking && action == MotionEvent.ACTION_MOVE && pointerCount >= 3) {
            var totalDeltaX = 0f
            var totalDeltaY = 0f
            for (i in 0 until 3) {
                totalDeltaX += event.getX(i) - mThreeFingerStartX[i]
                totalDeltaY += event.getY(i) - mThreeFingerStartY[i]
            }
            val avgDeltaX = totalDeltaX / 3f
            val avgDeltaY = totalDeltaY / 3f

            if (abs(avgDeltaX) > abs(avgDeltaY)) {
                val dir = when {
                    avgDeltaX > GlobalGestureManager.THREE_FINGER_THRESHOLD_PX ->
                        GlobalGestureManager.VSwipeDirection.THREE_FINGER_RIGHT

                    avgDeltaX < -GlobalGestureManager.THREE_FINGER_THRESHOLD_PX ->
                        GlobalGestureManager.VSwipeDirection.THREE_FINGER_LEFT

                    else -> GlobalGestureManager.VSwipeDirection.NONE
                }
                if (dir != GlobalGestureManager.VSwipeDirection.NONE) {
                    mPendingThreeFingerGesture = dir
                    if (!mThreeFingerDispatched) {
                        mThreeFingerDispatched = true
                        onThreeFingerSwipe(dir)
                        pilferThreeFingerPointers()
                        mIsThreeFingerTracking = false
                        mThreeFingerDispatched = false
                        return true
                    }
                }
            }
        }

        if (action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            if (mIsThreeFingerTracking) {
                if (!mThreeFingerDispatched) {
                    onThreeFingerSwipe(mPendingThreeFingerGesture)
                }
                mIsThreeFingerTracking = false
                mThreeFingerDispatched = false
            }
        }

        return mIsThreeFingerTracking
    }

    private fun pilferThreeFingerPointers() {
        try {
            if (!isSplit()) {
                Log.w(TAG, "pilferThreeFingerPointers: isSplit is false")
                return
            }
            val monitor = mInputMonitor ?: run {
                Log.w(TAG, "pilferThreeFingerPointers: mInputMonitor is null")
                return
            }
            val pilferMethod = monitor.javaClass.getMethod("pilferPointers")
            pilferMethod.invoke(monitor)
        } catch (e: Exception) {
            Log.w(TAG, "pilferThreeFingerPointers: ", e)
        }
    }

    private fun onSwipeRight() {
        log("单指边缘手势: 从左往右滑动 ")
        onSwipeDirection(GlobalGestureManager.VSwipeDirection.RIGHT)
        if (!ActivityStatusManager.isCanNotBackClearTopActivity()) {
            ReflectionUtil.injectGlobalBackKey(inputManager)
        }
        globalGestureSendSwipeDirection(GlobalGestureManager.VSwipeDirection.RIGHT)
    }

    private fun onSwipeLeft() {
        log("单指边缘手势: 从右往左滑动")
        onSwipeDirection(GlobalGestureManager.VSwipeDirection.LEFT)
        if (!ActivityStatusManager.isCanNotBackClearTopActivity()) {
            ReflectionUtil.injectGlobalBackKey(inputManager)
        }
        globalGestureSendSwipeDirection(GlobalGestureManager.VSwipeDirection.LEFT)
    }

    private fun onSwipeUp() {
        log("单指底边手势: 向上滑动 ${QS.isShowQS.value}")
        if (QS.isShowQS.value == 1f) {
            StatusBarManager.collapseQSPanel()
        } else {
            globalGestureSendSwipeDirection(GlobalGestureManager.VSwipeDirection.UP)
        }
        onSwipeDirection(GlobalGestureManager.VSwipeDirection.UP)
    }

    private fun globalGestureSendSwipeDirection(
        swipeDirection: GlobalGestureManager.VSwipeDirection
    ) {
        mJob?.cancel()
        mJob = serviceScope.launch {
            GlobalGestureManager.sendSwipeDirection(
                swipeDirection
            )
        }
    }

    private fun onSwipeDown() {
        log("单指底边手势: 向下滑动")
        if (!mIsMoving) {
            onSwipeDirection(GlobalGestureManager.VSwipeDirection.DOWN)
            mIsMoving = true
        }
    }

    private fun onSwipeDirection(what: GlobalGestureManager.VSwipeDirection) {
        Log.w(TAG, "onSwipeDirection direction=${what.name}")
        if (what == GlobalGestureManager.VSwipeDirection.NONE) return
        val count = callbackList.beginBroadcast()
        log("onSwipeDirection direction=${what.name} count=$count")
        val cbs = ArrayList<ISystemGestureCallBack>(count)
        for (i in 0 until count) {
            cbs.add(callbackList.getBroadcastItem(i))
        }
        callbackList.finishBroadcast()
        serviceScope.launch {
            cbs.forEach {
                try {
                    it.onSwipe(what.value)
                } catch (e: Exception) {
                    Log.w(TAG, "onSwipeDirection:", e)
                }
            }
            log("onSwipeDirection direction=${what.name} end")
        }
    }

    private fun onThreeFingerSwipe(what: GlobalGestureManager.VSwipeDirection) {
        Log.w(TAG, "onThreeFingerSwipe direction=${what.name}")
        if (what == GlobalGestureManager.VSwipeDirection.NONE) return
        val direction = when (what) {
            GlobalGestureManager.VSwipeDirection.THREE_FINGER_LEFT -> {
                GlobalGestureManager.THREE_FINGER_LEFT
            }

            GlobalGestureManager.VSwipeDirection.THREE_FINGER_RIGHT -> {
                GlobalGestureManager.THREE_FINGER_RIGHT
            }

            else -> return
        }
        val count = callbackList.beginBroadcast()
        log("onThreeFingerSwipe direction=${what.name} count=$count")
        val cbs = ArrayList<ISystemGestureCallBack>(count)
        for (i in 0 until count) {
            cbs.add(callbackList.getBroadcastItem(i))
        }
        callbackList.finishBroadcast()
        serviceScope.launch {
            cbs.forEach {
                try {
                    it.onThreeFingerSwipe(
                        direction,
                        mThreeFingerStartX[0], mThreeFingerStartY[0],
                        mThreeFingerStartX[1], mThreeFingerStartY[1],
                        mThreeFingerStartX[2], mThreeFingerStartY[2]
                    )
                } catch (e: Exception) {
                    Log.w(TAG, "onThreeFingerSwipe:", e)
                }
            }
            log("onThreeFingerSwipe direction=${what.name} end")
        }
    }

    private fun startGlobalInputMonitoring() {
        try {
            val obj = getSystemService(INPUT_SERVICE) as? InputManager ?: return
            inputManager = obj

            val monitorMethod = InputManager::class.java.getMethod(
                "monitorGestureInput",
                String::class.java,
                Int::class.javaPrimitiveType
            )
            mInputMonitor = monitorMethod.invoke(
                inputManager,
                "SystemUI-Global-Gesture",
                Display.DEFAULT_DISPLAY
            )

            if (mInputMonitor == null) {
                Log.w(TAG, "Failed to get InputMonitor instance.")
                return
            }
            val getInputChannelMethod = mInputMonitor?.javaClass?.getMethod("getInputChannel")
            val inputChannel = getInputChannelMethod?.invoke(mInputMonitor) as? InputChannel
            mInputThread =
                HandlerThread("Input-Thread", Process.THREAD_PRIORITY_FOREGROUND).apply {
                    start()
                }
            mInputHandler = Handler(mInputThread!!.looper)
            handleReceiver(inputChannel)
        } catch (e: Exception) {
            Log.w(TAG, "反射初始化 InputMonitor 失败,检查系统签名权限:", e)
        }
    }

    fun handleReceiver(inputChannel: InputChannel?) {
        if (mInputThread?.looper == null) return
        mInputEventReceiver = object : InputEventReceiver(inputChannel, mInputThread!!.looper) {
            override fun onInputEvent(event: InputEvent) {
                if (event !is MotionEvent) {
                    finishInputEvent(event, true)
                    return
                }
                val copiedEvent = MotionEvent.obtain(event)
                finishInputEvent(event, true)
                try {
                    if (isSkipInputEvent(copiedEvent)) return
                    touch(copiedEvent)
                } catch (e: Exception) {
                    Log.w(TAG, "handleReceiver:", e)
                } finally {
                    copiedEvent.recycle()
                }
            }
        }
    }

    /** 手势处理 */
    private fun touch(event: MotionEvent) {
        val isTouchEvent = (event.source and android.view.InputDevice.SOURCE_TOUCHSCREEN) != 0
        val action = event.actionMasked
        if (isTouchEvent &&
            action != MotionEvent.ACTION_HOVER_ENTER &&
            action != MotionEvent.ACTION_HOVER_MOVE &&
            action != MotionEvent.ACTION_HOVER_EXIT
        ) {
            if (action == MotionEvent.ACTION_DOWN) {
                mPendingThreeFingerGesture = GlobalGestureManager.VSwipeDirection.NONE
                mPendingSingleGesture = GlobalGestureManager.VSwipeDirection.NONE
                mIsThreeFingerTracking = false
                mThreeFingerDispatched = false
            }

            val threeFingerHandled = checkThreeFingerGesture(event)

            if (!threeFingerHandled && !mIsThreeFingerTracking) {
                mGestureDetector?.onTouchEvent(event)
            }

            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                if (action == MotionEvent.ACTION_UP && !threeFingerHandled) {
                    when (mPendingSingleGesture) {
                        GlobalGestureManager.VSwipeDirection.UP -> {
                            onSwipeUp()
                        }

                        GlobalGestureManager.VSwipeDirection.DOWN -> {
                            onSwipeDown()
                        }

                        GlobalGestureManager.VSwipeDirection.LEFT -> {
                            onSwipeLeft()
                        }

                        GlobalGestureManager.VSwipeDirection.RIGHT -> {
                            onSwipeRight()
                        }

                        else -> {}
                    }
                }
                mPendingThreeFingerGesture = GlobalGestureManager.VSwipeDirection.NONE
                mPendingSingleGesture = GlobalGestureManager.VSwipeDirection.NONE
                mIsThreeFingerTracking = false
                mThreeFingerDispatched = false
                mIsMoving = false
            }
        }
    }

    /** 拦截手势 */
    private fun isSkipInputEvent(event: MotionEvent): Boolean {
        val action = event.actionMasked
        log("isSkipInputEvent action=$action, x=${event.x} y=${event.y}")
        if (mIsInterceptActive) {
            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                mIsInterceptActive = false
                isFullScreenSkip = false
                log("isSkipInputEvent: intercept session end")
            }
            return true
        }
        when (action) {
            MotionEvent.ACTION_DOWN -> {
                isForbidGlobalGesture = InteractionAPIManager.isGlobalGestureDisabled()
                mInterceptDownX = event.x
                mInterceptDownY = event.y
                isFullScreenSkip = !SystemBarManager.isShowSystemBar()
                log("isSkipInputEvent isFullScreenSkip=$isFullScreenSkip, isForbidGlobalGesture=$isForbidGlobalGesture")
                if ((isForbidGlobalGesture || isFullScreenSkip) &&
                    isInEdgeZone(mInterceptDownX, mInterceptDownY)
                ) {
                    mIsInterceptActive = true
                    log("isSkipInputEvent: activate intercept session")
                    return true
                }
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                mIsInterceptActive = false
                isFullScreenSkip = false
            }
        }
        return false
    }

    private fun isInEdgeZone(x: Float, y: Float): Boolean {
        if (y < statusHeight) return true
        if (y > mScreenHeight - barHeight) return true
        val inMiddleVertical = y > statusHeight && y < mScreenHeight - barHeight
        if (inMiddleVertical && x < GlobalGestureManager.EDGE_ZONE_WIDTH_PX) return true
        if (inMiddleVertical && x > mScreenWidth - GlobalGestureManager.EDGE_ZONE_WIDTH_PX) return true
        return false
    }

    private fun isSplit() = Settings.Global.getInt(
        contentResolver,
        GLOBAL_LAUNCHER_SPLIT_STATE, 0
    ) == 1

    private val binder = object : ISystemUIGestureProxy.Stub() {
        override fun registerCallBack(callback: ISystemGestureCallBack?) {
            if (callback != null) {
                callbackList.register(callback)
                log("Launcher 注册回调成功")
            }
        }

        override fun unRegisterCallBack(callback: ISystemGestureCallBack?) {
            if (callback != null) {
                callbackList.unregister(callback)
                log("Launcher 注销回调成功")
            }
        }
    }

    override fun onBind(intent: Intent?): IBinder? {
        log("onBind isMainProcess=$isMainProcess")
        return if (isMainProcess) {
            binder
        } else {
            stopSelf()
            null
        }
    }

    override fun onDestroy() {
        log("GlobalGestureService 停止!")
        serviceScope.cancel()
        callbackList.kill()
        mInputHandler?.post {
            mInputEventReceiver?.dispose()
            mInputEventReceiver = null
        }
        mInputThread?.quitSafely()
        mInputThread = null
        mInputHandler = null
        mInputMonitor?.let {
            try {
                val disposeMethod = it.javaClass.getMethod("dispose")
                disposeMethod.invoke(it)
            } catch (e: Exception) {
                Log.w(TAG, "onDestroy $e")
            }
            mInputMonitor = null
        }
        super.onDestroy()
    }

    private fun log(string: String) = Log.i(TAG, string)
}
GlobalGestureService

 

posted on 2026-10-24 15:41  翻滚的咸鱼  阅读(5)  评论(0)    收藏  举报