HDMICEC: Instrumentation to register listeners
Use instrumentation tests to register vendor command listeners instead
of an app that uses HDMI_CEC permission.
Test: atest android.hdmicec.cts.common.HdmiCecVendorCommandsTest
Bug: 177061176
Change-Id: Idc9f363158c8756536b13f7d837738b511edbf63
diff --git a/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiCecVendorCommandListener.java b/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiCecVendorCommandListener.java
deleted file mode 100644
index c8a323a..0000000
--- a/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiCecVendorCommandListener.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2020 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.hdmicec.app;
-
-import android.app.Activity;
-import android.hardware.hdmi.HdmiClient;
-import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.HdmiDeviceInfo;
-import android.os.Bundle;
-import android.util.Log;
-
-/**
- * An application to register vendor command listeners. This can be used to test the vendor command
- * listener registration APIs. Actions supported are:
- *
- * <p>
- *
- * <p>1. android.hdmicec.app.VENDOR_LISTENER_WITH_ID: Registers a vendor command listener with
- * vendor ID
- *
- * <p>Usage: <code>START_COMMAND -a android.hdmicec.app.VENDOR_LISTENER_WITH_ID</code>
- *
- * <p>
- *
- * <p>2. android.hdmicec.app.VENDOR_LISTENER_WITHOUT_ID: Registers a vendor command listener without
- * a vendor ID associated with it.
- *
- * <p>Usage: <code>START_COMMAND -a android.hdmicec.app.VENDOR_LISTENER_WITHOUT_ID
- * </code>
- *
- * <p>
- *
- * <p>where START_COMMAND is
- *
- * <p><code>
- * adb shell am start -n "android.hdmicec.app/android.hdmicec.app.HdmiCecVendorCommandListener"
- * </code>
- */
-public class HdmiCecVendorCommandListener extends Activity {
-
- private static final String TAG = HdmiCecVendorCommandListener.class.getSimpleName();
- private static final int VENDOR_ID = 0xBADDAD;
- private HdmiControlManager mHdmiControlManager;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- mHdmiControlManager = getSystemService(HdmiControlManager.class);
- if (mHdmiControlManager == null) {
- Log.i(TAG, "Failed to get HdmiControlManager");
- return;
- }
- HdmiClient client = mHdmiControlManager.getClient(HdmiDeviceInfo.DEVICE_TV);
- if (client == null) {
- client = mHdmiControlManager.getClient(HdmiDeviceInfo.DEVICE_PLAYBACK);
- if (client == null) {
- Log.i(TAG, "Failed to get HDMI client");
- return;
- }
- }
-
- String action = getIntent().getAction();
- switch (action) {
- case "android.hdmicec.app.VENDOR_LISTENER_WITH_ID":
- HdmiControlManager.VendorCommandListener vendorCommandListenerWithId =
- new VendorCommandTestListener(VENDOR_ID);
- client.setVendorCommandListener(vendorCommandListenerWithId, VENDOR_ID);
- break;
- case "android.hdmicec.app.VENDOR_LISTENER_WITHOUT_ID":
- HdmiControlManager.VendorCommandListener vendorCommandListener =
- new VendorCommandTestListener();
- client.setVendorCommandListener(vendorCommandListener);
- break;
- default:
- Log.w(TAG, "Unknown intent!" + action);
- }
- }
-
- private static class VendorCommandTestListener
- implements HdmiControlManager.VendorCommandListener {
-
- int mVendorId = 0xFFFFFF;
-
- VendorCommandTestListener(int vendorId) {
- mVendorId = vendorId;
- }
-
- VendorCommandTestListener() {}
-
- @Override
- public void onReceived(
- int sourceAddress, int destAddress, byte[] params, boolean hasVendorId) {
- if (hasVendorId) {
- int receivedVendorId =
- ((params[0] & 0xFF) << 16) + ((params[1] & 0xFF) << 8) + (params[2] & 0xFF);
-
- if (mVendorId == receivedVendorId) {
- Log.i(TAG, "Received vendor command with correct vendor ID");
- } else {
- Log.i(TAG, "Received vendor command with wrong vendor ID");
- }
- } else {
- Log.i(TAG, "Received vendor command without vendor ID");
- }
- }
-
- @Override
- public void onControlStateChanged(boolean enabled, int reason) {}
- }
-}
diff --git a/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiControlManagerHelper.java b/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiControlManagerHelper.java
index 7a05c13..fbc07ae 100755
--- a/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiControlManagerHelper.java
+++ b/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiControlManagerHelper.java
@@ -18,11 +18,9 @@
import static android.Manifest.permission.HDMI_CEC;
-import android.app.Activity;
import android.content.Context;
import android.hardware.hdmi.HdmiClient;
import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiTvClient;
import android.util.Log;
import android.view.KeyEvent;
@@ -44,6 +42,12 @@
public final class HdmiControlManagerHelper {
private static final String LOGICAL_ADDR = "ARG_LOGICAL_ADDR";
private static final String TAG = HdmiControlManagerHelper.class.getSimpleName();
+ private static final int VENDOR_ID = 0xBADDAD;
+ private static final HdmiControlManager.VendorCommandListener vendorCommandListenerWithoutId =
+ new VendorCommandTestListener();
+ private static final HdmiControlManager.VendorCommandListener vendorCommandListenerWithId =
+ new VendorCommandTestListener(VENDOR_ID);
+
HdmiControlManager mHdmiControlManager;
@Before
@@ -114,4 +118,76 @@
Log.w(TAG, "Interrupted between keyevents, could not send all keyevents!");
}
}
+
+ @Test
+ public void vendorCmdListenerWithId() throws InterruptedException {
+ HdmiClient client = mHdmiControlManager.getPlaybackClient();
+ if (client == null) {
+ client = mHdmiControlManager.getTvClient();
+ }
+
+ if (client == null) {
+ Log.i(TAG, "Could not get a TV/Playback client, cannot register listener");
+ return;
+ }
+
+ client.setVendorCommandListener(vendorCommandListenerWithId, VENDOR_ID);
+ Log.i(TAG, "Registered vendor command listener with ID");
+
+ // Sleep for 20s, 10s waiting for the registration confirmation and 10s waiting for the
+ // callback.
+ TimeUnit.SECONDS.sleep(20);
+ }
+
+ @Test
+ public void vendorCmdListenerWithoutId() throws InterruptedException {
+ HdmiClient client = mHdmiControlManager.getPlaybackClient();
+ if (client == null) {
+ client = mHdmiControlManager.getTvClient();
+ }
+
+ if (client == null) {
+ Log.i(TAG, "Could not get a TV/Playback client, cannot register listener");
+ return;
+ }
+
+ client.setVendorCommandListener(vendorCommandListenerWithoutId);
+ Log.i(TAG, "Registered vendor command listener without ID");
+
+ // Sleep for 20s, 10s waiting for the registration confirmation and 10s waiting for the
+ // callback.
+ TimeUnit.SECONDS.sleep(20);
+ }
+
+ private static class VendorCommandTestListener
+ implements HdmiControlManager.VendorCommandListener {
+
+ int mVendorId = 0xFFFFFF;
+
+ VendorCommandTestListener(int vendorId) {
+ mVendorId = vendorId;
+ }
+
+ VendorCommandTestListener() {}
+
+ @Override
+ public void onReceived(
+ int sourceAddress, int destAddress, byte[] params, boolean hasVendorId) {
+ if (hasVendorId) {
+ int receivedVendorId =
+ ((params[0] & 0xFF) << 16) + ((params[1] & 0xFF) << 8) + (params[2] & 0xFF);
+
+ if (mVendorId == receivedVendorId) {
+ Log.i(TAG, "Received vendor command with correct vendor ID");
+ } else {
+ Log.i(TAG, "Received vendor command with wrong vendor ID");
+ }
+ } else {
+ Log.i(TAG, "Received vendor command without vendor ID");
+ }
+ }
+
+ @Override
+ public void onControlStateChanged(boolean enabled, int reason) {}
+ }
}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiControlManagerUtility.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiControlManagerUtility.java
index 8e81ab3..691490c 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiControlManagerUtility.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiControlManagerUtility.java
@@ -37,6 +37,12 @@
/** The method name of the set active source case. */
private static final String SEND_INTERRUPTED_LONG_PRESS = "interruptedLongPress";
+ /** The method name of the set active source case. */
+ private static final String VENDOR_CMD_LISTENER_WITHOUT_ID = "vendorCmdListenerWithoutId";
+
+ /** The method name of the set active source case. */
+ private static final String VENDOR_CMD_LISTENER_WITH_ID = "vendorCmdListenerWithId";
+
/** The key of the set active source case arguments. */
private static final String LOGICAL_ADDR = "ARG_LOGICAL_ADDR";
@@ -65,4 +71,16 @@
public static void sendLongPressKeyevent(BaseHostJUnit4Test host) throws DeviceNotAvailableException {
host.runDeviceTests(TEST_PKG, TEST_CLS, SEND_INTERRUPTED_LONG_PRESS);
}
+
+ /** Registers a vendor command listener without a vendor ID. */
+ public static void registerVendorCmdListenerWithoutId(BaseHostJUnit4Test host)
+ throws DeviceNotAvailableException {
+ host.runDeviceTests(TEST_PKG, TEST_CLS, VENDOR_CMD_LISTENER_WITHOUT_ID);
+ }
+
+ /** Registers a vendor command listener with vendor ID. */
+ public static void registerVendorCmdListenerWithId(BaseHostJUnit4Test host)
+ throws DeviceNotAvailableException {
+ host.runDeviceTests(TEST_PKG, TEST_CLS, VENDOR_CMD_LISTENER_WITH_ID);
+ }
}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java
index 646ce07..2074a49 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java
@@ -59,6 +59,24 @@
return testString;
}
+ public static void waitForLog(
+ ITestDevice device, String tag, int waitSeconds, String expectedOutput)
+ throws Exception {
+ long timeoutMillis = waitSeconds * 1000;
+ long startTime = System.currentTimeMillis();
+ long endTime = startTime;
+
+ while ((endTime - startTime <= timeoutMillis)) {
+ String testString = getLog(device, tag);
+ if (testString.contains(expectedOutput)) {
+ return;
+ }
+ endTime = System.currentTimeMillis();
+ }
+
+ throw new Exception("Timed out, could not find the log message.");
+ }
+
public static void assertLog(ITestDevice device, String tag, String ...expectedOutput)
throws Exception {
String testString = getLog(device, tag);
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
index 7b18497..96e026d 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
@@ -21,10 +21,13 @@
import android.hdmicec.cts.BaseHdmiCecCtsTest;
import android.hdmicec.cts.CecMessage;
import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.HdmiControlManagerUtility;
import android.hdmicec.cts.LogicalAddress;
import android.hdmicec.cts.LogHelper;
+import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Rule;
@@ -38,22 +41,21 @@
private static final int INCORRECT_VENDOR_ID = 0x0;
- /** The package name of the APK. */
- private static final String PACKAGE = "android.hdmicec.app";
- /** The class name of the main activity in the APK. */
- private static final String CLASS = "HdmiCecVendorCommandListener";
- /** The command to launch the main activity. */
- private static final String START_COMMAND =
- String.format("am start -W -n %s/%s.%s ", PACKAGE, PACKAGE, CLASS);
-
private static final String VENDOR_LISTENER_WITH_ID =
"-a android.hdmicec.app.VENDOR_LISTENER_WITH_ID";
private static final String VENDOR_LISTENER_WITHOUT_ID =
"-a android.hdmicec.app.VENDOR_LISTENER_WITHOUT_ID";
- /** The command to clear the main activity. */
- private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
- // This has to be the same as the vendor ID used in the HdmiCecVendorCommandListener
+ /** Log confirmation message after listener registration. */
+ private static final String REGISTERED_LISTENER = "Registered vendor command listener";
+
+ /** The TAG that the test class will use. */
+ private static final String TEST_LOG_TAG = "HdmiControlManagerHelper";
+
+ /**
+ * This has to be the same as the vendor ID used in the instrumentation test {@link
+ * HdmiControlManagerHelper#VENDOR_ID}
+ */
private static final int VENDOR_ID = 0xBADDAD;
@Rule
@@ -108,78 +110,116 @@
assertThat(CecMessage.getParams(message)).isNotEqualTo(INCORRECT_VENDOR_ID);
}
+ /* The four following tests test the registration of a callback, and if the callback is received
+ * when the DUT receives a <Vendor Command> message.
+ * When there are no listeners registered, the DUT should respond with <Feature Abort>[Refused].
+ * Since the number of listeners registered is not queryable, the case where there are no
+ * listeners registered is not tested.
+ */
+
+ private Thread registerVendorCmdListenerWithId() {
+ return new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ HdmiControlManagerUtility.registerVendorCmdListenerWithId(
+ HdmiCecVendorCommandsTest.this);
+ } catch (DeviceNotAvailableException dnae) {
+ CLog.w("HdmiCecVendorcommandstest", "Device not available exception");
+ }
+ }
+ });
+ }
+
+ private Thread registerVendorCmdListenerWithoutId() {
+ return new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ HdmiControlManagerUtility.registerVendorCmdListenerWithoutId(
+ HdmiCecVendorCommandsTest.this);
+ } catch (DeviceNotAvailableException dnae) {
+ CLog.w("HdmiCecVendorcommandstest", "Device not available exception");
+ }
+ }
+ });
+ }
+
@Test
public void cecVendorCommandListenerWithVendorIdTest() throws Exception {
ITestDevice device = getDevice();
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
- // Clear logcat.
- device.executeAdbCommand("logcat", "-c");
- // Start the APK and wait for it to complete.
- device.executeShellCommand(START_COMMAND + VENDOR_LISTENER_WITH_ID);
+ Thread test = registerVendorCmdListenerWithId();
- String params = CecMessage.formatParams(VENDOR_ID);
- params += CecMessage.formatParams("010203");
- hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND_WITH_ID, params);
+ test.start();
- LogHelper.assertLog(device, CLASS, "Received vendor command with correct vendor ID");
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
+ try {
+ LogHelper.waitForLog(getDevice(), TEST_LOG_TAG, 10, REGISTERED_LISTENER);
+ String params = CecMessage.formatParams(VENDOR_ID);
+ params += CecMessage.formatParams("010203");
+ hdmiCecClient.sendCecMessage(
+ LogicalAddress.TV, CecOperand.VENDOR_COMMAND_WITH_ID, params);
+
+ LogHelper.assertLog(
+ device, TEST_LOG_TAG, "Received vendor command with correct vendor ID");
+ } finally {
+ test.join();
+ }
}
@Test
public void cecVendorCommandListenerReceivesVendorCommandWithoutId() throws Exception {
ITestDevice device = getDevice();
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
- // Clear logcat.
- device.executeAdbCommand("logcat", "-c");
- // Start the APK and wait for it to complete.
- device.executeShellCommand(START_COMMAND + VENDOR_LISTENER_WITH_ID);
+ Thread test = registerVendorCmdListenerWithId();
+ test.start();
- String params = CecMessage.formatParams("010203");
- hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND, params);
+ try {
+ LogHelper.waitForLog(getDevice(), TEST_LOG_TAG, 10, REGISTERED_LISTENER);
- LogHelper.assertLog(device, CLASS, "Received vendor command without vendor ID");
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
+ String params = CecMessage.formatParams("010203");
+ hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND, params);
+
+ LogHelper.assertLog(device, TEST_LOG_TAG, "Received vendor command without vendor ID");
+ } finally {
+ test.join();
+ }
}
@Test
public void cecVendorCommandListenerWithoutVendorIdTest() throws Exception {
ITestDevice device = getDevice();
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
- // Clear logcat.
- device.executeAdbCommand("logcat", "-c");
- // Start the APK and wait for it to complete.
- device.executeShellCommand(START_COMMAND + VENDOR_LISTENER_WITHOUT_ID);
+ Thread test = registerVendorCmdListenerWithoutId();
+ test.start();
- String params = CecMessage.formatParams("010203");
- hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND, params);
+ try {
+ LogHelper.waitForLog(getDevice(), TEST_LOG_TAG, 10, REGISTERED_LISTENER);
- LogHelper.assertLog(device, CLASS, "Received vendor command without vendor ID");
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
+ String params = CecMessage.formatParams("010203");
+ hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND, params);
+
+ LogHelper.assertLog(device, TEST_LOG_TAG, "Received vendor command without vendor ID");
+ } finally {
+ test.join();
+ }
}
@Test
public void cecVendorCommandListenerWithoutVendorIdDoesNotReceiveTest() throws Exception {
ITestDevice device = getDevice();
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
- // Clear logcat.
- device.executeAdbCommand("logcat", "-c");
- // Start the APK and wait for it to complete.
- device.executeShellCommand(START_COMMAND + VENDOR_LISTENER_WITHOUT_ID);
+ Thread test = registerVendorCmdListenerWithoutId();
+ test.start();
- String params = CecMessage.formatParams(VENDOR_ID);
- params += CecMessage.formatParams("010203");
- hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND_WITH_ID, params);
+ try {
+ LogHelper.waitForLog(getDevice(), TEST_LOG_TAG, 10, REGISTERED_LISTENER);
- LogHelper.assertLogDoesNotContain(
- device, CLASS, "Received vendor command with correct vendor ID");
- // Clear activity
- device.executeShellCommand(CLEAR_COMMAND);
+ String params = CecMessage.formatParams(VENDOR_ID);
+ params += CecMessage.formatParams("010203");
+ hdmiCecClient.sendCecMessage(
+ LogicalAddress.TV, CecOperand.VENDOR_COMMAND_WITH_ID, params);
+
+ LogHelper.assertLogDoesNotContain(
+ device, TEST_LOG_TAG, "Received vendor command with correct vendor ID");
+ } finally {
+ test.join();
+ }
}
}