Add Rules to CarBuiltinApi Cts Test Cases

Car Builtin APIs relies on CarService. Added Rule checking to check if
the testing device has the AUTOMOTIVE feature.

Bug: 215411490
Test: atest CtsCarBuiltinApiHostTestCases over cf_x86_64_phone-userdebug
and cf_x86_64_auto-userdebug

Change-Id: Ife04fc60ff5fb91e934027a586aef05092710881
diff --git a/hostsidetests/car_builtin/src/android/car/cts/builtin/BinderHelperHostTest.java b/hostsidetests/car_builtin/src/android/car/cts/builtin/BinderHelperHostTest.java
index b8aa638..e2bfbad 100644
--- a/hostsidetests/car_builtin/src/android/car/cts/builtin/BinderHelperHostTest.java
+++ b/hostsidetests/car_builtin/src/android/car/cts/builtin/BinderHelperHostTest.java
@@ -23,13 +23,12 @@
 import android.car.cts.builtin.os.GetInitialUserInfoCommand;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public final class BinderHelperHostTest extends BaseHostJUnit4Test {
+public final class BinderHelperHostTest extends CarBuiltinApiHostCtsBase {
 
     // When a car shell command (such as, "cmd car_service get-do-activities") is called, it
     // triggers both BinderHelper.onTransactForCmd and
diff --git a/hostsidetests/car_builtin/src/android/car/cts/builtin/CarBuiltinApiHostCtsBase.java b/hostsidetests/car_builtin/src/android/car/cts/builtin/CarBuiltinApiHostCtsBase.java
new file mode 100644
index 0000000..156e02c
--- /dev/null
+++ b/hostsidetests/car_builtin/src/android/car/cts/builtin/CarBuiltinApiHostCtsBase.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package android.car.cts.builtin;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.ITestInformationReceiver;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Base class for all car mainline builtin API host test cases.
+ */
+// NOTE: must be public because of @Rules
+public abstract class CarBuiltinApiHostCtsBase extends BaseHostJUnit4Test {
+
+    @Rule
+    public final RequiredFeatureRule mHasAutomotiveRule = new RequiredFeatureRule(this,
+            "android.hardware.type.automotive");
+
+
+    protected static final class RequiredFeatureRule implements TestRule {
+
+        private final ITestInformationReceiver mReceiver;
+        private final String mFeature;
+
+        RequiredFeatureRule(ITestInformationReceiver receiver, String feature) {
+            mReceiver = receiver;
+            mFeature = feature;
+        }
+
+        @Override
+        public Statement apply(Statement base, Description description) {
+            return new Statement() {
+
+                @Override
+                public void evaluate() throws Throwable {
+                    boolean hasFeature = false;
+                    try {
+                        hasFeature = mReceiver.getTestInformation().getDevice()
+                                .hasFeature(mFeature);
+                    } catch (DeviceNotAvailableException e) {
+                        CLog.e("Could not check if device has feature %s: %e", mFeature, e);
+                        return;
+                    }
+
+                    if (!hasFeature) {
+                        CLog.d("skipping %s#%s"
+                                + " because device does not have feature '%s'",
+                                description.getClassName(), description.getMethodName(), mFeature);
+                        throw new AssumptionViolatedException("Device does not have feature '"
+                                + mFeature + "'");
+                    }
+                    base.evaluate();
+                }
+            };
+        }
+
+        @Override
+        public String toString() {
+            return "RequiredFeatureRule[" + mFeature + "]";
+        }
+    }
+}
diff --git a/hostsidetests/car_builtin/src/android/car/cts/builtin/LockPatternHelperHostTest.java b/hostsidetests/car_builtin/src/android/car/cts/builtin/LockPatternHelperHostTest.java
index e597c65..8ec7c70 100644
--- a/hostsidetests/car_builtin/src/android/car/cts/builtin/LockPatternHelperHostTest.java
+++ b/hostsidetests/car_builtin/src/android/car/cts/builtin/LockPatternHelperHostTest.java
@@ -22,13 +22,12 @@
 import android.car.cts.builtin.widget.CheckLockIsSecureCommand;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public final class LockPatternHelperHostTest extends BaseHostJUnit4Test {
+public final class LockPatternHelperHostTest extends CarBuiltinApiHostCtsBase {
 
     @Test
     public void testIsSecureApi() throws Exception {