Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 231859c2 authored by Etan Cohen's avatar Etan Cohen Committed by Mitchell Wills
Browse files

[NAN] Refactor session lifecycle to clarify API & eliminate race conditions

(cherry-pick of 2a73c7fb)

Bug: 27257965
Change-Id: I4d7eaa6fa1f089bed2e9185f59a37f59b530975d
(cherry picked from commit 88a60495)
parent 564355af
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -36,12 +36,14 @@ interface IWifiNanManager
    void disconnect(int clientId, in IBinder binder);
    void disconnect(int clientId, in IBinder binder);
    void requestConfig(int clientId, in ConfigRequest configRequest);
    void requestConfig(int clientId, in ConfigRequest configRequest);


    void publish(int clientId, in PublishConfig publishConfig, in IWifiNanSessionCallback callback);
    void subscribe(int clientId, in SubscribeConfig subscribeConfig,
            in IWifiNanSessionCallback callback);

    // session API
    // session API
    int createSession(int clientId, in IWifiNanSessionCallback callback);
    void updatePublish(int clientId, int sessionId, in PublishConfig publishConfig);
    void publish(int clientId, int sessionId, in PublishConfig publishConfig);
    void updateSubscribe(int clientId, int sessionId, in SubscribeConfig subscribeConfig);
    void subscribe(int clientId, int sessionId, in SubscribeConfig subscribeConfig);
    void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength,
    void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength,
            int messageId);
            int messageId);
    void stopSession(int clientId, int sessionId);
    void terminateSession(int clientId, int sessionId);
    void destroySession(int clientId, int sessionId);
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ package android.net.wifi.nan;
 */
 */
