Annotate AppRTCMobile with @Nulllable.

Bug: webrtc:8881
Change-Id: I32390b1e2586415757f0453b60d35b23160d2862
Reviewed-on: https://webrtc-review.googlesource.com/63641
Reviewed-by: Paulina Hensman <phensman@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22580}
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index 25b6a03..03c9d71 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -106,12 +106,19 @@
       "androidapp/src/org/appspot/apprtc/util/AsyncHttpURLConnection.java",
     ]
 
+    javac_args = [
+      "-Xep:ParameterNotNullable:ERROR",
+      "-Xep:FieldMissingNullable:ERROR",
+      "-Xep:ReturnMissingNullable:ERROR",
+    ]
+
     deps = [
       ":AppRTCMobile_resources",
       "../rtc_base:base_java",
       "../sdk/android:libjingle_peerconnection_java",
       "../sdk/android:libjingle_peerconnection_metrics_default_java",
       "androidapp/third_party/autobanh:autobanh_java",
+      "//third_party/jsr-305:jsr_305_javalib",
     ]
   }
 
diff --git a/examples/androidapp/src/org/appspot/apprtc/AppRTCAudioManager.java b/examples/androidapp/src/org/appspot/apprtc/AppRTCAudioManager.java
index 5418ca0..aff198e 100644
--- a/examples/androidapp/src/org/appspot/apprtc/AppRTCAudioManager.java
+++ b/examples/androidapp/src/org/appspot/apprtc/AppRTCAudioManager.java
@@ -24,6 +24,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import javax.annotation.Nullable;
 import org.appspot.apprtc.util.AppRTCUtils;
 import org.webrtc.ThreadUtils;
 
@@ -57,8 +58,10 @@
   }
 
   private final Context apprtcContext;
+  @Nullable
   private AudioManager audioManager;
 
+  @Nullable
   private AudioManagerEvents audioManagerEvents;
   private AudioManagerState amState;
   private int savedAudioMode = AudioManager.MODE_INVALID;
@@ -90,6 +93,7 @@
   // relative to the view screen of a device and can therefore be used to
   // assist device switching (close to ear <=> use headset earpiece if
   // available, far from ear <=> use speaker phone).
+  @Nullable
   private AppRTCProximitySensor proximitySensor = null;
 
   // Handles all tasks related to Bluetooth headset devices.
@@ -103,6 +107,7 @@
   private BroadcastReceiver wiredHeadsetReceiver;
 
   // Callback method for changes in audio focus.
+  @Nullable
   private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
 
   /**
diff --git a/examples/androidapp/src/org/appspot/apprtc/AppRTCBluetoothManager.java b/examples/androidapp/src/org/appspot/apprtc/AppRTCBluetoothManager.java
index 00e6b04..6720e92 100644
--- a/examples/androidapp/src/org/appspot/apprtc/AppRTCBluetoothManager.java
+++ b/examples/androidapp/src/org/appspot/apprtc/AppRTCBluetoothManager.java
@@ -24,6 +24,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Process;
+import javax.annotation.Nullable;
 import android.util.Log;
 import java.util.List;
 import java.util.Set;
@@ -64,14 +65,18 @@
 
   private final Context apprtcContext;
   private final AppRTCAudioManager apprtcAudioManager;
+  @Nullable
   private final AudioManager audioManager;
   private final Handler handler;
 
   int scoConnectionAttempts;
   private State bluetoothState;
   private final BluetoothProfile.ServiceListener bluetoothServiceListener;
+  @Nullable
   private BluetoothAdapter bluetoothAdapter;
+  @Nullable
   private BluetoothHeadset bluetoothHeadset;
+  @Nullable
   private BluetoothDevice bluetoothDevice;
   private final BroadcastReceiver bluetoothHeadsetReceiver;
 
@@ -390,6 +395,7 @@
   /**
    * Stubs for test mocks.
    */
+  @Nullable
   protected AudioManager getAudioManager(Context context) {
     return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
   }
diff --git a/examples/androidapp/src/org/appspot/apprtc/AppRTCProximitySensor.java b/examples/androidapp/src/org/appspot/apprtc/AppRTCProximitySensor.java
index b63e8b8..ac03a80 100644
--- a/examples/androidapp/src/org/appspot/apprtc/AppRTCProximitySensor.java
+++ b/examples/androidapp/src/org/appspot/apprtc/AppRTCProximitySensor.java
@@ -16,6 +16,7 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.os.Build;
+import javax.annotation.Nullable;
 import android.util.Log;
 import org.appspot.apprtc.util.AppRTCUtils;
 import org.webrtc.ThreadUtils;
@@ -39,6 +40,7 @@
 
   private final Runnable onSensorStateListener;
   private final SensorManager sensorManager;
