배포와 인프라8 분 읽기

제 진동은 제가 건드린 적 없는 설정에 꺼져 있었습니다

진동은 화면에 안 보이고 에뮬레이터에서는 느낄 수도 없습니다. 시스템 로그로 판정하는 방법을 세우다, 우리 호출이 기기 설정 하나에 통째로 꺼질 수 있다는 걸 알았습니다.

#android#verification#gotchas#debugging#reality-check
개념 도식: 용도를 지정하지 않은 진동이 터치 피드백으로 자동 분류돼 기기 설정에 의해 꺼지는 흐름
글 내용을 요약한 개념 도식.

"진동이 전혀 안 온다"는 신고를 조사하면서 근본적인 제약과 마주쳤습니다. 진동은 화면에 안 보이고, 에뮬레이터에서는 느낄 수도 없습니다.

느낌 대신 시스템 로그로 판정하는 방법을 세웠습니다. 그 과정에서, 우리 진동 호출이 기기 설정 하나에 의해 통째로 꺼질 수 있다는 걸 알게 됐습니다.

(같은 신고 조사에서 나온 절반만 고쳤는데 '고쳐졌다'는 보고가 돌아온 이야기가 따로 있습니다. 그건 수정의 이야기고, 이건 판정의 이야기입니다 — 다른 글입니다.)

당신은 "진동이 나갔다"를 무엇으로 증명합니까? 사용자에게 묻는 것 말고요.

시스템이 한 줄씩 남깁니다

안드로이드는 진동 요청마다 dumpsys vibrator_manager에 한 줄을 남깁니다. 무엇을 재생하려 했는지, 실제로 어떻게 끝났는지, 무시됐다면 왜인지까지요.

09-14 20:16:26 | effect | finished | duration: 267ms | usage: TOUCH | <앱>
  | played: [Primitive=CLICK(scale=0.75, pause=0ms),Primitive=CLICK(scale=0.75, pause=60ms)]

읽는 법:

  • ignored가 있으면 시스템이 버린 것입니다(이유도 같이 남습니다). 0건이면 우리 호출 경로는 살아 있습니다.
  • original과 played가 다르면 그 기기에 세밀한 진동 튜닝이 없어 플랫폼이 대체 파형으로 폴백한 것입니다.
  • **cancelled_superseded**는 다음 진동이 앞 진동을 취소한 것입니다. 자동화된 연속 조작에서는 정상입니다.
  • 로그 상단 설정 블록에는 진동 켜짐 여부·절전 모드·벨소리 모드·용도별 강도가 전부 나옵니다. 사용자에게 묻지 않고도 기기 쪽 억제 여부를 바로 읽을 수 있습니다.

계측 테스트 안에서도 셸 명령 실행 API로 이 로그를 직접 읽을 수 있습니다. "느낌"은 여전히 못 재지만, "의도한 신호가 그대로 하드웨어까지 나갔는가"는 코드로 단언할 수 있습니다.

위 로그에서 진짜 함정은 usage: TOUCH입니다

진동을 재생할 때 별도 속성(용도)을 안 붙이면, 시스템이 자동으로 "터치 피드백" 용도로 분류합니다.

그러면 기기의 터치 피드백 설정이나 절전 모드가 우리 진동을 알림 진동과는 별개로, 통째로 꺼버릴 수 있습니다.

"다른 앱은 진동이 오는데 우리 앱만 조용하다"는 신고가 이것만으로 충분히 성립합니다. 앱 로직은 멀쩡한데 사용자 기기의 설정 하나가 원인인 경우입니다.

그래서 이런 신고를 받으면 알림 진동이 오는지가 아니라 키보드 입력 진동이 오는지를 물어야 합니다. 알림은 다른 용도로 분류돼 있어서 설정이 달라도 계속 울리니까요. 질문을 잘못 고르면 사용자가 "진동 옵니다"라고 답하는데 원인은 그대로 남습니다.

여기서 선택이 갈립니다

이 조사에서 기존 테스트의 근본적인 약점도 드러났습니다. 테스트는 이렇게 돼 있었습니다.

assertEquals(longArrayOf(0, 8, 60, 8), actualPattern)

"우리가 지정한 값 그대로가 나왔는가"를 확인합니다. 통과합니다. 영원히 통과합니다.

당신이라면 이 테스트가 무엇을 못 잡는다고 보겠습니까?

우리가 실수로 지각 문턱 아래의 값을 지정했어도, 그 값 자체를 정답으로 고정해서 영원히 통과시킵니다. 값이 틀렸다는 사실 자체를 테스트가 검증할 수 없는 구조입니다.

성질을 단언하는 방식으로 바꿨습니다.

  • 켜짐 구간은 전부 20ms 이상이어야 한다
  • 구간 경계는 보통 탭과 다른 신호여야 한다
  • 목표 도달 신호는 경계 신호보다 강해야 한다

값이 아니라 관계를 확인하면, 실수로 너무 약한 값을 넣었을 때 테스트가 실제로 빨개집니다.

자가진단

  • 진동·소리·알림을 낼 때 용도(usage)를 명시하고 있습니까? 안 하면 시스템이 대신 골라줍니다.
  • 테스트가 당신이 적은 값을 그대로 단언하고 있습니까? 그건 값의 정당성을 검증하지 않습니다.
  • 사용자에게 묻는 질문이 원인을 가르는 질문입니까? "진동 오나요?"와 "키보드 진동 오나요?"는 다른 정보를 줍니다.

솔직한 부분

기기 능력에 따라 자동으로 대체 신호로 떨어지는 경로도 있습니다. 정밀한 진동 패턴을 지원하지 않는 기기는 미리 정의된 표준 효과로 폴백합니다.

이 폴백 목록 중 가장 약한 등급의 효과는 특정 실기기에서 사실상 지각되지 않는 수준이었습니다. 그 판단의 근거는 제 감각이 아니라 사용자의 증언입니다 — 같은 기기에서 키보드 타이핑 진동은 느껴진다고 확인했기 때문에, 그 등급을 주 신호로 쓰지 않기로 했습니다.

여전히 "느낌"은 못 잽니다. 잴 수 있는 건 신호가 하드웨어까지 나갔는지까지입니다.

당신 앱이 내는 진동 한 줄을 골라, usage가 뭘로 찍히는지 로그에서 확인해보세요.

관련 글