Merge "[NAN] Re-factor connect/config flow" into mm-wireless-dev
This commit is contained in:
@@ -22,9 +22,10 @@ import android.os.Parcelable;
|
|||||||
/**
|
/**
|
||||||
* Defines a request object to configure a Wi-Fi NAN network. Built using
|
* Defines a request object to configure a Wi-Fi NAN network. Built using
|
||||||
* {@link ConfigRequest.Builder}. Configuration is requested using
|
* {@link ConfigRequest.Builder}. Configuration is requested using
|
||||||
* {@link WifiNanManager#requestConfig(ConfigRequest)}. Note that the actual
|
* {@link WifiNanManager#connect(android.os.Looper, WifiNanEventCallback, ConfigRequest)}
|
||||||
* achieved configuration may be different from the requested configuration -
|
* . Note that the actual achieved configuration may be different from the
|
||||||
* since multiple applications may request different configurations.
|
* requested configuration - since multiple applications may request different
|
||||||
|
* configurations.
|
||||||
*
|
*
|
||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
@@ -146,6 +147,30 @@ public class ConfigRequest implements Parcelable {
|
|||||||
&& mEnableIdentityChangeCallback == lhs.mEnableIdentityChangeCallback;
|
&& mEnableIdentityChangeCallback == lhs.mEnableIdentityChangeCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for equality of two configuration - but only considering their
|
||||||
|
* on-the-air NAN configuration impact.
|
||||||
|
*
|
||||||
|
* @param o Object to compare to.
|
||||||
|
* @return true if configuration objects have the same on-the-air
|
||||||
|
* configuration, false otherwise.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean equalsOnTheAir(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(o instanceof ConfigRequest)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigRequest lhs = (ConfigRequest) o;
|
||||||
|
|
||||||
|
return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference
|
||||||
|
&& mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = 17;
|
int result = 17;
|
||||||
@@ -159,6 +184,39 @@ public class ConfigRequest implements Parcelable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the contents of the ConfigRequest are valid. Otherwise
|
||||||
|
* throws an IllegalArgumentException.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void validate() throws IllegalArgumentException {
|
||||||
|
if (mMasterPreference < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Master Preference specification must be non-negative");
|
||||||
|
}
|
||||||
|
if (mMasterPreference == 1 || mMasterPreference == 255 || mMasterPreference > 255) {
|
||||||
|
throw new IllegalArgumentException("Master Preference specification must not "
|
||||||
|
+ "exceed 255 or use 1 or 255 (reserved values)");
|
||||||
|
}
|
||||||
|
if (mClusterLow < CLUSTER_ID_MIN) {
|
||||||
|
throw new IllegalArgumentException("Cluster specification must be non-negative");
|
||||||
|
}
|
||||||
|
if (mClusterLow > CLUSTER_ID_MAX) {
|
||||||
|
throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
|
||||||
|
}
|
||||||
|
if (mClusterHigh < CLUSTER_ID_MIN) {
|
||||||
|
throw new IllegalArgumentException("Cluster specification must be non-negative");
|
||||||
|
}
|
||||||
|
if (mClusterHigh > CLUSTER_ID_MAX) {
|
||||||
|
throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
|
||||||
|
}
|
||||||
|
if (mClusterLow > mClusterHigh) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid argument combination - must have Cluster Low <= Cluster High");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder used to build {@link ConfigRequest} objects.
|
* Builder used to build {@link ConfigRequest} objects.
|
||||||
*/
|
*/
|
||||||
@@ -175,6 +233,7 @@ public class ConfigRequest implements Parcelable {
|
|||||||
* @param support5gBand Support for 5G band is required.
|
* @param support5gBand Support for 5G band is required.
|
||||||
* @return The builder to facilitate chaining
|
* @return The builder to facilitate chaining
|
||||||
* {@code builder.setXXX(..).setXXX(..)}.
|
* {@code builder.setXXX(..).setXXX(..)}.
|
||||||
|
* @hide PROPOSED_NAN_SYSTEM_API
|
||||||
*/
|
*/
|
||||||
public Builder setSupport5gBand(boolean support5gBand) {
|
public Builder setSupport5gBand(boolean support5gBand) {
|
||||||
mSupport5gBand = support5gBand;
|
mSupport5gBand = support5gBand;
|
||||||
@@ -188,6 +247,7 @@ public class ConfigRequest implements Parcelable {
|
|||||||
* @param masterPreference The requested master preference
|
* @param masterPreference The requested master preference
|
||||||
* @return The builder to facilitate chaining
|
* @return The builder to facilitate chaining
|
||||||
* {@code builder.setXXX(..).setXXX(..)}.
|
* {@code builder.setXXX(..).setXXX(..)}.
|
||||||
|
* @hide PROPOSED_NAN_SYSTEM_API
|
||||||
*/
|
*/
|
||||||
public Builder setMasterPreference(int masterPreference) {
|
public Builder setMasterPreference(int masterPreference) {
|
||||||
if (masterPreference < 0) {
|
if (masterPreference < 0) {
|
||||||
@@ -214,6 +274,7 @@ public class ConfigRequest implements Parcelable {
|
|||||||
* @param clusterLow The lower range of the generated cluster ID.
|
* @param clusterLow The lower range of the generated cluster ID.
|
||||||
* @return The builder to facilitate chaining
|
* @return The builder to facilitate chaining
|
||||||
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
|
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
|
||||||
|
* @hide PROPOSED_NAN_SYSTEM_API
|
||||||
*/
|
*/
|
||||||
public Builder setClusterLow(int clusterLow) {
|
public Builder setClusterLow(int clusterLow) {
|
||||||
if (clusterLow < CLUSTER_ID_MIN) {
|
if (clusterLow < CLUSTER_ID_MIN) {
|
||||||
@@ -238,6 +299,7 @@ public class ConfigRequest implements Parcelable {
|
|||||||
* @param clusterHigh The upper range of the generated cluster ID.
|
* @param clusterHigh The upper range of the generated cluster ID.
|
||||||
* @return The builder to facilitate chaining
|
* @return The builder to facilitate chaining
|
||||||
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
|
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
|
||||||
|
* @hide PROPOSED_NAN_SYSTEM_API
|
||||||
*/
|
*/
|
||||||
public Builder setClusterHigh(int clusterHigh) {
|
public Builder setClusterHigh(int clusterHigh) {
|
||||||
if (clusterHigh < CLUSTER_ID_MIN) {
|
if (clusterHigh < CLUSTER_ID_MIN) {
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import android.net.wifi.nan.ConfigRequest;
|
|||||||
*/
|
*/
|
||||||
oneway interface IWifiNanEventCallback
|
oneway interface IWifiNanEventCallback
|
||||||
{
|
{
|
||||||
void onConfigCompleted(in ConfigRequest completedConfig);
|
void onConnectSuccess();
|
||||||
void onConfigFailed(in ConfigRequest failedConfig, int reason);
|
void onConnectFail(int reason);
|
||||||
void onNanDown(int reason);
|
void onNanDown(int reason);
|
||||||
void onIdentityChanged();
|
void onIdentityChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ import android.net.wifi.nan.SubscribeConfig;
|
|||||||
interface IWifiNanManager
|
interface IWifiNanManager
|
||||||
{
|
{
|
||||||
// client API
|
// client API
|
||||||
int connect(in IBinder binder, in IWifiNanEventCallback callback);
|
int connect(in IBinder binder, in IWifiNanEventCallback callback,
|
||||||
|
in ConfigRequest configRequest);
|
||||||
void disconnect(int clientId, in IBinder binder);
|
void disconnect(int clientId, in IBinder binder);
|
||||||
void requestConfig(int clientId, in ConfigRequest configRequest);
|
|
||||||
|
|
||||||
void publish(int clientId, in PublishConfig publishConfig, in IWifiNanSessionCallback callback);
|
void publish(int clientId, in PublishConfig publishConfig, in IWifiNanSessionCallback callback);
|
||||||
void subscribe(int clientId, in SubscribeConfig subscribeConfig,
|
void subscribe(int clientId, in SubscribeConfig subscribeConfig,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ package android.net.wifi.nan;
|
|||||||
oneway interface IWifiNanSessionCallback
|
oneway interface IWifiNanSessionCallback
|
||||||
{
|
{
|
||||||
void onSessionStarted(int sessionId);
|
void onSessionStarted(int sessionId);
|
||||||
|
void onSessionConfigSuccess();
|
||||||
void onSessionConfigFail(int reason);
|
void onSessionConfigFail(int reason);
|
||||||
void onSessionTerminated(int reason);
|
void onSessionTerminated(int reason);
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import java.util.Arrays;
|
|||||||
/**
|
/**
|
||||||
* Defines the configuration of a NAN publish session. Built using
|
* Defines the configuration of a NAN publish session. Built using
|
||||||
* {@link PublishConfig.Builder}. Publish is done using
|
* {@link PublishConfig.Builder}. Publish is done using
|
||||||
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback, int)} or
|
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} or
|
||||||
* {@link WifiNanPublishSession#publish(PublishConfig)}.
|
* {@link WifiNanPublishSession#updatePublish(PublishConfig)}.
|
||||||
*
|
*
|
||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
@@ -264,6 +264,45 @@ public class PublishConfig implements Parcelable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the contents of the PublishConfig are valid. Otherwise
|
||||||
|
* throws an IllegalArgumentException.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void validate() throws IllegalArgumentException {
|
||||||
|
if (mServiceSpecificInfoLength != 0 && (mServiceSpecificInfo == null
|
||||||
|
|| mServiceSpecificInfo.length < mServiceSpecificInfoLength)) {
|
||||||
|
throw new IllegalArgumentException("Non-matching combination of "
|
||||||
|
+ "serviceSpecificInfo and serviceSpecificInfoLength");
|
||||||
|
}
|
||||||
|
if (mTxFilterLength != 0 && (mTxFilter == null || mTxFilter.length < mTxFilterLength)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-matching combination of txFilter and txFilterLength");
|
||||||
|
}
|
||||||
|
if (mRxFilterLength != 0 && (mRxFilter == null || mRxFilter.length < mRxFilterLength)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-matching combination of rxFilter and rxFilterLength");
|
||||||
|
}
|
||||||
|
if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) {
|
||||||
|
throw new IllegalArgumentException("Invalid publishType - " + mPublishType);
|
||||||
|
}
|
||||||
|
if (mPublishCount < 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
|
||||||
|
}
|
||||||
|
if (mTtlSec < 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
|
||||||
|
}
|
||||||
|
if (mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED && mRxFilterLength != 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
|
||||||
|
+ "publishes (active) can't have an Rx filter");
|
||||||
|
}
|
||||||
|
if (mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED && mTxFilterLength != 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid publish config: SOLICITED "
|
||||||
|
+ "publishes (passive) can't have a Tx filter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder used to build {@link PublishConfig} objects.
|
* Builder used to build {@link PublishConfig} objects.
|
||||||
*/
|
*/
|
||||||
@@ -417,7 +456,7 @@ public class PublishConfig implements Parcelable {
|
|||||||
* Sets the number of times a solicited (
|
* Sets the number of times a solicited (
|
||||||
* {@link PublishConfig.Builder#setPublishType(int)}) publish session
|
* {@link PublishConfig.Builder#setPublishType(int)}) publish session
|
||||||
* will transmit a packet. When the count is reached an event will be
|
* will transmit a packet. When the count is reached an event will be
|
||||||
* generated for {@link WifiNanSessionCallback#onPublishTerminated(int)}
|
* generated for {@link WifiNanSessionCallback#onSessionTerminated(int)}
|
||||||
* with reason={@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
* with reason={@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
||||||
*
|
*
|
||||||
* @param publishCount Number of publish packets to transmit.
|
* @param publishCount Number of publish packets to transmit.
|
||||||
@@ -437,7 +476,7 @@ public class PublishConfig implements Parcelable {
|
|||||||
* {@link PublishConfig.Builder#setPublishCount(int)}) publish session
|
* {@link PublishConfig.Builder#setPublishCount(int)}) publish session
|
||||||
* will be alive - i.e. transmitting a packet. When the TTL is reached
|
* will be alive - i.e. transmitting a packet. When the TTL is reached
|
||||||
* an event will be generated for
|
* an event will be generated for
|
||||||
* {@link WifiNanSessionCallback#onPublishTerminated(int)} with reason=
|
* {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
|
||||||
* {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
* {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
||||||
*
|
*
|
||||||
* @param ttlSec Lifetime of a publish session in seconds.
|
* @param ttlSec Lifetime of a publish session in seconds.
|
||||||
@@ -454,7 +493,7 @@ public class PublishConfig implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure whether a publish terminate notification
|
* Configure whether a publish terminate notification
|
||||||
* {@link WifiNanSessionCallback#onPublishTerminated(int)} is reported
|
* {@link WifiNanSessionCallback#onSessionTerminated(int)} is reported
|
||||||
* back to the callback.
|
* back to the callback.
|
||||||
*
|
*
|
||||||
* @param enable If true the terminate callback will be called when the
|
* @param enable If true the terminate callback will be called when the
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import java.util.Arrays;
|
|||||||
* Defines the configuration of a NAN subscribe session. Built using
|
* Defines the configuration of a NAN subscribe session. Built using
|
||||||
* {@link SubscribeConfig.Builder}. Subscribe is done using
|
* {@link SubscribeConfig.Builder}. Subscribe is done using
|
||||||
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} or
|
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} or
|
||||||
* {@link WifiNanSubscribeSession#subscribe(SubscribeConfig)}.
|
* {@link WifiNanSubscribeSession#updateSubscribe(SubscribeConfig)}.
|
||||||
*
|
*
|
||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
@@ -286,6 +286,49 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the contents of the SubscribeConfig are valid. Otherwise
|
||||||
|
* throws an IllegalArgumentException.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void validate() throws IllegalArgumentException {
|
||||||
|
if (mServiceSpecificInfoLength != 0 && (mServiceSpecificInfo == null
|
||||||
|
|| mServiceSpecificInfo.length < mServiceSpecificInfoLength)) {
|
||||||
|
throw new IllegalArgumentException("Non-matching combination of "
|
||||||
|
+ "serviceSpecificInfo and serviceSpecificInfoLength");
|
||||||
|
}
|
||||||
|
if (mTxFilterLength != 0 && (mTxFilter == null || mTxFilter.length < mTxFilterLength)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-matching combination of txFilter and txFilterLength");
|
||||||
|
}
|
||||||
|
if (mRxFilterLength != 0 && (mRxFilter == null || mRxFilter.length < mRxFilterLength)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-matching combination of rxFilter and rxFilterLength");
|
||||||
|
}
|
||||||
|
if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) {
|
||||||
|
throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType);
|
||||||
|
}
|
||||||
|
if (mSubscribeCount < 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
|
||||||
|
}
|
||||||
|
if (mTtlSec < 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
|
||||||
|
}
|
||||||
|
if (mMatchStyle != MATCH_STYLE_FIRST_ONLY && mMatchStyle != MATCH_STYLE_ALL) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
|
||||||
|
}
|
||||||
|
if (mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE && mRxFilterLength != 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
|
||||||
|
}
|
||||||
|
if (mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE && mTxFilterLength != 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder used to build {@link SubscribeConfig} objects.
|
* Builder used to build {@link SubscribeConfig} objects.
|
||||||
*/
|
*/
|
||||||
@@ -332,6 +375,11 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
|
public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
|
||||||
int serviceSpecificInfoLength) {
|
int serviceSpecificInfoLength) {
|
||||||
|
if (serviceSpecificInfoLength != 0 && (serviceSpecificInfo == null
|
||||||
|
|| serviceSpecificInfo.length < serviceSpecificInfoLength)) {
|
||||||
|
throw new IllegalArgumentException("Non-matching combination of "
|
||||||
|
+ "serviceSpecificInfo and serviceSpecificInfoLength");
|
||||||
|
}
|
||||||
mServiceSpecificInfoLength = serviceSpecificInfoLength;
|
mServiceSpecificInfoLength = serviceSpecificInfoLength;
|
||||||
mServiceSpecificInfo = serviceSpecificInfo;
|
mServiceSpecificInfo = serviceSpecificInfo;
|
||||||
return this;
|
return this;
|
||||||
@@ -374,6 +422,10 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
* {@code builder.setXXX(..).setXXX(..)}.
|
* {@code builder.setXXX(..).setXXX(..)}.
|
||||||
*/
|
*/
|
||||||
public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
|
public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
|
||||||
|
if (txFilterLength != 0 && (txFilter == null || txFilter.length < txFilterLength)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-matching combination of txFilter and txFilterLength");
|
||||||
|
}
|
||||||
mTxFilter = txFilter;
|
mTxFilter = txFilter;
|
||||||
mTxFilterLength = txFilterLength;
|
mTxFilterLength = txFilterLength;
|
||||||
return this;
|
return this;
|
||||||
@@ -397,6 +449,10 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
* {@code builder.setXXX(..).setXXX(..)}.
|
* {@code builder.setXXX(..).setXXX(..)}.
|
||||||
*/
|
*/
|
||||||
public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
|
public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
|
||||||
|
if (rxFilterLength != 0 && (rxFilter == null || rxFilter.length < rxFilterLength)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-matching combination of rxFilter and rxFilterLength");
|
||||||
|
}
|
||||||
mRxFilter = rxFilter;
|
mRxFilter = rxFilter;
|
||||||
mRxFilterLength = rxFilterLength;
|
mRxFilterLength = rxFilterLength;
|
||||||
return this;
|
return this;
|
||||||
@@ -427,8 +483,8 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
|
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
|
||||||
* session will transmit a packet. When the count is reached an event
|
* session will transmit a packet. When the count is reached an event
|
||||||
* will be generated for
|
* will be generated for
|
||||||
* {@link WifiNanSessionCallback#onSubscribeTerminated(int)} with
|
* {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
|
||||||
* reason= {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
* {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
||||||
*
|
*
|
||||||
* @param subscribeCount Number of subscribe packets to transmit.
|
* @param subscribeCount Number of subscribe packets to transmit.
|
||||||
* @return The builder to facilitate chaining
|
* @return The builder to facilitate chaining
|
||||||
@@ -447,8 +503,8 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
|
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
|
||||||
* session will be alive - i.e. transmitting a packet. When the TTL is
|
* session will be alive - i.e. transmitting a packet. When the TTL is
|
||||||
* reached an event will be generated for
|
* reached an event will be generated for
|
||||||
* {@link WifiNanSessionCallback#onSubscribeTerminated(int)} with
|
* {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
|
||||||
* reason= {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
* {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
|
||||||
*
|
*
|
||||||
* @param ttlSec Lifetime of a subscribe session in seconds.
|
* @param ttlSec Lifetime of a subscribe session in seconds.
|
||||||
* @return The builder to facilitate chaining
|
* @return The builder to facilitate chaining
|
||||||
@@ -486,7 +542,7 @@ public class SubscribeConfig implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure whether a subscribe terminate notification
|
* Configure whether a subscribe terminate notification
|
||||||
* {@link WifiNanSessionCallback#onSubscribeTerminated(int)} is reported
|
* {@link WifiNanSessionCallback#onSessionTerminated(int)} is reported
|
||||||
* back to the callback.
|
* back to the callback.
|
||||||
*
|
*
|
||||||
* @param enable If true the terminate callback will be called when the
|
* @param enable If true the terminate callback will be called when the
|
||||||
|
|||||||
@@ -16,6 +16,11 @@
|
|||||||
|
|
||||||
package android.net.wifi.nan;
|
package android.net.wifi.nan;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for NAN events callbacks. Should be extended by applications
|
* Base class for NAN events callbacks. Should be extended by applications
|
||||||
* wanting notifications. These are callbacks applying to the NAN connection as
|
* wanting notifications. These are callbacks applying to the NAN connection as
|
||||||
@@ -25,25 +30,59 @@ package android.net.wifi.nan;
|
|||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
public class WifiNanEventCallback {
|
public class WifiNanEventCallback {
|
||||||
|
@IntDef({
|
||||||
|
REASON_INVALID_ARGS, REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG, REASON_REQUESTED,
|
||||||
|
REASON_OTHER })
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface EventReasonCodes {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when NAN configuration is completed.
|
* Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
|
||||||
*
|
* invalid argument in the requested operation.
|
||||||
* @param completedConfig The actual configuration request which was
|
|
||||||
* completed. Note that it may be different from that requested
|
|
||||||
* by the application. The service combines configuration
|
|
||||||
* requests from all applications.
|
|
||||||
*/
|
*/
|
||||||
public void onConfigCompleted(ConfigRequest completedConfig) {
|
public static final int REASON_INVALID_ARGS = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
|
||||||
|
* that a {@link ConfigRequest} passed in
|
||||||
|
* {@link WifiNanManager#connect(android.os.Looper, WifiNanEventCallback, ConfigRequest)}
|
||||||
|
* couldn't be applied since other connections already exist with an
|
||||||
|
* incompatible configurations.
|
||||||
|
*/
|
||||||
|
public static final int REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG = 1001;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reason flag for {@link WifiNanEventCallback#onNanDown(int)} callback.
|
||||||
|
* Indicates NAN is shut-down per user request.
|
||||||
|
*/
|
||||||
|
public static final int REASON_REQUESTED = 1002;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
|
||||||
|
* an unspecified error occurred during the operation.
|
||||||
|
*/
|
||||||
|
public static final int REASON_OTHER = 1003;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when NAN connect operation
|
||||||
|
* {@link WifiNanManager#connect(android.os.Looper, WifiNanEventCallback)}
|
||||||
|
* is completed. Doesn't necessarily mean that have joined or started a NAN
|
||||||
|
* cluster. An indication is provided by {@link #onIdentityChanged()}.
|
||||||
|
*/
|
||||||
|
public void onConnectSuccess() {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when NAN configuration failed.
|
* Called when NAN connect operation
|
||||||
|
* {@code WifiNanManager#connect(android.os.Looper, WifiNanEventCallback)}
|
||||||
|
* failed.
|
||||||
*
|
*
|
||||||
* @param reason Failure reason code, see
|
* @param reason Failure reason code, see
|
||||||
* {@code WifiNanSessionCallback.FAIL_*}.
|
* {@code WifiNanEventCallback.REASON_*}.
|
||||||
*/
|
*/
|
||||||
public void onConfigFailed(@SuppressWarnings("unused") ConfigRequest failedConfig, int reason) {
|
public void onConnectFail(@EventReasonCodes int reason) {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +90,9 @@ public class WifiNanEventCallback {
|
|||||||
* Called when NAN cluster is down
|
* Called when NAN cluster is down
|
||||||
*
|
*
|
||||||
* @param reason Reason code for event, see
|
* @param reason Reason code for event, see
|
||||||
* {@code WifiNanSessionCallback.FAIL_*}.
|
* {@code WifiNanEventCallback.REASON_*}.
|
||||||
*/
|
*/
|
||||||
public void onNanDown(int reason) {
|
public void onNanDown(@EventReasonCodes int reason) {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ import android.os.Message;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the primary API for managing Wi-Fi NAN operation:
|
* This class provides the primary API for managing Wi-Fi NAN operation:
|
||||||
* including discovery and data-links. Get an instance of this class by calling
|
* including discovery and data-links. Get an instance of this class by calling
|
||||||
@@ -45,9 +49,31 @@ public class WifiNanManager {
|
|||||||
private static final boolean DBG = false;
|
private static final boolean DBG = false;
|
||||||
private static final boolean VDBG = false; // STOPSHIP if true
|
private static final boolean VDBG = false; // STOPSHIP if true
|
||||||
|
|
||||||
|
private final IWifiNanManager mService;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State transitions:
|
||||||
|
* UNCONNECTED -- (connect()) --> CONNECTING -- (onConnectSuccess()) --> CONNECTED
|
||||||
|
* UNCONNECTED -- (connect()) --> CONNECTING -- (onConnectFail()) --> UNCONNECTED
|
||||||
|
* CONNECTED||CONNECTING -- (disconnect()) --> UNCONNECTED
|
||||||
|
* CONNECTED||CONNECTING -- onNanDown() --> UNCONNECTED
|
||||||
|
*/
|
||||||
|
private static final int STATE_UNCONNECTED = 0;
|
||||||
|
private static final int STATE_CONNECTING = 1;
|
||||||
|
private static final int STATE_CONNECTED = 2;
|
||||||
|
|
||||||
|
private Object mLock = new Object(); // lock access to the following vars
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private int mState = STATE_UNCONNECTED;
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
private IBinder mBinder;
|
private IBinder mBinder;
|
||||||
private int mClientId = -1;
|
|
||||||
private IWifiNanManager mService;
|
@GuardedBy("mLock")
|
||||||
|
private int mClientId;
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
private Looper mLooper;
|
private Looper mLooper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +84,7 @@ public class WifiNanManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-connect to the Wi-Fi NAN service - enabling the application to execute
|
* Connect to the Wi-Fi NAN service - enabling the application to execute
|
||||||
* {@link WifiNanManager} APIs.
|
* {@link WifiNanManager} APIs.
|
||||||
*
|
*
|
||||||
* @param looper The Looper on which to execute all callbacks related to the
|
* @param looper The Looper on which to execute all callbacks related to the
|
||||||
@@ -67,25 +93,45 @@ public class WifiNanManager {
|
|||||||
* @param callback A callback extended from {@link WifiNanEventCallback}.
|
* @param callback A callback extended from {@link WifiNanEventCallback}.
|
||||||
*/
|
*/
|
||||||
public void connect(Looper looper, WifiNanEventCallback callback) {
|
public void connect(Looper looper, WifiNanEventCallback callback) {
|
||||||
if (VDBG) Log.v(TAG, "connect()");
|
connect(looper, callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
if (callback == null) {
|
/**
|
||||||
throw new IllegalArgumentException("Invalid callback - must not be null");
|
* Connect to the Wi-Fi NAN service - enabling the application to execute
|
||||||
|
* {@link WifiNanManager} APIs. Allows requesting a specific configuration
|
||||||
|
* using {@link ConfigRequest} structure. Limited to privileged access.
|
||||||
|
*
|
||||||
|
* @param looper The Looper on which to execute all callbacks related to the
|
||||||
|
* connection - including all sessions opened as part of this
|
||||||
|
* connection.
|
||||||
|
* @param callback A callback extended from {@link WifiNanEventCallback}.
|
||||||
|
* @param configRequest The requested NAN configuration.
|
||||||
|
*/
|
||||||
|
public void connect(Looper looper, WifiNanEventCallback callback, ConfigRequest configRequest) {
|
||||||
|
if (VDBG) {
|
||||||
|
Log.v(TAG, "connect(): looper=" + looper + ", callback=" + callback + ", configRequest="
|
||||||
|
+ configRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mClientId != -1) {
|
synchronized (mLock) {
|
||||||
Log.e(TAG, "connect(): mClientId=" + mClientId
|
if (mState != STATE_UNCONNECTED) {
|
||||||
+ ": seems to calling connect() without disconnecting() first!");
|
Log.e(TAG, "connect(): Calling connect() when state != UNCONNECTED!");
|
||||||
throw new IllegalStateException("Calling connect() without disconnecting() first!");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLooper = looper;
|
mLooper = looper;
|
||||||
mBinder = new Binder();
|
mBinder = new Binder();
|
||||||
|
mState = STATE_CONNECTING;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mClientId = mService.connect(mBinder, new WifiNanEventCallbackProxy(mLooper, callback));
|
mClientId = mService.connect(mBinder,
|
||||||
} catch (RemoteException e) {
|
new WifiNanEventCallbackProxy(this, looper, callback), configRequest);
|
||||||
Log.w(TAG, "connect RemoteException (FYI - ignoring): " + e);
|
} catch (RemoteException e) {
|
||||||
|
mLooper = null;
|
||||||
|
mBinder = null;
|
||||||
|
mState = STATE_UNCONNECTED;
|
||||||
|
e.rethrowAsRuntimeException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,61 +145,39 @@ public class WifiNanManager {
|
|||||||
* {@link WifiNanManager#connect(Looper, WifiNanEventCallback)} .
|
* {@link WifiNanManager#connect(Looper, WifiNanEventCallback)} .
|
||||||
*/
|
*/
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
if (mClientId == -1) {
|
if (VDBG) Log.v(TAG, "disconnect()");
|
||||||
/*
|
|
||||||
* Warning only since could be called multiple times as cleaning-up
|
IBinder binder;
|
||||||
* (and no damage done).
|
int clientId;
|
||||||
*/
|
synchronized (mLock) {
|
||||||
Log.w(TAG, "disconnect(): called without calling connect() first - or called "
|
if (mState == STATE_UNCONNECTED) {
|
||||||
+ "multiple times.");
|
Log.e(TAG, "disconnect(): called while UNCONNECTED - ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if (VDBG) Log.v(TAG, "disconnect()");
|
binder = mBinder;
|
||||||
mService.disconnect(mClientId, mBinder);
|
clientId = mClientId;
|
||||||
|
|
||||||
|
mState = STATE_UNCONNECTED;
|
||||||
mBinder = null;
|
mBinder = null;
|
||||||
mClientId = -1;
|
mLooper = null;
|
||||||
|
mClientId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
mService.disconnect(clientId, binder);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "disconnect RemoteException (FYI - ignoring): " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
if (mBinder != null) {
|
if (mState != STATE_UNCONNECTED) {
|
||||||
if (DBG) Log.d(TAG, "finalize: disconnect() not called - executing now");
|
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests a NAN configuration, specified by {@link ConfigRequest}. Note
|
|
||||||
* that NAN is a shared resource and the device can only be a member of a
|
|
||||||
* single cluster. Thus the service may merge configuration requests from
|
|
||||||
* multiple applications and configure NAN differently from individual
|
|
||||||
* requests.
|
|
||||||
* <p>
|
|
||||||
* The {@link WifiNanEventCallback#onConfigCompleted(ConfigRequest)} will be
|
|
||||||
* called when configuration is completed (if a callback is registered for
|
|
||||||
* this specific event).
|
|
||||||
*
|
|
||||||
* @param configRequest The requested NAN configuration.
|
|
||||||
*/
|
|
||||||
public void requestConfig(ConfigRequest configRequest) {
|
|
||||||
if (VDBG) Log.v(TAG, "requestConfig(): configRequest=" + configRequest);
|
|
||||||
|
|
||||||
if (mClientId == -1) {
|
|
||||||
Log.e(TAG, "requestConfig(): called without an initial connect()!");
|
|
||||||
throw new IllegalStateException("Calling requestConfig() without a connect() first!");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
mService.requestConfig(mClientId, configRequest);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "requestConfig RemoteException (FYI - ignoring): " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a NAN publish session. The actual publish session is provided by
|
* Request a NAN publish session. The actual publish session is provided by
|
||||||
* the
|
* the
|
||||||
@@ -170,30 +194,22 @@ public class WifiNanManager {
|
|||||||
public void publish(PublishConfig publishConfig, WifiNanSessionCallback callback) {
|
public void publish(PublishConfig publishConfig, WifiNanSessionCallback callback) {
|
||||||
if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
|
if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
|
||||||
|
|
||||||
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
|
int clientId;
|
||||||
&& publishConfig.mRxFilterLength != 0) {
|
Looper looper;
|
||||||
throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
|
synchronized (mLock) {
|
||||||
+ "publishes (active) can't have an Rx filter");
|
if (mState != STATE_CONNECTED) {
|
||||||
}
|
Log.e(TAG, "publish(): called when not CONNECTED!");
|
||||||
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED
|
return;
|
||||||
&& publishConfig.mTxFilterLength != 0) {
|
}
|
||||||
throw new IllegalArgumentException("Invalid publish config: SOLICITED "
|
|
||||||
+ "publishes (passive) can't have a Tx filter");
|
|
||||||
}
|
|
||||||
if (callback == null) {
|
|
||||||
throw new IllegalArgumentException("Invalid callback - must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mClientId == -1) {
|
clientId = mClientId;
|
||||||
Log.e(TAG, "publish(): called without an initial connect()!");
|
looper = mLooper;
|
||||||
throw new IllegalStateException("Calling publish() without a connect() first!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mService.publish(mClientId, publishConfig,
|
mService.publish(clientId, publishConfig,
|
||||||
new WifiNanSessionCallbackProxy(mLooper, true, callback));
|
new WifiNanSessionCallbackProxy(this, looper, true, callback));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "publish RemoteException: " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,21 +219,19 @@ public class WifiNanManager {
|
|||||||
public void updatePublish(int sessionId, PublishConfig publishConfig) {
|
public void updatePublish(int sessionId, PublishConfig publishConfig) {
|
||||||
if (VDBG) Log.v(TAG, "updatePublish(): config=" + publishConfig);
|
if (VDBG) Log.v(TAG, "updatePublish(): config=" + publishConfig);
|
||||||
|
|
||||||
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
|
int clientId;
|
||||||
&& publishConfig.mRxFilterLength != 0) {
|
synchronized (mLock) {
|
||||||
throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
|
if (mState != STATE_CONNECTED) {
|
||||||
+ "publishes (active) can't have an Rx filter");
|
Log.e(TAG, "updatePublish(): called when not CONNECTED)!");
|
||||||
}
|
return;
|
||||||
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED
|
}
|
||||||
&& publishConfig.mTxFilterLength != 0) {
|
|
||||||
throw new IllegalArgumentException("Invalid publish config: SOLICITED "
|
|
||||||
+ "publishes (passive) can't have a Tx filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
clientId = mClientId;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
mService.updatePublish(mClientId, sessionId, publishConfig);
|
mService.updatePublish(clientId, sessionId, publishConfig);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "updatePublish RemoteException: " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,27 +253,23 @@ public class WifiNanManager {
|
|||||||
Log.v(TAG, "subscribe(): config=" + subscribeConfig);
|
Log.v(TAG, "subscribe(): config=" + subscribeConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
|
int clientId;
|
||||||
&& subscribeConfig.mRxFilterLength != 0) {
|
Looper looper;
|
||||||
throw new IllegalArgumentException(
|
synchronized (mLock) {
|
||||||
"Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
|
if (mState != STATE_CONNECTED) {
|
||||||
}
|
Log.e(TAG, "subscribe(): called when not CONNECTED!");
|
||||||
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE
|
return;
|
||||||
&& subscribeConfig.mTxFilterLength != 0) {
|
}
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mClientId == -1) {
|
clientId = mClientId;
|
||||||
Log.e(TAG, "subscribe(): called without an initial connect()!");
|
looper = mLooper;
|
||||||
throw new IllegalStateException("Calling subscribe() without a connect() first!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mService.subscribe(mClientId, subscribeConfig,
|
mService.subscribe(clientId, subscribeConfig,
|
||||||
new WifiNanSessionCallbackProxy(mLooper, false, callback));
|
new WifiNanSessionCallbackProxy(this, looper, false, callback));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "subscribe RemoteException: " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,21 +281,20 @@ public class WifiNanManager {
|
|||||||
Log.v(TAG, "subscribe(): config=" + subscribeConfig);
|
Log.v(TAG, "subscribe(): config=" + subscribeConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
|
int clientId;
|
||||||
&& subscribeConfig.mRxFilterLength != 0) {
|
synchronized (mLock) {
|
||||||
throw new IllegalArgumentException(
|
if (mState != STATE_CONNECTED) {
|
||||||
"Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
|
Log.e(TAG, "updateSubscribe(): called when not CONNECTED!");
|
||||||
}
|
return;
|
||||||
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE
|
}
|
||||||
&& subscribeConfig.mTxFilterLength != 0) {
|
|
||||||
throw new IllegalArgumentException(
|
clientId = mClientId;
|
||||||
"Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mService.updateSubscribe(mClientId, sessionId, subscribeConfig);
|
mService.updateSubscribe(clientId, sessionId, subscribeConfig);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "updateSubscribe RemoteException: " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,10 +304,20 @@ public class WifiNanManager {
|
|||||||
public void terminateSession(int sessionId) {
|
public void terminateSession(int sessionId) {
|
||||||
if (DBG) Log.d(TAG, "Terminate NAN session #" + sessionId);
|
if (DBG) Log.d(TAG, "Terminate NAN session #" + sessionId);
|
||||||
|
|
||||||
|
int clientId;
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mState != STATE_CONNECTED) {
|
||||||
|
Log.e(TAG, "terminateSession(): called when not CONNECTED!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clientId = mClientId;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mService.terminateSession(mClientId, sessionId);
|
mService.terminateSession(clientId, sessionId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "terminateSession RemoteException (FYI - ignoring): " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,24 +326,34 @@ public class WifiNanManager {
|
|||||||
*/
|
*/
|
||||||
public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength,
|
public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength,
|
||||||
int messageId) {
|
int messageId) {
|
||||||
try {
|
if (VDBG) {
|
||||||
if (VDBG) {
|
Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
|
||||||
Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
|
+ ", messageLength=" + messageLength + ", messageId=" + messageId);
|
||||||
+ ", messageLength=" + messageLength + ", messageId=" + messageId);
|
}
|
||||||
|
|
||||||
|
int clientId;
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mState != STATE_CONNECTED) {
|
||||||
|
Log.e(TAG, "sendMessage(): called when not CONNECTED!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
mService.sendMessage(mClientId, sessionId, peerId, message, messageLength, messageId);
|
|
||||||
|
clientId = mClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
mService.sendMessage(clientId, sessionId, peerId, message, messageLength, messageId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "subscribe RemoteException (FYI - ignoring): " + e);
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class WifiNanEventCallbackProxy extends IWifiNanEventCallback.Stub {
|
private static class WifiNanEventCallbackProxy extends IWifiNanEventCallback.Stub {
|
||||||
private static final int CALLBACK_CONFIG_COMPLETED = 0;
|
private static final int CALLBACK_CONNECT_SUCCESS = 0;
|
||||||
private static final int CALLBACK_CONFIG_FAILED = 1;
|
private static final int CALLBACK_CONNECT_FAIL = 1;
|
||||||
private static final int CALLBACK_NAN_DOWN = 2;
|
private static final int CALLBACK_NAN_DOWN = 2;
|
||||||
private static final int CALLBACK_IDENTITY_CHANGED = 3;
|
private static final int CALLBACK_IDENTITY_CHANGED = 3;
|
||||||
|
|
||||||
private final WifiNanEventCallback mOriginalCallback;
|
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,26 +362,64 @@ public class WifiNanManager {
|
|||||||
*
|
*
|
||||||
* @param looper The looper on which to execute the callbacks.
|
* @param looper The looper on which to execute the callbacks.
|
||||||
*/
|
*/
|
||||||
WifiNanEventCallbackProxy(Looper looper, WifiNanEventCallback originalCallback) {
|
WifiNanEventCallbackProxy(WifiNanManager mgr, Looper looper,
|
||||||
mOriginalCallback = originalCallback;
|
final WifiNanEventCallback originalCallback) {
|
||||||
|
final WeakReference<WifiNanManager> nanManager = new WeakReference<WifiNanManager>(mgr);
|
||||||
|
|
||||||
if (VDBG) Log.v(TAG, "WifiNanEventCallbackProxy ctor: looper=" + looper);
|
if (VDBG) Log.v(TAG, "WifiNanEventCallbackProxy ctor: looper=" + looper);
|
||||||
mHandler = new Handler(looper) {
|
mHandler = new Handler(looper) {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
|
if (DBG) {
|
||||||
|
Log.d(TAG, "WifiNanEventCallbackProxy: What=" + msg.what + ", msg=" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiNanManager mgr = nanManager.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "WifiNanEventCallbackProxy: handleMessage post GC");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case CALLBACK_CONFIG_COMPLETED:
|
case CALLBACK_CONNECT_SUCCESS:
|
||||||
mOriginalCallback.onConfigCompleted((ConfigRequest) msg.obj);
|
synchronized (mgr.mLock) {
|
||||||
|
if (mgr.mState != STATE_CONNECTING) {
|
||||||
|
Log.w(TAG, "onConnectSuccess indication received but not in "
|
||||||
|
+ "CONNECTING state. Ignoring.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mgr.mState = STATE_CONNECTED;
|
||||||
|
}
|
||||||
|
originalCallback.onConnectSuccess();
|
||||||
break;
|
break;
|
||||||
case CALLBACK_CONFIG_FAILED:
|
case CALLBACK_CONNECT_FAIL:
|
||||||
mOriginalCallback.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
|
synchronized (mgr.mLock) {
|
||||||
|
if (mgr.mState != STATE_CONNECTING) {
|
||||||
|
Log.w(TAG, "onConnectFail indication received but not in "
|
||||||
|
+ "CONNECTING state. Ignoring.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr.mState = STATE_UNCONNECTED;
|
||||||
|
mgr.mBinder = null;
|
||||||
|
mgr.mLooper = null;
|
||||||
|
mgr.mClientId = 0;
|
||||||
|
}
|
||||||
|
nanManager.clear();
|
||||||
|
originalCallback.onConnectFail(msg.arg1);
|
||||||
break;
|
break;
|
||||||
case CALLBACK_NAN_DOWN:
|
case CALLBACK_NAN_DOWN:
|
||||||
mOriginalCallback.onNanDown(msg.arg1);
|
synchronized (mgr.mLock) {
|
||||||
|
mgr.mState = STATE_UNCONNECTED;
|
||||||
|
mgr.mBinder = null;
|
||||||
|
mgr.mLooper = null;
|
||||||
|
mgr.mClientId = 0;
|
||||||
|
}
|
||||||
|
nanManager.clear();
|
||||||
|
originalCallback.onNanDown(msg.arg1);
|
||||||
break;
|
break;
|
||||||
case CALLBACK_IDENTITY_CHANGED:
|
case CALLBACK_IDENTITY_CHANGED:
|
||||||
mOriginalCallback.onIdentityChanged();
|
originalCallback.onIdentityChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,24 +427,19 @@ public class WifiNanManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigCompleted(ConfigRequest completedConfig) {
|
public void onConnectSuccess() {
|
||||||
if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
|
if (VDBG) Log.v(TAG, "onConnectSuccess");
|
||||||
|
|
||||||
Message msg = mHandler.obtainMessage(CALLBACK_CONFIG_COMPLETED);
|
Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_SUCCESS);
|
||||||
msg.obj = completedConfig;
|
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigFailed(ConfigRequest failedConfig, int reason) {
|
public void onConnectFail(int reason) {
|
||||||
if (VDBG) {
|
if (VDBG) Log.v(TAG, "onConfigFailed: reason=" + reason);
|
||||||
Log.v(TAG,
|
|
||||||
"onConfigFailed: failedConfig=" + failedConfig + ", reason=" + reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
Message msg = mHandler.obtainMessage(CALLBACK_CONFIG_FAILED);
|
Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_FAIL);
|
||||||
msg.arg1 = reason;
|
msg.arg1 = reason;
|
||||||
msg.obj = failedConfig;
|
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,27 +461,30 @@ public class WifiNanManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WifiNanSessionCallbackProxy extends IWifiNanSessionCallback.Stub {
|
private static class WifiNanSessionCallbackProxy extends IWifiNanSessionCallback.Stub {
|
||||||
private static final int CALLBACK_SESSION_STARTED = 0;
|
private static final int CALLBACK_SESSION_STARTED = 0;
|
||||||
private static final int CALLBACK_SESSION_CONFIG_FAIL = 1;
|
private static final int CALLBACK_SESSION_CONFIG_SUCCESS = 1;
|
||||||
private static final int CALLBACK_SESSION_TERMINATED = 2;
|
private static final int CALLBACK_SESSION_CONFIG_FAIL = 2;
|
||||||
private static final int CALLBACK_MATCH = 3;
|
private static final int CALLBACK_SESSION_TERMINATED = 3;
|
||||||
private static final int CALLBACK_MESSAGE_SEND_SUCCESS = 4;
|
private static final int CALLBACK_MATCH = 4;
|
||||||
private static final int CALLBACK_MESSAGE_SEND_FAIL = 5;
|
private static final int CALLBACK_MESSAGE_SEND_SUCCESS = 5;
|
||||||
private static final int CALLBACK_MESSAGE_RECEIVED = 6;
|
private static final int CALLBACK_MESSAGE_SEND_FAIL = 6;
|
||||||
|
private static final int CALLBACK_MESSAGE_RECEIVED = 7;
|
||||||
|
|
||||||
private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id";
|
private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id";
|
||||||
private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
|
private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
|
||||||
private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
|
private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
|
||||||
|
|
||||||
|
private final WeakReference<WifiNanManager> mNanManager;
|
||||||
private final boolean mIsPublish;
|
private final boolean mIsPublish;
|
||||||
private final WifiNanSessionCallback mOriginalCallback;
|
private final WifiNanSessionCallback mOriginalCallback;
|
||||||
|
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
private WifiNanSession mSession;
|
private WifiNanSession mSession;
|
||||||
|
|
||||||
WifiNanSessionCallbackProxy(Looper looper, boolean isPublish,
|
WifiNanSessionCallbackProxy(WifiNanManager mgr, Looper looper, boolean isPublish,
|
||||||
WifiNanSessionCallback originalCallback) {
|
WifiNanSessionCallback originalCallback) {
|
||||||
|
mNanManager = new WeakReference<>(mgr);
|
||||||
mIsPublish = isPublish;
|
mIsPublish = isPublish;
|
||||||
mOriginalCallback = originalCallback;
|
mOriginalCallback = originalCallback;
|
||||||
|
|
||||||
@@ -429,12 +494,28 @@ public class WifiNanManager {
|
|||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
|
if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
|
||||||
|
|
||||||
|
if (mNanManager.get() == null) {
|
||||||
|
Log.w(TAG, "WifiNanSessionCallbackProxy: handleMessage post GC");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case CALLBACK_SESSION_STARTED:
|
case CALLBACK_SESSION_STARTED:
|
||||||
onProxySessionStarted(msg.arg1);
|
onProxySessionStarted(msg.arg1);
|
||||||
break;
|
break;
|
||||||
|
case CALLBACK_SESSION_CONFIG_SUCCESS:
|
||||||
|
mOriginalCallback.onSessionConfigSuccess();
|
||||||
|
break;
|
||||||
case CALLBACK_SESSION_CONFIG_FAIL:
|
case CALLBACK_SESSION_CONFIG_FAIL:
|
||||||
onProxySessionConfigFail(msg.arg1);
|
mOriginalCallback.onSessionConfigFail(msg.arg1);
|
||||||
|
if (mSession == null) {
|
||||||
|
/*
|
||||||
|
* creation failed (as opposed to update
|
||||||
|
* failing)
|
||||||
|
*/
|
||||||
|
mNanManager.clear();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CALLBACK_SESSION_TERMINATED:
|
case CALLBACK_SESSION_TERMINATED:
|
||||||
onProxySessionTerminated(msg.arg1);
|
onProxySessionTerminated(msg.arg1);
|
||||||
@@ -472,6 +553,14 @@ public class WifiNanManager {
|
|||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSessionConfigSuccess() {
|
||||||
|
if (VDBG) Log.v(TAG, "onSessionConfigSuccess");
|
||||||
|
|
||||||
|
Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_SUCCESS);
|
||||||
|
mHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSessionConfigFail(int reason) {
|
public void onSessionConfigFail(int reason) {
|
||||||
if (VDBG) Log.v(TAG, "onSessionConfigFail: reason=" + reason);
|
if (VDBG) Log.v(TAG, "onSessionConfigFail: reason=" + reason);
|
||||||
@@ -554,32 +643,34 @@ public class WifiNanManager {
|
|||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"onSessionStarted: sessionId=" + sessionId + ": session already created!?");
|
"onSessionStarted: sessionId=" + sessionId + ": session already created!?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WifiNanManager mgr = mNanManager.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "onProxySessionStarted: mgr GC'd");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mIsPublish) {
|
if (mIsPublish) {
|
||||||
WifiNanPublishSession session = new WifiNanPublishSession(WifiNanManager.this,
|
WifiNanPublishSession session = new WifiNanPublishSession(mgr, sessionId);
|
||||||
sessionId, mOriginalCallback);
|
|
||||||
mSession = session;
|
mSession = session;
|
||||||
mOriginalCallback.onPublishStarted(session);
|
mOriginalCallback.onPublishStarted(session);
|
||||||
} else {
|
} else {
|
||||||
WifiNanSubscribeSession session = new WifiNanSubscribeSession(WifiNanManager.this,
|
WifiNanSubscribeSession session = new WifiNanSubscribeSession(mgr, sessionId);
|
||||||
sessionId, mOriginalCallback);
|
|
||||||
mSession = session;
|
mSession = session;
|
||||||
mOriginalCallback.onSubscribeStarted(session);
|
mOriginalCallback.onSubscribeStarted(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onProxySessionConfigFail(int reason) {
|
|
||||||
if (VDBG) Log.v(TAG, "Proxy: onSessionConfigFail: reason=" + reason);
|
|
||||||
mOriginalCallback.onSessionConfigFail(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onProxySessionTerminated(int reason) {
|
public void onProxySessionTerminated(int reason) {
|
||||||
if (VDBG) Log.v(TAG, "Proxy: onSessionTerminated: reason=" + reason);
|
if (VDBG) Log.v(TAG, "Proxy: onSessionTerminated: reason=" + reason);
|
||||||
mOriginalCallback.onSessionTerminated(reason);
|
|
||||||
if (mSession != null) {
|
if (mSession != null) {
|
||||||
mSession.terminate();
|
mSession.setTerminated();
|
||||||
|
mSession = null;
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
|
Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
|
||||||
}
|
}
|
||||||
|
mNanManager.clear();
|
||||||
|
mOriginalCallback.onSessionTerminated(reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.net.wifi.nan;
|
package android.net.wifi.nan;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a NAN publish session. Created when
|
* A representation of a NAN publish session. Created when
|
||||||
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} is
|
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} is
|
||||||
@@ -25,12 +27,13 @@ package android.net.wifi.nan;
|
|||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
public class WifiNanPublishSession extends WifiNanSession {
|
public class WifiNanPublishSession extends WifiNanSession {
|
||||||
|
private static final String TAG = "WifiNanPublishSession";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public WifiNanPublishSession(WifiNanManager manager, int sessionId,
|
public WifiNanPublishSession(WifiNanManager manager, int sessionId) {
|
||||||
WifiNanSessionCallback callback) {
|
super(manager, sessionId);
|
||||||
super(manager, sessionId, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,10 +46,16 @@ public class WifiNanPublishSession extends WifiNanSession {
|
|||||||
*/
|
*/
|
||||||
public void updatePublish(PublishConfig publishConfig) {
|
public void updatePublish(PublishConfig publishConfig) {
|
||||||
if (mTerminated) {
|
if (mTerminated) {
|
||||||
mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
|
Log.w(TAG, "updatePublish: called on terminated session");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
mManager.updatePublish(mSessionId, publishConfig);
|
WifiNanManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "updatePublish: called post GC on WifiNanManager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr.updatePublish(mSessionId, publishConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package android.net.wifi.nan;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a single publish or subscribe NAN session. This object
|
* A representation of a single publish or subscribe NAN session. This object
|
||||||
* will not be created directly - only its child classes are available:
|
* will not be created directly - only its child classes are available:
|
||||||
@@ -30,22 +32,29 @@ public class WifiNanSession {
|
|||||||
private static final boolean DBG = false;
|
private static final boolean DBG = false;
|
||||||
private static final boolean VDBG = false; // STOPSHIP if true
|
private static final boolean VDBG = false; // STOPSHIP if true
|
||||||
|
|
||||||
protected WifiNanManager mManager;
|
/**
|
||||||
protected final int mSessionId;
|
* @hide
|
||||||
protected final WifiNanSessionCallback mCallback;
|
*/
|
||||||
|
protected WeakReference<WifiNanManager> mMgr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
protected final int mSessionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
protected boolean mTerminated = false;
|
protected boolean mTerminated = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public WifiNanSession(WifiNanManager manager, int sessionId,
|
public WifiNanSession(WifiNanManager manager, int sessionId) {
|
||||||
WifiNanSessionCallback callback) {
|
|
||||||
if (VDBG) Log.v(TAG, "New client created: manager=" + manager + ", sessionId=" + sessionId);
|
if (VDBG) Log.v(TAG, "New client created: manager=" + manager + ", sessionId=" + sessionId);
|
||||||
|
|
||||||
mManager = manager;
|
mMgr = new WeakReference<>(manager);
|
||||||
mSessionId = sessionId;
|
mSessionId = sessionId;
|
||||||
mCallback = callback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,9 +64,29 @@ public class WifiNanSession {
|
|||||||
* additional operations are termination.
|
* additional operations are termination.
|
||||||
*/
|
*/
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
mManager.terminateSession(mSessionId);
|
WifiNanManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "terminate: called post GC on WifiNanManager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mgr.terminateSession(mSessionId);
|
||||||
mTerminated = true;
|
mTerminated = true;
|
||||||
mManager = null;
|
mMgr.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of the session to terminated - i.e. an indication that
|
||||||
|
* already terminated rather than executing a termination.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setTerminated() {
|
||||||
|
if (mTerminated) {
|
||||||
|
Log.w(TAG, "terminate: already terminated.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mTerminated = true;
|
||||||
|
mMgr.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -66,8 +95,8 @@ public class WifiNanSession {
|
|||||||
Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId
|
Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId
|
||||||
+ " was not explicitly terminated. The session may use resources until "
|
+ " was not explicitly terminated. The session may use resources until "
|
||||||
+ "terminated so step should be done explicitly");
|
+ "terminated so step should be done explicitly");
|
||||||
|
terminate();
|
||||||
}
|
}
|
||||||
terminate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,11 +118,16 @@ public class WifiNanSession {
|
|||||||
*/
|
*/
|
||||||
public void sendMessage(int peerId, byte[] message, int messageLength, int messageId) {
|
public void sendMessage(int peerId, byte[] message, int messageLength, int messageId) {
|
||||||
if (mTerminated) {
|
if (mTerminated) {
|
||||||
mCallback.onMessageSendFail(messageId,
|
Log.w(TAG, "sendMessage: called on terminated session");
|
||||||
WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
|
WifiNanManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "sendMessage: called post GC on WifiNanManager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mManager.sendMessage(mSessionId, peerId, message, messageLength, messageId);
|
mgr.sendMessage(mSessionId, peerId, message, messageLength, messageId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,57 +16,70 @@
|
|||||||
|
|
||||||
package android.net.wifi.nan;
|
package android.net.wifi.nan;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for NAN session events callbacks. Should be extended by
|
* Base class for NAN session events callbacks. Should be extended by
|
||||||
* applications wanting notifications. The callbacks are registered when a
|
* applications wanting notifications. The callbacks are registered when a
|
||||||
* publish or subscribe session is created using
|
* publish or subscribe session is created using
|
||||||
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} or
|
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} or
|
||||||
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} .
|
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} .
|
||||||
* These are callbacks applying to a specific NAN session. Events corresponding
|
* These are callbacks applying to a specific NAN session.
|
||||||
* to the NAN link are delivered using {@link WifiNanEventCallback}.
|
|
||||||
* <p>
|
* <p>
|
||||||
* A single callback is registered at session creation - it cannot be replaced.
|
* A single callback is registered at session creation - it cannot be replaced.
|
||||||
*
|
*
|
||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
public class WifiNanSessionCallback {
|
public class WifiNanSessionCallback {
|
||||||
/**
|
@IntDef({
|
||||||
* Failure reason flag for {@link WifiNanEventCallback} and
|
REASON_NO_RESOURCES, REASON_INVALID_ARGS, REASON_NO_MATCH_SESSION,
|
||||||
* {@link WifiNanSessionCallback} callbacks. Indicates no resources to
|
REASON_TX_FAIL, REASON_OTHER })
|
||||||
* execute the requested operation.
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
*/
|
public @interface SessionReasonCodes {
|
||||||
public static final int FAIL_REASON_NO_RESOURCES = 0;
|
}
|
||||||
|
|
||||||
/**
|
@IntDef({
|
||||||
* Failure reason flag for {@link WifiNanEventCallback} and
|
TERMINATE_REASON_DONE, TERMINATE_REASON_FAIL })
|
||||||
* {@link WifiNanSessionCallback} callbacks. Indicates invalid argument in
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
* the requested operation.
|
public @interface SessionTerminateCodes {
|
||||||
*/
|
}
|
||||||
public static final int FAIL_REASON_INVALID_ARGS = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Failure reason flag for {@link WifiNanEventCallback} and
|
|
||||||
* {@link WifiNanSessionCallback} callbacks. Indicates a message is
|
|
||||||
* transmitted without a match (i.e. a discovery) occurring first.
|
|
||||||
*/
|
|
||||||
public static final int FAIL_REASON_NO_MATCH_SESSION = 2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
|
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
|
||||||
* Indicates that a command has been issued to a session which is
|
* Indicates no resources to execute the requested operation.
|
||||||
* terminated. Session termination may have been caused explicitly by the
|
|
||||||
* user using the {@code WifiNanSession#terminate()} or implicitly as a
|
|
||||||
* result of the original session reaching its lifetime or being terminated
|
|
||||||
* due to an error.
|
|
||||||
*/
|
*/
|
||||||
public static final int FAIL_REASON_SESSION_TERMINATED = 3;
|
public static final int REASON_NO_RESOURCES = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Failure reason flag for {@link WifiNanEventCallback} and
|
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
|
||||||
* {@link WifiNanSessionCallback} callbacks. Indicates an unspecified error
|
* Indicates invalid argument in the requested operation.
|
||||||
* occurred during the operation.
|
|
||||||
*/
|
*/
|
||||||
public static final int FAIL_REASON_OTHER = 4;
|
public static final int REASON_INVALID_ARGS = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
|
||||||
|
* Indicates a message is transmitted without a match (i.e. a discovery)
|
||||||
|
* occurring first.
|
||||||
|
*/
|
||||||
|
public static final int REASON_NO_MATCH_SESSION = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failure reason flag for
|
||||||
|
* {@link WifiNanSessionCallback#onMessageSendFail(int, int)} callback.
|
||||||
|
* Indicates transmission failure: this may be due to local transmission
|
||||||
|
* failure or to no ACK received - i.e. remote device didn't receive the
|
||||||
|
* sent message.
|
||||||
|
*/
|
||||||
|
public static final int REASON_TX_FAIL = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
|
||||||
|
* Indicates an unspecified error occurred during the operation.
|
||||||
|
*/
|
||||||
|
public static final int REASON_OTHER = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Failure reason flag for
|
* Failure reason flag for
|
||||||
@@ -75,7 +88,7 @@ public class WifiNanSessionCallback {
|
|||||||
* requested operations (per {@link PublishConfig} or
|
* requested operations (per {@link PublishConfig} or
|
||||||
* {@link SubscribeConfig}) have been executed.
|
* {@link SubscribeConfig}) have been executed.
|
||||||
*/
|
*/
|
||||||
public static final int TERMINATE_REASON_DONE = 0;
|
public static final int TERMINATE_REASON_DONE = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Failure reason flag for
|
* Failure reason flag for
|
||||||
@@ -83,7 +96,7 @@ public class WifiNanSessionCallback {
|
|||||||
* Indicates that publish or subscribe session is terminated due to a
|
* Indicates that publish or subscribe session is terminated due to a
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
public static final int TERMINATE_REASON_FAIL = 1;
|
public static final int TERMINATE_REASON_FAIL = 101;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a publish operation is started successfully.
|
* Called when a publish operation is started successfully.
|
||||||
@@ -105,15 +118,22 @@ public class WifiNanSessionCallback {
|
|||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a session update configuration (publish or subscribe update)
|
||||||
|
* succeeds.
|
||||||
|
*/
|
||||||
|
public void onSessionConfigSuccess() {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a session configuration (publish or subscribe setup or
|
* Called when a session configuration (publish or subscribe setup or
|
||||||
* update) fails.
|
* update) fails.
|
||||||
*
|
*
|
||||||
* @param reason The failure reason using
|
* @param reason The failure reason using
|
||||||
* {@code WifiNanSessionCallback.FAIL_*} codes.
|
* {@code WifiNanSessionCallback.REASON_*} codes.
|
||||||
*/
|
*/
|
||||||
public void onSessionConfigFail(int reason) {
|
public void onSessionConfigFail(@SessionReasonCodes int reason) {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +143,7 @@ public class WifiNanSessionCallback {
|
|||||||
* @param reason The termination reason using
|
* @param reason The termination reason using
|
||||||
* {@code WifiNanSessionCallback.TERMINATE_*} codes.
|
* {@code WifiNanSessionCallback.TERMINATE_*} codes.
|
||||||
*/
|
*/
|
||||||
public void onSessionTerminated(int reason) {
|
public void onSessionTerminated(@SessionTerminateCodes int reason) {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,9 +191,10 @@ public class WifiNanSessionCallback {
|
|||||||
* - never both
|
* - never both
|
||||||
*
|
*
|
||||||
* @param reason The failure reason using
|
* @param reason The failure reason using
|
||||||
* {@code WifiNanSessionCallback.FAIL_*} codes.
|
* {@code WifiNanSessionCallback.REASON_*} codes.
|
||||||
*/
|
*/
|
||||||
public void onMessageSendFail(@SuppressWarnings("unused") int messageId, int reason) {
|
public void onMessageSendFail(@SuppressWarnings("unused") int messageId,
|
||||||
|
@SessionReasonCodes int reason) {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.net.wifi.nan;
|
package android.net.wifi.nan;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a NAN subscribe session. Created when
|
* A representation of a NAN subscribe session. Created when
|
||||||
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} is
|
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} is
|
||||||
@@ -25,12 +27,13 @@ package android.net.wifi.nan;
|
|||||||
* @hide PROPOSED_NAN_API
|
* @hide PROPOSED_NAN_API
|
||||||
*/
|
*/
|
||||||
public class WifiNanSubscribeSession extends WifiNanSession {
|
public class WifiNanSubscribeSession extends WifiNanSession {
|
||||||
|
private static final String TAG = "WifiNanSubscribeSession";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public WifiNanSubscribeSession(WifiNanManager manager, int sessionId,
|
public WifiNanSubscribeSession(WifiNanManager manager, int sessionId) {
|
||||||
WifiNanSessionCallback callback) {
|
super(manager, sessionId);
|
||||||
super(manager, sessionId, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,10 +46,16 @@ public class WifiNanSubscribeSession extends WifiNanSession {
|
|||||||
*/
|
*/
|
||||||
public void updateSubscribe(SubscribeConfig subscribeConfig) {
|
public void updateSubscribe(SubscribeConfig subscribeConfig) {
|
||||||
if (mTerminated) {
|
if (mTerminated) {
|
||||||
mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
|
Log.w(TAG, "updateSubscribe: called on terminated session");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
mManager.updateSubscribe(mSessionId, subscribeConfig);
|
WifiNanManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "updateSubscribe: called post GC on WifiNanManager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr.updateSubscribe(mSessionId, subscribeConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user