Camera2: Tests: Add CLI arguments for disabling forking and changing camera ID

Change-Id: I0adfda42e861d7e5a85801f7e0c3f0b3950b6e0e
diff --git a/tests/camera2/Android.mk b/tests/camera2/Android.mk
index 29a028b..b312328 100644
--- a/tests/camera2/Android.mk
+++ b/tests/camera2/Android.mk
@@ -12,6 +12,7 @@
 	CameraBurstTests.cpp \
 	ForkedTests.cpp \
 	TestForkerEventListener.cpp \
+	TestSettings.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
 	libutils \
diff --git a/tests/camera2/CameraBurstTests.cpp b/tests/camera2/CameraBurstTests.cpp
index ea567f7..356ed37 100644
--- a/tests/camera2/CameraBurstTests.cpp
+++ b/tests/camera2/CameraBurstTests.cpp
@@ -51,7 +51,6 @@
 namespace tests {
 
 static CameraStreamParams STREAM_PARAMETERS = {
-    /*mCameraId*/   0,
     /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
     /*mHeapCount*/  CAMERA_HEAP_COUNT
 };
diff --git a/tests/camera2/CameraFrameTests.cpp b/tests/camera2/CameraFrameTests.cpp
index b24f4ac..fc681c4 100644
--- a/tests/camera2/CameraFrameTests.cpp
+++ b/tests/camera2/CameraFrameTests.cpp
@@ -46,7 +46,6 @@
 namespace tests {
 
 static CameraStreamParams STREAM_PARAMETERS = {
-    /*mCameraId*/   0,
     /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
     /*mHeapCount*/  CAMERA_HEAP_COUNT
 };
diff --git a/tests/camera2/CameraMetadataTests.cpp b/tests/camera2/CameraMetadataTests.cpp
index 18710bc..d02d104 100644
--- a/tests/camera2/CameraMetadataTests.cpp
+++ b/tests/camera2/CameraMetadataTests.cpp
@@ -42,7 +42,6 @@
 
 //FIXME: dont hardcode
 static CameraStreamParams METADATA_STREAM_PARAMETERS = {
-    /*mCameraId*/   0,
     /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
     /*mHeapCount*/  2
 };
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
index d93d26b..7a6fa31 100644
--- a/tests/camera2/CameraStreamFixture.h
+++ b/tests/camera2/CameraStreamFixture.h
@@ -33,14 +33,12 @@
 namespace tests {
 
 struct CameraStreamParams {
-    int mCameraId;
     int mFormat;
     int mHeapCount;
 };
 
 inline void PrintTo(const CameraStreamParams& p, ::std::ostream* os) {
     *os <<  "{ ";
-    *os <<  "CameraID: "  << p.mCameraId  << ", ";
     *os <<  "Format: "    << p.mFormat    << ", ";
     *os <<  "HeapCount: " << p.mHeapCount;
     *os << " }";
@@ -51,7 +49,7 @@
 
 public:
     CameraStreamFixture(CameraStreamParams p)
-    : CameraModuleFixture(p.mCameraId) {
+    : CameraModuleFixture(TestSettings::DeviceId()) {
         TEST_EXTENSION_FORKING_CONSTRUCTOR;
 
         mParam = p;
diff --git a/tests/camera2/CameraStreamTests.cpp b/tests/camera2/CameraStreamTests.cpp
index 26b2551..cff8394 100644
--- a/tests/camera2/CameraStreamTests.cpp
+++ b/tests/camera2/CameraStreamTests.cpp
@@ -74,62 +74,50 @@
 //TODO: use a combinatoric generator
 static CameraStreamParams TestParameters[] = {
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
         /*mHeapCount*/ 1
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
         /*mHeapCount*/ 2
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
         /*mHeapCount*/ 3
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP, // NV21
         /*mHeapCount*/ 1
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
         /*mHeapCount*/ 2
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
         /*mHeapCount*/ 3
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
         /*mHeapCount*/ 1
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
         /*mHeapCount*/ 2
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
         /*mHeapCount*/ 3
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_RAW_SENSOR,
         /*mHeapCount*/ 1
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_RAW_SENSOR,
         /*mHeapCount*/ 2
     },
     {
-        /*cameraId*/   0,
         /*mFormat*/    HAL_PIXEL_FORMAT_RAW_SENSOR,
         /*mHeapCount*/ 3
     },
diff --git a/tests/camera2/TestExtensions.h b/tests/camera2/TestExtensions.h
index 68a5e97..2af587d 100644
--- a/tests/camera2/TestExtensions.h
+++ b/tests/camera2/TestExtensions.h
@@ -18,6 +18,7 @@
 #define __ANDROID_HAL_CAMERA2_TESTS_EXTENSIONS__
 
 #include "TestForkerEventListener.h"
+#include "TestSettings.h"
 
 // Use at the beginning of each Test::SetUp() impl
 #define TEST_EXTENSION_FORKING_SET_UP                                       \
@@ -46,7 +47,8 @@
     } while(false)                                                          \
 
 // Are we running each test by forking it?
-#define TEST_EXTENSION_FORKING_ENABLED  (TestForkerEventListener::mUsingForking)
+#define TEST_EXTENSION_FORKING_ENABLED                                      \
+    (android::camera2::tests::TestSettings::ForkingEnabled())
 
 
 
diff --git a/tests/camera2/TestForkerEventListener.cpp b/tests/camera2/TestForkerEventListener.cpp
index c9f1942..9416db2 100644
--- a/tests/camera2/TestForkerEventListener.cpp
+++ b/tests/camera2/TestForkerEventListener.cpp
@@ -33,7 +33,6 @@
 namespace camera2 {
 namespace tests {
 
-bool TestForkerEventListener::mUsingForking     = true;
 bool TestForkerEventListener::mIsForked         = false;
 
 TestForkerEventListener::TestForkerEventListener() {
@@ -42,10 +41,6 @@
     mTermSignal = 0;
 }
 
-void TestForkerEventListener::SetForking(bool enabled) {
-    mUsingForking = enabled;
-}
-
 // Called before a test starts.
 void TestForkerEventListener::OnTestStart(const ::testing::TestInfo&) {
 
diff --git a/tests/camera2/TestForkerEventListener.h b/tests/camera2/TestForkerEventListener.h
index 2383f17..347a06b 100644
--- a/tests/camera2/TestForkerEventListener.h
+++ b/tests/camera2/TestForkerEventListener.h
@@ -30,9 +30,6 @@
 
     TestForkerEventListener();
 
-    // Should we fork before running each test?
-    static void SetForking(bool enabled);
-
 private:
 
     // Called before a test starts.
@@ -50,7 +47,6 @@
 
 public:
     // do not read directly. use TEST_EXTENSION macros instead
-    static bool mUsingForking;
     static bool mIsForked;
 };
 
diff --git a/tests/camera2/TestSettings.cpp b/tests/camera2/TestSettings.cpp
new file mode 100644
index 0000000..f07adc8
--- /dev/null
+++ b/tests/camera2/TestSettings.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+#include <getopt.h>
+#include <cstring>
+#include <iostream>
+
+#include "TestSettings.h"
+
+#include "TestForkerEventListener.h"
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+bool TestSettings::mForkingDisabled     = false;
+int  TestSettings::mDeviceId            = 0;
+char* const* TestSettings::mArgv;
+
+// --forking-disabled, false by default
+bool TestSettings::ForkingDisabled() {
+    return mForkingDisabled;
+}
+
+// reverse of --forking-disabled (not a flag), true by default
+bool TestSettings::ForkingEnabled() {
+    return !ForkingDisabled();
+}
+
+// --device-id, 0 by default
+int TestSettings::DeviceId() {
+    return mDeviceId;
+}
+
+// returns false if usage should be printed and we should exit early
+bool TestSettings::ParseArgs(int argc, char* const argv[])
+{
+    {
+        char *env = getenv("CAMERA2_TEST_FORKING_DISABLED");
+        if (env) {
+            mForkingDisabled = atoi(env);
+        }
+
+        env = getenv("CAMERA2_TEST_DEVICE_ID");
+        if (env) {
+            mDeviceId = atoi(env);
+        }
+    }
+
+    bool printHelp = false;
+    bool unknownArgs = false;
+
+    opterr = 0; // do not print errors for unknown arguments
+    while (true) {
+        int c;
+        int option_index = 0;
+
+        static struct option long_options[] = {
+            /* name              has_arg          flag val */
+            {"forking-disabled", optional_argument, 0,  0  },
+            {"device-id",        required_argument, 0,  0  },
+            {"help",             no_argument,       0, 'h' },
+            {0,                  0,                 0,  0  }
+        };
+
+        // Note: '+' in optstring means do not mutate argv
+        c = getopt_long(argc, argv, "+h", long_options, &option_index);
+
+        if (c == -1) { // All arguments exhausted
+            break;
+        }
+        if (c == '?') { // Argument not in option lists
+            const char *arg = argv[optind-1];
+            // Anything beginning with gtest_ will get handled by gtest
+            if (strstr(arg, "--gtest_") != arg) {
+                std::cerr << "Unknown argument: " << arg << std::endl;
+                unknownArgs = true;
+            }
+            continue;
+        }
+
+        switch (c) {
+        case 0: // long option
+            switch (option_index) {
+            case 0: {
+                const char *arg = optarg ?: "1";
+                mForkingDisabled = atoi(arg);
+                break;
+            }
+            case 1: {
+                mDeviceId = atoi(optarg);
+                break;
+            }
+            default:
+                std::cerr << "Unknown long option: " << option_index << std::endl;
+                break;
+            }
+            break; // case 0
+        case 'h': // help
+            printHelp = true;
+            break;
+        default: // case '?'
+            std::cerr << "Unknown option: " << optarg << std::endl;
+        }
+    }
+
+    if (unknownArgs) {
+        std::cerr << std::endl;
+    }
+
+    mArgv = argv;
+
+    if (printHelp || unknownArgs) {
+        return false;
+    }
+
+    std::cerr << "Forking Disabled: "
+              << (mForkingDisabled ? "yes" : "no") << std::endl;
+
+    std::cerr << "Device ID: " << mDeviceId << std::endl;
+
+    return true;
+}
+
+// print usage/help list of commands (non-gtest)
+void TestSettings::PrintUsage() {
+    std::cerr << "Usage: " << mArgv[0] << " [OPTIONS]" << std::endl;
+    std::cerr << std::endl;
+
+    std::cerr << "Main modes of operation:"
+              << std::endl;
+    std::cerr << "   --forking-disabled[=1]  don't fork process before "
+              << std::endl
+              << "                           running a new test."
+              << std::endl
+              << "                           (default enabled)"
+              << std::endl;
+    std::cerr << "   --device-id=ID          specify a different camera ID"
+              << std::endl
+              << "                           (default 0)"
+              << std::endl;
+
+    std::cerr << "   -h, --help              print this help listing"
+              << std::endl;
+
+
+    std::cerr << std::endl;
+}
+
+}
+}
+}
+
diff --git a/tests/camera2/TestSettings.h b/tests/camera2/TestSettings.h
new file mode 100644
index 0000000..6164de5
--- /dev/null
+++ b/tests/camera2/TestSettings.h
@@ -0,0 +1,56 @@
+/*
+:qa
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_HAL_CAMERA2_TESTS_SETTINGS__
+#define __ANDROID_HAL_CAMERA2_TESTS_SETTINGS__
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+class TestSettings {
+
+public:
+    // --forking-disabled, false by default
+    static bool ForkingDisabled();
+
+    // reverse of --forking-disabled (not a flag), true by default
+    static bool ForkingEnabled();
+
+    // --device-id, 0 by default
+    static int DeviceId();
+
+    // returns false if usage should be printed and we should exit early
+    static bool ParseArgs(int argc, char* const argv[]);
+
+    // print usage/help list of commands (non-gtest)
+    static void PrintUsage();
+
+private:
+    TestSettings();
+    ~TestSettings();
+
+    static bool mForkingDisabled;
+    static int  mDeviceId;
+    static char* const* mArgv;
+};
+
+}
+}
+}
+
+#endif
diff --git a/tests/camera2/main.cpp b/tests/camera2/main.cpp
index 92c117a..e0ebbe9 100644
--- a/tests/camera2/main.cpp
+++ b/tests/camera2/main.cpp
@@ -14,25 +14,22 @@
  * limitations under the License.
  */
 
-#include <stdlib.h>
-
 #include <gtest/gtest.h>
 #include "TestForkerEventListener.h"
+#include "TestSettings.h"
 
 using android::camera2::tests::TestForkerEventListener;
+using android::camera2::tests::TestSettings;
 
 int main(int argc, char **argv) {
 
+    bool printUsage = !TestSettings::ParseArgs(argc, argv);
+
     ::testing::InitGoogleTest(&argc, argv);
 
-    {
-        //TODO: have a command line flag as well
-        char *env = getenv("CAMERA2_TEST_FORKING_DISABLED");
-        if (env) {
-            int forking = atoi(env);
-
-            TestForkerEventListener::SetForking(!forking);
-        }
+    if (printUsage) {
+        TestSettings::PrintUsage();
+        return 0;
     }
 
     // Gets hold of the event listener list.