~robertcarr/mir/add-log-all-option

« back to all changes in this revision

Viewing changes to 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp

  • Committer: Tarmac
  • Author(s): Daniel d'Andrada
  • Date: 2013-11-04 07:41:55 UTC
  • mfrom: (1154.2.3 touchIds)
  • Revision ID: tarmac-20131104074155-x9zwch49ocuq6lcy
android-input - Assign more unique touch ids

Have touch ids remain valid for some time after its touches have physically ended,
so one can still refer to a touch that has already ended.

Approved by Daniel van Vugt, PS Jenkins bot, Robert Carr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
152
152
                pointerCount, MAX_POINTERS);
153
153
        return false;
154
154
    }
155
 
    BitSet32 pointerIdBits;
 
155
    IntSet pointerIds;
156
156
    for (size_t i = 0; i < pointerCount; i++) {
157
157
        int32_t id = pointerProperties[i].id;
158
158
        if (id < 0 || id > MAX_POINTER_ID) {
160
160
                    id, MAX_POINTER_ID);
161
161
            return false;
162
162
        }
163
 
        if (pointerIdBits.hasBit(id)) {
 
163
        if (pointerIds.contains(id)) {
164
164
            ALOGE("Motion event has duplicate pointer id %d", id);
165
165
            return false;
166
166
        }
167
 
        pointerIdBits.markBit(id);
 
167
        pointerIds.insert(id);
168
168
    }
169
169
    return true;
170
170
}
1043
1043
    // Success!  Output targets.
1044
1044
    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1045
1045
    addWindowTargetLocked(mFocusedWindowHandle,
1046
 
            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
 
1046
            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, IntSet(),
1047
1047
            inputTargets);
1048
1048
 
1049
1049
    // Done.
1181
1181
                    }
1182
1182
 
1183
1183
                    mTempTouchState.addOrUpdateWindow(
1184
 
                            windowHandle, outsideTargetFlags, BitSet32(0));
 
1184
                            windowHandle, outsideTargetFlags, IntSet());
1185
1185
                }
1186
1186
            }
1187
1187
        });
1250
1250
        }
1251
1251
 
1252
1252
        // Update the temporary touch state.
1253
 
        BitSet32 pointerIds;
 
1253
        IntSet pointerIds;
1254
1254
        if (isSplit) {
1255
 
            uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1256
 
            pointerIds.markBit(pointerId);
 
1255
            int32_t pointerId = entry->pointerProperties[pointerIndex].id;
 
1256
            pointerIds.insert(pointerId);
1257
1257
        }
1258
1258
        mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1259
1259
    } else {
1288
1288
#endif
1289
1289
                // Make a slippery exit from the old window.
1290
1290
                mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1291
 
                        InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
 
1291
                        InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, IntSet());
1292
1292
 
1293
1293
                // Make a slippery entrance into the new window.
1294
1294
                if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1304
1304
                    targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1305
1305
                }
1306
1306
 
1307
 
                BitSet32 pointerIds;
 
1307
                IntSet pointerIds;
1308
1308
                if (isSplit) {
1309
 
                    pointerIds.markBit(entry->pointerProperties[0].id);
 
1309
                    pointerIds.insert(entry->pointerProperties[0].id);
1310
1310
                }
1311
1311
                mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1312
1312
            }
1321
1321
                c_str(mLastHoverWindowHandle->getName()));
1322
1322
#endif
1323
1323
            mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1324
 
                    InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
 
1324
                    InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, IntSet());
1325
1325
        }
1326
1326
 
1327
1327
        // Let the new window know that the hover sequence is starting.
1331
1331
                c_str(newHoverWindowHandle->getName()));
1332
1332
#endif
1333
1333
            mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1334
 
                    InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
 
1334
                    InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, IntSet());
1335
1335
        }
1336
1336
    }
1337
1337
 
1375
1375
                sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1376
1376
                if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1377
1377
                    mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1378
 
                            InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
 
1378
                            InputTarget::FLAG_ZERO_COORDS, IntSet());
1379
1379
                }
1380
1380
            }
1381
1381
        }
1421
1421
                    mTempTouchState.addOrUpdateWindow(windowHandle,
1422
1422
                            InputTarget::FLAG_WINDOW_IS_OBSCURED
1423
1423
                                    | InputTarget::FLAG_DISPATCH_AS_IS,
1424
 
                            BitSet32(0));
 
1424
                            IntSet());
1425
1425
                }
1426
1426
            });
1427
1427
        }
1491
1491
                // One pointer went up.
