"피팅키보드" 버그 발견 후 수정 중

이상빈·2021년 11월 9일
0

(현재 버그)

일부 EditText 뷰에서, 특정 방식으로 텍스트 입력을 취소하면, 오토마타가 꼬이는 현상이 발생 중이다.

감사하게도 한 사용자분께서 카톡에서 발생한 영상까지 첨부해서 제보해주셨는데, 해당 핸드폰 기종과 비슷한 환경의 에뮬레이터를 구성해서 재현해봤다.

에뮬레이터에 설치된 유튜브 어플을 이용해 재현해본 결과, 유튜브 검색창의 "x" 버튼을 누르면 입력중인 텍스트가 초기화되어야하는데, "오토마타 로직"은 초기화되지 않는 것이 발견되었다.
(추측해보건대, 구글에서 저 x버튼의 동작을 설계할 때 뭔가 이벤트를 넣어줘야하는데, 그러질 않은 듯..)

만약 "오토마타 로직"이 초기화되지 않으면, 위 상황과 같이 커서 위치가 변경되어도 Comsposing 상태였던 글자로 이어서 Composing이 되는 현상이 발생한다.

그러니까, 버그 해결을 위해서는 "X"버튼 누르는 방식처럼 텍스트 초기화를 시키면, 오토마타 로직도 초기화를 시켜주면 해결되는 버그다.

일단은 저 버그를 해결하기 위해 커서 위치가 변경되었다는 사실을 키보드가 알아채야 한다.

기존에는

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onUpdateSelection(
        oldSelStart: Int,
        oldSelEnd: Int,
        newSelStart: Int,
        newSelEnd: Int,
        candidatesStart: Int,
        candidatesEnd: Int
    ) {
        Log.d("onUpdateSelection", "oldSelStart: $oldSelStart\noldSelEnd: $oldSelEnd\nnewSelStart: $newSelStart\nnewSelEnd: $newSelEnd\ncandidatesStart: $candidatesStart\ncandidatesEnd: $candidatesEnd")
        if (candidatesStart != -1) {
            if ((candidatesStart != oldSelStart && candidatesEnd != newSelStart)) {
                clearComposing()
            }
        } else if (newSelStart == 0 && newSelEnd == 0 && candidatesStart == -1 && candidatesEnd == -1) {
            clearComposing()
        }
        /** TextField의 첫글자로 돌아갔을 때 대문자로 수정 **/
        if (vm.observeKBAutoCapitalization.value!!
            && currentInputConnection.requestCursorUpdates(CURSOR_UPDATE_IMMEDIATE)
            && vm.mode.value == 2
        ) {
            var autoCapitalCondition = false
            for (i in 0..3) {
                if (currentInputConnection
                        .getTextBeforeCursor(
                            i + 2, GET_TEXT_WITH_STYLES
                        )
                        .toString()
                        .replace(
                            "\\s"
                                .toRegex(), ""
                        ) == "."
                ) {
                    autoCapitalCondition = true
                }
            }
            if ((newSelStart == 0 && newSelEnd == 0 && candidatesStart == -1 && candidatesEnd == -1) || autoCapitalCondition) {
                vm.changeMode(1)
            }
        }
    }

위와 같은 onUpdateSelection 메소드를 오버라이드해서,

커서 위치가 모종의 이유로 변경되었다. 그러니 오토마타 로직을 초기화해라

는 명령을 주면 됐지만, 로그를 찍어본 결과, 버그 발생 상황에서는 커서 변경 이벤트가 들어오지 않았다.

(버그 수정 시도1)

일단, IME 서비스의 생명주기를 다시한번 찬찬히 뜯어봤다..

저 유튜브 "x"버튼은 무슨 이유인지는 모르겠지만 onFinishInput()과 onFinishInputView()를 호출하지 않고, 텍스트를 초기화한 다음 다시 onStartInputView()와 onStartInput() 메소드를 호출한다.(뭐지?)

override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
        super.onStartInput(attribute, restarting)
        println("onStartInput() 호출됨")
    }

    override fun onFinishInput() {
        super.onFinishInput()
        println("onFinishInput() 호출됨")
    }

위 생명주기 메소드를 오버라이드해서 확인 결과, onFinishInput()도 호출되지 않았다..

결국엔 어떤 방식으로든 저 "X" 버튼은 사용중인 키보드의 onStartInput()과 onStartInputView()를 호출한다는 뜻이다.

그래서 혹시나 해서 문서의 onStartInput()을 살펴봤더니 아래와 같았다.

/**
     * Called to inform the input method that text input has started in an
     * editor.  You should use this callback to initialize the state of your
     * input to match the state of the editor given to it.
     * 
     * @param attribute The attributes of the editor that input is starting
     * in.
     * @param restarting Set to true if input is restarting in the same
     * editor such as because the application has changed the text in
     * the editor.  Otherwise will be false, indicating this is a new
     * session with the editor.
     */

해석: onStartInput() 메소드는, 키보드에게 "텍스트 입력이 시작됐다"고 알리기 위해 호출된다. 당신은 당신의 입력 상태를 초기화해서 텍스트 에디터의 상태와 매치시키기 위해 이 콜백을 작성하여 이용할 수 있다.

그러네..ㅋㅋ

그러면 문제는 간단해진다. onStartInput()에서 오토마타 로직을 초기화시켜주면 된다.

override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
        super.onStartInput(attribute, restarting)
        clearComposing()
    }

clearComposing() 함수가 오토마타 로직 초기화 함수다.

이제 이게 다른 에딧텍스트뷰에서도 동일한 효과를 내며, 다른 버그는 없는지 알아봐야한다..

profile
발전을 좋아하는 사람

0개의 댓글