Android13 WifiP2pService discoverPeers流程

通过代码分析一下WifiP2p discoverPeers流程:

//packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java
public class WifiP2pManager {
    @RequiresPermission(allOf = {
            android.Manifest.permission.NEARBY_WIFI_DEVICES,
            android.Manifest.permission.ACCESS_FINE_LOCATION
            }, conditional = true)
    public void discoverPeersOnSpecificFrequency(
            @NonNull Channel channel, int frequencyMhz, @Nullable ActionListener listener) {
        if (!isChannelConstrainedDiscoverySupported()) {
            throw new UnsupportedOperationException();
        }
        checkChannel(channel);
        if (frequencyMhz <= 0) {
            throw new IllegalArgumentException("This frequency must be a positive value.");
        }
        Bundle extras = prepareExtrasBundle(channel);
        extras.putInt(EXTRA_PARAM_KEY_PEER_DISCOVERY_FREQ, frequencyMhz);
        channel.mAsyncChannel.sendMessage(DISCOVER_PEERS, WIFI_P2P_SCAN_SINGLE_FREQ,
                channel.putListener(listener), extras); //发送DISCOVER_PEERS消息
    }
}

DISCOVER_PEERS消息在ClientHandler的handleMessage方法中处理:

//packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pServiceImpl .java
public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
    private P2pStateMachine mP2pStateMachine;
    private class ClientHandler extends Handler {


        ClientHandler(String tag, android.os.Looper looper) {
            super(looper);
        }


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case WifiP2pManager.SET_DEVICE_NAME:
                case WifiP2pManager.SET_WFD_INFO:
                case WifiP2pManager.DISCOVER_PEERS:
                case WifiP2pManager.STOP_DISCOVERY:
                case WifiP2pManager.CONNECT:
                case WifiP2pManager.CANCEL_CONNECT:
                case WifiP2pManager.CREATE_GROUP:
                case WifiP2pManager.REMOVE_GROUP:
                case WifiP2pManager.START_LISTEN:
                case WifiP2pManager.STOP_LISTEN:
                case WifiP2pManager.SET_CHANNEL:
                case WifiP2pManager.START_WPS:
                case WifiP2pManager.ADD_LOCAL_SERVICE:
                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
                case WifiP2pManager.DISCOVER_SERVICES:
                case WifiP2pManager.ADD_SERVICE_REQUEST:
                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
                case WifiP2pManager.REQUEST_PEERS:
                case WifiP2pManager.REQUEST_CONNECTION_INFO:
                case WifiP2pManager.REQUEST_GROUP_INFO:
                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
                case WifiP2pManager.FACTORY_RESET:
                case WifiP2pManager.SET_ONGOING_PEER_CONFIG:
                case WifiP2pManager.REQUEST_ONGOING_PEER_CONFIG:
                case WifiP2pManager.REQUEST_P2P_STATE:
                case WifiP2pManager.REQUEST_DISCOVERY_STATE:
                case WifiP2pManager.REQUEST_NETWORK_INFO:
                case WifiP2pManager.UPDATE_CHANNEL_INFO:
                case WifiP2pManager.REQUEST_DEVICE_INFO:
                case WifiP2pManager.REMOVE_CLIENT:
                case WifiP2pManager.ADD_EXTERNAL_APPROVER:
                case WifiP2pManager.REMOVE_EXTERNAL_APPROVER:
                case WifiP2pManager.SET_CONNECTION_REQUEST_RESULT:
                case WifiP2pManager.SET_VENDOR_ELEMENTS:
                    mP2pStateMachine.sendMessage(Message.obtain(msg)); //调用P2pStateMachine的sendMessage方法
                    break;
                default:
                    Log.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
                    break;
            }
        }
    }
}

在WifiP2pServiceImpl内部类P2pStateMachine的processMessage中处理消息:

//packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pServiceImpl.java
public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
    private WifiP2pNative mWifiNative;
    private class P2pStateMachine extends StateMachine {
        class P2pEnabledState extends State {
            @Override
            public boolean processMessage(Message message) {
                if (isVerboseLoggingEnabled()) logd(getName() + message.toString());
                switch (message.what) {
                    case WifiP2pManager.DISCOVER_PEERS: {
                        String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
                        if (packageName == null) {
                            replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                                    WifiP2pManager.ERROR);
                            break;
                        }
                        int scanType = message.arg1;
                        int uid = message.sendingUid;
                        Bundle extras = (Bundle) message.obj;
                        int freq = extras.getInt(
                                    WifiP2pManager.EXTRA_PARAM_KEY_PEER_DISCOVERY_FREQ,
                                    WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED);
                        boolean hasPermission = false;
                        if (scanType != WifiP2pManager.WIFI_P2P_SCAN_FULL
                                && !isFeatureSupported(WifiP2pManager.FEATURE_FLEXIBLE_DISCOVERY)) {
                            replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                                    WifiP2pManager.ERROR);
                        }
                        if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
                            hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
                                    packageName,
                                    getCallingFeatureId(message.sendingUid, message.replyTo),
                                    uid, true);
                        } else {
                            hasPermission = checkNearbyDevicesPermission(uid, packageName,
                                    extras, "DISCOVER_PEERS");
                        }


                        if (!hasPermission) {
                            replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                                    WifiP2pManager.ERROR);
                            // remain at this state.
                            break;
                        }
                        if (mDiscoveryBlocked) {
                            replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                                    WifiP2pManager.BUSY);
                            break;
                        }
                        // do not send service discovery request while normal find operation.
  // 在正常查找操作时不发送服务发现请求。
                        clearSupplicantServiceRequest();
                        Log.e(TAG, "-------discover_peers before p2pFind");
                        if (p2pFind(scanType, freq, DISCOVER_TIMEOUT_S)) { // 调用p2pFind方法
                            mWifiP2pMetrics.incrementPeerScans(); 
                            replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
                            sendP2pDiscoveryChangedBroadcast(true);
                        } else {
                            replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                                    WifiP2pManager.ERROR);
                        }
                        break;
                    ...... 
                } 
                return HANDLED;
            }
        }
        ......
        private boolean p2pFind(@WifiP2pManager.WifiP2pScanType int scanType, int freq,
                                int timeout) {
            if (isFeatureSupported(WifiP2pManager.FEATURE_SET_VENDOR_ELEMENTS)) {
                Set<ScanResult.InformationElement> aggregatedVendorElements = new HashSet<>();
                mVendorElements.forEach((k, v) -> aggregatedVendorElements.addAll(v));
                if (!mWifiNative.setVendorElements(aggregatedVendorElements)) {
                    Log.w(TAG, "cannot set vendor elements to the native service.");
                    // Don't block p2p find or it might affect regular P2P functinalities.
                    mWifiNative.removeVendorElements();
                }
            }
            if (scanType == WifiP2pManager.WIFI_P2P_SCAN_FULL) {
                return mWifiNative.p2pFind(timeout); //调用WifiP2pNative的p2pFind方法
            } else if (scanType == WifiP2pManager.WIFI_P2P_SCAN_SOCIAL
                    && freq == WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED) {
                return mWifiNative.p2pFind(scanType, freq, timeout);
            } else if (scanType == WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ
                    && freq != WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED) {
                return mWifiNative.p2pFind(scanType, freq, timeout);
            }
            return false;
        }
    }
}

调用WifiP2pNative的p2pFind方法:

//packages/modules/Wifi/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
public class WifiP2pNative {
    private final SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
    public boolean p2pFind(int timeout) {
        return mSupplicantP2pIfaceHal.find(timeout); //调用SupplicantP2pIfaceHal的find方法
    }
}

调用SupplicantP2pIfaceHal的find方法:

//packages/modules/Wifi/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
public class SupplicantP2pIfaceHal {
    private ISupplicantP2pIfaceHal mP2pIfaceHal;
    public boolean find(int timeout) {
        synchronized (mLock) {
            String methodStr = "find";
            if (mP2pIfaceHal == null) {
                return handleNullHal(methodStr);
            }
            return mP2pIfaceHal.find(timeout); //调用ISupplicantP2pIfaceHal 的find方法
        }
    }
}

调用ISupplicantP2pIfaceHal的find方法,ISupplicantP2pIfaceHal是一个接口,由SupplicantP2pIfaceHalAidlImpl实现:

//packages/modules/Wifi/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImpl.java
public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
    private ISupplicantP2pIface mISupplicantP2pIface = null;
    public boolean find(int timeout) {
        synchronized (mLock) {
            if (!checkSupplicantP2pIfaceAndLogFailure("find")) return false;


            if (timeout < 0) {
                Log.e(TAG, "Invalid timeout value: " + timeout);
                return false;
            }
            SupplicantResult<Void> result = new SupplicantResult("find(" + timeout + ")");
            try {
                result.setResult(mISupplicantP2pIface.find(timeout)); //调用ISupplicantP2pIface的find方法
            } catch (RemoteException e) {
                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
                supplicantServiceDiedHandler();
            }
            return result.isSuccess();
        }
    }
}

调用mISupplicantP2pIface的find方法,ISupplicantP2pIface是一个接口,由HAL层的Supplicant实现,到这就到HAL层了,这里就不再继续分析了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值