+  @Nullable
   private Sensor proximitySensor = null;
   private boolean lastStateReportIsNear = false;
 
diff --git a/examples/androidapp/src/org/appspot/apprtc/CallActivity.java b/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
index 3ff1230..4377d84 100644
--- a/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
+++ b/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
@@ -36,6 +36,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import javax.annotation.Nullable;
 import org.appspot.apprtc.AppRTCAudioManager.AudioDevice;
 import org.appspot.apprtc.AppRTCAudioManager.AudioManagerEvents;
 import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
@@ -168,18 +169,26 @@
 
   private final ProxyRenderer remoteProxyRenderer = new ProxyRenderer();
   private final ProxyVideoSink localProxyVideoSink = new ProxyVideoSink();
+  @Nullable
   private PeerConnectionClient peerConnectionClient = null;
+  @Nullable
   private AppRTCClient appRtcClient;
+  @Nullable
   private SignalingParameters signalingParameters;
+  @Nullable
   private AppRTCAudioManager audioManager = null;
+  @Nullable
   private SurfaceViewRenderer pipRenderer;
+  @Nullable
   private SurfaceViewRenderer fullscreenRenderer;
+  @Nullable
   private VideoFileRenderer videoFileRenderer;
   private final List<VideoRenderer.Callbacks> remoteRenderers = new ArrayList<>();
   private Toast logToast;
   private boolean commandLineRun;
   private boolean activityRunning;
   private RoomConnectionParameters roomConnectionParameters;
+  @Nullable
   private PeerConnectionParameters peerConnectionParameters;
   private boolean iceConnected;
   private boolean isError;
@@ -440,7 +449,7 @@
     return getIntent().getBooleanExtra(EXTRA_CAPTURETOTEXTURE_ENABLED, false);
   }
 
-  private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
+  private @Nullable VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
     final String[] deviceNames = enumerator.getDeviceNames();
 
     // First, try to find front facing camera
@@ -473,7 +482,7 @@
   }
 
   @TargetApi(21)
-  private VideoCapturer createScreenCapturer() {
+  private @Nullable VideoCapturer createScreenCapturer() {
     if (mediaProjectionPermissionResultCode != Activity.RESULT_OK) {
       reportError("User didn't give permission to capture the screen.");
       return null;
@@ -710,7 +719,7 @@
     });
   }
 
