android系统启动及wifi框架分析

android系统启动:http://blog.csdn.net/yicao821/article/details/6893752

最近在分析Android WIIF框架,顺便就把Android系统启动过程做了个流程分析,在这分享下我的学习经验。部分有修正网络文章。欢迎拍砖!

Android系统从Linux内核启动后分为4个基本步骤:

(1) init进程启动
(2) Native服务启动
(3) System Server,Android服务启动
(4) Home启动

后面的内容都是在上面几个大部分做的分析!

          

一、init进程(system\core\init\init.c)

init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。

Init.rc
Init.marvel.rc
Init进程一起来就根据init.rc和init.xxx.rc脚本文件建立了几个基本的服务:
 servicemanamger
 zygote
 。。。
最后Init并不退出,而是担当起property service的功能。

1.1脚本文件
Init.c: parse_config_file(Init.rc)
   @parse_config_file(Init.marvel.rc)

解析脚本文件:Init.rcInit.xxxx.rc(硬件平台相关)

Init.rc是Android自己规定的初始化脚本(Android Init Language, System/Core/Init/readme.txt)
该脚本包含四个类型的声明:

Commands       命令
Actions        动作
Triggers       触发
Services       服务
Options        选项
Propertise     属性

1.2 服务启动机制
我们来看看Init是这样解析.rc文件开启服务的。
(1)打开.rc文件,解析文件内容@ system\core\init\init.c
将service信息放置到service_list中。@ system\core\init parser.c
(2)restart_service()@ system\core\init\init.c
 service_start
 execve(…).建立service进程。

二、zygote

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

zygote主要经过其下几个过程:
registerZygoteSocket();//登记Listen端口
startSystemServer();
进入Zygote服务框架。
经过这几个步骤,Zygote就建立好了,利用Socket通讯,接收ActivityManangerService的请求,Fork应用程序。
三、SystemServer

(frameworks/base/service/java/com/android/server/SystemServer.java)
 pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null);
在SystemServer.java中看不到循环结构,只是可以看到建立了init2的实现函数,建立了一大堆服务,并AddService到service Manager。
main() @ com/android/server/SystemServer
{
init1();
}

四、init1 

Init1()是在Native空间实现的(com_andoird_server_systemServer.cpp)。我们一看这个函数就知道了,init1->system_init()
frameworks/base/cmds/system_server/library/System_init.cpp

system_init()我们看到了循环闭合管理框架。
{        // Start the AudioFlinger  
        // Start the media playback service     
        // Start the camera service  
        // Start the audio policy service
Call "SystemServer.java", "init2"
runtime->callStatic("com/android/server/SystemServer", "init2");
…..
ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}
public static final void init2() {
        Log.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
}

五、init2

init2()@SystemServer.java中建立了Android中所有要用到的服务。这个init2()建立了一个线程,来New Service和AddService来建立服务

public void run() {
// Critical services...
power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);
    battery = new BatteryService(context);
                ServiceManager.addService("battery", battery);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);

    (ActivityManagerService)ServiceManager.getService("activity"))
                .setWindowManager(wm);
    if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
        try {
    connectivity = ConnectivityService.getInstance(context);
                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

                 //后文Android WIFI框架分析(1) 有相关
     Log.i(TAG, "Search Service");
                ServiceManager.addService( Context.SEARCH_SERVICE, new SearchManagerService(context) );
        }
    }
}

六、Home Activity

在ServerThread@SystemServer.java后半段,我们可以看到系统在启动完所有的Android服务后,做了这样一些动作:
(1) 使用xxx.systemReady()通知各个服务,系统已经就绪。
(2) 特别对于ActivityManagerService.systemReady(回调)
Widget.wallpaper,imm(输入法)等ready通知。

Home就是在ActivityManagerService.systemReady()通知的过程中建立的。下面是ActivityManagerService.systemReady()的伪代码:
systemReady()@ActivityManagerService.java
resumeTopActivityLocked()
startHomeActivityLocked();//如果是第一个则启动HomeActivity
startActivityLocked(。。。)CATEGORY_HOME


android wifi框架分析:http://blog.csdn.net/menuconfig/article/details/7306931


