Android 9 WIFI 打开流程

时间:2025-01-25 14:14:00

Wifi 打开 流程

App端 打开wifi操作

private WifiManager mWifiManager; 
mWifiManager = (WifiManager) mContext.getSystemService(WifiManager.class);\\获取WIFI的服务
mWifiManager.setWifiEnabled(true) 

让我们看一下WifiManager设置的时候是如何操作

	/**
      * 创建一个新的 WifiManager 实例。
      * 应用程序几乎总是想要使用
      * {@link #getSystemService ()} 检索
      * 标准{@link #WIFI_SERVICE Context.WIFI_SERVICE}。
      * @param context 应用程序上下文
      * @param 服务Binder接口
      * @hide - 隐藏它,因为它接受一个 IWifiManager 类型的参数,这是一个系统私有类。
      */
public WifiManager(Context context, IWifiManager service, Looper looper) {
        mContext = context;
        mService = service; //拿到IWifiManager的接口
        mLooper = looper;
        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
}

/**
 *启用或禁用Wi-Fi。
 * 应用程序必须具有 {@link #CHANGE_WIFI_STATE}
 *切换wifi的权限。
 * @param enabled {@code true} 启用,{@code false} 禁用。
 * @return {@code false} 如果请求不能被满足; {@code true} 表示 wifi 已经处于请求状态,或者正在向请求状态前进。
 * @throws {@link } 如果调用者缺少所需的权限。
 */ 
public boolean setWifiEnabled(boolean enabled) {
  try {
       return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);//通过IWifiManager与服务进行通讯
      } catch (RemoteException e) {
          throw e.rethrowFromSystemServer();
      }
  }

WifiManager通过Binder机制与WifiServiceImpl进行通讯

WifiServerImpl
(路径:frameworks\opt\net\wifi\service\java\com\android\server\wifi\)

public class WifiServiceImpl extends IWifiManager.Stub {
 	 /**
      * 见 {@link #setWifiEnabled(boolean)}
      * @param enable {@code true} 启用,{@code false} 禁用。
      * @return {@code true} 如果启用/禁用操作已启动或已在队列中。
      */
    @Override
    public synchronized boolean setWifiEnabled(String packageName, boolean enable)
            throws RemoteException {
            //判断调用的app是否具有权限
        if (enforceChangePermission(packageName) != MODE_ALLOWED) {
            return false;
        }

        Slog.d(TAG, "setWifiEnabled: " + enable + " ptoken operator">+ Binder.getCallingPid()
                    + ", utoken operator">+ Binder.getCallingUid() + ", package=" + packageName);
        mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
                .c(Binder.getCallingUid()).c(enable).flush();

        boolean isFromSettings = checkNetworkSettingsPermission(
                Binder.getCallingPid(), Binder.getCallingUid());
		
        // 判断是否为飞行模式
        if (mSettingsStore.isAirplaneModeOn() && !isFromSettings) {
            mLog.info("setWifiEnabled in Airplane mode: only Settings can enable wifi").flush();
            return false;
        }

        // If SoftAp is enabled, only Settings is allowed to toggle wifi
        boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;

        if (apEnabled && !isFromSettings) {
            mLog.info("setWifiEnabled SoftAp not disabled: only Settings can enable wifi").flush();
            return false;
        }

       /*
         * 调用者可能没有 WRITE_SECURE_SETTINGS,
         * 只有 CHANGE_WIFI_STATE 被强制执行
         */
        long ident = Binder.clearCallingIdentity();
        try {
        	//保存wifi状态
            if (! mSettingsStore.handleWifiToggled(enable)) {
                // Nothing to do if wifi cannot be toggled
                return true;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }


        if (mPermissionReviewRequired) {
            final int wiFiEnabledState = getWifiEnabledState();
            if (enable) {
                if (wiFiEnabledState == WifiManager.WIFI_STATE_DISABLING
                        || wiFiEnabledState == WifiManager.WIFI_STATE_DISABLED) {
                    if (startConsentUi(packageName, Binder.getCallingUid(),
                            WifiManager.ACTION_REQUEST_ENABLE)) {
                        return true;
                    }
                }
            } else if (wiFiEnabledState == WifiManager.WIFI_STATE_ENABLING
                    || wiFiEnabledState == WifiManager.WIFI_STATE_ENABLED) {
                if (startConsentUi(packageName, Binder.getCallingUid(),
                        WifiManager.ACTION_REQUEST_DISABLE)) {
                    return true;
                }
            }
        }
		//主要执行是这一句
        mWifiController.sendMessage(CMD_WIFI_TOGGLED); 
        return true;
    }
}

WififController 管理wifi开关,热点开关等状态

public class WifiController extends StateMachine {
...
	class StaDisabledState extends State {
		...
		@Override
        public boolean processMessage(Message msg) {
        	  switch (msg.what) {
                case CMD_WIFI_TOGGLED:
                	if (mSettingsStore.isWifiToggleEnabled()) {
                        ...
                        transitionTo(mDeviceActiveState);//转换到了DeviceActiveState状态;
                    } else if (checkScanOnlyModeAvailable()) {  //检测是否有被禁用位置服务
                       // 只有在我们不处于飞行模式时才进入扫描模式
                        if (mSettingsStore.isAirplaneModeOn()) {
                            transitionTo(mStaDisabledWithScanState);//转换到了DeviceActiveState状态
                        }
                    }
                    break;
                }
        }
        ...
	}
...
}
class DeviceActiveState extends State {
		@Override
        public void enter() {
            ...
            mWifiStateMachinePrime.enterClientMode();//调用方法
            ...
        }
}

(路径:frameworks\opt\net\wifi\service\java\com\android\server\wifi\)

public class WifiStateMachinePrime {
		....
		/**
		 * 将 wifi 切换到客户端模式的方法,将尝试连接到配置的网络。
		 */
	    public void enterClientMode() {
	        changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
	    }

