Android 无线启动过程分析 无线启动过程分析

Android 无线启动过程分析 无线启动过程分析

开机过程中无线模块的初始化过程:

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模块。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岩-悠然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值