趁做Android WIFI驱动移植,对Android WIFI框架做了深刻的分析,并做此文档共同学习。

       对上层WIFI的应用,基本流程为:(1)WIFI初始化  (2)Wifi启动      (3)开始扫描AP        (4)显示扫描的AP      (5)配置AP        (6)连接AP     (7)获取IP地址      (8)上网            

一、Android WIFI模块初始化

上文Android系统启动分析  讲到在SystemServer中实例化了ConnectivityService,接着的便是WIFI初始化:
frameworks/base/services/java/com/android/server/ConnectivityService.java
ConnectivityService 的构造函数会创建WifiService,

if (DBG) Log.v(TAG, "Starting Wifi Service.");
      WifiStateTracker wst = new WifiStateTracker(context, mHandler);
      WifiService wifiService = new WifiService(context, wst);
      ServiceManager.addService(Context.WIFI_SERVICE, wifiService);

WifiStateTracker 会创建WifiMonitor接收来自底层的事件,WifiService 和WifiMonitor 是整个模块的核心。WifiService负责启动关闭wpa_supplicant、启动关闭WifiMonitor监视线程和把命令下发给wpa_supplicant,而WifiMonitor 则负责从wpa_supplicant 接收事件通知。
具体流程图如下:

二、WIFI模块启动

         WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮 WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮     

Packages\apps\settings\src\com\android\settings\WirelessSettings.java
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.wireless_settings);
        initToggles();
        mAirplaneModePreference = (CheckBoxPreference) findPreference(KEY_TOGGLE_AIRPLANE);
    }
private void initToggles() {
    …………
    mWifiEnabler = new WifiEnabler(
                this, (WifiManager) getSystemService(WIFI_SERVICE),
                (CheckBoxPreference) wifiPreference);
…………
}

        当用户按下Wifi 按钮后,Android 会调用WifiEnabler的onPreferenceChange,再由WifiEnabler调用WifiManager 的setWifiEnabled接口函数,通过AIDL,实际调用的是WifiService 的setWifiEnabled 函数,WifiService接着向自身发送一条MESSAGE_ENABLE_WIFI 消息,在处理该消息的代码中做真正的使能工作:
首先装载WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/libertas_sdio.ko" ),
然后启动wpa_supplicant ( 配置文件硬编码为"/data/misc/wifi/wpa_supplicant.conf"),再通过WifiStateTracker 来启动WifiMonitor 中的监视线程。
WifiEnabler.java

public boolean onPreferenceChange(Preference preference, Object value) {
        // Turn on/off Wi-Fi
        setWifiEnabled((Boolean) value);        
    }
private void setWifiEnabled(final boolean enable) {
        if (!mWifiManager.setWifiEnabled(enable)) {
        }
    }  

WifiManager.java
 public boolean setWifiEnabled(boolean enabled) {
            return mService.setWifiEnabled(enabled);
    }
 IWifiManager mService;
 interface IWifiManager{
    …………
    boolean startScan(boolean forceActive);
    boolean setWifiEnabled(boolean enable);
 …………
 }
IWifiManger.aidl编译后生成了IWifiManger.java,并生成IWifiManger.Stub(服务器端抽象类)和IWifiManger.Stub.Proxy(客户端代理实现类)。WifiService通过继承IWifiManger.Stub实现,而客户端通过getService()函数获取IWifiManger.Stub.Proxy(即Service的代理类),将其作为参数传递给WifiManger,供其与WifiService通信时使用。
WifiService.java 

public boolean setWifiEnabled(boolean enable) {
…………
sendEnableMessage(enable, true, Binder.getCallingUid());
    …………
}
private void sendEnableMessage(boolean enable, boolean persist, int uid) {
        Message msg = Message.obtain(mWifiHandler,
                                     (enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
                                     (persist ? 1 : 0), uid);
        msg.sendToTarget();
    }
public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_ENABLE_WIFI:
                    setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);
                case MESSAGE_START_WIFI:                  
                    mWifiStateTracker.restart(); 
               case MESSAGE_DISABLE_WIFI:                 
                    setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2);              
                case MESSAGE_STOP_WIFI:
                    mWifiStateTracker.disconnectAndStop();
                    break;
            }
        }
    }
