这个图片是说明的是WifiService和wpa_supplicant的启动流程,我自己跟了一下代码,做了些记录。
public class SystemServer {
private static final String TAG = "SystemServer";
public static final int FACTORY_TEST_OFF = 0;
public static final int FACTORY_TEST_LOW_LEVEL = 1;
public static final int FACTORY_TEST_HIGH_LEVEL = 2;
static Timer timer;
static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
// The earliest supported time. We pick one day into 1970, to
// give any timezone code room without going into negative time.
private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
public static void main(String[] args) {
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it
// shortly.
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
System.loadLibrary("android_servers");
init1(args);
}
public static final void init2() { //look init2 Android Service
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread(); //look 创建一个新的ServerThread线程
thr.setName("android.server.ServerThread");
thr.start(); //look 启动这个ServerThread
}
}
hardware/libhardware_legacy/wifi/SystemServer.java
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
看这个注释,说明需要Zygote来初始化系统的时候会调用native services(包括SurfaceFlinger,AudioFlinger等),启动之后
会回调init2()来启动Android services
frameworks/base/serives/java/com/android/server/WifiService.java
public class WifiService extends IWifiManager.Stub {
private static final String TAG = "WifiService";
private static final boolean DBG = true;
private final WifiStateMachine mWifiStateMachine;//look 注意这个!
private Context mContext;
private AlarmManager mAlarmManager;
private PendingIntent mIdleIntent;
private static final int IDLE_REQUEST = 0;
private boolean mScreenOff;
private boolean mDeviceIdle;
private boolean mEmergencyCallbackMode = false;
private int mPluggedType;
/* Chipset supports background scan */
private final boolean mBackgroundScanSupported;
private final LockList mLocks = new LockList();
// some wifi lock statistics
private int mFullHighPerfLocksAcquired;
private int mFullHighPerfLocksReleased;
private int mFullLocksAcquired;
private int mFullLocksReleased;
private int mScanLocksAcquired;
private int mScanLocksReleased;
private final List<Multicaster> mMulticasters =
new ArrayList<Multicaster>();
private int mMulticastEnabled;
private int mMulticastDisabled;
private final IBatteryStats mBatteryStats;
//..
//..
//..太多了
}
private final WifiStateMachine mWifiStateMachine;
public synchronized boolean setWifiEnabled(boolean enable) {
enforceChangePermission();
if (DBG) {
Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
}
if (enable) {
reportStartWorkSource();
}
mWifiStateMachine.setWifiEnabled(enable); //look 这个是调用上面类里面那个mWifiStateMachine这个成员的一个函数去使能wifi
//我们去找这个实现
/*
* Caller might not have WRITE_SECURE_SETTINGS,
* only CHANGE_WIFI_STATE is enforced
*/
/* Avoids overriding of airplane state when wifi is already in the expected state */
if (enable != mWifiEnabled) {
long ident = Binder.clearCallingIdentity();
persistWifiState(enable);
Binder.restoreCallingIdentity(ident);
}
if (enable) {
if (!mIsReceiverRegistered) {
registerForBroadcasts();
mIsReceiverRegistered = true;
}
} else if (mIsReceiverRegistered) {
mContext.unregisterReceiver(mReceiver);
mIsReceiverRegistered = false;
}
return true;
}
frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
public void setWifiEnabled(boolean enable) {
mLastEnableUid.set(Binder.getCallingUid());
if (enable) {
/* Argument is the state that is entered prior to load */
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));//look
sendMessage(CMD_START_SUPPLICANT); //look 我们分成两路 1driver 2wap_supplicant
} else {
sendMessage(CMD_STOP_SUPPLICANT);
/* Argument is the state that is entered upon success */
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
}
}
第一步 load driver
------------------------------------------------------------------------------------
class DriverLoadingState extends State { //注意这里DriverLoadingState 是Loading!!!后面还有Loaded
@Override
public void enter() {
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
final Message message = new Message();
message.copyFrom(getCurrentMessage());
/* TODO: add a timeout to fail when driver load is hung.
* Similarly for driver unload.
*/
new Thread(new Runnable() {
public void run() {
mWakeLock.acquire();
//enabling state
switch(message.arg1) {
case WIFI_STATE_ENABLING:
setWifiState(WIFI_STATE_ENABLING);
break;
case WIFI_AP_STATE_ENABLING:
setWifiApState(WIFI_AP_STATE_ENABLING);
break;
}
if(WifiNative.loadDriver()) { //look 去调用WifiNative的loaderDriver去加载驱动
if (DBG) log("Driver load successful");
sendMessage(CMD_LOAD_DRIVER_SUCCESS);
} else {
loge("Failed to load driver!");
switch(message.arg1) {
case WIFI_STATE_ENABLING:
setWifiState(WIFI_STATE_UNKNOWN);
break;
case WIFI_AP_STATE_ENABLING:
setWifiApState(WIFI_AP_STATE_FAILED);
break;
}
sendMessage(CMD_LOAD_DRIVER_FAILURE);
}
mWakeLock.release();
}
}).start();
}
@Override
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER_SUCCESS:
transitionTo(mDriverLoadedState);
break;
case CMD_LOAD_DRIVER_FAILURE:
transitionTo(mDriverFailedState);
break;
case CMD_LOAD_DRIVER:
case CMD_UNLOAD_DRIVER:
case CMD_START_SUPPLICANT:
case CMD_STOP_SUPPLICANT:
case CMD_START_AP:
case CMD_STOP_AP:
case CMD_START_DRIVER:
case CMD_STOP_DRIVER:
case CMD_SET_SCAN_MODE:
case CMD_SET_SCAN_TYPE:
case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_COUNTRY_CODE:
case CMD_SET_FREQUENCY_BAND:
case CMD_START_PACKET_FILTERING:
case CMD_STOP_PACKET_FILTERING:
deferMessage(message);
break;
default:
return NOT_HANDLED;
}
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
return HANDLED;
}
}
WifiNative.loadDriver在
frameworks/base/wifi/java/android/net/wifi/WifiNative.java
public class WifiNative {
static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
public native static String getErrorString(int errorCode);
public native static boolean loadDriver(); //look 这个成员函数!就是我们需要的
//..
//..
//..
}
它的实现应该是在
frameworks/base/core/jni/android_net_wifi_wifi.cpp
static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
{
return (jboolean)(::wifi_load_driver() == 0); //look wifi_loader_driver是我们需要的
}
wifi_loader_driver()在hardware/libhardware_legacy/wifi/wifi.c
int wifi_load_driver()
{
LOGI("[semco] wifi_load_driver.");
#ifdef WIFI_DRIVER_MODULE_PATH
char driver_status[PROPERTY_VALUE_MAX];
int count = 100; /* wait at most 20 seconds for completion */
if (is_wifi_driver_loaded()) {
return 0;
}
if (insmod(WIFI_SDIO_DRIVER_MODULE_PATH, WIFI_SDIO_DRIVER_MODULE_ARG) < 0) //look 看看这insmod多熟悉 先安装SDIO驱动
{ //WIFI_SDIO_DRIVER_MODULE_PATH
LOGE("[semco] cfg80211 module loading fail."); //WIFI_SDIO_DRIVER_MODULE_ARG
return -1;
}
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) //look 还有这个 再安装wifi驱动
return -1; //DRIVER_MODULE_PATH 这几个宏我们都在BoardConfig.mk中定义了
if (strcmp(FIRMWARE_LOADER,"") == 0) {
usleep(WIFI_DRIVER_LOADER_DELAY);
property_set(DRIVER_PROP_NAME, "ok");
}
else {
property_set("ctl.start", FIRMWARE_LOADER);
}
sched_yield();
while (count-- > 0) {
if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
if (strcmp(driver_status, "ok") == 0)
return 0;
else if (strcmp(driver_status, "failed") == 0) {
wifi_unload_driver();
return -1;
}
}
usleep(200000);
}
property_set(DRIVER_PROP_NAME, "timeout");
wifi_unload_driver();
return -1;
#else
property_set(DRIVER_PROP_NAME, "ok");
return 0;
#endif
}
load driver end
--------------------------------------------------------------------------------------------
第二步 start supplicant
--------------------------------------------------------------------------------------------
CMD_START_SUPPLICANT之后我们来到了这里
frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
class DriverLoadedState extends State { //look 这里注意,这里是DriverLoadedState loaded!!!说明driver已经insmod了
@Override
public void enter() {
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case CMD_UNLOAD_DRIVER:
transitionTo(mDriverUnloadingState);
break;
case CMD_START_SUPPLICANT:
//from semco
//try {
// mNwService.wifiFirmwareReload(mInterfaceName, "STA");
//} catch (Exception e) {
// loge("Failed to reload STA firmware " + e);
// continue
//}
try {
//A runtime crash can leave the interface up and
//this affects connectivity when supplicant starts up.
//Ensure interface is down before a supplicant start.
mNwService.setInterfaceDown(mInterfaceName);
//Set privacy extensions
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
} catch (RemoteException re) {
loge("Unable to change interface settings: " + re);
} catch (IllegalStateException ie) {
loge("Unable to change interface settings: " + ie);
}
if(WifiNative.startSupplicant()) { //look 调用WifiNative.startSupplicant()
if (DBG) log("Supplicant start successful");
mWifiMonitor.startMonitoring();
transitionTo(mSupplicantStartingState);
} else {
loge("Failed to start supplicant!");
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
}
break;
case CMD_START_AP:
transitionTo(mSoftApStartingState);
break;
default:
return NOT_HANDLED;
}
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
return HANDLED;
}
}
WifiNative.startSupplicant()在哪?
frameworks/base/core/jni/android_net_wifi_wifi.cpp
static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject)
{
return (jboolean)(::wifi_start_supplicant() == 0);
}
它调用wifi.c中的wifi_start_supplicant(),
wifi_loader_driver()在hardware/libhardware_legacy/wifi/wifi.c
int wifi_start_supplicant()
{
LOGI("[semco] wifi_start_supplicant!");
return wifi_start_supplicant_common(SUPP_CONFIG_FILE);
}
int wifi_start_supplicant_common(const char *config_file)
{
char daemon_cmd[PROPERTY_VALUE_MAX];
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
const prop_info *pi;
unsigned serial = 0;
#endif
/* Check whether already running */
if (property_get(SUPP_PROP_NAME, supp_status, NULL)
&& strcmp(supp_status, "running") == 0) {
return 0;
}
/* Before starting the daemon, make sure its config file exists */
if (ensure_config_file_exists(config_file) < 0) {
LOGE("Wi-Fi will not be enabled");
return -1;
}
if (ensure_entropy_file_exists() < 0) {
LOGE("Wi-Fi entropy file was not created");
}
/* Clear out any stale socket files that might be left over. */
wifi_wpa_ctrl_cleanup();
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
/*
* Get a reference to the status property, so we can distinguish
* the case where it goes stopped => running => stopped (i.e.,
* it start up, but fails right away) from the case in which
* it starts in the stopped state and never manages to start
* running at all.
*/
pi = __system_property_find(SUPP_PROP_NAME);
if (pi != NULL) {
serial = pi->serial;
}
#endif
//from semco
// property_get("wifi.interface", iface, WIFI_TEST_INTERFACE);
// snprintf(daemon_cmd, PROPERTY_VALUE_MAX, "%s:-i%s -c%s", SUPPLICANT_NAME, iface, config_file);
property_set("ctl.start", SUPPLICANT_NAME); //look 在这里是启动了
sched_yield();
while (count-- > 0) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
if (pi == NULL) {
pi = __system_property_find(SUPP_PROP_NAME);
}
if (pi != NULL) {
__system_property_read(pi, NULL, supp_status);
if (strcmp(supp_status, "running") == 0) {
return 0;
} else if (pi->serial != serial &&
strcmp(supp_status, "stopped") == 0) {
return -1;
}
}
#else
if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
if (strcmp(supp_status, "running") == 0)
return 0;
}
#endif
usleep(100000);
}
return -1;
}
--------------------------------------------------------------------------------------------
start supplicant end