App调用接口

public static final int TETHERING_WIFI      = 0;
mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));

ConnectivityManager.java 客户端提供接口

try {String pkgName = mContext.getOpPackageName();Log.i(TAG, "startTethering caller:" + pkgName);mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);} catch (RemoteException e) {Log.e(TAG, "Exception trying to start tethering.", e);wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);}

ConnectivityService.java 服务端执行

@Overridepublic void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,String callerPkg) {ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);if (!isTetheringSupported()) {receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);return;}mTethering.startTethering(type, receiver, showProvisioningUi);}

Tethering.java

public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi);enableTetheringInternal(type, true /* enabled */, receiver);
}
private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {int result;switch (type) {case TETHERING_WIFI:result = setWifiTethering(enable);sendTetherResult(receiver, result);break;case TETHERING_USB:result = setUsbTethering(enable);sendTetherResult(receiver, result);break;case TETHERING_BLUETOOTH:setBluetoothTethering(enable, receiver);break;default:Log.w(TAG, "Invalid tether type.");sendTetherResult(receiver, TETHER_ERROR_UNKNOWN_IFACE);}}
private int setWifiTethering(final boolean enable) {final long ident = Binder.clearCallingIdentity();try {synchronized (mPublicSync) {final WifiManager mgr = getWifiManager();if (mgr == null) {mLog.e("setWifiTethering: failed to get WifiManager!");return TETHER_ERROR_SERVICE_UNAVAIL;}if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||(!enable && mgr.stopSoftAp())) {mWifiTetherRequested = enable;return TETHER_ERROR_NO_ERROR;}}} finally {Binder.restoreCallingIdentity(ident);}return TETHER_ERROR_MASTER_ERROR;}private void sendTetherResult(ResultReceiver receiver, int result) {if (receiver != null) {receiver.send(result, null);}}

这里ResultReceiver 根据setWifiTethering的结果发送了一个 广播出去,暂时掐断不管,只看mgr.startSoftAp();