private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {
if (enable) {
            if (!WifiNative.loadDriver()) {               
                setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
            }
            if (!WifiNative.startSupplicant()) {
                WifiNative.unloadDriver();             
                setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
            }
            registerForBroadcasts();
            mWifiStateTracker.startEventLoop();
        } else {
  ………………
  }
    // Success!       
        setWifiEnabledState(eventualWifiState, uid);
}
private void setWifiEnabledState(int wifiState, int uid) {
 // Broadcast
        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
 JNI android_net_wifi_wifi.cpp
// ----------------------------------------------------------------------------

/*
* JNI registration.
*/
static JNINativeMethod gWifiMethods[] = {
    /* name, signature, funcPtr */
    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },   
    { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },   
    { "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },      
    { "reconnectCommand", "()Z",  (void *)android_net_wifi_reconnectCommand },  
    { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
}
1)static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
{
    return (jboolean)(::wifi_load_driver() == 0);
}
2)static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
{
    return (jboolean)(::wifi_start_supplicant() == 0);
}
3)WifiStateTracker.java
mWifiStateTracker.startEventLoop();
public void startEventLoop() {
        mWifiMonitor.startMonitoring();
    }
//WifiMonitor.java
public void startMonitoring() {
        new MonitorThread().start();
    }

当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。// Success!后广播的。

http://blog.csdn.net/yicao821/article/details/6895044


上文讲到WIFI的启动流程,当然接着便扫描热点(AP),然后显示扫描到的AP、配置AP(填写IP地址等信息)、连接AP、获取IP地址、最后就是想要的上网咯!

一、扫描热点(AP)

上文启动WIFI成功后:// Success!       
        setWifiEnabledState(eventualWifiState, uid);
private void setWifiEnabledState(int wifiState, int uid) {
 // Broadcast
        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}

当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。WifiLayer 创建的时候就会向Android 注册接收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描。

WifiSetting.java:

protected void onCreate(Bundle savedInstanceState) {
    mWifiLayer.onCreate();
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

WifiLayer.java:
public void onCreate() {
        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
       
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);        
    }
public void onResume() {
        mContext.registerReceiver(mReceiver, mIntentFilter);       
        if (isWifiEnabled()) {
            // Kick start the continual scan
            queueContinuousScan();
        }
    }

以上就是WifiLayer.java注册接收的部分事件。接收部分事件处理有:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                handleNetworkStateChanged(
                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
                        intent.getStringExtra(WifiManager.EXTRA_BSSID));
            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                handleScanResultsAvailable();
            } ……

           else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                        WifiManager.WIFI_STATE_UNKNOWN));
            }           
        }
    };

从可接受的事件看,当WIFI_STATE_CHANGED_ACTION时,对应的处理函数有:

handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                        WifiManager.WIFI_STATE_UNKNOWN));

private void handleWifiStateChanged(int wifiState) {
   attemptScan();
   …………
 }

public void attemptScan() {
  if (!mWifiManager.startScanActive()) {
            postAttemptScan();
        }
}

WifiManager.java:
public boolean startScanActive() {
 return mService.startScan(true);
}

-------AIDL-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

WifiService.java:
public boolean startScan(boolean forceActive) {
 …………
 return WifiNative.scanCommand(forceActive);
}

---------JNI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

android_net_wifi_wifi.cpp:
{ "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz, jboolean forceActive)
{
 …………
 result = doBooleanCommand("SCAN", "OK");
}
static jboolean doBooleanCommand(const char *cmd, const char *expect)
{
 if (doCommand(cmd, reply, sizeof(reply)) != 0) {
        return (jboolean)JNI_FALSE;
    }
}
static int doCommand(const char *cmd, char *replybuf, int replybuflen)
{
 if (::wifi_command(cmd, replybuf, &reply_len) != 0)
        return -1;
 …………
}

-------HAL------------------------------------------------------------------------------------------------------------------------------------------------------------------------

wifi.c:
int wifi_command(const char *command, char *reply, size_t *reply_len)
{
    return wifi_send_command(ctrl_conn, command, reply, reply_len);
}
int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len)
{
 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);
 …………
}
wpa_ctrl.c:
int wpa_ctrl_request()在wpa_ctrl.c中其实就是执行SCAN命令。

