softap的interface会将p2p的interface替换掉,适合于下面列出来的rule 4
HalDeviceManager
/**
* Returns true if we're allowed to delete the existing interface type for the requested
* interface type.
*
* Rules - applies in order:
*
* General rules:
* 1. No interface will be destroyed for a requested interface of the same type
* 2. No interface will be destroyed if one of the requested interfaces already exists
* 3. If there are >1 interface of an existing type, then it is ok to destroy that type
* interface
*
* Type-specific rules (but note that the general rules are appied first):
* 4. Request for AP or STA will destroy any other interface
* 5. Request for P2P will destroy NAN-only (but will destroy a second STA per #3)
* 6. Request for NAN will not destroy any interface (but will destroy a second STA per #3)
*
* Note: the 'numNecessaryInterfaces' is used to specify how many interfaces would be needed to
* be deleted. This is used to determine whether there are that many low priority interfaces
* of the requested type to delete.
*/
private boolean allowedToDeleteIfaceTypeForRequestedType(int existingIfaceType,
int requestedIfaceType, WifiIfaceInfo[][] currentIfaces, int numNecessaryInterfaces) {
// rule 0: check for any low priority interfaces
int numAvailableLowPriorityInterfaces = 0;
for (InterfaceCacheEntry entry : mInterfaceInfoCache.values()) {
if (entry.type == existingIfaceType && entry.isLowPriority) {
numAvailableLowPriorityInterfaces++;
}
}
if (numAvailableLowPriorityInterfaces >= numNecessaryInterfaces) {
return true;
}
// rule 1
if (existingIfaceType == requestedIfaceType) {
return false;
}
// rule 2
if (currentIfaces[requestedIfaceType].length != 0) {
return false;
}
// rule 3
if (currentIfaces[existingIfaceType].length > 1) {
return true;
}
// rule 6
if (requestedIfaceType == IfaceType.NAN) {
return false;
}
// rule 5
if (requestedIfaceType == IfaceType.P2P) {
return existingIfaceType == IfaceType.NAN;
}
// rule 4, the requestIfaceType is either AP or STA
return true;
}
p2p打不开,因为softap优先级比较高,适用于上面的rule 5
原理在于interface destroy后会通知监听的listener
/**
* Removes (releases/destroys) the given interface. Will trigger any registered
* InterfaceDestroyedListeners and possibly some InterfaceAvailableForRequestListeners if we
* can potentially create some other interfaces as a result of removing this interface.
*/
public boolean removeIface(IWifiIface iface) {
boolean success = removeIfaceInternal(iface);
dispatchAvailableForRequestListeners();
return success;
}
// dispatch all available for request listeners of the specified type AND clean-out the list:
// listeners are called once at most!
private boolean dispatchAvailableForRequestListeners() {
if (VDBG) Log.d(TAG, "dispatchAvailableForRequestListeners");
synchronized (mLock) {
WifiChipInfo[] chipInfos = getAllChipInfo();
if (chipInfos == null) {
Log.e(TAG, "dispatchAvailableForRequestListeners: no chip info found");
stopWifi(); // major error: shutting down
return false;
}
if (VDBG) {
Log.d(TAG, "dispatchAvailableForRequestListeners: chipInfos="
+ Arrays.deepToString(chipInfos));
}
for (int ifaceType : IFACE_TYPES_BY_PRIORITY) {
dispatchAvailableForRequestListenersForType(ifaceType, chipInfos);
}
}
return true;
}
依次按优先级通知各个interface type对应的listener(只有在有可能创建的时候才会真正去通知)
private void dispatchAvailableForRequestListenersForType(int ifaceType,
WifiChipInfo[] chipInfos) {
if (VDBG) Log.d(TAG, "dispatchAvailableForRequestListenersForType: ifaceType=" + ifaceType);
synchronized (mLock) {
Map listeners =
mInterfaceAvailableForRequestListeners.get(ifaceType);
if (listeners.size() == 0) {
return;
}
boolean isAvailable = isItPossibleToCreateIface(chipInfos, ifaceType);
if (VDBG) {
Log.d(TAG, "Interface available for: ifaceType=" + ifaceType + " = " + isAvailable);
}
for (Map.Entry listenerEntry :
listeners.entrySet()) {
if (listenerEntry.getValue() == null || listenerEntry.getValue() != isAvailable) {
if (VDBG) {
Log.d(TAG, "Interface available listener dispatched: ifaceType=" + ifaceType
+ ", listener=" + listenerEntry.getKey());
}
listenerEntry.getKey().triggerWithArg(isAvailable);
}
listenerEntry.setValue(isAvailable);
}
}
}
看下哪些interface会注册监听器
/**
* Register a listener to be called when an interface of the specified type could be requested.
* No guarantees are provided (some other entity could request it first). The listener is
* active from registration until unregistration - using
* unregisterInterfaceAvailableForRequestListener().
*
* Only a single instance of a listener will be registered (even if the specified looper is
* different).
*
* Note that if it is possible to create the specified interface type at registration time
* then the callback will be triggered immediately.
*
* @param ifaceType The interface type (IfaceType) to be monitored.
* @param listener Listener to call when an interface of the requested
* type could be created
* @param handler Handler on which to dispatch listener. Null implies the listener will be
* invoked synchronously from the context of the client which triggered the
* mode change.
*/
public void registerInterfaceAvailableForRequestListener(int ifaceType,
@NonNull InterfaceAvailableForRequestListener listener, @Nullable Handler handler) {
if (VDBG) {
Log.d(TAG, "registerInterfaceAvailableForRequestListener: ifaceType=" + ifaceType
+ ", listener=" + listener + ", handler=" + handler);
}
synchronized (mLock) {
InterfaceAvailableForRequestListenerProxy proxy =
new InterfaceAvailableForRequestListenerProxy(listener, handler);
if (mInterfaceAvailableForRequestListeners.get(ifaceType).containsKey(proxy)) {
if (VDBG) {
Log.d(TAG,
"registerInterfaceAvailableForRequestListener: dup listener skipped: "
+ listener);
}
return;
}
mInterfaceAvailableForRequestListeners.get(ifaceType).put(proxy, null);
}
WifiChipInfo[] chipInfos = getAllChipInfo();
if (chipInfos == null) {
Log.e(TAG,
"registerInterfaceAvailableForRequestListener: no chip info found - but "
+ "possibly registered pre-started - ignoring");
return;
}
dispatchAvailableForRequestListenersForType(ifaceType, chipInfos);
}
这边判断key是不是一样是判断listener是不是一个
private abstract class ListenerProxy {
protected LISTENER mListener;
private Handler mHandler;
// override equals & hash to make sure that the container HashSet is unique with respect to
// the contained listener
@Override
public boolean equals(Object obj) {
return mListener == ((ListenerProxy) obj).mListener;
}
主要有两个地方会调用这个监听器
http://androidxref.com/9.0.0_r3/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java#90
NAN
http://androidxref.com/9.0.0_r3/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pNative.java#162
P2P
主要看下P2P
// Internal callback registered to HalDeviceManager.
private class InterfaceAvailableListenerInternal implements
HalDeviceManager.InterfaceAvailableForRequestListener {
private final HalDeviceManager.InterfaceAvailableForRequestListener mExternalListener;
InterfaceAvailableListenerInternal(
HalDeviceManager.InterfaceAvailableForRequestListener externalListener) {
mExternalListener = externalListener;
}
@Override
public void onAvailabilityChanged(boolean isAvailable) {
Log.d(TAG, "P2P InterfaceAvailableListener " + isAvailable);
// We need another level of abstraction here. When a P2P interface is created,
// we should mask the availability change callback from WifiP2pService.
// This is because when the P2P interface is created, we'll get a callback
// indicating that we can no longer create a new P2P interface. We don't need to
// propagate this internal state to WifiP2pServiceImpl.
if (mIWifiP2pIface != null && !isAvailable) {
Log.i(TAG, "Masking interface non-availability callback because "
+ "we created a P2P iface");
return;
}
mExternalListener.onAvailabilityChanged(isAvailable);
}
}
/**
* Register for an interface available callbacks from HalDeviceManager.
*
* @param listener callback to be invoked when the interface is available/not available.
*/
public void registerInterfaceAvailableListener(
@NonNull HalDeviceManager.InterfaceAvailableForRequestListener listener,
Handler handler) {
mInterfaceAvailableListener = new InterfaceAvailableListenerInternal(listener);
// The interface available callbacks are cleared on every HAL stop, so need to
// re-register these callbacks on every start.
mHalDeviceManager.registerStatusListener(() -> {
if (mHalDeviceManager.isStarted()) {
Log.i(TAG, "Registering for interface available listener");
mHalDeviceManager.registerInterfaceAvailableForRequestListener(
IfaceType.P2P, mInterfaceAvailableListener, handler);
}
}, handler);
if (mHalDeviceManager.isStarted()) {
mHalDeviceManager.registerInterfaceAvailableForRequestListener(
IfaceType.P2P, mInterfaceAvailableListener, handler);
}
}
http://androidxref.com/9.0.0_r3/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java#744
// Register for interface availability from HalDeviceManager
mWifiNative.registerInterfaceAvailableListener((boolean isAvailable) -> {
mIsInterfaceAvailable = isAvailable;
if (isAvailable) {
checkAndReEnableP2p();
}
checkAndSendP2pStateChangedBroadcast();
}, getHandler());
// Check & re-enable P2P if needed.
// P2P interface will be created if all of the below are true:
// a) Wifi is enabled.
// b) P2P interface is available.
// c) There is atleast 1 client app which invoked initialize().
private void checkAndReEnableP2p() {
Log.d(TAG, "Wifi enabled=" + mIsWifiEnabled + ", P2P Interface availability="
+ mIsInterfaceAvailable + ", Number of clients=" + mDeathDataByBinder.size());
if (mIsWifiEnabled && mIsInterfaceAvailable && !mDeathDataByBinder.isEmpty()) {
sendMessage(ENABLE_P2P);
}
}
原生逻辑会在WiFi打开p2p可得并且当前有p2p client的情况下将p2p打开
总结下softap的优先级比p2p高,只有在关闭热点的情况下才能使用p2p相关功能。
原生p2p一直打开,不知道是处于什么考虑,热点打开的时候ap会替换掉p2p,p2p无法取代ap,但ap关闭后p2p会有条件开启。