个人网站可以做商城吗,百度sem推广具体做什么,wordpress footer错位,巴州网站建设接上篇文章#xff1a;展锐平台#xff1a;记录一次带触控笔的MIPI屏幕调试踩坑过程#xff0c;在使用触控笔的主动橡皮擦功能时#xff0c;系统会出现类似重启的现象。之所以说是类似重启#xff0c;是因为从log中看#xff0c;整个系统是还在运行的#xff0c;只是某些…接上篇文章展锐平台记录一次带触控笔的MIPI屏幕调试踩坑过程在使用触控笔的主动橡皮擦功能时系统会出现类似重启的现象。之所以说是类似重启是因为从log中看整个系统是还在运行的只是某些服务重启了。下面看一下问题log的一些分析以及如何解决。第一次发现问题时抓的log关键日志如下C0BF041 12-05 11:58:26.324 23715 23715 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** C0BF042 12-05 11:58:26.324 23715 23715 F DEBUG : Build fingerprint: UNISOC/ums9620_1h10_native/ums9620_1h10:14/UP1A.231005.007/eng.a53sw0.20251205.093503:userdebug/test-keys C0BF043 12-05 11:58:26.324 23715 23715 F DEBUG : Revision: 0 C0BF044 12-05 11:58:26.324 23715 23715 F DEBUG : ABI: arm64 C0BF045 12-05 11:58:26.324 23715 23715 F DEBUG : Timestamp: 2025-12-05 11:58:25.4902406610800 C0BF046 12-05 11:58:26.324 23715 23715 F DEBUG : Process uptime: 189s C0BF047 12-05 11:58:26.324 23715 23715 F DEBUG : Cmdline: system_server C0BF048 12-05 11:58:26.324 23715 23715 F DEBUG : pid: 19505, tid: 19886, name: InputDispatcher system_server C0BF049 12-05 11:58:26.324 23715 23715 F DEBUG : uid: 1000 C0BF04A 12-05 11:58:26.324 23715 23715 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) C0BF04B 12-05 11:58:26.325 23715 23715 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- C0BF04C 12-05 11:58:26.325 23715 23715 F DEBUG : Abort message: Splitting motion events requires a down time to be set for the target on connection c1a807b com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher (server) for MotionEvent(deviceId3, eventTime8512674950000, sourceTOUCHSCREEN | STYLUS, displayId0, actionBUTTON_PRESS, actionButton0x00000020, flags0x00000000, metaState0x00000000, buttonState0x00000020, classificationNONE, edgeFlags0x00000000, xPrecision10.0, yPrecision10.0, xCursorPositionnan, yCursorPositionnan, pointers[0: (1143.9, 566.0)]), policyFlags0x62000000 C0BF04D 12-05 11:58:26.325 23715 23715 F DEBUG : x0 0000000000000000 x1 0000000000004dae x2 0000000000000006 x3 000000790c15b5f0 C0BF04E 12-05 11:58:26.325 23715 23715 F DEBUG : x4 626f1f3130221f39 x5 626f1f3130221f39 x6 626f1f3130221f39 x7 7f7f7f7f7f7f7f7f C0BF04F 12-05 11:58:26.325 23715 23715 F DEBUG : x8 00000000000000f0 x9 0000007cb82340b0 x10 0000000000000001 x11 0000007cb828ab60 C0BF050 12-05 11:58:26.325 23715 23715 F DEBUG : x12 000000000000ce3a x13 000000007fffffff x14 0000000000327ef2 x15 000000339dfb2aab C0BF051 12-05 11:58:26.325 23715 23715 F DEBUG : x16 0000007cb8304cf8 x17 0000007cb82d35e0 x18 000000790aefe000 x19 0000000000004c31 C0BF052 12-05 11:58:26.325 23715 23715 F DEBUG : x20 0000000000004dae x21 00000000ffffffff x22 000000790c15c000 x23 00000079f6c54000 C0BF053 12-05 11:58:26.325 23715 23715 F DEBUG : x24 b400007a5902fbd0 x25 b400007b89066e70 x26 b400007a69037918 x27 b400007bf9163888 C0BF054 12-05 11:58:26.325 23715 23715 F DEBUG : x28 000000790c15c000 x29 000000790c15b670 C0BF055 12-05 11:58:26.325 23715 23715 F DEBUG : lr 0000007cb827b178 sp 000000790c15b5d0 pc 0000007cb827b1a4 pst 0000000000001000 C0BF056 12-05 11:58:26.325 23715 23715 F DEBUG : 14 total frames C0BF057 12-05 11:58:26.325 23715 23715 F DEBUG : backtrace: C0BF058 12-05 11:58:26.325 23715 23715 F DEBUG : #00 pc 00000000000691a4 /apex/com.android.runtime/lib64/bionic/libc.so (abort164) (BuildId: c3622b5c0a4cde0d723ea2d964ec71b7) C0BF059 12-05 11:58:26.325 23715 23715 F DEBUG : #01 pc 000000000064ac20 /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)1456) (BuildId: b37c98d000c57dbaf28462133142cc42) C0BF05A 12-05 11:58:26.325 23715 23715 F DEBUG : #02 pc 0000000000044730 /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::functionvoid (char const*))::$_0::__invoke(char const*)80) (BuildId: 404dcc4830dee81873a1cc7d0bff3046) C0BF05B 12-05 11:58:26.325 23715 23715 F DEBUG : #03 pc 0000000000024d90 /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()352) (BuildId: 994836fb17568408113cb3be7a6dfaad) C0BF05C 12-05 11:58:26.325 23715 23715 F DEBUG : #04 pc 00000000000a95a0 /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::prepareDispatchCycleLocked(long, std::__1::shared_ptrandroid::inputdispatcher::Connection const, std::__1::shared_ptrandroid::inputdispatcher::EventEntry, android::inputdispatcher::InputTarget const)2160) (BuildId: 85a971c1a495be3c4e4e6bf83197b4a7) C0BF05D 12-05 11:58:26.325 23715 23715 F DEBUG : #05 pc 00000000000a42b0 /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchEventLocked(long, std::__1::shared_ptrandroid::inputdispatcher::EventEntry, std::__1::vectorandroid::inputdispatcher::InputTarget, std::__1::allocatorandroid::inputdispatcher::InputTarget const)384) (BuildId: 85a971c1a495be3c4e4e6bf83197b4a7) C0BF05E 12-05 11:58:26.325 23715 23715 F DEBUG : #06 pc 00000000000a1470 /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchMotionLocked(long, std::__1::shared_ptrandroid::inputdispatcher::MotionEntry, android::inputdispatcher::InputDispatcher::DropReason*, long*)1056) (BuildId: 85a971c1a495be3c4e4e6bf83197b4a7) C0BF05F 12-05 11:58:26.325 23715 23715 F DEBUG : #07 pc 000000000009dc94 /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchOnceInnerLocked(long*)1668) (BuildId: 85a971c1a495be3c4e4e6bf83197b4a7) C0BF060 12-05 11:58:26.326 23715 23715 F DEBUG : #08 pc 000000000009d564 /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchOnce()84) (BuildId: 85a971c1a495be3c4e4e6bf83197b4a7) C0BF061 12-05 11:58:26.326 23715 23715 F DEBUG : #09 pc 0000000000013db8 /system/lib64/libinputflinger_base.so (android::(anonymous namespace)::InputThreadImpl::threadLoop()24) (BuildId: 4ac03616f24d0925d9b9ffb9a048dcd5) C0BF062 12-05 11:58:26.326 23715 23715 F DEBUG : #10 pc 000000000001530c /system/lib64/libutils.so (android::Thread::_threadLoop(void*)284) (BuildId: e1aa88e73f8cbe876b1da77e01ae24a5) C0BF063 12-05 11:58:26.326 23715 23715 F DEBUG : #11 pc 00000000000ee19c /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)140) (BuildId: f03947044b57438629212d4a2dbc07a6) C0BF064 12-05 11:58:26.326 23715 23715 F DEBUG : #12 pc 00000000000d6e3c /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)204) (BuildId: c3622b5c0a4cde0d723ea2d964ec71b7) C0BF065 12-05 11:58:26.326 23715 23715 F DEBUG : #13 pc 000000000006ab00 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread64) (BuildId: c3622b5c0a4cde0d723ea2d964ec71b7)可以看到是InputDispatcher在分割动作时缺少了down time导致system_server崩溃然后重启了。注意到此时的动作是actionBUTTON_PRESS也就是按下触控笔的主动橡皮擦键。在源码中查找分析frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp// Split a motion event if needed. if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) { LOG_ALWAYS_FATAL_IF(eventEntry-type ! EventEntry::Type::MOTION, Entry type %s should not have Flags::SPLIT, ftl::enum_string(eventEntry-type).c_str()); const MotionEntry originalMotionEntry static_castconst MotionEntry(*eventEntry); if (inputTarget.pointerIds.count() ! originalMotionEntry.pointerCount) { if (!inputTarget.firstDownTimeInTarget.has_value()) { logDispatchStateLocked(); LOG(FATAL) Splitting motion events requires a down time to be set for the target on connection connection-getInputChannelName() for originalMotionEntry.getDescription(); } std::unique_ptrMotionEntry splitMotionEntry splitMotionEvent(originalMotionEntry, inputTarget.pointerIds, inputTarget.firstDownTimeInTarget.value()); if (!splitMotionEntry) { return; // split event was dropped } if (splitMotionEntry-action AMOTION_EVENT_ACTION_CANCEL) { std::string reason std::string(reasonpointer cancel on split window); android_log_event_list(LOGTAG_INPUT_CANCEL) connection-getInputChannelName().c_str() reason LOG_ID_EVENTS; } if (DEBUG_FOCUS || gInputDispatcherLog) { ALOGD(channel %s ~ Split motion event., connection-getInputChannelName().c_str()); logOutboundMotionDetails( , *splitMotionEntry); } enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry), inputTarget); return; } }注意到在源码中分割动作时缺少firstDownTimeInTarget那么就会发生致命错误。那么就要看是在哪里设置的firstDownTimeInTarget为什么现在没有设置firstDownTimeInTarget。接着查找发现在InputDispatcher.cpp中有两处可能会设置firstDownTimeInTarget。frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp 2379 std::vectorInputTarget InputDispatcher::findTouchedWindowTargetsLocked( 2380 nsecs_t currentTime, const MotionEntry entry, bool* outConflictingPointerActions, 2381 InputEventInjectionResult outInjectionResult) { ... 2453 if (newGesture || (isSplit maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN)) { ... set firstDownTimeInTarget 2555 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds, 2556 isDownOrPointerDown 2557 ? std::make_optional(entry.eventTime) 2558 : std::nullopt); 2559 ... 2602 } else { 2603 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */ ... 2653 if (newTouchedWindowHandle ! nullptr 2654 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) { 2655 ALOGD(Touch is slipping out of window %s into window %s in display % PRId32, 2656 oldTouchedWindowHandle-getName().c_str(), 2657 newTouchedWindowHandle-getName().c_str(), displayId); ... set firstDownTimeInTarget 2689 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds, 2690 /frameworks/native/services/inputflinger/dispatcher/TouchState.cpp 65 void TouchState::addOrUpdateWindow(const spWindowInfoHandle windowHandle, 66 ftl::FlagsInputTarget::Flags targetFlags, 67 std::bitsetMAX_POINTER_ID 1 pointerIds, 68 std::optionalnsecs_t firstDownTimeInTarget) { 69 for (TouchedWindow touchedWindow : windows) { ... 80 touchedWindow.pointerIds | pointerIds; 81 if (!touchedWindow.firstDownTimeInTarget.has_value()) { set touchedWindow.firstDownTimeInTarget 82 touchedWindow.firstDownTimeInTarget firstDownTimeInTarget; 83 } 84 return; ... set touchedWindow.firstDownTimeInTarget 91 touchedWindow.firstDownTimeInTarget firstDownTimeInTarget;添加一些调试log后确认使用主动橡皮擦功能时走的是这个ifif (newGesture || (isSplit maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN)) { ....... ....... const bool isDownOrPointerDown maskedAction AMOTION_EVENT_ACTION_DOWN || maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN; // TODO(b/211379801): Currently, even if pointerIds are empty (hover case), we would // still add a window to the touch state. We should avoid doing that, but some of the // later checks (at least one foreground window) rely on this in order to dispatch // the event properly, so that needs to be updated, possibly by looking at InputTargets. tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds, isDownOrPointerDown ? std::make_optional(entry.eventTime) : std::nullopt); ......通过添加一些调试log后确认当使用主动橡皮擦时isDownOrPointerDown为0maskedAction11。查询代码后知道frameworks/native/include/android/input.h /* One or more buttons have been pressed. */ AMOTION_EVENT_ACTION_BUTTON_PRESS 11, /* One or more buttons have been released. */ AMOTION_EVENT_ACTION_BUTTON_RELEASE 12,至此我们知道应该是缺少了对AMOTION_EVENT_ACTION_BUTTON_PRESS和AMOTION_EVENT_ACTION_BUTTON_RELEASE的处理才导致出错的。那么在相应的地方不全动作判断是不是就可以了呢添加以下修改进行测试diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 657efea445..1f034cb27c 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp -2452,7 2452,10 std::vectorInputTarget InputDispatcher::findTouchedWindowTargetsLocked( tempTouchState.clearHoveringPointers(); } - if (newGesture || (isSplit maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN)) { ALOGD(wrl: newGesture%d, isSplit%d, maskedAction%d, newGesture, isSplit, maskedAction); if (newGesture || (isSplit (maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN || maskedAction AMOTION_EVENT_ACTION_BUTTON_PRESS || maskedAction AMOTION_EVENT_ACTION_BUTTON_RELEASE))) { /* Case 1: New splittable pointer going down, or need target for hover or scroll. */ const auto [x, y] resolveTouchedPosition(entry); const int32_t pointerIndex getMotionEventActionPointerIndex(action); -2548,7 2551,9 std::vectorInputTarget InputDispatcher::findTouchedWindowTargetsLocked( } const bool isDownOrPointerDown maskedAction AMOTION_EVENT_ACTION_DOWN || - maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN; maskedAction AMOTION_EVENT_ACTION_POINTER_DOWN || maskedAction AMOTION_EVENT_ACTION_BUTTON_PRESS || maskedAction AMOTION_EVENT_ACTION_BUTTON_RELEASE; // TODO(b/211379801): Currently, even if pointerIds are empty (hover case), we would // still add a window to the touch state. We should avoid doing that, but some of the测试后发现主动橡皮擦功能还是有小概率导致system_server出错M01D422 12-11 15:34:50.647 1160 1310 D InputDispatcher: wrl: newGesture0, isSplit1, maskedAction10 M01D423 12-11 15:34:50.647 1160 1310 I InputDispatcher: else Case2 isFromMouse0, tempTouchState.down1, tempTouchState.windows.empty() 0, tempDisplayId0, displayId0 M01D424 12-11 15:34:50.648 1160 1310 F system_server: Assertion failed: (pointerIds newPointerIds).any()maskedAction10对应的动作是AMOTION_EVENT_ACTION_HOVER_EXIT 10, 为什么在处理这个动作时会出错呢通过添加log发现当出现log中的情况时下面的代码都会执行。而在addWindowTargetLocked函数中也会有addPointers的操作。因此就会执行两次addPointers操作重复添加同一个pointerIds进而导致报错。// Update dispatching for hover enter and exit. { std::vectorTouchedWindow hoveringWindows getHoveringWindowsLocked(oldState, tempTouchState, entry); for (const TouchedWindow touchedWindow : hoveringWindows) { std::optionalInputTarget target createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, touchedWindow.firstDownTimeInTarget); if (!target) { continue; } // Hardcode to single hovering pointer for now. std::bitsetMAX_POINTER_ID 1 pointerIds; pointerIds.set(entry.pointerProperties[0].id); target-addPointers(pointerIds, touchedWindow.windowHandle-getInfo()-transform); targets.push_back(*target); } } ...... // Output targets from the touch state. for (const TouchedWindow touchedWindow : tempTouchState.windows) { if (touchedWindow.pointerIds.none() !touchedWindow.hasHoveringPointers(entry.deviceId)) { // Windows with hovering pointers are getting persisted inside TouchState. // Do not send this event to those windows. continue; } addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget, targets); }那么是不是可以在// Update dispatching for hover enter and exit这一段处理完了 AMOTION_EVENT_ACTION_HOVER_EXIT动作后添加一个flag在// Output targets from the touch state这一段不进行addPointers操作。修改如下 -2760,6 2765,7 std::vectorInputTarget InputDispatcher::findTouchedWindowTargetsLocked( } // Update dispatching for hover enter and exit. bool hover_exit_flag false; { std::vectorTouchedWindow hoveringWindows getHoveringWindowsLocked(oldState, tempTouchState, entry); -2775,6 2781,8 std::vectorInputTarget InputDispatcher::findTouchedWindowTargetsLocked( pointerIds.set(entry.pointerProperties[0].id); target-addPointers(pointerIds, touchedWindow.windowHandle-getInfo()-transform); targets.push_back(*target); if (maskedAction AMOTION_EVENT_ACTION_HOVER_EXIT) hover_exit_flag true; } } -2834,6 2842,12 std::vectorInputTarget InputDispatcher::findTouchedWindowTargetsLocked( continue; } // 添加检查如果是悬浮事件并且这个窗口已经通过hovering路径处理过了就跳过 if (hover_exit_flag) { ALOGD(wrl: hover_exit_flag is true, skip this window.); continue; } addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget, targets);OK经过测试这种修改是可以解决该问题的。这里在提供另外一种方法也是有效果的。即在分割动作时判断动作类型对于 BUTTON_PRESS/BUTTON_RELEASE 动作且处于悬停状态不进行分割。修改如下diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 657efea445..2bf7b4bec2 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp -3401,7 3401,13 void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, ftl::enum_string(eventEntry-type).c_str()); const MotionEntry originalMotionEntry static_castconst MotionEntry(*eventEntry); - if (inputTarget.pointerIds.count() ! originalMotionEntry.pointerCount) { // 新增对于 BUTTON_PRESS/BUTTON_RELEASE 动作且处于悬停状态不进行分割 ALOGD(wrl: count%zu, pointerCount%d, inputTarget.pointerIds.count(), originalMotionEntry.pointerCount); const int32_t maskedAction MotionEvent::getActionMasked(originalMotionEntry.action); const bool isHoverButtonAction (maskedAction AMOTION_EVENT_ACTION_BUTTON_PRESS || maskedAction AMOTION_EVENT_ACTION_BUTTON_RELEASE) originalMotionEntry.pointerCount 1; // 单指针悬停 if (inputTarget.pointerIds.count() ! originalMotionEntry.pointerCount !isHoverButtonAction) { if (!inputTarget.firstDownTimeInTarget.has_value()) { logDispatchStateLocked(); LOG(FATAL) Splitting motion events requires a down time to be set for the -3428,7 3434,12 void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry), inputTarget); return; - } } else if (isHoverButtonAction) { // 对于悬停按钮事件直接使用原始事件不进行分割 ALOGD(wrl: isHoverButtonAction); enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget); return; } } // Not splitting. Enqueue dispatch entries for the event as is.