Почему ACTION_OUTSIDE возвращается каждый раз на KitKat 4.4.2?

Я реализовал окно размером 1 и хочу поймать событие ACTION_OUTSIDE.

mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(1,1,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);       

Я получаю триггер, и я получаю событие ACTION_OUTSIDE, но при чтении event.getRawX() и event.getRawY() они оба возвращают 0 каждый раз. Я тестировал то же самое с Android 2.3.6, и он сработал. И я не могу найти ничего, что устарело.

Это проблема с Android или кто-нибудь знает решение? спасибо

Ответ 1

Tniederm, я ответил на аналогичный вопрос здесь для справки, но я переделаю его здесь с некоторыми незначительными изменениями:

После очистки исходного кода я нашел источник проблемы:

https://github.com/android/platform_frameworks_base/blob/79e0206ef3203a1842949242e58fa8f3c25eb129/services/input/InputDispatcher.cpp#L1417

// Check whether windows listening for outside touches are owned by the same UID. If it is
// set the policy flag that we will not reveal coordinate information to this window.
if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
    sp<InputWindowHandle> foregroundWindowHandle =
            mTempTouchState.getFirstForegroundWindowHandle();
    const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
        if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
            sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
            if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
                mTempTouchState.addOrUpdateWindow(inputWindowHandle,
                        InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
            }
        }
    }
}

Если "внешнее касание" приземляется в представлении, которое не делит его UID (читает об этом здесь) с представлением о том, что прислушиваясь к внешним касаниям, диспетчер событий устанавливает свои координаты на 0,0. Это было сделано специально для обеспечения безопасности, но я не уверен, что вижу полный объем угрозы, которую он предназначен для смягчения. Вы можете попытаться найти более старые версии InputDispatcher, чтобы узнать, когда именно эта функция была введена - я сам не выглядел.

Я открыл билет об ошибке, если вы хотите следовать ему. По крайней мере, документация должна включать эту информацию... Я также хотел бы знать, действительно ли нужна эта функция безопасности.

Проблема 72746: FLAG_WATCH_OUTSIDE_TOUCH не возвращает местоположение для событий ACTION_OUTSIDE в версии 4.2+