[NAN] Use a hidden class for peer ID opaque handle

Results in clearer run-time exception (relatively to using Integer).

(cherry-pick of commit 57db2b3eea5333e5ee144ea29e4a4af02fae7309)

Bug: 31689166
Test: unit-tests + integrated (sl4a).
Change-Id: I79d0e8061204834b9775b02d503cb18fd03ed8c6
diff --git a/wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java b/wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java
index 5b84eb2..17e974b 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java
@@ -16,6 +16,7 @@
 
 package android.net.wifi.nan;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.wifi.RttManager;
@@ -163,7 +164,7 @@
      *            (note: no retransmissions are attempted in other failure cases). A value of 0
      *            indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}.
      */
-    public void sendMessage(Object peerHandle, int messageId, @Nullable byte[] message,
+    public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message,
             int retryCount) {
         if (mTerminated) {
             Log.w(TAG, "sendMessage: called on terminated session");
@@ -205,7 +206,7 @@
      *                  can be arbitrary and non-unique.
      * @param message The message to be transmitted.
      */
-    public void sendMessage(Object peerHandle, int messageId, @Nullable byte[] message) {
+    public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message) {
         sendMessage(peerHandle, messageId, message, 0);
     }
 
@@ -270,8 +271,8 @@
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifier(@WifiNanManager.DataPathRole int role, Object peerHandle,
-            @Nullable byte[] token) {
+    public String createNetworkSpecifier(@WifiNanManager.DataPathRole int role,
+            @Nullable Object peerHandle, @Nullable byte[] token) {
         if (mTerminated) {
             Log.w(TAG, "createNetworkSpecifier: called on terminated session");
             return null;
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
index 815defb..705ba4a 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -459,15 +459,20 @@
     /** @hide */
     public void sendMessage(int clientId, int sessionId, Object peerHandle, byte[] message,
             int messageId, int retryCount) {
+        if (peerHandle == null) {
+            throw new IllegalArgumentException(
+                    "sendMessage: invalid peerHandle - must be non-null");
+        }
+
         if (VDBG) {
             Log.v(TAG, "sendMessage(): clientId=" + clientId + ", sessionId=" + sessionId
-                    + ", peerHandle=" + peerHandle + ", messageId=" + messageId + ", retryCount="
-                    + retryCount);
+                    + ", peerHandle=" + ((OpaquePeerHandle) peerHandle).peerId + ", messageId="
+                    + messageId + ", retryCount=" + retryCount);
         }
 
         try {
-            mService.sendMessage(clientId, sessionId, (Integer) peerHandle, message, messageId,
-                    retryCount);
+            mService.sendMessage(clientId, sessionId, ((OpaquePeerHandle) peerHandle).peerId,
+                    message, messageId, retryCount);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -499,7 +504,8 @@
             byte[] token) {
         if (VDBG) {
             Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
-                    + ", peerHandle=" + peerHandle + ", token=" + token);
+                    + ", peerHandle=" + ((peerHandle == null) ? peerHandle
+                    : ((OpaquePeerHandle) peerHandle).peerId) + ", token=" + token);
         }
 
         int type;
@@ -539,7 +545,7 @@
             json.put(NETWORK_SPECIFIER_KEY_CLIENT_ID, clientId);
             json.put(NETWORK_SPECIFIER_KEY_SESSION_ID, sessionId);
             if (peerHandle != null) {
-                json.put(NETWORK_SPECIFIER_KEY_PEER_ID, (Integer) peerHandle);
+                json.put(NETWORK_SPECIFIER_KEY_PEER_ID, ((OpaquePeerHandle) peerHandle).peerId);
             }
             if (token != null) {
                 json.put(NETWORK_SPECIFIER_KEY_TOKEN,
@@ -844,7 +850,7 @@
                             break;
                         case CALLBACK_MATCH:
                             mOriginalCallback.onServiceDiscovered(
-                                    Integer.valueOf(msg.arg1),
+                                    new OpaquePeerHandle(msg.arg1),
                                     msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
                                     msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2));
                             break;
@@ -855,7 +861,7 @@
                             mOriginalCallback.onMessageSendFailed(msg.arg1);
                             break;
                         case CALLBACK_MESSAGE_RECEIVED:
-                            mOriginalCallback.onMessageReceived(Integer.valueOf(msg.arg1),
+                            mOriginalCallback.onMessageReceived(new OpaquePeerHandle(msg.arg1),
                                     (byte[]) msg.obj);
                             break;
                     }
@@ -986,4 +992,13 @@
             mOriginalCallback.onSessionTerminated(reason);
         }
     }
+
+    /** @hide */
+    public static class OpaquePeerHandle {
+        public OpaquePeerHandle(int peerId) {
+            this.peerId = peerId;
+        }
+
+        public int peerId;
+    }
 }