package android.net.wifi.nan;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Defines a request object to configure a Wi-Fi NAN network. Built using
* {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiNanManager#attach(android.os.Handler, WifiNanEventCallback)}.
+ * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)}.
* Note that the actual achieved configuration may be different from the
* requested configuration - since different applications may request different
* configurations.
*
- * @hide PROPOSED_NAN_API
+ * @hide
*/
public final class ConfigRequest implements Parcelable {
/**
* Lower range of possible cluster ID.
- *
- * @hide
*/
public static final int CLUSTER_ID_MIN = 0;
/**
* Upper range of possible cluster ID.
- *
- * @hide
*/
public static final int CLUSTER_ID_MAX = 0xFFFF;
/**
* Indicates whether 5G band support is requested.
- *
- * @hide
*/
public final boolean mSupport5gBand;
/**
* Specifies the desired master preference.
- *
- * @hide
*/
public final int mMasterPreference;
/**
* Specifies the desired lower range of the cluster ID. Must be lower then
* {@link ConfigRequest#mClusterHigh}.
- *
- * @hide
*/
public final int mClusterLow;
/**
* Specifies the desired higher range of the cluster ID. Must be higher then
* {@link ConfigRequest#mClusterLow}.
- *
- * @hide
*/
public final int mClusterHigh;
- /**
- * Indicates whether we want to get callbacks when our identity is changed.
- *
- * @hide
- */
- public final boolean mEnableIdentityChangeCallback;
-
private ConfigRequest(boolean support5gBand, int masterPreference, int clusterLow,
- int clusterHigh, boolean enableIdentityChangeCallback) {
+ int clusterHigh) {
mSupport5gBand = support5gBand;
mMasterPreference = masterPreference;
mClusterLow = clusterLow;
mClusterHigh = clusterHigh;
- mEnableIdentityChangeCallback = enableIdentityChangeCallback;
}
@Override
public String toString() {
return "ConfigRequest [mSupport5gBand=" + mSupport5gBand + ", mMasterPreference="
+ mMasterPreference + ", mClusterLow=" + mClusterLow + ", mClusterHigh="
- + mClusterHigh + ", mEnableIdentityChangeCallback=" + mEnableIdentityChangeCallback
- + "]";
+ + mClusterHigh + "]";
}
@Override
dest.writeInt(mMasterPreference);
dest.writeInt(mClusterLow);
dest.writeInt(mClusterHigh);
- dest.writeInt(mEnableIdentityChangeCallback ? 1 : 0);
}
public static final Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
int masterPreference = in.readInt();
int clusterLow = in.readInt();
int clusterHigh = in.readInt();
- boolean enableIdentityChangeCallback = in.readInt() != 0;
- return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh,
- enableIdentityChangeCallback);
+ return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh);
}
};
ConfigRequest lhs = (ConfigRequest) o;
return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference
- && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
- && 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;
}
/**
- * Checks whether the configuration's settings which impact on-air behavior are non-default.
- *
- * @return true if any of the on-air-impacting settings are non-default.
+ * Checks whether the configuration's settings are non-default.
*
- * @hide
+ * @return true if any of the settings are non-default.
*/
- public boolean isNonDefaultOnTheAir() {
+ public boolean isNonDefault() {
return mSupport5gBand || mMasterPreference != 0 || mClusterLow != CLUSTER_ID_MIN
|| mClusterHigh != CLUSTER_ID_MAX;
}
result = 31 * result + mMasterPreference;
result = 31 * result + mClusterLow;
result = 31 * result + mClusterHigh;
- result = 31 * result + (mEnableIdentityChangeCallback ? 1 : 0);
return result;
}
/**
* Verifies that the contents of the ConfigRequest are valid. Otherwise
* throws an IllegalArgumentException.
- *
- * @hide
*/
public void validate() throws IllegalArgumentException {
if (mMasterPreference < 0) {
private int mMasterPreference = 0;
private int mClusterLow = CLUSTER_ID_MIN;
private int mClusterHigh = CLUSTER_ID_MAX;
- private boolean mEnableIdentityChangeCallback = false;
/**
* Specify whether 5G band support is required in this request. Disabled by default.
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
- *
- * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setSupport5gBand(boolean support5gBand) {
mSupport5gBand = support5gBand;
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
- *
- * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setMasterPreference(int masterPreference) {
if (masterPreference < 0) {
*
* @return The builder to facilitate chaining
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
- *
- * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setClusterLow(int clusterLow) {
if (clusterLow < CLUSTER_ID_MIN) {
*
* @return The builder to facilitate chaining
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
- *
- * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setClusterHigh(int clusterHigh) {
if (clusterHigh < CLUSTER_ID_MIN) {
}
/**
- * Indicate whether or not we want to enable the
- * {@link WifiNanEventCallback#onIdentityChanged(byte[])} callback. A
- * device identity is its Discovery MAC address which is randomized at regular intervals.
- * An application may need to know the MAC address, e.g. when using OOB (out-of-band)
- * discovery together with NAN connections.
- * <p>
- * The callbacks are disabled by default since it may result in additional wake-ups
- * of the host -
- * increasing power.
- *
- * @param enableIdentityChangeCallback Enable the callback informing
- * listener when identity is changed.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setEnableIdentityChangeCallback(boolean enableIdentityChangeCallback) {
- mEnableIdentityChangeCallback = enableIdentityChangeCallback;
- return this;
- }
-
- /**
* Build {@link ConfigRequest} given the current requests made on the
* builder.
*/
"Invalid argument combination - must have Cluster Low <= Cluster High");
}
- return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh,
- mEnableIdentityChangeCallback);
+ return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh);
}
}
}
// client API
void connect(in IBinder binder, in String callingPackage, in IWifiNanEventCallback callback,
- in ConfigRequest configRequest);
+ in ConfigRequest configRequest, boolean notifyOnIdentityChanged);
void disconnect(int clientId, in IBinder binder);
void publish(int clientId, in PublishConfig publishConfig,
import java.lang.annotation.RetentionPolicy;
/**
- * Base class for NAN events callbacks. Should be extended by applications and set when calling
- * {@link WifiNanManager#attach(android.os.Handler, WifiNanEventCallback)}. These are callbacks
+ * Base class for NAN attach callbacks. Should be extended by applications and set when calling
+ * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)}. These are callbacks
* applying to the NAN connection as a whole - not to specific publish or subscribe sessions -
* for that see {@link WifiNanDiscoverySessionCallback}.
*
* @hide PROPOSED_NAN_API
*/
-public class WifiNanEventCallback {
+public class WifiNanAttachCallback {
/** @hide */
@IntDef({
REASON_INVALID_ARGS, REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG, REASON_OTHER
/**
* Indicates invalid argument in the requested operation. Failure reason flag for
- * {@link WifiNanEventCallback#onAttachFailed(int)}.
+ * {@link WifiNanAttachCallback#onAttachFailed(int)}.
*/
public static final int REASON_INVALID_ARGS = 1000;
/**
* Indicates that a {@link ConfigRequest} passed in
- * {@link WifiNanManager#attach(android.os.Handler, ConfigRequest, WifiNanEventCallback)}
+ * {@code WifiNanManager#attach(android.os.Handler, ConfigRequest, WifiNanAttachCallback)}
* couldn't be applied since other connections already exist with an incompatible
- * configurations. Failure reason flag for {@link WifiNanEventCallback#onAttachFailed(int)}.
+ * configurations. Failure reason flag for {@link WifiNanAttachCallback#onAttachFailed(int)}.
*/
public static final int REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG = 1001;
/**
* Indicates an unspecified error occurred during the operation. Failure reason flag for
- * {@link WifiNanEventCallback#onAttachFailed(int)}.
+ * {@link WifiNanAttachCallback#onAttachFailed(int)}.
*/
public static final int REASON_OTHER = 1002;
/**
* Called when NAN attach operation
- * {@link WifiNanManager#attach(android.os.Handler, WifiNanEventCallback)}
+ * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)}
* is completed and that we can now start discovery sessions or connections.
*
* @param session The NAN object on which we can execute further NAN operations - e.g.
/**
* Called when NAN attach operation
- * {@link WifiNanManager#attach(android.os.Handler, WifiNanEventCallback)} failed.
+ * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)} failed.
*
* @param reason Failure reason code, see
* {@code WifiNanEventCallback.REASON_*}.
public void onAttachFailed(@EventReasonCodes int reason) {
/* empty */
}
-
- /**
- * Called when NAN identity (the MAC address representing our NAN discovery interface) has
- * changed. Change may be due to device joining a cluster, starting a cluster, or discovery
- * interface change (addresses are randomized at regular intervals). The implication is that
- * peers you've been communicating with may no longer recognize you and you need to
- * re-establish your identity - e.g. by starting a discovery session. This actual MAC address
- * of the interface may also be useful if the application uses alternative (non-NAN)
- * discovery but needs to set up a NAN connection. The provided NAN discovery interface MAC
- * address can then be used in
- * {@link WifiNanSession#createNetworkSpecifier(int, byte[], byte[])}.
- * <p>
- * This callback is only called if the NAN connection enables it using
- * {@link ConfigRequest.Builder#setEnableIdentityChangeCallback(boolean)} in
- * {@link WifiNanManager#attach(android.os.Handler, ConfigRequest, WifiNanEventCallback)}
- * . It is disabled by default since it may result in additional wake-ups of the host -
- * increasing power.
- *
- * @param mac The MAC address of the NAN discovery interface. The application must have the
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to get the actual MAC address,
- * otherwise all 0's will be provided.
- */
- public void onIdentityChanged(byte[] mac) {
- /* empty */
- }
}
--- /dev/null
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+/**
+ * Base class for a listener which is called with the MAC address of the NAN interface whenever
+ * it is changed. Change may be due to device joining a cluster, starting a cluster, or discovery
+ * interface change (addresses are randomized at regular intervals). The implication is that
+ * peers you've been communicating with may no longer recognize you and you need to re-establish
+ * your identity - e.g. by starting a discovery session. This actual MAC address of the
+ * interface may also be useful if the application uses alternative (non-NAN) discovery but needs
+ * to set up a NAN connection. The provided NAN discovery interface MAC address can then be used
+ * in {@link WifiNanSession#createNetworkSpecifier(int, byte[], byte[])}.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanIdentityChangedListener {
+ /**
+ * @param mac The MAC address of the NAN discovery interface. The application must have the
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to get the actual MAC address,
+ * otherwise all 0's will be provided.
+ */
+ public void onIdentityChanged(byte[] mac) {
+ /* empty */
+ }
+}
* The class provides access to:
* <ul>
* <li>Initialize a NAN cluster (peer-to-peer synchronization). Refer to
- * {@link #attach(Handler, WifiNanEventCallback)}. <li>Create discovery sessions (publish or
- * subscribe sessions). Refer to
+ * {@link #attach(Handler, WifiNanAttachCallback)}.
+ * <li>Create discovery sessions (publish or subscribe sessions). Refer to
* {@link WifiNanSession#publish(PublishConfig, WifiNanDiscoverySessionCallback)} and
- * {@link WifiNanSession#subscribe(SubscribeConfig, WifiNanDiscoverySessionCallback)}. <li>Create
- * a NAN network specifier to be used with
+ * {@link WifiNanSession#subscribe(SubscribeConfig, WifiNanDiscoverySessionCallback)}.
+ * <li>Create a NAN network specifier to be used with
* {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
* to set-up a NAN connection with a peer. Refer to
* {@link WifiNanDiscoveryBaseSession#createNetworkSpecifier(int, int, byte[])} and
* Note that this broadcast is not sticky - you should register for it and then check the
* above API to avoid a race condition.
* <p>
- * An application must use {@link #attach(Handler, WifiNanEventCallback)} to initialize a NAN
+ * An application must use {@link #attach(Handler, WifiNanAttachCallback)} to initialize a NAN
* cluster - before making any other NAN operation. NAN cluster membership is a device-wide
* operation - the API guarantees that the device is in a cluster or joins a NAN cluster (or
* starts one if none can be found). Information about attach success (or failure) are
- * returned in callbacks of {@link WifiNanEventCallback}. Proceed with NAN discovery or
+ * returned in callbacks of {@link WifiNanAttachCallback}. Proceed with NAN discovery or
* connection setup only after receiving confirmation that NAN attach succeeded -
- * {@link WifiNanEventCallback#onAttached(WifiNanSession)}. When an application is
+ * {@link WifiNanAttachCallback#onAttached(WifiNanSession)}. When an application is
* finished using NAN it <b>must</b> use the {@link WifiNanSession#destroy()} API
* to indicate to the NAN service that the device may detach from the NAN cluster. The
* device will actually disable NAN once the last application detaches.
}
/**
- * Attach to the Wi-Fi NAN service - enabling the application to create discovery session or
- * create connection to peers. The device will attach to an existing cluster if it can find
+ * Attach to the Wi-Fi NAN service - enabling the application to create discovery sessions or
+ * create connections to peers. The device will attach to an existing cluster if it can find
* one or create a new cluster (if it is the first to enable NAN in its vicinity). Results
- * (e.g. successful attach to a cluster) are provided to the {@code callback} object.
+ * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
* An application <b>must</b> call {@link WifiNanSession#destroy()} when done with the
* Wi-Fi NAN object.
* <p>
* Note: a NAN cluster is a shared resource - if the device is already attached to a cluster
- * than this function will simply indicate success immediately.
+ * then this function will simply indicate success immediately using the same {@code
+ * attachCallback}.
*
* @param handler The Handler on whose thread to execute all callbacks related to the
* attach request - including all sessions opened as part of this
* attach. If a null is provided then the application's main thread will be used.
- * @param callback A callback extended from {@link WifiNanEventCallback}.
+ * @param attachCallback A callback for attach events, extended from
+ * {@link WifiNanAttachCallback}.
*/
- public void attach(@Nullable Handler handler, @NonNull WifiNanEventCallback callback) {
- attach(handler, null, callback);
+ public void attach(@Nullable Handler handler, @NonNull WifiNanAttachCallback attachCallback) {
+ attach(handler, null, attachCallback, null);
}
/**
- * Attach to the Wi-Fi NAN service - enabling the application to create discovery session or
- * create connection to peers. The device will attach to an existing cluster if it can find
+ * Attach to the Wi-Fi NAN service - enabling the application to create discovery sessions or
+ * create connections to peers. The device will attach to an existing cluster if it can find
* one or create a new cluster (if it is the first to enable NAN in its vicinity). Results
- * (e.g. successful attach to a cluster) are provided to the {@code callback} object.
+ * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
* An application <b>must</b> call {@link WifiNanSession#destroy()} when done with the
- * Wi-Fi NAN object. Allows requesting a specific configuration using
- * {@link ConfigRequest}. If not necessary (default configuration should usually work) use
- * the {@link #attach(Handler, WifiNanEventCallback)} method instead.
+ * Wi-Fi NAN object.
* <p>
* Note: a NAN cluster is a shared resource - if the device is already attached to a cluster
- * than this function will simply indicate success immediately.
+ * then this function will simply indicate success immediately using the same {@code
+ * attachCallback}.
+ * <p>
+ * This version of the API attaches a listener to receive the MAC address of the NAN interface
+ * on startup and whenever it is updated (it is randomized at regular intervals for privacy).
+ * The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
+ * permission to execute this attach request. Otherwise, use the
+ * {@link #attach(Handler, WifiNanAttachCallback)} version. Note that aside from permission
+ * requirements this listener will wake up the host at regular intervals causing higher power
+ * consumption, do not use it unless the information is necessary (e.g. for OOB discovery).
*
* @param handler The Handler on whose thread to execute all callbacks related to the
* attach request - including all sessions opened as part of this
* attach. If a null is provided then the application's main thread will be used.
- * @param configRequest The requested NAN configuration.
- * @param callback A callback extended from {@link WifiNanEventCallback}.
+ * @param attachCallback A callback for attach events, extended from
+ * {@link WifiNanAttachCallback}.
+ * @param identityChangedListener A listener for changed identity.
*/
- public void attach(@Nullable Handler handler, @Nullable ConfigRequest configRequest,
- @NonNull WifiNanEventCallback callback) {
+ public void attach(@Nullable Handler handler, @NonNull WifiNanAttachCallback attachCallback,
+ @NonNull WifiNanIdentityChangedListener identityChangedListener) {
+ attach(handler, null, attachCallback, identityChangedListener);
+ }
+
+ /** @hide */
+ public void attach(Handler handler, ConfigRequest configRequest,
+ WifiNanAttachCallback attachCallback,
+ WifiNanIdentityChangedListener identityChangedListener) {
if (VDBG) {
- Log.v(TAG,
- "attach(): handler=" + handler + ", callback=" + callback + ", configRequest="
- + configRequest);
+ Log.v(TAG, "attach(): handler=" + handler + ", callback=" + attachCallback
+ + ", configRequest=" + configRequest + ", identityChangedListener="
+ + identityChangedListener);
}
synchronized (mLock) {
try {
Binder binder = new Binder();
mService.connect(binder, mContext.getOpPackageName(),
- new WifiNanEventCallbackProxy(this, looper, binder, callback),
- configRequest);
+ new WifiNanEventCallbackProxy(this, looper, binder, attachCallback,
+ identityChangedListener), configRequest,
+ identityChangedListener != null);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
}
/**
- * Constructs a {@link WifiNanEventCallback} using the specified looper.
+ * Constructs a {@link WifiNanAttachCallback} using the specified looper.
* All callbacks will delivered on the thread of the specified looper.
*
* @param looper The looper on which to execute the callbacks.
*/
WifiNanEventCallbackProxy(WifiNanManager mgr, Looper looper, Binder binder,
- final WifiNanEventCallback originalCallback) {
+ final WifiNanAttachCallback attachCallback,
+ final WifiNanIdentityChangedListener identityChangedListener) {
mNanManager = new WeakReference<>(mgr);
mLooper = looper;
mBinder = binder;
switch (msg.what) {
case CALLBACK_CONNECT_SUCCESS:
- originalCallback.onAttached(
+ attachCallback.onAttached(
new WifiNanSession(mgr, mBinder, mLooper, msg.arg1));
break;
case CALLBACK_CONNECT_FAIL:
mNanManager.clear();
- originalCallback.onAttachFailed(msg.arg1);
+ attachCallback.onAttachFailed(msg.arg1);
break;
case CALLBACK_IDENTITY_CHANGED:
- originalCallback.onIdentityChanged((byte[]) msg.obj);
+ identityChangedListener.onIdentityChanged((byte[]) msg.obj);
break;
case CALLBACK_RANGING_SUCCESS: {
RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);