-  private VideoCapturer createVideoCapturer() {
+  private @Nullable VideoCapturer createVideoCapturer() {
     final VideoCapturer videoCapturer;
     String videoFileAsCamera = getIntent().getStringExtra(EXTRA_VIDEO_FILE_AS_CAMERA);
     if (videoFileAsCamera != null) {
diff --git a/examples/androidapp/src/org/appspot/apprtc/CpuMonitor.java b/examples/androidapp/src/org/appspot/apprtc/CpuMonitor.java
index e15abeb..8e2881c 100644
--- a/examples/androidapp/src/org/appspot/apprtc/CpuMonitor.java
+++ b/examples/androidapp/src/org/appspot/apprtc/CpuMonitor.java
@@ -31,6 +31,7 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
 
 /**
  * Simple CPU monitor.  The caller creates a CpuMonitor object which can then
@@ -91,6 +92,7 @@
   // CPU frequency in percentage from maximum.
   private final MovingAverage frequencyScale;
 
+  @Nullable
   private ScheduledExecutorService executor;
   private long lastStatLogTimeMs;
   private long[] cpuFreqMax;
@@ -101,6 +103,7 @@
   private String[] maxPath;
   private String[] curPath;
   private double[] curFreqScales;
+  @Nullable
   private ProcStat lastProcStat;
 
   private static class ProcStat {
@@ -485,7 +488,7 @@
    * of /proc/stat.
    */
   @SuppressWarnings("StringSplitter")
-  private ProcStat readProcStat() {
+  private @Nullable ProcStat readProcStat() {
     long userTime = 0;
     long systemTime = 0;
     long idleTime = 0;
diff --git a/examples/androidapp/src/org/appspot/apprtc/DirectRTCClient.java b/examples/androidapp/src/org/appspot/apprtc/DirectRTCClient.java
index ae3a522..9762e79 100644
--- a/examples/androidapp/src/org/appspot/apprtc/DirectRTCClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/DirectRTCClient.java
@@ -10,6 +10,7 @@
 
 package org.appspot.apprtc;
 
+import javax.annotation.Nullable;
 import android.util.Log;
 
 import org.json.JSONArray;
@@ -53,6 +54,7 @@
 
   private final ExecutorService executor;
   private final SignalingEvents events;
+  @Nullable
   private TCPChannelClient tcpClient;
   private RoomConnectionParameters connectionParameters;
 
diff --git a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
index be6cae6..52cab67 100644
--- a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
@@ -34,6 +34,7 @@
 import java.util.concurrent.Executors;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 import org.appspot.apprtc.AppRTCClient.SignalingParameters;
 import org.appspot.apprtc.RecordedAudioToFileController;
 import org.webrtc.AudioSource;
@@ -121,10 +122,15 @@
 
   private final EglBase rootEglBase;
   private final Context appContext;
+  @Nullable
   private PeerConnectionFactory factory;
+  @Nullable
   private PeerConnection peerConnection;
+  @Nullable
   PeerConnectionFactory.Options options = null;
+  @Nullable
   private AudioSource audioSource;
+  @Nullable
   private VideoSource videoSource;
   private boolean videoCallEnabled;
   private boolean preferIsac;
@@ -132,7 +138,9 @@
   private boolean videoCapturerStopped;
   private boolean isError;
   private Timer statsTimer;
+  @Nullable
   private VideoSink localRender;
+  @Nullable
   private List<VideoRenderer.Callbacks> remoteRenders;
   private SignalingParameters signalingParameters;
   private int videoWidth;
@@ -144,26 +152,38 @@
   // Queued remote ICE candidates are consumed only after both local and
   // remote descriptions are set. Similarly local ICE candidates are sent to
   // remote peer after both local and remote description are set.
+  @Nullable
   private List<IceCandidate> queuedRemoteCandidates;
+  @Nullable
   private PeerConnectionEvents events;
   private boolean isInitiator;
+  @Nullable
   private SessionDescription localSdp; // either offer or answer SDP
+  @Nullable
   private MediaStream mediaStream;
+  @Nullable
   private VideoCapturer videoCapturer;
   // enableVideo is set to true if video should be rendered and sent.
   private boolean renderVideo;
+  @Nullable
   private VideoTrack localVideoTrack;
+  @Nullable
   private VideoTrack remoteVideoTrack;
+  @Nullable
   private RtpSender localVideoSender;
   // enableAudio is set to true if audio should be sent.
   private boolean enableAudio;
+  @Nullable
   private AudioTrack localAudioTrack;
+  @Nullable
   private DataChannel dataChannel;
   private boolean dataChannelEnabled;
   // Enable RtcEventLog.
+  @Nullable
   private RtcEventLog rtcEventLog;
   // Implements the WebRtcAudioRecordSamplesReadyCallback interface and writes
   // recorded audio samples to an output file.
+  @Nullable
   private RecordedAudioToFileController saveRecordedAudioToFile = null;
 
   /**
@@ -950,7 +970,7 @@
     });
   }
 
-  public void setVideoMaxBitrate(final Integer maxBitrateKbps) {
+  public void setVideoMaxBitrate(@Nullable final Integer maxBitrateKbps) {
     executor.execute(new Runnable() {
       @Override
       public void run() {
@@ -994,6 +1014,7 @@
     });
   }
 
+  @Nullable
   private AudioTrack createAudioTrack() {
     audioSource = factory.createAudioSource(audioConstraints);
     localAudioTrack = factory.createAudioTrack(AUDIO_TRACK_ID, audioSource);
@@ -1001,6 +1022,7 @@
     return localAudioTrack;
   }
 
+  @Nullable
   private VideoTrack createVideoTrack(VideoCapturer capturer) {
     videoSource = factory.createVideoSource(capturer);
     capturer.startCapture(videoWidth, videoHeight, videoFps);
@@ -1024,7 +1046,7 @@
   }
 
   // Returns the remote VideoTrack, assuming there is only one.
-  private VideoTrack getRemoteVideoTrack() {
+  private @Nullable VideoTrack getRemoteVideoTrack() {
     for (RtpTransceiver transceiver : peerConnection.getTransceivers()) {
       MediaStreamTrack track = transceiver.getReceiver().track();
       if (track instanceof VideoTrack) {
@@ -1125,7 +1147,8 @@
     return buffer.toString();
   }
 
-  private static String movePayloadTypesToFront(List<String> preferredPayloadTypes, String mLine) {
+  private static @Nullable String movePayloadTypesToFront(
+      List<String> preferredPayloadTypes, String mLine) {
     // The format of the media description line should be: m=<media> <port> <proto> <fmt> ...
     final List<String> origLineParts = Arrays.asList(mLine.split(" "));
     if (origLineParts.size() <= 3) {
diff --git a/examples/androidapp/src/org/appspot/apprtc/RecordedAudioToFileController.java b/examples/androidapp/src/org/appspot/apprtc/RecordedAudioToFileController.java
index 58c519f..62dde95 100644
--- a/examples/androidapp/src/org/appspot/apprtc/RecordedAudioToFileController.java
+++ b/examples/androidapp/src/org/appspot/apprtc/RecordedAudioToFileController.java
@@ -12,6 +12,7 @@
 
 import android.media.AudioFormat;
 import android.os.Environment;
+import javax.annotation.Nullable;
 import android.util.Log;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -33,6 +34,7 @@
 
   private final Object lock = new Object();
   private final ExecutorService executor;
+  @Nullable
   private OutputStream rawAudioFileOutputStream = null;
   private long fileSizeInBytes = 0;
 
diff --git a/examples/androidapp/src/org/appspot/apprtc/RtcEventLog.java b/examples/androidapp/src/org/appspot/apprtc/RtcEventLog.java
index e1cf8ce..bbbd06b 100644
--- a/examples/androidapp/src/org/appspot/apprtc/RtcEventLog.java
+++ b/examples/androidapp/src/org/appspot/apprtc/RtcEventLog.java
@@ -71,4 +71,4 @@
     state = RtcEventLogState.STOPPED;
     Log.d(TAG, "RtcEventLog stopped.");
   }
-}
\ No newline at end of file
+}
diff --git a/examples/androidapp/src/org/appspot/apprtc/TCPChannelClient.java b/examples/androidapp/src/org/appspot/apprtc/TCPChannelClient.java
index 39f41f8..e9fd7be 100644
--- a/examples/androidapp/src/org/appspot/apprtc/TCPChannelClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/TCPChannelClient.java
@@ -10,6 +10,7 @@
 
 package org.appspot.apprtc;
 
+import javax.annotation.Nullable;
 import android.util.Log;
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -123,7 +124,9 @@
   private abstract class TCPSocket extends Thread {
     // Lock for editing out and rawSocket
     protected final Object rawSocketLock;
+    @Nullable
     private PrintWriter out;
+    @Nullable
     private Socket rawSocket;
 
     /**
@@ -131,6 +134,7 @@
      *
      * @return Socket connection, null if connection failed.
      */
+    @Nullable
     public abstract Socket connect();
 
     /** Returns true if sockets is a server rawSocket. */
@@ -263,6 +267,7 @@
 
   private class TCPSocketServer extends TCPSocket {
     // Server socket is also guarded by rawSocketLock.
+    @Nullable
     private ServerSocket serverSocket;
 
     final private InetAddress address;
@@ -274,6 +279,7 @@
     }
 
     /** Opens a listening socket and waits for a connection. */
+    @Nullable
     @Override
     public Socket connect() {
       Log.d(TAG, "Listening on [" + address.getHostAddress() + "]:" + Integer.toString(port));
@@ -335,6 +341,7 @@
     }
 
     /** Connects to the peer. */
+    @Nullable
     @Override
     public Socket connect() {
       Log.d(TAG, "Connecting to [" + address.getHostAddress() + "]:" + Integer.toString(port));
diff --git a/examples/androidapp/src/org/appspot/apprtc/WebSocketChannelClient.java b/examples/androidapp/src/org/appspot/apprtc/WebSocketChannelClient.java
index d3e5c87..07b7847 100644
--- a/examples/androidapp/src/org/appspot/apprtc/WebSocketChannelClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/WebSocketChannelClient.java
@@ -11,6 +11,7 @@
 package org.appspot.apprtc;
 
 import android.os.Handler;
+import javax.annotation.Nullable;
 import android.util.Log;
 import de.tavendo.autobahn.WebSocket.WebSocketConnectionObserver;
 import de.tavendo.autobahn.WebSocketConnection;
@@ -39,7 +40,9 @@
   private WebSocketConnection ws;
   private String wsServerUrl;
   private String postServerUrl;
+  @Nullable
   private String roomID;
+  @Nullable
   private String clientID;
   private WebSocketConnectionState state;
   // Do not remove this member variable. If this is removed, the observer gets garbage collected and
diff --git a/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java b/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java
index 3215051..dbe34be 100644
--- a/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java
@@ -10,6 +10,7 @@
 
 package org.appspot.apprtc;
 
+import javax.annotation.Nullable;
 import org.appspot.apprtc.RoomParametersFetcher.RoomParametersFetcherEvents;
 import org.appspot.apprtc.WebSocketChannelClient.WebSocketChannelEvents;
 import org.appspot.apprtc.WebSocketChannelClient.WebSocketConnectionState;
@@ -380,7 +381,7 @@
 
   // Send SDP or ICE candidate to a room server.
   private void sendPostMessage(
-      final MessageType messageType, final String url, final String message) {
+      final MessageType messageType, final String url, @Nullable final String message) {
     String logInfo = url;
     if (message != null) {
       logInfo += ". Message: " + message;