WifiManager.java

    public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {try {return mService.startSoftAp(wifiConfig);//Tethering.java传递的参数到这里是null} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

然后 BaseWifiService extends IWifiManager.Stub

WifiServiceImpl extends BaseWifiService,看WifiServiceImpl.java

    @Overridepublic boolean startSoftAp(WifiConfiguration wifiConfig) {mLog.info("startSoftAp Band:"+wifiConfig);// NETWORK_STACK is a signature only permission.enforceNetworkStackPermission();mLog.info("startSoftAp uid=%").c(Binder.getCallingUid()).flush();synchronized (mLocalOnlyHotspotRequests) {// If a tethering request comes in while we have an existing tethering session, return// error.if (mIfaceIpModes.contains(WifiManager.IFACE_IP_MODE_TETHERED)) {mLog.err("Tethering is already active.").flush();return false;}// If a tethering request comes in while we have LOHS running (or requested), call stop// for softap mode and restart softap with the tethering config.if (!isConcurrentLohsAndTetheringSupported() && !mLocalOnlyHotspotRequests.isEmpty()) {stopSoftApInternal(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);}return startSoftApInternal(wifiConfig, WifiManager.IFACE_IP_MODE_TETHERED);}}private boolean startSoftApInternal(WifiConfiguration wifiConfig, int mode) {mLog.trace("startSoftApInternal uid=% mode=%").c(Binder.getCallingUid()).c(mode).flush();// null wifiConfig is a meaningful input for CMD_SET_APif (wifiConfig == null || WifiApConfigStore.validateApWifiConfiguration(wifiConfig)) {SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);//看这里Slog.d(TAG,"softApConfig Band"+wifiConfig);return true;}Slog.e(TAG, "Invalid WifiConfiguration");return false;}

先看一下这个 Android学习 StateMachine与State模式,再看WifiController.java,WifiController extends StateMachine,看StateMachine.java的sendMessage();

    @UnsupportedAppUsagepublic void sendMessage(int what, int arg1, int arg2, Object obj) {// mSmHandler can be null if the state machine has quit.SmHandler smh = mSmHandler;if (smh == null) return;smh.sendMessage(obtainMessage(what, arg1, arg2, obj));}

WifiController.java中,

class DefaultState extends State,

class DefaultState extends State,

class StaEnabledState extends State,

class StaDisabledWithScanState extends State,

都实现了processMessage()方法,所以看这里有对CMD_SET_AP的处理

         case CMD_SET_AP:// note: CMD_SET_AP is handled/dropped in ECM mode - will not start hereLog.d(TAG,"CMD_SET_AP enterSoftAPMode stopSoftAPMode msg.arg1:"+msg.arg1);if (msg.arg1 == 1) {SoftApModeConfiguration config = (SoftApModeConfiguration) msg.obj;mActiveModeWarden.enterSoftAPMode((SoftApModeConfiguration) msg.obj);} else {mActiveModeWarden.stopSoftAPMode(msg.arg2);}break;case CMD_SET_AP:Log.d(TAG,"CMD_SET_AP WIFI_DISABLED msg.arg1:"+msg.arg1);if (msg.arg1 == 1) {// remember that we were disabled, but pass the command up to start softapmSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);}return NOT_HANDLED;case CMD_SET_AP:Log.d(TAG,"CMD_SET_AP setWifiSavedState msg.arg1:"+msg.arg1);if (msg.arg1 == 1) {// remember that we were disabled, but pass the command up to start softapmSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);//这里关闭了wifi,待确认}return NOT_HANDLED;case CMD_SET_AP:Log.d(TAG,"CMD_SET_AP HANDLED");// do not want to start softap if we are in emergency modereturn HANDLED;

然后看mActiveModeWarden.enterSoftAPMode((SoftApModeConfiguration) msg.obj);

./opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java

    public void enterSoftAPMode(@NonNull SoftApModeConfiguration wifiConfig) {mHandler.post(() -> {startSoftAp(wifiConfig);});}private void startSoftAp(SoftApModeConfiguration softapConfig) {Log.d(TAG, "Starting SoftApModeManager");WifiConfiguration config = softapConfig.getWifiConfiguration();//Log.d(TAG,"startSoftAp Band:"+config.apBand);if (config != null && config.SSID != null) {Log.d(TAG, "Passing config to SoftApManager! " + config);} else {config = null;}SoftApCallbackImpl callback = new SoftApCallbackImpl(softapConfig.getTargetMode());ActiveModeManager manager = mWifiInjector.makeSoftApManager(callback, softapConfig);callback.setActiveModeManager(manager);manager.start();mActiveModeManagers.add(manager);updateBatteryStatsWifiState(true);}

然后,重点来了!public class SoftApManager implements ActiveModeManager.java

    public void start() {mStateMachine.sendMessage(SoftApStateMachine.CMD_START, mApConfig);Log.d(TAG,"start() BAND:"+mApConfig.apBand);}

然后private class IdleState extends State

待续

android Q softAp流程相关推荐

  1. Android WiFi —softAP流程分析

    Android WiFi - Ap功能实现与源码分析 0. 前言 wifiAp的ip WifiAp的config分析 2.1 默认的config 2.2 修改wifiAp的config配置流程 开启/ ...

  2. Android Q 适配指南

    在Android 10开始版本中,官方的改动较大,相应的开发者适配成本还是很高的. 这里按照2019.11.11 google android q workshop流程,大概说明一下Android Q ...

  3. Android Q 开机启动流程

    https://www.it610.com/article/1304931662924124160.htm Android Q 开机启动流程 开机启动概述: step 1: 上电开机 长按power键 ...

  4. android 解锁流程,Android Q 指纹解锁流程

    Android Q 指纹解锁流程 // Authentation Finger Schedule: (close Screen, Authentation with finger(Success)) ...

  5. 让最新的 Android Q Beta 3 强制重启的 Project Mainline,到底是什么?

    一. 序 最新的 Android 版本 Q,已经发布了 Android Q Beta 3,虽然没有正式发布,但是不少用户已经加入了测试计划,抢先体验 Android Q 的新功能. 近期不少体验用户反 ...

  6. 探索 Android Q:位置权限

    原文链接 Exploring Android Q: Location Permissions. 目录 前台位置权限 后台位置权限 本文最初发表于  https://joebirch.co/ 上周(本文 ...

  7. 适配Android Q指南

    一 .行为变更:所有应用 Android Q 平台包含一些行为变更,这些变更可能会影响您的应用.以下行为变更将影响在 Android Q 上运行的所有应用,无论其采用哪种 targetSdkVersi ...

  8. Android Q Beta 正式发布 | 精于形,安于内

    移动行业在 2019 年创新不断,随着 5G 时代的到来与折叠屏技术的成熟,智能设备正在迈向未来新时代,而 Android 更是处在颠覆创新的风口浪尖.通过与生态圈伙伴们的深度合作,我们从软件到硬件不 ...

  9. 基于Android Q电池服务分析

    基于Android Q的电池服务分析之充电类型判断 开局先说明一下我的需求和我遇到的难题 问题 插入充电没有提示音和图标更新 插入充电没有任何反应和提示,但是确实是在充电 需求 在设置的电池中增加充电 ...

最新文章

  1. open(/dev/ietctl, O_RDWR) 参数含义
  2. 开发者应具备的产品设计意识
  3. 互斥信号量的删除与状态查询
  4. Netty之实现一个简单的群聊系统
  5. 无影云电脑居家办公最佳实践(AD域账号)
  6. JSP常用Form表单控件
  7. leetcode力扣64. 最小路径和
  8. 项目启动报 myql字符集报错的问题
  9. 在SQL 2014 Server上安装Northwind和Pubs示例数据库
  10. 微信小游戏开发实战教程13-随机生成形状功能的实现
  11. 单机Eureka构建步骤
  12. 解决webpack打包css时CssSyntaxError的问题
  13. python海龟作图画爱心_用python的turtle,画爱心,表白,求婚完整代码,海龟作图创意...
  14. 导航上显示某个地点已关闭什么意思_想要玩好iPhone手机,6个关闭、4个开启,要牢记!...
  15. 【全】在 Docker 的Solr容器中安装 IK 中文分词器
  16. 基于JAVA校园快递联盟系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  17. Wireshark抓包定位系统网页响应慢 | 网络工程师甩锅技术
  18. signature=501807407682dd47ffe7345fc7b18d2e,Signature-Free Intrusion Detection
  19. java设计模式之——单例模式(八种实现)
  20. 类Unix系统目录结构

热门文章

  1. 配置表测试框架搭建-②数据读取篇
  2. packer插件_如何使用Packer和Terraform轻松部署应用程序
  3. Scala特证/特质【6.7 特质(Trait)】
  4. 英文名字大全(男篇)(ZT)
  5. 计算机网络服务三要素,计算机网络协议三要素
  6. Python_7分钟笔记_基础四(函数、递归)
  7. Unity--简单Buff系统
  8. 扭曲文字动态效果怎么制作?教程来了
  9. 虚拟机VM安装linux以及网卡配置
  10. Dx11---纹理与光照(火焰动画,纹理的旋转,贴不同的纹理)