Merge "LocalDrive fails fast on P devices"
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
index 8464b8df..91d6490 100644
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
+++ b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
@@ -62,7 +62,7 @@
         if (process.waitFor() == 0) {
             logger.fine("Adb command successful.");
         } else {
-            logger.severe("Abnormal adb shell cmd termination for: " + String.join(",", commands));
+            logger.severe("Abnormal adb shell termination for: " + String.join(",", commands));
             throw new RuntimeException("Error running adb command: " + err.toString());
         }
     }
@@ -118,6 +118,52 @@
         logger.addHandler(handler);
     }
 
+    /**
+     * Attempt to determine whether tool will work with this statsd, i.e. whether statsd is
+     * minCodename or higher.
+     * Algorithm: true if (sdk >= minSdk) || (sdk == minSdk-1 && codeName.startsWith(minCodeName))
+     * If all else fails, assume it will work (letting future commands deal with any errors).
+     */
+    public static boolean isAcceptableStatsd(Logger logger, int minSdk, String minCodename) {
+        BufferedReader in = null;
+        try {
+            File outFileSdk = File.createTempFile("shelltools_sdk", "tmp");
+            outFileSdk.deleteOnExit();
+            runCommand(outFileSdk, logger,
+                    "adb", "shell", "getprop", "ro.build.version.sdk");
+            in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileSdk)));
+            // If NullPointerException/NumberFormatException/etc., just catch and return true.
+            int sdk = Integer.parseInt(in.readLine().trim());
+            if (sdk >= minSdk) {
+                return true;
+            } else if (sdk == minSdk - 1) { // Could be minSdk-1, or could be minSdk development.
+                in.close();
+                File outFileCode = File.createTempFile("shelltools_codename", "tmp");
+                outFileCode.deleteOnExit();
+                runCommand(outFileCode, logger,
+                        "adb", "shell", "getprop", "ro.build.version.codename");
+                in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileCode)));
+                return in.readLine().startsWith(minCodename);
+            } else {
+                return false;
+            }
+        } catch (Exception e) {
+            logger.fine("Could not determine whether statsd version is compatibile "
+                    + "with tool: " + e.toString());
+        } finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException e) {
+                logger.fine("Could not close temporary file: " + e.toString());
+            }
+        }
+        // Could not determine whether statsd is acceptable version.
+        // Just assume it is; if it isn't, we'll just get future errors via adb and deal with them.
+        return true;
+    }
+
     public static class LocalToolsFormatter extends Formatter {
         public String format(LogRecord record) {
             return record.getMessage() + "\n";
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
index 67fb906..2eb4660 100644
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
+++ b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
@@ -37,6 +37,9 @@
 public class LocalDrive {
     private static final boolean DEBUG = false;
 
+    public static final int MIN_SDK = 29;
+    public static final String MIN_CODENAME = "Q";
+
     public static final long DEFAULT_CONFIG_ID = 56789;
 
     public static final String BINARY_FLAG = "--binary";
@@ -46,7 +49,7 @@
     public static final String HELP_STRING =
         "Usage:\n\n" +
 
-        "statsd_local upload CONFIG_FILE [CONFIG_ID] [--binary]\n" +
+        "statsd_localdrive upload CONFIG_FILE [CONFIG_ID] [--binary]\n" +
         "  Uploads the given statsd config file (in binary or human-readable-text format).\n" +
         "  If a config with this id already exists, removes it first.\n" +
         "    CONFIG_FILE    Location of config file on host.\n" +
@@ -56,12 +59,12 @@
         // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
         "\n" +
 
-        "statsd_local update CONFIG_FILE [CONFIG_ID] [--binary]\n" +
+        "statsd_localdrive update CONFIG_FILE [CONFIG_ID] [--binary]\n" +
         "  Same as upload, but does not remove the old config first (if it already exists).\n" +
         // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
         "\n" +
 
-        "statsd_local get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]\n" +
+        "statsd_localdrive get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]\n" +
         "  Prints the output statslog data (in binary or human-readable-text format).\n" +
         "    CONFIG_ID      Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
         "    --binary       Output should be in binary, instead of default human-readable text.\n" +
@@ -72,13 +75,13 @@
         //                                                      --include_current_bucket --proto
         "\n" +
 
-        "statsd_local remove [CONFIG_ID]\n" +
+        "statsd_localdrive remove [CONFIG_ID]\n" +
         "  Removes the config.\n" +
         "    CONFIG_ID      Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
         // Equivalent to: adb shell cmd stats config remove SHELL_UID CONFIG_ID
         "\n" +
 
-        "statsd_local clear [CONFIG_ID]\n" +
+        "statsd_localdrive clear [CONFIG_ID]\n" +
         "  Clears the data associated with the config.\n" +
         "    CONFIG_ID      Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
         // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID
@@ -92,6 +95,12 @@
     public static void main(String[] args) {
         Utils.setUpLogger(sLogger, DEBUG);
 
+        if (!Utils.isAcceptableStatsd(sLogger, MIN_SDK, MIN_CODENAME)) {
+            sLogger.severe("LocalDrive only works with statsd versions for Android "
+                    + MIN_CODENAME + " or higher.");
+            return;
+        }
+
         if (args.length > 0) {
             switch (args[0]) {
                 case "clear":