android wifi flow

 

复习并记录下android wifi相关知识,因为下载的是androidp 的source code,因此codebase就用androidP的版本,复习整个android wifi的flow,我大概会分为以下几个部分来讲解

1 android wifi enable flow

2 androi wifi scanning flow

3 android wifi user connect flow

4 android wifi auto connect flow

5 android network type swtich flow

.....

暂时想写的有上面这些,后续想到了再补充

今天这篇来写一下android wifi enable flow

android 发展到现在,wifi flow 从android N开始实际上已经开始了有了很多的变化,可以说整个架构都已经和原来的不一样了。上层与wpa_supplicant 之间 IPC也在将unix socket (android domain socket) 替换成hidl 方式。更有scan get_scan_result这些都是直接建立netlink socket 与kernel 通信而不通过wpa_supplicant。

首先先看下Wifiservice的注册,以及开机自动检测wifi的开启或关闭流程如下:

一般获取WifiManager有两种方式,

1 mWifiManager = mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());

2 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE )

第一种比较好理解,就是new一个WifiManager的实例,而第二种实际上也是new 一个WifiManager的实例,只不过是

这个new 实例的过程是在framework层做的,而不是在app层做的.以下讲解下这个流程,先上图,再解析source code

SystemServiceRegistry

        registerService(Context.WIFI_SERVICE, WifiManager.class,
                new CachedServiceFetcher<WifiManager>() {
            @Override
            public WifiManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_SERVICE);
                IWifiManager service = IWifiManager.Stub.asInterface(b);
                return new WifiManager(ctx.getOuterContext(), service,
                        ConnectivityThread.getInstanceLooper());
            }});

而registerService,实际上就是把该类与名称对应存入map中 

    /**
     * Statically registers a system service with the context.
     * This method must be called during static initialization only.
     */
    private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }

 使用如下接口获取WifiManger实例mContext.getSystemService(Context.WIFI_SERVICE )则是从map表中查找

Context.java 

public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);

==>

ContextWrapper.java

    @Override
    public Object getSystemService(String name) {
        return mBase.getSystemService(name);
    }

==>

ConttextImpl.java

1738     @Override
1739     public Object getSystemService(String name) {
1740         return SystemServiceRegistry.getSystemService(this, name);
1741     }

==>SystemServiceRegistry

    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }

则是用service name在之前注册的map里查找类WifiManger


UI上面打开wifi的flow 如下 

app层会调用到WifiManager的接口

    public boolean setWifiEnabled(boolean enabled) {
        try {
            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

通过binder 继而call到 WifiServiceImpl.java

    public synchronized boolean setWifiEnabled(String packageName, boolean enable)
            throws RemoteException {
        if (enforceChangePermission(packageName) != MODE_ALLOWED) {
            return false;
        }
        //打印出uid和apk名称,便于debug
        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
                    + ", uid=" + 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 Airplane mode is enabled, only Settings is allowed to toggle Wifi
        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;
        }

//权限检测,详细可参照另一篇文章
//https://blog.csdn.net/lpboss/article/details/86610726

        /*
        * Caller might not have WRITE_SECURE_SETTINGS,
        * only CHANGE_WIFI_STATE is enforced
        */
        long ident = Binder.clearCallingIdentity();
        try {
            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_STAT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值