vibrator: aidl: Apply Compose API Feedback

- Make Thud and Spin optional due to complexity.
- Make "scale" inclusive of zero, which represents minimum "feelable"
  intensity.
- Update VTS tests appropriately.
- Fix typo in VTS test names.

Bug: 151084263
Test: VTS on Flame, Walleye, and Cuttlefish
Signed-off-by: Harpreet \"Eli\" Sangha <eliptus@google.com>
Change-Id: Ib0d046be83ee79ab38e0b9c3fb87a41f23879f8b
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 8b16025..8340517 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -21,6 +21,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
+#include <cmath>
 #include <future>
 
 using android::ProcessState;
@@ -53,6 +54,11 @@
         android::enum_range<CompositePrimitive>().begin(),
         android::enum_range<CompositePrimitive>().end()};
 
+const std::vector<CompositePrimitive> kOptionalPrimitives = {
+        CompositePrimitive::THUD,
+        CompositePrimitive::SPIN,
+};
+
 const std::vector<CompositePrimitive> kInvalidPrimitives = {
         static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
         static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
@@ -264,38 +270,56 @@
 
         EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
 
-        std::sort(supported.begin(), supported.end());
+        for (auto primitive : kCompositePrimitives) {
+            bool isPrimitiveSupported =
+                    std::find(supported.begin(), supported.end(), primitive) != supported.end();
+            bool isPrimitiveOptional =
+                    std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) !=
+                    kOptionalPrimitives.end();
 
-        EXPECT_EQ(kCompositePrimitives, supported);
+            EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive);
+        }
     }
 }
 
 TEST_P(VibratorAidl, GetPrimitiveDuration) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
-        int32_t duration;
+        std::vector<CompositePrimitive> supported;
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
 
         for (auto primitive : kCompositePrimitives) {
-            EXPECT_EQ(Status::EX_NONE,
-                      vibrator->getPrimitiveDuration(primitive, &duration).exceptionCode());
+            bool isPrimitiveSupported =
+                    std::find(supported.begin(), supported.end(), primitive) != supported.end();
+            int32_t duration;
+
+            Status status = vibrator->getPrimitiveDuration(primitive, &duration);
+
+            if (isPrimitiveSupported) {
+                EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+            } else {
+                EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+            }
         }
     }
 }
 
 TEST_P(VibratorAidl, ComposeValidPrimitives) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+        std::vector<CompositePrimitive> supported;
         int32_t maxDelay, maxSize;
 
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
         EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
         EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
 
         std::vector<CompositeEffect> composite;
 
-        for (auto primitive : kCompositePrimitives) {
+        for (auto primitive : supported) {
             CompositeEffect effect;
 
             effect.delayMs = std::rand() % (maxDelay + 1);
             effect.primitive = primitive;
-            effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
+            effect.scale = static_cast<float>(std::rand()) / RAND_MAX;
             composite.emplace_back(effect);
 
             if (composite.size() == maxSize) {
@@ -314,7 +338,21 @@
 
 TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
-        for (auto primitive : kInvalidPrimitives) {
+        auto unsupported = kInvalidPrimitives;
+        std::vector<CompositePrimitive> supported;
+
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+
+        for (auto primitive : kCompositePrimitives) {
+            bool isPrimitiveSupported =
+                    std::find(supported.begin(), supported.end(), primitive) != supported.end();
+
+            if (!isPrimitiveSupported) {
+                unsupported.push_back(primitive);
+            }
+        }
+
+        for (auto primitive : unsupported) {
             std::vector<CompositeEffect> composite(1);
 
             for (auto& effect : composite) {
@@ -329,7 +367,33 @@
     }
 }
 
-TEST_P(VibratorAidl, CompseDelayBoundary) {
+TEST_P(VibratorAidl, ComposeScaleBoundary) {
+    if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+        std::vector<CompositeEffect> composite(1);
+        CompositeEffect& effect = composite[0];
+
+        effect.delayMs = 0;
+        effect.primitive = CompositePrimitive::CLICK;
+
+        effect.scale = std::nextafter(0.0f, -1.0f);
+        EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+                  vibrator->compose(composite, nullptr).exceptionCode());
+
+        effect.scale = 0.0f;
+        EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+        effect.scale = 1.0f;
+        EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+        effect.scale = std::nextafter(1.0f, 2.0f);
+        EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+                  vibrator->compose(composite, nullptr).exceptionCode());
+
+        vibrator->off();
+    }
+}
+
+TEST_P(VibratorAidl, ComposeDelayBoundary) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
         int32_t maxDelay;
 
@@ -354,7 +418,7 @@
     }
 }
 
-TEST_P(VibratorAidl, CompseSizeBoundary) {
+TEST_P(VibratorAidl, ComposeSizeBoundary) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
         int32_t maxSize;