1492
1492
                if (isSplit) {
1493
1493
                    int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1494
 
                    uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
 
1494
                    int32_t pointerId = entry->pointerProperties[pointerIndex].id;
1495
1495
 
1496
1496
                    for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1497
1497
                        TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1498
1498
                        if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1499
 
                            touchedWindow.pointerIds.clearBit(pointerId);
 
1499
                            touchedWindow.pointerIds.remove(pointerId);
1500
1500
                            if (touchedWindow.pointerIds.isEmpty()) {
1501
1501
                                mTempTouchState.windows.removeAt(i);
1502
1502
                                continue;
1538
1538
}
1539
1539
 
1540
1540
void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
1541
 
        int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
 
1541
        int32_t targetFlags, const IntSet &pointerIds, Vector<InputTarget>& inputTargets) {
1542
1542
    inputTargets.push();
1543
1543
 
1544
1544
    const InputWindowInfo* windowInfo = windowHandle->getInfo();
1693
1693
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1694
1694
        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1695
1695
#if DEBUG_DISPATCH_CYCLE
 
1696
    std::string pointerIdsString = inputTarget->pointerIds.toString();
1696
1697
    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
1697
1698
            "xOffset=%f, yOffset=%f, scaleFactor=%f, "
1698
 
            "pointerIds=0x%x",
 
1699
            "pointerIds=%s",
1699
1700
            connection->getInputChannelName(), inputTarget->flags,
1700
1701
            inputTarget->xOffset, inputTarget->yOffset,
1701
 
            inputTarget->scaleFactor, inputTarget->pointerIds.value);
 
1702
            inputTarget->scaleFactor, pointerIdsString.c_str());
1702
1703
#endif
1703
1704
 
1704
1705
    // Skip this event if the connection status is not normal.
2163
2164
}
2164
2165
 
2165
2166
InputDispatcher::MotionEntry*
2166
 
InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2167
 
    ALOG_ASSERT(pointerIds.value != 0);
 
2167
InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, const IntSet &pointerIds) {
 
2168
    ALOG_ASSERT(!pointerIds.isEmpty());
2168
2169
 
2169
2170
    uint32_t splitPointerIndexMap[MAX_POINTERS];
2170
2171
    PointerProperties splitPointerProperties[MAX_POINTERS];
2178
2179
        const PointerProperties& pointerProperties =
2179
2180
                originalMotionEntry->pointerProperties[originalPointerIndex];
2180
2181
        uint32_t pointerId = uint32_t(pointerProperties.id);
2181
 
        if (pointerIds.hasBit(pointerId)) {
 
2182
        if (pointerIds.contains(pointerId)) {
2182
2183
            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2183
2184
            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2184
2185
            splitPointerCoords[splitPointerCount].copyFrom(
2207
2208
        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2208
2209
        const PointerProperties& pointerProperties =
2209
2210
                originalMotionEntry->pointerProperties[originalPointerIndex];
2210
 
        uint32_t pointerId = uint32_t(pointerProperties.id);
2211
 
        if (pointerIds.hasBit(pointerId)) {
 
2211
        int32_t pointerId = pointerProperties.id;
 
2212
        if (pointerIds.contains(pointerId)) {
2212
2213
            if (pointerIds.count() == 1) {
2213
2214
                // The first/last pointer went down/up.
2214
2215
                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2216
2217
            } else {
2217
2218
                // A secondary pointer went down/up.
2218
2219
                uint32_t splitPointerIndex = 0;
2219
 
                while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
 
2220
                while (pointerId != splitPointerProperties[splitPointerIndex].id) {
2220
2221
                    splitPointerIndex += 1;
2221
2222
                }
2222
2223
                action = maskedAction | (splitPointerIndex
2901
2902
            const TouchedWindow& touchedWindow = mTouchState.windows[i];
2902
2903
            if (touchedWindow.windowHandle == fromWindowHandle) {
2903
2904
                int32_t oldTargetFlags = touchedWindow.targetFlags;
2904
 
                BitSet32 pointerIds = touchedWindow.pointerIds;
 
2905
                IntSet pointerIds = touchedWindow.pointerIds;
2905
2906
 
2906
2907
                mTouchState.windows.removeAt(i);
2907
2908
 
3000
3001
        dump.append(INDENT "TouchedWindows:\n");
3001
3002
        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3002
3003
            const TouchedWindow& touchedWindow = mTouchState.windows[i];
3003
 
            appendFormat(dump, INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3004
 
                    i, c_str(touchedWindow.windowHandle->getName()),
3005
 
                    touchedWindow.pointerIds.value,
3006
 
                    touchedWindow.targetFlags);
 
3004
            appendFormat(dump, INDENT2 "%d: name='%s'",
 
3005
                    i, c_str(touchedWindow.windowHandle->getName()));
 
3006
 
 
3007
            dump.append(", pointerIds=(");
 
3008
            touchedWindow.pointerIds.forEach([&](int32_t id) {appendFormat(dump, ", %d", id);});
 
3009
            dump.append(")");
 
3010
 
 
3011
            appendFormat(dump, ", targetFlags=0x%x\n", touchedWindow.targetFlags);
3007
3012
        }
3008
3013
    } else {
3009
3014
        dump.append(INDENT "TouchedWindows: <none>\n");
4191
4196
}
4192
4197
 
4193
4198
void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
4194
 
        int32_t targetFlags, BitSet32 pointerIds) {
 
4199
        int32_t targetFlags, const IntSet &pointerIds) {
4195
4200
    if (targetFlags & InputTarget::FLAG_SPLIT) {
4196
4201
        split = true;
4197
4202
    }
4203
4208
            if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
4204
4209
                touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
4205
4210
            }
4206
 
            touchedWindow.pointerIds.value |= pointerIds.value;
 
4211
            pointerIds.forEach([&](int32_t id) {
 
4212
                touchedWindow.pointerIds.insert(id);
 
4213
            });
4207
4214
            return;
4208
4215
        }
4209
4216
    }