二、显示扫描的AP

当扫描成后,WifiMonitor 中的MonitorThread 会被执行来出来这个事件:

  void handleEvent(int event, String remainder) {
            switch (event) {   
                case SCAN_RESULTS:
                    mWifiStateTracker.notifyScanResultsAvailable();
->sendEmptyMessage(EVENT_SCAN_RESULTS_AVAILABLE);
    break;
}

 WifiStateTracker.java
public void handleMessage(Message msg) {              
  switch (msg.what) {
               case EVENT_SCAN_RESULTS_AVAILABLE:
                        if (ActivityManagerNative.isSystemReady()) {
                                mContext.sendBroadcast(new   Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));       
                     }
}

WifiLayer注册接收SCAN_RESULTS_AVAILABLE_ACTION这个Intent:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
 else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
       {             

             handleScanResultsAvailable();     

     }
 handleScanResultsAvailable();
       -> list = mWifiManager.getScanResults();
        -> mCallback.onAccessPointSetChanged(ap, true);

handleScanResultsAvailable()中首先会去拿到SCAN的结果(最终是往wpa_supplicant中发送SCAN_RESULT命令并读取返回值来实现的),对每一个扫描返回的AP,WifiLayer会回调WifiSetting的onAccessPointSetChanged函数,从而最终把该AP加到GUI显示列表中。

三、配置AP

当用户在 WifiSettings 界面上选择了一个AP 后,会显示配置AP 参数的一个对话框:

public boolean onPreferenceTreeClick()
          ->showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
                    ->AccessPointDialog dialog   =
                                            new AccessPointDialog(this,    mWifiLayer);
                                     showDialog(dialog);

当用户在AccessPointDialog中选择好加密方式和输入密钥之后,再点击连接按钮,Android就会去连接这个AP。

四、连接AP

在AccessPointDialog.java中点击连接后会执行:

public void onClick(DialogInterface dialog, int which) {
           handleConnect();
   -> mWifiLayer.connectToNetwork(mState);
    ->  // Need WifiConfiguration for the AP
                               WifiConfiguration config = findConfiguredNetwork(state);
                                config = addConfiguration(state, 0);
                                managerEnableNetwork(state, false)
          ->mWifiManager.enableNetwork()
                                         ->mService.enalbeNetwork()
                     ->WifiNative.enableNetworkCommand() 

接下去就JNI { "enableNetworkCommand", "(IZ)Z", (void*)android_net_wifi_enableNetworkCommand},最终就是向wpa_supplicant发送连接命令
五、获取IP地址

当wpa_supplicant成功连接上AP之后,它会向控制通道发送事件通知连接上AP了,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件:

void handleEvent(int event, String remainder) {
       switch (event) {   
              case CONNECTED:
                  handleNetworkStateChange();
                  -> mWifiStateTracker.notifyStateChange(newState, BSSID, networkId);
  ->msg.sendToTarget();
                  break;
}

WifiStateTracker.java
public void handleMessage(Message msg) {         
  switch (msg.what) {              
            case EVENT_NETWORK_STATE_CHANGED:
                       sendNetworkStateChangeBroadcast(mWifiInfo.getBSSID());      
                     }
}
WifiStateTracker中注册的对Wifi相关数据库的观察者if(changed)   则启动:
 private void configureInterface()
   ->  mDhcpTarget.sendEmptyMessage();
 private class DhcpHandler extends Handler
          handleMessage()
              ->switch (msg.what) {
                      case EVENT_DHCP_START:
                              Target.sendEmptyMessage(event);

DhcpHandler会发送EVENT_DHCP_START消息启动DHCP去获取IP地址,当DHCP拿到IP地址之后,会发送EVENT_INTERFACE_CONFIGURATION_SUCCEEDED的消息,然后WifiStateTacker中的handleMessage会处理这样的消息 

case EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:
     sendNetworkStateChangeBroadcast(mWifiInfo.getBSSID());
            ->  Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
            -> mContext.sendStickyBroadcast(intent);

这次带上完整的IP地址信息。WifiLayer中注册了此Intent的接受者,会调用handleNetworkStateChanged进行处理。最后就可以自由的上网了



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值