//开机过程中无线模块的初始化过程: //rild 调用参考实现 Reference-ril.c (hardware/ril/reference-ril) 中的函数: const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv) ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL); static void *mainLoop(void *param) ret = at_open(fd, onUnsolicited); RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0); //在 initializeCallback 函数中对猫进行了初始化。 static void initializeCallback(void *param) { ATResponse *p_response = NULL; int err; setRadioState (RADIO_STATE_OFF); at_handshake(); /* note: we don't check errors here. Everything important will be handled in onATTimeout and onATReaderClosed */ /* atchannel is tolerant of echo but it must */ /* have verbose result codes */ at_send_command("ATE0Q0V1", NULL); /* No auto-answer */ at_send_command("ATS0=0", NULL); /* Extended errors */ at_send_command("AT+CMEE=1", NULL); /* Network registration events */ err = at_send_command("AT+CREG=2", &p_response); /* some handsets -- in tethered mode -- don't support CREG=2 */ if (err success == 0) { at_send_command("AT+CREG=1", NULL); } at_response_free(p_response); /* GPRS registration events */ at_send_command("AT+CGREG=1", NULL); /* Call Waiting notifications */ at_send_command("AT+CCWA=1", NULL); /* Alternating voice/data off */ at_send_command("AT+CMOD=0", NULL); /* Not muted */ at_send_command("AT+CMUT=0", NULL); /* +CSSU unsolicited supp service notifications */ at_send_command("AT+CSSN=0,1", NULL); /* no connected line identification */ at_send_command("AT+COLP=0", NULL); /* HEX character set */ at_send_command("AT+CSCS=/"HEX/"", NULL); /* USSD unsolicited */ at_send_command("AT+CUSD=1", NULL); /* Enable +CGEV GPRS event notifications, but don't buffer */ at_send_command("AT+CGEREP=1,0", NULL); /* SMS PDU mode */ at_send_command("AT+CMGF=0", NULL); #ifdef USE_TI_COMMANDS at_send_command("AT%CPI=3", NULL); /* TI specific -- notifications when SMS is ready (currently ignored) */ at_send_command("AT%CSTAT=1", NULL); #endif /* USE_TI_COMMANDS */ /* assume radio is off on error */ if (isRadioOn() > 0) { setRadioState (RADIO_STATE_SIM_NOT_READY); } } // 默认状况下假设射频模块是好的, // 通过 setRadioState (RADIO_STATE_SIM_NOT_READY) 来触发对无线模块的初始化。 // 通过 static void onRadioPowerOn() 对无线模块初始化。 // 首先通过 pollSIMState(NULL); 轮询 sim卡状态 。 static void pollSIMState (void *param) { ATResponse *p_response; int ret; if (sState != RADIO_STATE_SIM_NOT_READY) { // no longer valid to poll return; } switch(getSIMStatus()) { case RIL_SIM_ABSENT: case RIL_SIM_PIN: case RIL_SIM_PUK: case RIL_SIM_NETWORK_PERSONALIZATION: default: setRadioState(RADIO_STATE_SIM_LOCKED_OR_ABSENT); return; case RIL_SIM_NOT_READY: RIL_requestTimedCallback (pollSIMState, NULL, &TIMEVAL_SIMPOLL); return; case RIL_SIM_READY: setRadioState(RADIO_STATE_SIM_READY); return; } } // 读取sim卡状态的函数是:getSIMStatus() // err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response); // 它向猫发送了at命令 AT+CPIN? 来查询无线模块的状态,如果无线模块还没有就绪,那么他隔1秒钟继续调用sim卡状态轮询函数 pollSIMState,直到获得sim卡状态。 // 当sim卡状态为就绪,那么通过 setRadioState(RADIO_STATE_SIM_READY) 设置变量 sState 为:RADIO_STATE_SIM_READY,这时候会调用函数 static void onSIMReady()来进一步初始化无线模块。 // 发送的at命令有: // at_send_command_singleline("AT+CSMS=1", "+CSMS:", NULL); // at_send_command("AT+CNMI=1,2,2,1,1", NULL); // 如果sim卡锁开启,或者pin被锁住的时候,会要求输入pin或者puk,但是这个解锁动作必须在系统初始化完成以后才能进行。(图形系统都还没有初始化怎么输入密码阿?)当系统初始化完成以后会调用 wm.systemReady()来通知大家。 // 这时候该做什么就做什么。 // ========== wm.systemReady()的调用会触发解锁界面。具体流程如下: 因为有: WindowManagerService wm = null;所以 wm.systemReady() 调用的是 WindowManagerService 中的函数: public void systemReady() { mPolicy.systemReady(); } WindowManagerService 中有: final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager(); PolicyManager.makeNewWindowManager 调用的是文件 PolicyManager.java 中的函数: public static WindowManagerPolicy makeNewWindowManager() { return sPolicy.makeNewWindowManager(); } sPolicy.makeNewWindowManager 调用的是文件 Policy.java 中的函数: public PhoneWindowManager makeNewWindowManager() { return new PhoneWindowManager(); } 因为 PhoneWindowManager 继承自 WindowManagerPolicy 所以 mPolicy.systemReady() 最终调用的是文件 PhoneWindowManager.java 中的函数: public void systemReady() mKeyguardMediator.onSystemReady(); doKeyguard(); showLocked(); Message msg = mHandler.obtainMessage(SHOW); mHandler.sendMessage(msg); 发送 SHOW 的消息。 文件 KeyguardViewMediator.java 中的消息处理函数: public void handleMessage(Message msg) 对 SHOW 消息进行了处理。 如果 msg.what 等于 SHOW 那么执行: handleShow(); private void handleShow() ... mCallback.onKeyguardShow(); mKeyguardViewManager.show(); mShowing = true; mKeyguardViewManager.show() 调用的是文件 KeyguardViewManager.java 中的函数: public synchronized void show() ... mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this); ... mKeyguardViewProperties.createKeyguardView 调用的是文件 LockPatternKeyguardViewProperties.java 中的函数: public KeyguardViewBase createKeyguardView(Context context, KeyguardUpdateMonitor updateMonitor, KeyguardWindowController controller) { return new LockPatternKeyguardView(context, updateMonitor, mLockPatternUtils, controller); } new LockPatternKeyguardView 调用了类 LockPatternKeyguardView 的构造函数: public LockPatternKeyguardView( Context context, KeyguardUpdateMonitor updateMonitor, LockPatternUtils lockPatternUtils, KeyguardWindowController controller) ... mLockScreen = createLockScreen(); addView(mLockScreen); final UnlockMode unlockMode = getUnlockMode(); mUnlockScreen = createUnlockScreenFor(unlockMode); mUnlockScreenMode = unlockMode; addView(mUnlockScreen); updateScreen(mMode); 执行上面的程序然后弹出解锁界面,getUnlockMode 获得锁类型,通常有三种: enum UnlockMode { Pattern, //图案锁 SimPin, //输入pin或者puk Account //账号锁 } 通过上面的过程我们可以知道,在系统初始化阶段启动rild的时候,rild与猫进行了通信,并对猫进行初始化。 保存了网络的一系列状态。 //========= 待机状态下,飞行模式切换流程分析: 飞行模式切换比较复杂,它状态改变时涉及到极大模块状态切换: GSM模块,蓝牙模块,wifi模块。 飞行模式的enabler层会发送广播消息:ACTION_AIRPLANE_MODE_CHANGED private void setAirplaneModeOn(boolean enabling) { mCheckBoxPref.setEnabled(false); mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on : R.string.airplane_mode_turning_off); // Change the system setting Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, enabling ? 1 : 0); // Post the intent Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); intent.putExtra("state", enabling); mContext.sendBroadcast(intent); } 因为GSM ,蓝牙,wifi模块分别注册了对 ACTION_AIRPLANE_MODE_CHANGED 消息的监测,所以收到 该消息后,模块会进行切换。 BluetoothDeviceService.java 开启蓝牙:enable(false); 关闭蓝牙:disable(false); PhoneApp.java (packages/apps/phone/src/com/android/phone) 设置GSM模块状态 phone.setRadioPower(enabled); WifiService.java 设置 wifi 状态 setWifiEnabledBlocking(wifiEnabled, false, Process.myUid()); //========== GSM模块切换过程分析: phone.setRadioPower(enabled)调用的是: 文件 GSMPhone.java 中的的函数: public void setRadioPower(boolean power) mSST.setRadioPower(power); 因为有 ServiceStateTracker mSST; mSST.setRadioPower 调用的是文件 ServiceStateTracker.java 中的函数: public void setRadioPower(boolean power) mDesiredPowerState = power; setPowerStateToDesired(); cm.setRadioPower(true, null); 或者 cm.setRadioPower(false, null); 因为有: CommandsInterface cm; public final class RIL extends BaseCommands implements CommandsInterface 所以 cm.setRadioPower 调用的是文件 RIL.java 中的函数: public void setRadioPower(boolean on, Message result) RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result); rr.mp.writeInt(1); ... send(rr) 通过 send 向 rild 发送 RIL_REQUEST_RADIO_POWER 请求来开启或者关闭GSM模块。 rild 数据接收流程: 收到 RIL_REQUEST_RADIO_POWER 执行: requestRadioPower(data, datalen, t); 然后根据条件往无线模块发送模块开启和关闭请求 主要的at命令有: err = at_send_command("AT+CFUN=0", &p_response); err = at_send_command("AT+CFUN=1", &p_response); //========== 蓝牙模块切换过程分析: enable(false); 蓝牙开启调用文件 BluetoothDeviceService.java 中的函数: public synchronized boolean enable(boolean saveSetting) setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_TURNING_ON); mEnableThread = new EnableThread(saveSetting); mEnableThread.start(); ---- disable(false) 蓝牙关闭调用文件 中的函数: public synchronized boolean disable(boolean saveSetting) setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF); //========== wifi模块切换过程分析: 广播 wifi 状态改变的消息:WIFI_STATE_CHANGED_ACTION setWifiEnabledState(enable ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid); 更新 wifi 状态: private void updateWifiState() 如果需要使能开启 wifi 那么会发送: sendEnableMessage(true, false, mLastEnableUid); sendStartMessage(strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY); mWifiHandler.sendEmptyMessage(MESSAGE_STOP_WIFI); 消息循环中处理命令消息: public void handleMessage(Message msg) 如果使能wifi:setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2); 开启wifi: mWifiStateTracker.setScanOnlyMode(msg.arg1 != 0); setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2); 断开 mWifiStateTracker.disconnectAndStop(); 开启过程步骤: 1> 装载 wifi 驱动: WifiNative.loadDriver() 2> 启动后退 daemo supplicant: WifiNative.startSupplicant() 关闭过程步骤: 1> 停止后退 daemo supplicant:WifiNative.stopSupplicant() 2> 卸载 wifi 驱动: WifiNative.unloadDriver() 如果 wifi 状态默认为开启那么 WifiService 服务的构造函数: WifiService(Context context, WifiStateTracker tracker) boolean wifiEnabled = getPersistedWifiEnabled(); setWifiEnabledBlocking(wifiEnabled, false, Process.myUid()); 会开启wifi模块。
|
|