Throw IllegalStateException if native objects are used after dispose.

This makes it easier to debug issues related to double dispose /
use after dispose.

Bug: webrtc:7566, webrtc:8297
Change-Id: I07429b2b794deabb62b5f3ea1cf92eea6f66a149
Reviewed-on: https://webrtc-review.googlesource.com/102540
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Paulina Hensman <phensman@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24894}
diff --git a/sdk/android/api/org/webrtc/DataChannel.java b/sdk/android/api/org/webrtc/DataChannel.java
index 53ea0d8..f51dab9 100644
--- a/sdk/android/api/org/webrtc/DataChannel.java
+++ b/sdk/android/api/org/webrtc/DataChannel.java
@@ -102,7 +102,7 @@
     }
   }
 
-  private final long nativeDataChannel;
+  private long nativeDataChannel;
   private long nativeObserver;
 
   @CalledByNative
@@ -112,6 +112,7 @@
 
   /** Register |observer|, replacing any previously-registered observer. */
   public void registerObserver(Observer observer) {
+    checkDataChannelExists();
     if (nativeObserver != 0) {
       nativeUnregisterObserver(nativeObserver);
     }
@@ -120,18 +121,22 @@
 
   /** Unregister the (only) observer. */
   public void unregisterObserver() {
+    checkDataChannelExists();
     nativeUnregisterObserver(nativeObserver);
   }
 
   public String label() {
+    checkDataChannelExists();
     return nativeLabel();
   }
 
   public int id() {
+    checkDataChannelExists();
     return nativeId();
   }
 
   public State state() {
+    checkDataChannelExists();
     return nativeState();
   }
 
@@ -141,16 +146,19 @@
    * to the network.
    */
   public long bufferedAmount() {
+    checkDataChannelExists();
     return nativeBufferedAmount();
   }
 
   /** Close the channel. */
   public void close() {
+    checkDataChannelExists();
     nativeClose();
   }
 
   /** Send |data| to the remote peer; return success. */
   public boolean send(Buffer buffer) {
+    checkDataChannelExists();
     // TODO(fischman): this could be cleverer about avoiding copies if the
     // ByteBuffer is direct and/or is backed by an array.
     byte[] data = new byte[buffer.data.remaining()];
@@ -160,7 +168,9 @@
 
   /** Dispose of native resources attached to this channel. */
   public void dispose() {
+    checkDataChannelExists();
     JniCommon.nativeReleaseRef(nativeDataChannel);
+    nativeDataChannel = 0;
   }
 
   @CalledByNative
@@ -168,6 +178,12 @@
     return nativeDataChannel;
   }
 
+  private void checkDataChannelExists() {
+    if (nativeDataChannel == 0) {
+      throw new IllegalStateException("DataChannel has been disposed.");
+    }
+  }
+
   private native long nativeRegisterObserver(Observer observer);
   private native void nativeUnregisterObserver(long observer);
   private native String nativeLabel();