Update app_api to fix style/lint issues

Test: manually invoked/profiled MainActivity

- Added Nullable/NonNull annotations
- Added RequiredAPI annotations
- Switch to consistent mFoo naming

And several other lint suggestions Android Studio suggested.

Additionally, updated target/compile API of demo.

These lint / style issues were found when copying this code into
Jetpack Benchmark, in the AndroidX repository:

https://android-review.googlesource.com/c/platform/frameworks/support/+/1343923

Change-Id: I9fd876f1d15a4812d1ef52958661050b258ca38d
diff --git a/simpleperf/app_api/java/com/android/simpleperf/ProfileSession.java b/simpleperf/app_api/java/com/android/simpleperf/ProfileSession.java
index a3d4796..d1dbc53 100644
--- a/simpleperf/app_api/java/com/android/simpleperf/ProfileSession.java
+++ b/simpleperf/app_api/java/com/android/simpleperf/ProfileSession.java
@@ -19,6 +19,10 @@
 import android.os.Build;
 import android.system.OsConstants;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -55,6 +59,7 @@
  * process, filter logcat with `simpleperf`.
  * </p>
  */
+@RequiresApi(28)
 public class ProfileSession {
     private static final String SIMPLEPERF_PATH_IN_IMAGE = "/system/bin/simpleperf";
 
@@ -65,27 +70,27 @@
         STOPPED,
     }
 
-    private State state = State.NOT_YET_STARTED;
-    private String appDataDir;
-    private String simpleperfPath;
-    private String simpleperfDataDir;
-    private Process simpleperfProcess;
-    private boolean traceOffcpu = false;
+    private State mState = State.NOT_YET_STARTED;
+    private final String mAppDataDir;
+    private String mSimpleperfPath;
+    private final String mSimpleperfDataDir;
+    private Process mSimpleperfProcess;
+    private boolean mTraceOffCpu = false;
 
     /**
      * @param appDataDir the same as android.content.Context.getDataDir().
      *                   ProfileSession stores profiling data in appDataDir/simpleperf_data/.
      */
