在“设置”->“无线和网络”,有一项飞行模式的checkbox。根据其描述“禁用所有无线连接”,可略知其功能,但具体实现了哪些功能呢,我们从代码的角度来分析。
在类WirelessSettings中,包含一个成员变量mAirplaneModeEnabler,飞行模式的功能是由类AirplaneModeEnabler来实现的。setAirplaneModeOn(boolean enabling)是该类用来设置飞行模式开关的方法,该方法最重要的实现是广播Intent.ACTION_AIRPLANE_MODE_CHANGED,并携带开/关的标志位。
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enabling);
mContext.sendBroadcast(intent);
查找源代码,有3个模块响应该事件。
- PhoneApp:关闭电话射频信号
- WifiService:关闭wifi信号
- BluetoothService:关闭bluetooth信号
但wifi模块稍有区别,即使在飞行模式下,wifi也可以开启。
飞行模式设置入口,下拉状态栏,点击飞行模式图标,我们就从这里看起,其他入口逻辑差不多。这个源码位于
frameworks\base\packages\SystemUI\src\com\android\systemui\qs\tiles\AirplaneModeTile.java
public void handleClick() {MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);setEnabled(!mState.value);mEnable.setAllowAnimation(true);mDisable.setAllowAnimation(true);}private void setEnabled(boolean enabled) {final ConnectivityManager mgr =(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);mgr.setAirplaneMode(enabled);}
接下来调用 ConnectivityManager#setAirplaneMode 方法。
位于 frameworks/base/core/java/android/net/ConnectivityManager.java
public void setAirplaneMode(boolean enable) {try {mService.setAirplaneMode(enable);} catch (RemoteException e) {}}
mService 是 IConnectivityManager,是个接口,其实现看
ConnectivityService#setAirplaneMode,位于frameworks/base/services/core/java/com/android/server
public class ConnectivityService extends IConnectivityManager.Stubimplements PendingIntent.OnFinished {private static final String TAG = "ConnectivityService";private static final boolean DBG = true;private static final boolean VDBG = false;private static final boolean LOGD_RULES = false;... public void setAirplaneMode(boolean enable) {enforceConnectivityInternalPermission();final long ident = Binder.clearCallingIdentity();try {final ContentResolver cr = mContext.getContentResolver();Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);intent.putExtra("state", enable);mContext.sendBroadcastAsUser(intent, UserHandle.ALL);} finally {Binder.restoreCallingIdentity(ident);}}
}
这里设置了飞行模式状态的系统变量以及发送 ACTION_AIRPLANE_MODE_CHANGED 系统广播,接下来看看该广播的接受。经过查找,ACTION_AIRPLANE_MODE_CHANGED 广播接受有好几次,而手机开启或关闭飞行模式时,主要是开启或关闭 Radio 无线通信,其处理逻辑在 PhoneGlobals 类中。另外 WiFi 、蜂窝数据和蓝牙处理都能相应追踪到。