oneway interface IWifiNanSessionCallback
oneway interface IWifiNanSessionCallback
{
{
    void onSessionStarted(int sessionId);
    void onSessionConfigFail(int reason);
    void onSessionConfigFail(int reason);
    void onSessionTerminated(int reason);
    void onSessionTerminated(int reason);


+9 −124
Original line number Original line Diff line number Diff line
@@ -16,11 +16,6 @@


package android.net.wifi.nan;
package android.net.wifi.nan;


import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

/**
/**
 * 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
@@ -30,65 +25,8 @@ import android.util.Log;
 * @hide PROPOSED_NAN_API
 * @hide PROPOSED_NAN_API
 */
 */
public class WifiNanEventCallback {
public class WifiNanEventCallback {
    private static final String TAG = "WifiNanEventCallback";
    private static final boolean DBG = false;
    private static final boolean VDBG = false; // STOPSHIP if true

    /** @hide */
    public static final int CALLBACK_CONFIG_COMPLETED = 0;
    /** @hide */
    public static final int CALLBACK_CONFIG_FAILED = 1;
    /** @hide */
    public static final int CALLBACK_NAN_DOWN = 2;
    /** @hide */
    public static final int CALLBACK_IDENTITY_CHANGED = 3;

    private final Handler mHandler;

    /**
    /**
     * Constructs a {@link WifiNanEventCallback} using the looper of the current
     * Called when NAN configuration is completed.
     * thread. I.e. all callbacks will be delivered on the current thread.
     */
    public WifiNanEventCallback() {
        this(Looper.myLooper());
    }

    /**
     * Constructs a {@link WifiNanEventCallback} using the specified looper.
     * I.e. all callbacks will delivered on the thread of the specified looper.
     *
     * @param looper The looper on which to execute the callbacks.
     */
    public WifiNanEventCallback(Looper looper) {
        if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
        mHandler = new Handler(looper) {
            @Override
            public void handleMessage(Message msg) {
                if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
                switch (msg.what) {
                    case CALLBACK_CONFIG_COMPLETED:
                        WifiNanEventCallback.this.onConfigCompleted((ConfigRequest) msg.obj);
                        break;
                    case CALLBACK_CONFIG_FAILED:
                        WifiNanEventCallback.this.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
                        break;
                    case CALLBACK_NAN_DOWN:
                        WifiNanEventCallback.this.onNanDown(msg.arg1);
                        break;
                    case CALLBACK_IDENTITY_CHANGED:
                        WifiNanEventCallback.this.onIdentityChanged();
                        break;
                }
            }
        };
    }

    /**
     * Called when NAN configuration is completed. Event will only be delivered
     * if registered using
     * {@link WifiNanEventCallback#CALLBACK_CONFIG_COMPLETED}. A dummy (empty
     * implementation printing out a warning). Make sure to override if
     * registered.
     *
     *
     * @param completedConfig The actual configuration request which was
     * @param completedConfig The actual configuration request which was
     *            completed. Note that it may be different from that requested
     *            completed. Note that it may be different from that requested
@@ -96,89 +34,36 @@ public class WifiNanEventCallback {
     *            requests from all applications.
     *            requests from all applications.
     */
     */
    public void onConfigCompleted(ConfigRequest completedConfig) {
    public void onConfigCompleted(ConfigRequest completedConfig) {
        Log.w(TAG, "onConfigCompleted: called in stub - override if interested or disable");
        /* empty */
    }
    }


    /**
    /**
     * Called when NAN configuration failed. Event will only be delivered if
     * Called when NAN configuration failed.
     * registered using {@link WifiNanEventCallback#CALLBACK_CONFIG_FAILED}. A
     * dummy (empty implementation printing out a warning). Make sure to
     * override if registered.
     *
     *
     * @param reason Failure reason code, see
     * @param reason Failure reason code, see
     *            {@code WifiNanSessionCallback.FAIL_*}.
     *            {@code WifiNanSessionCallback.FAIL_*}.
     */
     */
    public void onConfigFailed(ConfigRequest failedConfig, int reason) {
    public void onConfigFailed(@SuppressWarnings("unused") ConfigRequest failedConfig, int reason) {
        Log.w(TAG, "onConfigFailed: called in stub - override if interested or disable");
        /* empty */
    }
    }


    /**
    /**
     * Called when NAN cluster is down. Event will only be delivered if
     * Called when NAN cluster is down
     * registered using {@link WifiNanEventCallback#CALLBACK_NAN_DOWN}. A dummy
     * (empty implementation printing out a warning). Make sure to override if
     * registered.
     *
     *
     * @param reason Reason code for event, see
     * @param reason Reason code for event, see
     *            {@code WifiNanSessionCallback.FAIL_*}.
     *            {@code WifiNanSessionCallback.FAIL_*}.
     */
     */
    public void onNanDown(int reason) {
    public void onNanDown(int reason) {
        Log.w(TAG, "onNanDown: called in stub - override if interested or disable");
        /* empty */
    }
    }


    /**
    /**
     * Called when NAN identity has changed. This may be due to joining a
     * Called when NAN identity has changed. This may be due to joining a
     * cluster, starting a cluster, or discovery interface change. The
     * cluster, starting a cluster, or discovery interface change. The
     * implication is that peers you've been communicating with may no longer
     * implication is that peers you've been communicating with may no longer
     * recognize you and you need to re-establish your identity. Event will only
     * recognize you and you need to re-establish your identity.
     * be delivered if registered using
     * {@link WifiNanEventCallback#CALLBACK_IDENTITY_CHANGED}. A dummy (empty
     * implementation printing out a warning). Make sure to override if
     * registered.
     */
     */
    public void onIdentityChanged() {
    public void onIdentityChanged() {
        if (VDBG) Log.v(TAG, "onIdentityChanged: called in stub - override if interested");
        /* empty */
    }

    /**
     * {@hide}
     */
    public IWifiNanEventCallback callback = new IWifiNanEventCallback.Stub() {
        @Override
        public void onConfigCompleted(ConfigRequest completedConfig) {
            if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);

            Message msg = mHandler.obtainMessage(CALLBACK_CONFIG_COMPLETED);
            msg.obj = completedConfig;
            mHandler.sendMessage(msg);
        }

        @Override
        public void onConfigFailed(ConfigRequest failedConfig, int reason) {
            if (VDBG) {
                Log.v(TAG, "onConfigFailed: failedConfig=" + failedConfig + ", reason=" + reason);
            }

            Message msg = mHandler.obtainMessage(CALLBACK_CONFIG_FAILED);
            msg.arg1 = reason;
            msg.obj = failedConfig;
            mHandler.sendMessage(msg);
        }

        @Override
        public void onNanDown(int reason) {
            if (VDBG) Log.v(TAG, "onNanDown: reason=" + reason);

            Message msg = mHandler.obtainMessage(CALLBACK_NAN_DOWN);
            msg.arg1 = reason;
            mHandler.sendMessage(msg);
        }

        @Override
        public void onIdentityChanged() {
            if (VDBG) Log.v(TAG, "onIdentityChanged");

            Message msg = mHandler.obtainMessage(CALLBACK_IDENTITY_CHANGED);
            mHandler.sendMessage(msg);
    }
    }
    };
}
}
+348 −61

File changed.

Preview size limit exceeded, changes collapsed.

+12 −6
Original line number Original line Diff line number Diff line
@@ -18,7 +18,7 @@ package android.net.wifi.nan;


/**
/**
 * A representation of a NAN publish session. Created when
 * A representation of a NAN publish session. Created when
 * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback, int)} is
 * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} is
 * executed. The object can be used to stop and re-start (re-configure) the
 * executed. The object can be used to stop and re-start (re-configure) the
 * publish session.
 * publish session.
 *
 *
@@ -28,19 +28,25 @@ public class WifiNanPublishSession extends WifiNanSession {
    /**
    /**
     * {@hide}
     * {@hide}
     */
     */
    public WifiNanPublishSession(WifiNanManager manager, int sessionId) {
    public WifiNanPublishSession(WifiNanManager manager, int sessionId,
        super(manager, sessionId);
            WifiNanSessionCallback callback) {
        super(manager, sessionId, callback);
    }
    }


    /**
    /**
     * Restart/re-configure the publish session. Note that the
     * Re-configure the publish session. Note that the
     * {@link WifiNanSessionCallback} is not replaced - the same listener used
     * {@link WifiNanSessionCallback} is not replaced - the same listener used
     * at creation is still used.
     * at creation is still used.
     *
     *
     * @param publishConfig The configuration ({@link PublishConfig}) of the
     * @param publishConfig The configuration ({@link PublishConfig}) of the
     *            publish session.
     *            publish session.
     */
     */
    public void publish(PublishConfig publishConfig) {
    public void updatePublish(PublishConfig publishConfig) {
        mManager.publish(mSessionId, publishConfig);
        if (mTerminated) {
            mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
            return;
        } else {
            mManager.updatePublish(mSessionId, publishConfig);
        }
    }
    }
}
}
Loading