这个图片是说明的是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