		//
		private void changeMode(int newMode) {
        	mModeStateMachine.sendMessage(newMode);
    	}

		private class ModeStateMachine extends StateMachine {
		...
		//最后会走到checkForAndHandleModeChange
			private boolean checkForAndHandleModeChange(Message message) {
            switch(message.what) {
                case ModeStateMachine.CMD_START_CLIENT_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
                    //切换到ClientModeActiveState状态。
                    mModeStateMachine.transitionTo(mClientModeActiveState);
                    break;
                    ...
            }
            return HANDLED;
        	}
		}
}

转到ClientModeActiviteState状态

class ClientModeActiveState extends ModeActiveState {
		...
			@Override
            public void enter() {
				mManager = mWifiInjector.makeClientModeManager(mListener);
                mManager.start();//跳转到ClientModeManager的start方法
			}
	   ...
}

(路径:frameworks\opt\net\wifi\service\java\com\android\server\wifi\)

public class ClientModeManager implements ActiveModeManager {
	....
	/**
     * Start client mode.
     */
    public void start() {
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);//会跳转到IdleState(初始化时候默认是IdleState)
    }
	...
	private class IdleState extends State {
		@Override
        public boolean processMessage(Message message) {
			switch (message.what) {
                    case CMD_START:
                    	/**
					     * Update Wifi state and send the broadcast.
					     * @param newState new Wifi state
					     * @param currentState current wifi state
					     */
                    	updateWifiState(WifiManager.WIFI_STATE_ENABLING,
                                        WifiManager.WIFI_STATE_DISABLED);

                        if (WifiInjector.getInstance().getAtcAospEnhancement()) {
                            mEnableTime = Calendar.getInstance().getTimeInMillis();
                            Log.d(TAG, "We will check Wi-Fi Enable time");
                        }
						//setupInterfaceForClientMode方法startHal
                        mClientInterfaceName = mWifiNative.setupInterfaceForClientMode(
                                false /* not low priority */, mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
                            Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
                            updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
                                            WifiManager.WIFI_STATE_ENABLING);
                            updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                                            WifiManager.WIFI_STATE_UNKNOWN);
                            break;
                        }
                        sendScanAvailableBroadcast(false);
                        mScanRequestProxy.enableScanningForHiddenNetworks(false);
                        mScanRequestProxy.clearScanResults();
                        transitionTo(mStartedState);
                        break;
                   ...     
            }
		}
	}
}

总结:App端都是通过wifimanager暴露的接口通过binder机制与WifiServer进行通信。
//setupInterfaceForClientMode方法startHal,下面就是开始到hal层(后面会继续更新),可能会根据硬件芯片厂商做一些定制化的操作