summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nathalie Le Clair <lcnathalie@google.com> 2022-04-04 16:13:43 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2022-04-04 16:13:43 +0000
commitd27da8101bb1878833e66dc0b874958731152593 (patch)
tree5178229b1791e5a5df93e0dc1bcf52ca0576c801
parentcc03484e9d5bf6dad4f8196fc914bdffcc0f99ce (diff)
parentc188a5688898bc801b80d2dfee03e1bb5bf6b035 (diff)
Don't remove devices on onHotplug() am: c188a56888
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2039064 Change-Id: I222cf5c44dfc9059f3e503cd2d6b0a10b3d76e46 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl2
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java1
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java5
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecNetwork.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java4
-rw-r--r--services/core/java/com/android/server/hdmi/HotplugDetectionAction.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java28
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java122
8 files changed, 167 insertions, 8 deletions
diff --git a/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl b/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl
index 69f29111635c..b2ddef9c29a6 100644
--- a/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl
@@ -22,6 +22,8 @@ import android.hardware.hdmi.HdmiDeviceInfo;
* Callback interface definition for HDMI client to get informed of
* the CEC logical device status change event.
*
+ * Only to be used on TV panel and Audio System devices (b/226317598).
+ *
* @hide
*/
oneway interface IHdmiDeviceEventListener {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 40718585c484..1be8d327c405 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -127,6 +127,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
// We'll not invalidate the active source on the hotplug event to pass CETC 11.2.2-2 ~ 3.
if (!connected) {
getWakeLock().release();
+ mService.getHdmiCecNetwork().removeDevicesConnectedToPort(portId);
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 3d218cffc5df..b1ffbda8d773 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1218,6 +1218,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@ServiceThreadOnly
void onHotplug(int portId, boolean connected) {
assertRunOnServiceThread();
+
+ if (!connected) {
+ mService.getHdmiCecNetwork().removeCecSwitches(portId);
+ }
+
// Turning System Audio Mode off when the AVR is unlugged or standby.
// When the device is not unplugged but reawaken from standby, we check if the System
// Audio Control Feature is enabled or not then decide if turning SAM on/off accordingly.
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 1234d7fa0832..04a7259a2b2d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -698,7 +698,7 @@ public class HdmiCecNetwork {
return mCecSwitches;
}
- void removeDevicesConnectedToPort(int portId) {
+ void removeCecSwitches(int portId) {
Iterator<Integer> it = mCecSwitches.iterator();
while (it.hasNext()) {
int path = it.next();
@@ -707,6 +707,11 @@ public class HdmiCecNetwork {
it.remove();
}
}
+ }
+
+ void removeDevicesConnectedToPort(int portId) {
+ removeCecSwitches(portId);
+
List<Integer> toRemove = new ArrayList<>();
for (int i = 0; i < mDeviceInfos.size(); i++) {
int key = mDeviceInfos.keyAt(i);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 8dadf5a8d20d..a16bd3b5e6ba 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1251,10 +1251,6 @@ public class HdmiControlService extends SystemService {
device.onHotplug(portId, connected);
}
- if (!connected) {
- mHdmiCecNetwork.removeDevicesConnectedToPort(portId);
- }
-
announceHotplugEvent(portId, connected);
}
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
index 4c4c9783fab0..3d771646df6a 100644
--- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -36,9 +36,9 @@ import java.util.List;
final class HotplugDetectionAction extends HdmiCecFeatureAction {
private static final String TAG = "HotPlugDetectionAction";
- private static final int POLLING_INTERVAL_MS = 5000;
- private static final int TIMEOUT_COUNT = 3;
- private static final int AVR_COUNT_MAX = 3;
+ public static final int POLLING_INTERVAL_MS = 5000;
+ public static final int TIMEOUT_COUNT = 3;
+ public static final int AVR_COUNT_MAX = 3;
// State in which waits for next polling
private static final int STATE_WAIT_FOR_NEXT_POLLING = 1;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 524ad6282397..77af22598c43 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -1789,4 +1789,32 @@ public class HdmiCecLocalDevicePlaybackTest {
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortPressed);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortReleased);
}
+
+ @Test
+ public void onHotplugClearsDevices() {
+ mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ // Add a device to the network and assert that this device is included in the list of
+ // devices.
+ HdmiDeviceInfo infoPlayback = new HdmiDeviceInfo(
+ Constants.ADDR_PLAYBACK_3,
+ 0x1000,
+ PORT_1,
+ HdmiDeviceInfo.DEVICE_PLAYBACK,
+ 0x1000,
+ "Playback 3",
+ HdmiControlManager.POWER_STATUS_ON);
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoPlayback);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .hasSize(1);
+
+ // HAL detects a hotplug out. Assert that this device gets removed from the list of devices.
+ mHdmiControlService.onHotplug(PORT_1, false);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 59711a62f3f3..06cd0bce659e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -56,12 +56,14 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.List;
@SmallTest
@RunWith(JUnit4.class)
/** Tests for {@link HdmiCecLocalDeviceTv} class. */
public class HdmiCecLocalDeviceTvTest {
private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1;
+ private static final int PORT_1 = 1;
private HdmiControlService mHdmiControlService;
private HdmiCecController mHdmiCecController;
@@ -73,6 +75,25 @@ public class HdmiCecLocalDeviceTvTest {
private int mTvPhysicalAddress;
private int mTvLogicalAddress;
private boolean mWokenUp;
+ private List<DeviceEventListener> mDeviceEventListeners = new ArrayList<>();
+
+ private class DeviceEventListener {
+ private HdmiDeviceInfo mDevice;
+ private int mStatus;
+
+ DeviceEventListener(HdmiDeviceInfo device, int status) {
+ this.mDevice = device;
+ this.mStatus = status;
+ }
+
+ int getStatus() {
+ return mStatus;
+ }
+
+ HdmiDeviceInfo getDeviceInfo() {
+ return mDevice;
+ }
+ }
@Mock
private IPowerManager mIPowerManagerMock;
@@ -124,6 +145,11 @@ public class HdmiCecLocalDeviceTvTest {
AudioManager getAudioManager() {
return mAudioManager;
}
+
+ @Override
+ void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) {
+ mDeviceEventListeners.add(new DeviceEventListener(device, status));
+ }
};
mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
@@ -596,4 +622,100 @@ public class HdmiCecLocalDeviceTvTest {
verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
}
+
+ @Test
+ public void hotplugDetectionActionClearsDevices() {
+ mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ // Add a device to the network and assert that this device is included in the list of
+ // devices.
+ HdmiDeviceInfo infoPlayback = new HdmiDeviceInfo(
+ Constants.ADDR_PLAYBACK_2,
+ 0x1000,
+ PORT_1,
+ HdmiDeviceInfo.DEVICE_PLAYBACK,
+ 0x1000,
+ "Playback 2",
+ HdmiControlManager.POWER_STATUS_ON);
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoPlayback);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .hasSize(1);
+ mDeviceEventListeners.clear();
+ assertThat(mDeviceEventListeners.size()).isEqualTo(0);
+
+ // HAL detects a hotplug out. Assert that this device stays in the list of devices.
+ mHdmiControlService.onHotplug(PORT_1, false);
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .hasSize(1);
+ assertThat(mDeviceEventListeners).isEmpty();
+ mTestLooper.dispatchAll();
+ // Make the device not acknowledge the poll message sent by the HotplugDetectionAction.
+ // Assert that this device is removed from the list of devices.
+ mNativeWrapper.setPollAddressResponse(Constants.ADDR_PLAYBACK_2, SendMessageResult.NACK);
+ for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) {
+ mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_INTERVAL_MS);
+ mTestLooper.dispatchAll();
+ }
+
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ assertThat(mDeviceEventListeners.size()).isEqualTo(1);
+ assertThat(mDeviceEventListeners.get(0).getStatus())
+ .isEqualTo(HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
+ HdmiDeviceInfo removedDeviceInfo = mDeviceEventListeners.get(0).getDeviceInfo();
+ assertThat(removedDeviceInfo.getPortId()).isEqualTo(PORT_1);
+ assertThat(removedDeviceInfo.getLogicalAddress()).isEqualTo(Constants.ADDR_PLAYBACK_2);
+ assertThat(removedDeviceInfo.getPhysicalAddress()).isEqualTo(0x1000);
+ assertThat(removedDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK);
+ }
+
+ @Test
+ public void hotplugDetectionActionClearsDevices_AudioSystem() {
+ mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ // Add a device to the network and assert that this device is included in the list of
+ // devices.
+ HdmiDeviceInfo infoAudioSystem = new HdmiDeviceInfo(
+ ADDR_AUDIO_SYSTEM,
+ 0x1000,
+ PORT_1,
+ HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM,
+ 0x1000,
+ "Audio System",
+ HdmiControlManager.POWER_STATUS_ON);
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoAudioSystem);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .hasSize(1);
+ mDeviceEventListeners.clear();
+ assertThat(mDeviceEventListeners.size()).isEqualTo(0);
+
+ // HAL detects a hotplug out. Assert that this device stays in the list of devices.
+ mHdmiControlService.onHotplug(PORT_1, false);
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .hasSize(1);
+ assertThat(mDeviceEventListeners).isEmpty();
+ mTestLooper.dispatchAll();
+ // Make the device not acknowledge the poll message sent by the HotplugDetectionAction.
+ // Assert that this device is removed from the list of devices.
+ mNativeWrapper.setPollAddressResponse(ADDR_AUDIO_SYSTEM, SendMessageResult.NACK);
+ for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) {
+ mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_INTERVAL_MS);
+ mTestLooper.dispatchAll();
+ }
+
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ assertThat(mDeviceEventListeners.size()).isEqualTo(1);
+ assertThat(mDeviceEventListeners.get(0).getStatus())
+ .isEqualTo(HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
+ HdmiDeviceInfo removedDeviceInfo = mDeviceEventListeners.get(0).getDeviceInfo();
+ assertThat(removedDeviceInfo.getPortId()).isEqualTo(PORT_1);
+ assertThat(removedDeviceInfo.getLogicalAddress()).isEqualTo(Constants.ADDR_AUDIO_SYSTEM);
+ assertThat(removedDeviceInfo.getPhysicalAddress()).isEqualTo(0x1000);
+ assertThat(removedDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
+ }
}