스크린타임 앱을 혼자 만들어서 8월에 Play에 올렸습니다.

최근에 좀 황당한 문제를 발견해서 혹시 비슷한 앱 만드시는 분들이 있을까 싶어 적어봅니다.

제 앱은 사용시간 한도에 도달하면 지정한 앱을 잠그는 방식입니다.

그런데 기기 시간을 직접 바꿔보니까 문제가 생기더라고요.

시간을 앞으로 돌리면 사용시간 판정도 같이 움직이고, 뒤로 돌리면 또 그에 맞춰 움직였습니다.

확인해보니 문제가 있던 곳이 세 군데였습니다.

  • 주 1회 비상 해제
  • 오늘 사용량
  • 수면 잠금

처음에는 그냥 사용자가 자기 기기 시간을 바꿔서 자기 앱을 우회하는 문제니까 대수롭지 않게 생각했습니다.

그런데 스크린타임 앱은 결국 사용자가 스스로 정한 규칙을 지켜주는 도구인데, 마음만 먹으면 시간 한 번 바꾸는 걸로 풀려버리면 좀 허무하겠더라고요.

그래서 핵심 시간 계산에서 System.currentTimeMillis()를 빼고,

서버에서 한 번 받아온 시간을 기준으로 SystemClock.elapsedRealtime()을 더해서 현재 시간을 계산하도록 바꿨습니다.

물론 이것도 완벽한 방법은 아닙니다.

elapsedRealtime()은 기기를 재부팅하면 초기화되니까 서버에서 받아온 기준 시간도 부팅 세션 안에서만 유효합니다. 앵커를 잃어버리면 시스템 시간으로 돌아가는 폴백도 남겨뒀고요.

즉, 기기 시간을 바꾼다고 바로 우회하기는 어려워졌지만, 작정하고 뚫으려고 하면 아직 방법은 있다는 정도입니다.

그런데 여기서 또 하나 놓친 게 있었습니다.

저는 웹뷰 쪽만 수정하면 되는 줄 알았는데, 실제로 앱을 잠그는 건 네이티브 서비스 쪽이었습니다.

웹뷰에서는 서버 시간을 기준으로 제대로 계산하고 있는데 정작 네이티브 서비스는 그 시간을 알 방법이 없었던 겁니다.

앵커를 웹뷰 저장소에만 저장해놨으니 네이티브에서는 당연히 못 읽더라고요.

결국 시간 계산 로직을 고치는 것보다 웹뷰와 네이티브 사이에서 그 값을 전달하는 것부터 다시 손봤습니다.

이번에 제대로 느낀 게,

"여기 고쳤으니까 됐겠지"가 제일 위험하다는 거였습니다.

실제로 사용자를 막는 마지막 단계까지 따라가 보지 않으면 절반만 고친 거더라고요.

아직 실기기에서 시간을 실제로 앞으로 돌렸다가 뒤로 돌려보는 테스트도 더 해봐야 하고, 이번 주에 리뷰하면서 같은 쪽에서 문제가 하나 더 나왔습니다.

비상 해제의 '주 1회' 기준을 로컬 타임존 기준으로 잡아놨더니, 타임존만 바꿔도 같은 주에 두 번 사용할 수 있더라고요.

이건 아직 못 고쳤습니다.

혹시 스크린타임이나 사용 제한 같은 기능을 만들어보신 분들은 궁금합니다.

사용자가 규칙을 쉽게 우회하지 못하게 하면서도, 너무 귀찮아서 그냥 앱을 삭제해버리지는 않게 만드는 그 중간 지점을 어떻게 잡으셨나요?

제 앱은 한도에 도달하면 화면에 나온 문장을 그대로 따라 입력해야 해제되는 방식인데, 이 정도가 적당한지 아직도 감으로 잡고 있습니다.

혹시 궁금하신 분들을 위해 제가 만든 앱도 같이 남겨봅니다.

https://play.google.com/store/apps/details?id=com.elpisstudio.doff