모바일

WiFi Enable process 분석 - Wifi Scanning (2)

손가든 2024. 11. 8. 22:19

오블완 챌린지 2일차!

 

언제까지 유지되나 함 보자 싶지만,

오늘까지는 일단써보자 (대충 내일 일기 쓸 궁리중)

 

오늘은 어제 리뷰한 State Machine을 사용해서 Wifi가 연결하기 위해 주변 AP를 Scanning하는 코드를 분석하겠다.

 

하면서 항상 느끼지만 나처럼 이런 내용을 분석해주는 사람이 단 한명도 없어서 골머리를 앓고 있는데

누가 나대신 분석해서 이렇게 친절히 정리좀 해줬으면 좋겠음.

 

 


 

 

Wifi Scanning

 

 

 

Wifi Scanning을 하기 위해 이전 Wifi 버튼을 ON해서 따라오던 흐름으로 돌아가보자.

 

WIFI_TOGGLED 명령어를 전달하여 Controller의 StateMachine에 전달되는데,

이때 WifiController의 State가 당연히 아직 Wifi가 꺼져있었기 때문에 Disabled라고 생각했다.

 

근데 요놈이 Enabled였다.

WifiController면 꺼져있을때 disable 되어 있어야 될 거 아니냐고

(이놈때문에 흐름 쫓아간다고 머리 몇단 빠졌음)

 

사실은 Wifi가 꺼져있더라도,

Location service가 켜져있으면 Wifi의 AP들(Access Point라고 하는데, 공유기같은 역할을 하는 포인트를 AP라고 함) 과

통신하면서 Location 정보를 받을 수 있게 해당 스캐닝을 켜놓고 있는다.

 

이거 때문에 WifiController는 Enabled 상태이다.

 

이 흐름은 ConcreteClientModeManager 클래스의 sendMessage 호출 메소드로

CMD_SWITCH_TO_CONNECT_MODE를 전송한다.

 

이젠 진짜 Wifi를 Connect하나보다~ 하고 들어가보니

 

 

State Machine이 또있다.

요놈은 ClientModeStateMachine이다.

오른쪽에 State의 구조와 같고 이 상황에서 현재는 SCANONLY 모드이다.

Wifi 연결은 하지 않고 SCAN 만 수행하는 모드로 이해하면 좋다.

 

 

아무튼 SCANONLY 모드에서 메시지를 수신했으니 process를 해야한다.

근데 NOT_HANDLED

 

그래서 지난번 말했듯이 StateMachine의 상태가 메시지를 처리하지 못하면

부모로 처리를 전가한다.

 

따라서 Started의 processMessage로 전환한다.

이곳에선 해당 CMD를 처리하고 있다.

 

아주 간단하게 빨간 박스를 순서대로 그 동작을 설명하면,

첫번째 updateConnectModeState는 Wifi의 상태를 전역으로 관리하는 WifiState라는 변수가 있는데,

이는 StateMachine과는 다른 것이고 전역적인 신호라고 보면 좋다.

 

아무튼 이 WifiState가 현재 Disabled(세번쨰인자)에서 Enabling(두번째인자)로 전환하는 것을

Wifi 관련 모든 객체에 broadcasting 한다.

 

이 동작이 사실 scanning에 있어서 매우 중요한 역할을 하는데,

나중에 Enabled로 전환되는 브로드캐스트를 쏘면

해당 브로드캐스트를 리시브하는 객체가 scanner를 start하면서 스캐닝이 시작되기 때문이다.

 

아무튼 그렇고(?)

두번째 네모박스를 설명하자면

아키텍처 구조로 봤을 때 Android Framework Layer와 커널에 있는 드라이버가 통신하기 위한 중간 추상 인터페이스인 HAL이라는 것이 있는데,

 

이 HAL 인터페이스를 생성하고, Wifi를 관리하는 Supplicant라는 소프트웨어를 가동시키는 등 Low level layer과의 셋업과정을 수행한다.

 

그리고 마지막으로 Clientmode StateMachine을 connectmode로 전환한다.

 

 

그러면 이제 ConnectMode로 전환됬으니 Enter 메소드가 수행되어야 한다.

 

뭐 ClientModeImpl 객체를 생성하여 그 내부의 StateMachine도 가동되고,

WifiScanningServiceImpl 객체를 생성하여 세가지 스캐닝 모드에 대한 StateMachine도 가동하는데

 

그건 이 흐름에서 필요없는 분석이라 넘어가고

 

제일 중요한 Enabled로 Wifi가 전환됨을 브로드캐스팅하는 코드를 확인해보면

오른쪽 BaseWifiTracker에서 Scanner.start 메소드를 수행한다. (잘 안보여서 죄송합니다.)

 

 

이 메소드는 postScan() 메소드를 호출하고,

또 postScan() 메소드는 이제 본격적인 scan 요청을 시작하는 WifiManager의 startScan 메소드를 수행한다.

 

여기서 킥이 하나 존재한다.

 

Wifi Scanning은 사용자의 주변에 사용할 수 있는 AP(WIFI 네트워크들)들을 화면에 띄워주기 위한 목적이다.

따라서 해당 스캐닝은 지속적으로 수행해야 한다.

(Wifi를 연결하는 창에 들어가면 계속 wifi 목록들이 실시간으로 변경되는걸 볼 수 있을 것이다.)

 

이 스캐닝을 뭐 쉬지도 않고 수행하면 CPU는 너무 힘들어진다. 배터리가 증발할것이다.

 

따라서 해당 스캐닝 요청을 적당한 시간(보통 안드로이드는 15초인데 우리 회사는 10초로 포팅했음) 간격을 두고 재 수행한다.

 

그래서 저 아래 박스의 postDelayed를 활용하여 해당 메소드를 10초 간격을 두고

재기 호출하도록 해서 이 스캐닝이 반복 수행되도록 되어있는 것을 볼 수 있다.

 

그리고 WifiManager는 이제 StartScan을 시작한다.

 

다음 포스팅에서는 해당 Scan을 어떤 흐름으로 요청하는지,

스캔 결과를 어떻게 가져와서 목록에 전시하는지를 알아보겠다.

 

수고연 ~