第1章 WIFI热点鉴权
Wifi热点是将手机接收的GPRS、3G或4G信号转化为wifi信号发出去的技术,手机必须有无线AP功能,才能当做热点。
1.1 主要相关类
1、TetherSettings:是WiFi热点对应的界面;
2、WifiTetherSwitchBarController.java是用来负责热电开关的相关处理逻辑;
3、WifiTetherPreferenceController.java实现对preference的精细化控制。
1.1.1 开关控制
/packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
1、WifiTetherSwitchBarController. onSwitchToggled—》startTether()
2、WifiTetherSwitchBarController.startTether:
mSwitchBar.setEnabled(false);
mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
可以看出WiFi热点代开是通过ConnectivityManager.startTethering方法实现的。
3、ConnectivityManager.startTethering方法:是通过OnStartTetheringCallback实现的。可以看出wifi热点代开是通过ConnectivityManager.startTethering方法实现的。
4、WifiTetherSwitchBarController进行状态监听onReceive(),handleWifiApStateChanged
1.1.2 WifiTetherSwitchBarController
/packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
ConnectivityManager.startTethering方法。
1)WifiTetherSwitchBarController.startTether à mConnectivityManager.startTethering ,callback抽象类直接new出来
public void startTethering(int type, boolean showProvisioningUi,final OnStartTetheringCallback callback, Handler handler) {
2)状态监听
WifiTetherSwitchBarController. onReceiveResult()
WifiTetherSwitchBarController. handleWifiApStateChanged
WifiTetherSwitchBarController. updateWifiSwitch();
1.1.3 ConnectivityManager
/frameworks/base/core/java/android/net/ConnectivityManager.java
ConnectivityManager.startTethering方法。
在startTethering方法中,调用mService.startTethering(type, wrappedCallback, showProvisioningUi);,发现mService类型为IConnectivityManager,这里用到了android里面的aidl通信机制,定义在IConnectivityManager.aidl文件中,实现在/frameworks/base/services/core/java/com/android/server/ConnectivityService.java中,所以在ConnectivityManager中的调用相当如调用的是ConnectivityService.java中的startTethering方法。
- ConnectivityService
/frameworks/base/services/core/java/com/android/server/ConnectivityService.java
ConnectivityService中的startTethering方法最终调用Tethering中的startTethering方法
- Tethering
/frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
1.1.4 Tethering
/frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
1. Tethering. startTethering:打开tethering需要provision。
if (!isTetherProvisioningRequired()) { enableTetheringInternal}
if (showProvisioningUi) {runUiTetherProvisioningAndEnable(type, receiver);}
else {runSilentTetherProvisioningAndEnable(type, receiver);}
runUiTetherProvisioningAndEnable—》getProxyReceiver、sendUiTetherProvisionIntent
2、enableTetheringInternal方法,在这里面会涉及到我们的关键问题。
在这里有3个重要方法:
Wifi共享:setWifiTethering(enable);
USB共享:setUsbTethering(enable);
蓝牙共享:setBluetoothTethering(enable, receiver);
这里会走到WifiManager,wifi config为空表示使用已有的wifi config。 后面的sendTetherResult就是会调之前的receiver通知执行结果。
1.1.5 ATT需求模块
1)Tethering.onReceive:监听wifi状态,如果监听到WifiManager.WIFI_AP_STATE_CHANGED_ACTION---》handleWifiApAction()。
2)在handleWifiApAction方法里面检测到wifi时开启过程中还是已开启。如果已经开启wifi,会调用enableWifiIpServingLocked。enableWifiIpServingLocked—》changeInterfaceState()--》tether()有if(!permit){ (ifname, requestedState)。--》checkPermission()--》isATTSimCard()判断是不是att的卡
在if(!permit){方法里面判断一下是否是ATT,权限是否允许
permit = checkPermission(iface);
if(!permit){//如果是ATT的且权限允许的话,执行……}
else{//如果不是ATT的话就执行
return tether_internel(iface,requestedState);}
3)看一下checkPermission:
在这个方法里面会判断是否是ATT的卡,ATT的卡为False,非ATT的卡为true。
ATT的卡changeInterfaceState()就会返回true,enableWifiIpServingLocked()方法返回true
1.1.6 ATT需求模块
1)Tethering
/vendor/tct/source/apps/serviceEntitlement/src/com/app/serviceEntitlement/HttpUtils.java
在开启wifi,usb需要AT&T的认证,到对应的网站去发起请求,根据返回码做对应处理。
2)serviceEntitlementService.java
/vendor/tct/source/apps/serviceEntitlement/src/com/app/serviceEntitlement/serviceEntitlementService.java
在serviceEntitlementService.java中的entitlementHandle类的run函数中调用checkPermission。
entitlementHandle又是如何创建的呢?是在 TetherChangeReceiver中创建,TetherChangeReceiver是广播,专门来处理Tethering状态发生改变的事件,该广播注册在serviceEntitlementService的onCreate方法中。
最为重要的部分,serviceEntitlementService又是如何启动的呢?
通过查看/vendor/tct/source/apps/serviceEntitlement/AndroidManifest.xml文件,发现在该文件中注册了一个广播serviceEntitlementReceiver。
在serviceEntitlementReceiver.java中接收ACTION_BOOT_COMPLETED广播时,将开启服务serviceEntitlementService。
1.1.7 总结
- 在手机开机后,发出广播ACTION_BOOT_COMPLETED,serviceEntitlementReceiver接收到该广播,开启服务serviceEntitlementService。
- serviceEntitlementService的onCreate方法中注册广播TetherChangeReceiver,onDestroy方法中注销。
- TetherChangeReceiver中主要处理action为ACTION_SERVICE_ENTITLEMENT广播,最终创建entitlementHandle,并调用process方法,开启线程(entitlementHandle实现了Runnable接口)
- entitlementHandle中的run方法调用checkPermission,得到response,发送Intent(ACTION_SERVICE_ENTITLEMENT_RESULT)
1.1.8 serviceEntitlementService与Tethering模块交互
通过两个类型Intent:
ACTION_SERVICE_ENTITLEMENT
ACTION_SERVICE_ENTITLEMENT_RESULT
第一个Intent发送的方法为checkPermission,调用该方法的 tether,调用tether的方法为tetherMatchingInterfaces,最终调用的地方也是StateReceiver广播
第二个Intent接收的方法为StateReceiver广播内接收。
总结:两个模块之间的通信机制使用的是android里面的广播,两个之间处理流程是在开启网络共享功能时,会发生状态的改变,StateReceiver专门接收这类型的广播,最终调用对应的方法去做验证。
1.1.9 Tethering选择
Tethering构造方法中调用 updateConfiguration()去新建TetheringConfiguration对象,该对象保存分享配置的信息,其中有关apn选择的操作在 TetheringConfiguration的构造方法中.
通过checkDunRequired最终调用TelephonyManager类中的方法getTetherApnRequired.
在PhoneInterfaceManager中具体实现,调用phone.hasMatchedTetherApnSetting然后通过DcTracker对象的hasMatchedTetherApnSetting方法去获取有无DUN APN
当 StateReceiver广播接收器收到ConnectivityManager.CONNECTIVITY_ACTION广播时,调用handleConnectivityAction.
在handleConnectivityAction发出消息mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED)
TetherModeAliveState中processMessage调用chooseUpstreamType.
chooseUpstreamType中调用maybeUpdateConfiguration去更新TetheringConfiguration的信息,然后UpstreamNetworkMonitor中的selectPreferredUpstreamType根据传进来的参数选择网络类型去请求建立对应的网络.
具体实现在registerMobileNetworkRequest中,调用ConnectivityService中的requestNetwork去请求对应的网络
3.拿 setWifiTethering说明举例:
484 mWifiTetherRequested = enable;
//使用用已存在的wifi配置
485 final WifiManager mgr = getWifiManager();
1.1.5 WifiManager
1)/frameworks/base/wifi/java/android/net/wifi/WifiManager.java
startSoftAp --》mService.startSoftAp(wifiConfig)
IWifiManager mService;
WifiServiceImpl对IWifiManager.Stub进行实现
2)WifiServiceImpl.startSoftAp—》WifiServiceImpl.startSoftApInternal
3)WifiServiceImpl.startSoftApInternal:
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);
转变对空的wifi config 包装成了SoftApModeConfiguration 接下来有WifiController 处理。
4)WifiController.java
WifiController类继承自StateMachine 里面,采用的机制是android实现的状态机,它的创建和开启工作都在WifiServiceImpl中。