-    public ProfileSession(String appDataDir) {
-        this.appDataDir = appDataDir;
-        simpleperfDataDir = appDataDir + "/simpleperf_data";
+    public ProfileSession(@NonNull String appDataDir) {
+        mAppDataDir = appDataDir;
+        mSimpleperfDataDir = appDataDir + "/simpleperf_data";
     }
 
     /**
      * ProfileSession assumes appDataDir as /data/data/app_package_name.
      */
     public ProfileSession() {
-        String packageName = "";
+        String packageName;
         try {
             String s = readInputStream(new FileInputStream("/proc/self/cmdline"));
             for (int i = 0; i < s.length(); i++) {
@@ -101,15 +106,15 @@
         if (packageName.isEmpty()) {
             throw new Error("failed to find packageName");
         }
-        appDataDir = "/data/data/" + packageName;
-        simpleperfDataDir = appDataDir + "/simpleperf_data";
+        mAppDataDir = "/data/data/" + packageName;
+        mSimpleperfDataDir = mAppDataDir + "/simpleperf_data";
     }
 
     /**
      * Start recording.
      * @param options RecordOptions
      */
-    public void startRecording(RecordOptions options) {
+    public void startRecording(@NonNull RecordOptions options) {
         startRecording(options.toRecordArgs());
     }
 
@@ -117,77 +122,77 @@
      * Start recording.
      * @param args arguments for `simpleperf record` cmd.
      */
-    public synchronized void startRecording(List<String> args) {
-        if (state != State.NOT_YET_STARTED) {
-            throw new AssertionError("startRecording: session in wrong state " + state);
+    public synchronized void startRecording(@NonNull List<String> args) {
+        if (mState != State.NOT_YET_STARTED) {
+            throw new AssertionError("startRecording: session in wrong state " + mState);
         }
         for (String arg : args) {
             if (arg.equals("--trace-offcpu")) {
-                traceOffcpu = true;
+                mTraceOffCpu = true;
             }
         }
-        simpleperfPath = findSimpleperf();
+        mSimpleperfPath = findSimpleperf();
         checkIfPerfEnabled();
         createSimpleperfDataDir();
-        createSimpleperfProcess(simpleperfPath, args);
-        state = State.STARTED;
+        createSimpleperfProcess(mSimpleperfPath, args);
+        mState = State.STARTED;
     }
 
     /**
      * Pause recording. No samples are generated in paused state.
      */
     public synchronized void pauseRecording() {
-        if (state != State.STARTED) {
-            throw new AssertionError("pauseRecording: session in wrong state " + state);
+        if (mState != State.STARTED) {
+            throw new AssertionError("pauseRecording: session in wrong state " + mState);
         }
-        if (traceOffcpu) {
+        if (mTraceOffCpu) {
             throw new AssertionError(
                     "--trace-offcpu option doesn't work well with pause/resume recording");
         }
         sendCmd("pause");
-        state = State.PAUSED;
+        mState = State.PAUSED;
     }
 
     /**
      * Resume a paused session.
      */
     public synchronized void resumeRecording() {
-        if (state != State.PAUSED) {
-            throw new AssertionError("resumeRecording: session in wrong state " + state);
+        if (mState != State.PAUSED) {
+            throw new AssertionError("resumeRecording: session in wrong state " + mState);
         }
         sendCmd("resume");
-        state = State.STARTED;
+        mState = State.STARTED;
     }
 
     /**
      * Stop recording and generate a recording file under appDataDir/simpleperf_data/.
      */
     public synchronized void stopRecording() {
-        if (state != State.STARTED && state != State.PAUSED) {
-            throw new AssertionError("stopRecording: session in wrong state " + state);
+        if (mState != State.STARTED && mState != State.PAUSED) {
+            throw new AssertionError("stopRecording: session in wrong state " + mState);
         }
-        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P + 1 &&
-                simpleperfPath.equals(SIMPLEPERF_PATH_IN_IMAGE)) {
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P + 1
+                && mSimpleperfPath.equals(SIMPLEPERF_PATH_IN_IMAGE)) {
             // The simpleperf shipped on Android Q contains a bug, which may make it abort if
             // calling simpleperfProcess.destroy().
             destroySimpleperfProcessWithoutClosingStdin();
         } else {
-            simpleperfProcess.destroy();
+            mSimpleperfProcess.destroy();
         }
         try {
-            int exitCode = simpleperfProcess.waitFor();
+            int exitCode = mSimpleperfProcess.waitFor();
             if (exitCode != 0) {
                 throw new AssertionError("simpleperf exited with error: " + exitCode);
             }
         } catch (InterruptedException e) {
         }
-        simpleperfProcess = null;
-        state = State.STOPPED;
+        mSimpleperfProcess = null;
+        mState = State.STOPPED;
     }
 
     private void destroySimpleperfProcessWithoutClosingStdin() {
         // In format "Process[pid=? ..."
-        String s = simpleperfProcess.toString();
+        String s = mSimpleperfProcess.toString();
         final String prefix = "Process[pid=";
         if (s.startsWith(prefix)) {
             int startIndex = prefix.length();
@@ -198,7 +203,7 @@
                 return;
             }
         }
-        simpleperfProcess.destroy();
+        mSimpleperfProcess.destroy();
     }
 
     private String readInputStream(InputStream in) {
@@ -225,19 +230,20 @@
         throw new Error("can't find simpleperf on device. Please run api_profiler.py.");
     }
 
-    private boolean isExecutableFile(String path) {
+    private boolean isExecutableFile(@NonNull String path) {
         File file = new File(path);
         return file.canExecute();
     }
 
+    @Nullable
     private String findSimpleperfInTempDir() {
         String path = "/data/local/tmp/simpleperf";
         File file = new File(path);
-        if (!file.isFile()){
+        if (!file.isFile()) {
             return null;
         }
         // Copy it to app dir to execute it.
-        String toPath = appDataDir + "/simpleperf";
+        String toPath = mAppDataDir + "/simpleperf";
         try {
             Process process = new ProcessBuilder()
                     .command("cp", path, toPath).start();
@@ -255,7 +261,7 @@
             Process process = new ProcessBuilder().command(toPath, "list", "sw").start();
             process.waitFor();
             String data = readInputStream(process.getInputStream());
-            if (data.indexOf("cpu-clock") == -1) {
+            if (!data.contains("cpu-clock")) {
                 return null;
             }
         } catch (Exception e) {
@@ -265,7 +271,7 @@
     }
 
     private void checkIfPerfEnabled() {
-        String value = "";
+        String value;
         Process process;
         try {
             process = new ProcessBuilder()
@@ -280,13 +286,13 @@
         }
         value = readInputStream(process.getInputStream());
         if (value.startsWith("1")) {
-            throw new Error("linux perf events aren't enabled on the device." +
-                            " Please run api_profiler.py.");
+            throw new Error("linux perf events aren't enabled on the device."
+                    + " Please run api_profiler.py.");
         }
     }
 
     private void createSimpleperfDataDir() {
-        File file = new File(simpleperfDataDir);
+        File file = new File(mSimpleperfDataDir);
         if (!file.isDirectory()) {
             file.mkdir();
         }
@@ -307,9 +313,9 @@
         args.addAll(recordArgs);
 
         // 2. Create the simpleperf process.
-        ProcessBuilder pb = new ProcessBuilder(args).directory(new File(simpleperfDataDir));
+        ProcessBuilder pb = new ProcessBuilder(args).directory(new File(mSimpleperfDataDir));
         try {
-            simpleperfProcess = pb.start();
+            mSimpleperfProcess = pb.start();
         } catch (IOException e) {
             throw new Error("failed to create simpleperf process: " + e.getMessage());
         }
@@ -321,11 +327,11 @@
         }
     }
 
-    private void sendCmd(String cmd) {
+    private void sendCmd(@NonNull String cmd) {
         cmd += "\n";
         try {
-            simpleperfProcess.getOutputStream().write(cmd.getBytes());
-            simpleperfProcess.getOutputStream().flush();
+            mSimpleperfProcess.getOutputStream().write(cmd.getBytes());
+            mSimpleperfProcess.getOutputStream().flush();
         } catch (IOException e) {
             throw new Error("failed to send cmd to simpleperf: " + e.getMessage());
         }
@@ -334,6 +340,7 @@
         }
     }
 
+    @NonNull
     private String readReply() {
         // Read one byte at a time to stop at line break or EOF. BufferedReader will try to read
         // more than available and make us blocking, so don't use it.
@@ -341,13 +348,13 @@
         while (true) {
             int c = -1;
             try {
-                c = simpleperfProcess.getInputStream().read();
+                c = mSimpleperfProcess.getInputStream().read();
             } catch (IOException e) {
             }
             if (c == -1 || c == '\n') {
                 break;
             }
-            s += (char)c;
+            s += (char) c;
         }
         return s;
     }
diff --git a/simpleperf/app_api/java/com/android/simpleperf/RecordOptions.java b/simpleperf/app_api/java/com/android/simpleperf/RecordOptions.java
index 3ed39fb..ae65b94 100644
--- a/simpleperf/app_api/java/com/android/simpleperf/RecordOptions.java
+++ b/simpleperf/app_api/java/com/android/simpleperf/RecordOptions.java
@@ -18,6 +18,10 @@
 
 import android.system.Os;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
@@ -39,30 +43,34 @@
  *   session.startRecording(options);
  * </p>
  */
+@RequiresApi(28)
 public class RecordOptions {
 
     /**
      * Set output filename. Default is perf-<month>-<day>-<hour>-<minute>-<second>.data.
      * The file will be generated under simpleperf_data/.
      */
-    public RecordOptions setOutputFilename(String filename) {
-        outputFilename = filename;
+    @NonNull
+    public RecordOptions setOutputFilename(@NonNull String filename) {
+        mOutputFilename = filename;
         return this;
     }
 
     /**
      * Set event to record. Default is cpu-cycles. See `simpleperf list` for all available events.
      */
-    public RecordOptions setEvent(String event) {
-        this.event = event;
+    @NonNull
+    public RecordOptions setEvent(@NonNull String event) {
+        mEvent = event;
         return this;
     }
 
     /**
      * Set how many samples to generate each second running. Default is 4000.
      */
+    @NonNull
     public RecordOptions setSampleFrequency(int freq) {
-        this.freq = freq;
+        mFreq = freq;
         return this;
     }
 
@@ -70,86 +78,92 @@
      * Set record duration. The record stops after `durationInSecond` seconds. By default,
      * record stops only when stopRecording() is called.
      */
+    @NonNull
     public RecordOptions setDuration(double durationInSecond) {
-        this.durationInSecond = durationInSecond;
+        mDurationInSeconds = durationInSecond;
         return this;
     }
 
     /**
      * Record some threads in the app process. By default, record all threads in the process.
      */
-    public RecordOptions setSampleThreads(List<Integer> threads) {
-        this.threads.addAll(threads);
+    @NonNull
+    public RecordOptions setSampleThreads(@NonNull List<Integer> threads) {
+        mThreads.addAll(threads);
         return this;
     }
 
     /**
      * Record dwarf based call graph. It is needed to get Java callstacks.
      */
+    @NonNull
     public RecordOptions recordDwarfCallGraph() {
-        this.dwarfCallGraph = true;
-        this.fpCallGraph = false;
+        mDwarfCallGraph = true;
+        mFpCallGraph = false;
         return this;
     }
 
     /**
      * Record frame pointer based call graph. It is suitable to get C++ callstacks on 64bit devices.
      */
+    @NonNull
     public RecordOptions recordFramePointerCallGraph() {
-        this.fpCallGraph = true;
-        this.dwarfCallGraph = false;
+        mFpCallGraph = true;
+        mDwarfCallGraph = false;
         return this;
     }
 
     /**
      * Trace context switch info to show where threads spend time off cpu.
      */
+    @NonNull
     public RecordOptions traceOffCpu() {
-        this.traceOffCpu = true;
+        mTraceOffCpu = true;
         return this;
     }
 
     /**
      * Translate record options into arguments for `simpleperf record` cmd.
      */
+    @NonNull
     public List<String> toRecordArgs() {
         ArrayList<String> args = new ArrayList<>();
 
-        String filename = outputFilename;
+        String filename = mOutputFilename;
         if (filename == null) {
             filename = getDefaultOutputFilename();
         }
         args.add("-o");
         args.add(filename);
         args.add("-e");
-        args.add(event);
+        args.add(mEvent);
         args.add("-f");
-        args.add(String.valueOf(freq));
-        if (durationInSecond != 0.0) {
+        args.add(String.valueOf(mFreq));
+        if (mDurationInSeconds != 0.0) {
             args.add("--duration");
-            args.add(String.valueOf(durationInSecond));
+            args.add(String.valueOf(mDurationInSeconds));
         }
-        if (threads.isEmpty()) {
+        if (mThreads.isEmpty()) {
             args.add("-p");
             args.add(String.valueOf(Os.getpid()));
         } else {
             String s = "";
-            for (int i = 0; i < threads.size(); i++) {
+            for (int i = 0; i < mThreads.size(); i++) {
                 if (i > 0) {
                     s += ",";
                 }
-                s += threads.get(i).toString();
+                s += mThreads.get(i).toString();
             }
             args.add("-t");
             args.add(s);
         }
-        if (dwarfCallGraph) {
+        if (mDwarfCallGraph) {
             args.add("-g");
-        } else if (fpCallGraph) {
+        } else if (mFpCallGraph) {
             args.add("--call-graph");
             args.add("fp");
         }
-        if (traceOffCpu) {
+        if (mTraceOffCpu) {
             args.add("--trace-offcpu");
         }
         return args;
@@ -161,12 +175,22 @@
         return time.format(formatter);
     }
 
-    private String outputFilename;
-    private String event = "cpu-cycles";
-    private int freq = 4000;
-    private double durationInSecond = 0.0;
-    private ArrayList<Integer> threads = new ArrayList<>();
-    private boolean dwarfCallGraph = false;
-    private boolean fpCallGraph = false;
-    private boolean traceOffCpu = false;
+    @Nullable
+    private String mOutputFilename;
+
+    @NonNull
+    private String mEvent = "cpu-cycles";
+
+    private int mFreq = 4000;
+
+    private double mDurationInSeconds = 0.0;
+
+    @NonNull
+    private ArrayList<Integer> mThreads = new ArrayList<>();
+
+    private boolean mDwarfCallGraph = false;
+
+    private boolean mFpCallGraph = false;
+
+    private boolean mTraceOffCpu = false;
 }
diff --git a/simpleperf/demo/JavaApi/app/build.gradle b/simpleperf/demo/JavaApi/app/build.gradle
index be32645..e53f7da 100644
--- a/simpleperf/demo/JavaApi/app/build.gradle
+++ b/simpleperf/demo/JavaApi/app/build.gradle
@@ -1,13 +1,13 @@
 apply plugin: 'com.android.application'
 
 android {
-    compileSdkVersion 28
+    compileSdkVersion 29
     defaultConfig {
         applicationId "simpleperf.demo.java_api"
         // Simpleperf profiles interpreted/jitted Java code on Android >= P.
         // https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/README.md#prepare-an-android-application
         minSdkVersion 28
-        targetSdkVersion 28
+        targetSdkVersion 29
         versionCode 1
         versionName "1.0"
     }