diff options
8 files changed, 311 insertions, 33 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 27f64ecbe99a..ccb27eef2075 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -214,6 +214,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { } else { // We'll not invalidate the active source on the hotplug event to pass CETC 11.2.2-2 ~ 3 getWakeLock().release(); + mService.getHdmiCecNetwork().removeDevicesConnectedToPort(portId); mDelayedStandbyHandler.removeCallbacksAndMessages(null); mDelayedStandbyHandler.postDelayed(new DelayedStandbyRunnable(), diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index d249d578cf67..9212fb604721 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1245,6 +1245,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 185eaa92d511..8b6d16a171f5 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java @@ -259,7 +259,10 @@ public class HdmiCecNetwork { // The addition of a local device should not notify listeners return; } - if (old == null) { + if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) { + // Don't notify listeners of devices that haven't reported their physical address yet + return; + } else if (old == null || old.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } else if (!old.equals(info)) { @@ -286,7 +289,10 @@ public class HdmiCecNetwork { assertRunOnServiceThread(); HdmiDeviceInfo old = addDeviceInfo(info); - if (old == null) { + if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) { + // Don't notify listeners of devices that haven't reported their physical address yet + return; + } else if (old == null || old.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } else if (!old.equals(info)) { @@ -360,10 +366,12 @@ public class HdmiCecNetwork { // This only applies to TV devices. // Returns true if the policy is set to true, and the device to check does not have // a parent CEC device (which should be the CEC-enabled switch) in the list. + // Devices with an invalid physical address are assumed to NOT be connected to a legacy switch. private boolean hideDevicesBehindLegacySwitch(HdmiDeviceInfo info) { return isLocalDeviceAddress(Constants.ADDR_TV) && HdmiConfig.HIDE_DEVICES_BEHIND_LEGACY_SWITCH - && !isConnectedToCecSwitch(info.getPhysicalAddress(), getCecSwitches()); + && !isConnectedToCecSwitch(info.getPhysicalAddress(), getCecSwitches()) + && info.getPhysicalAddress() != HdmiDeviceInfo.PATH_INVALID; } /** @@ -377,6 +385,10 @@ public class HdmiCecNetwork { HdmiDeviceInfo info = removeDeviceInfo(HdmiDeviceInfo.idForCecDevice(address)); localDevice.mCecMessageCache.flushMessagesFrom(address); + if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) { + // Don't notify listeners of devices that haven't reported their physical address yet + return; + } invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); } @@ -489,6 +501,34 @@ public class HdmiCecNetwork { } /** + * Attempts to deduce the device type of a device given its logical address. + * If multiple types are possible, returns {@link HdmiDeviceInfo#DEVICE_RESERVED}. + */ + private static int logicalAddressToDeviceType(int logicalAddress) { + switch (logicalAddress) { + case Constants.ADDR_TV: + return HdmiDeviceInfo.DEVICE_TV; + case Constants.ADDR_RECORDER_1: + case Constants.ADDR_RECORDER_2: + case Constants.ADDR_RECORDER_3: + return HdmiDeviceInfo.DEVICE_RECORDER; + case Constants.ADDR_TUNER_1: + case Constants.ADDR_TUNER_2: + case Constants.ADDR_TUNER_3: + case Constants.ADDR_TUNER_4: + return HdmiDeviceInfo.DEVICE_TUNER; + case Constants.ADDR_PLAYBACK_1: + case Constants.ADDR_PLAYBACK_2: + case Constants.ADDR_PLAYBACK_3: + return HdmiDeviceInfo.DEVICE_PLAYBACK; + case Constants.ADDR_AUDIO_SYSTEM: + return HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM; + default: + return HdmiDeviceInfo.DEVICE_RESERVED; + } + } + + /** * Passively listen to incoming CEC messages. * * This shall not result in any CEC messages being sent. @@ -502,6 +542,7 @@ public class HdmiCecNetwork { HdmiDeviceInfo newDevice = HdmiDeviceInfo.cecDeviceBuilder() .setLogicalAddress(sourceAddress) .setDisplayName(HdmiUtils.getDefaultDeviceName(sourceAddress)) + .setDeviceType(logicalAddressToDeviceType(sourceAddress)) .build(); addCecDevice(newDevice); } @@ -699,7 +740,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(); @@ -708,6 +749,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); @@ -816,7 +862,10 @@ public class HdmiCecNetwork { public void clearDeviceList() { assertRunOnServiceThread(); for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) { - if (info.getPhysicalAddress() == getPhysicalAddress()) { + if (info.getPhysicalAddress() == getPhysicalAddress() + || info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) { + // Don't notify listeners of local devices or devices that haven't reported their + // physical address yet continue; } invokeDeviceEventListener(info, @@ -863,10 +912,13 @@ public class HdmiCecNetwork { * on the current device. */ int physicalAddressToPortId(int path) { + int physicalAddress = getPhysicalAddress(); + if (path == physicalAddress) { + // The local device isn't connected to any port; assign portId 0 + return Constants.CEC_SWITCH_HOME; + } int mask = 0xF000; int finalMask = 0xF000; - int physicalAddress; - physicalAddress = getPhysicalAddress(); int maskedAddress = physicalAddress; while (maskedAddress != 0) { diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 8ac233114b48..12380abd0d38 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -1363,10 +1363,6 @@ public class HdmiControlService extends SystemService { device.onHotplug(portId, connected); } - if (!connected) { - mHdmiCecNetwork.removeDevicesConnectedToPort(portId); - } - announceHotplugEvent(portId, connected); } 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 6fc3354f07e7..86130daf4aac 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -2033,4 +2033,32 @@ public class HdmiCecLocalDevicePlaybackTest { mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isFalse(); } + + @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 = HdmiDeviceInfo.cecDeviceBuilder() + .setLogicalAddress(Constants.ADDR_PLAYBACK_3) + .setPhysicalAddress(0x1000) + .setPortId(PORT_1) + .setDeviceType(HdmiDeviceInfo.DEVICE_PLAYBACK) + .setVendorId(0x1000) + .setDisplayName("Playback 3") + .build(); + 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 d104871f488a..df4aa5dac9df 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -19,6 +19,7 @@ import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; import static com.android.server.hdmi.Constants.ADDR_BROADCAST; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; +import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2; import static com.android.server.hdmi.Constants.ADDR_RECORDER_1; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; @@ -53,6 +54,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; @SmallTest @@ -61,6 +63,7 @@ import java.util.concurrent.TimeUnit; /** 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 static final String[] SADS_NOT_TO_QUERY = new String[]{ HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MPEG1, @@ -90,6 +93,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 AudioManager mAudioManager; @@ -133,6 +155,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); @@ -609,4 +636,147 @@ public class HdmiCecLocalDeviceTvTest { ADDR_TV, ADDR_PLAYBACK_1); assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress); } + + @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 = HdmiDeviceInfo.cecDeviceBuilder() + .setLogicalAddress(Constants.ADDR_PLAYBACK_2) + .setPhysicalAddress(0x1000) + .setPortId(PORT_1) + .setDeviceType(HdmiDeviceInfo.DEVICE_PLAYBACK) + .setVendorId(0x1000) + .setDisplayName("Playback 2") + .build(); + 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_FOR_TV); + 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 = HdmiDeviceInfo.cecDeviceBuilder() + .setLogicalAddress(ADDR_AUDIO_SYSTEM) + .setPhysicalAddress(0x1000) + .setPortId(PORT_1) + .setDeviceType(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) + .setVendorId(0x1000) + .setDisplayName("Audio System") + .build(); + 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_FOR_TV); + 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); + } + + @Test + public void listenerInvokedIfPhysicalAddressReported() { + mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .isEmpty(); + HdmiCecMessage reportPhysicalAddress = + HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( + ADDR_PLAYBACK_2, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK); + mNativeWrapper.onCecMessage(reportPhysicalAddress); + mTestLooper.dispatchAll(); + + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .hasSize(1); + assertThat(mDeviceEventListeners.size()).isEqualTo(1); + assertThat(mDeviceEventListeners.get(0).getStatus()) + .isEqualTo(HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); + } + + @Test + public void listenerNotInvokedIfPhysicalAddressUnknown() { + mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .isEmpty(); + HdmiCecMessage setOsdName = HdmiCecMessageBuilder.buildSetOsdNameCommand( + ADDR_PLAYBACK_2, ADDR_TV, "Playback 2"); + mNativeWrapper.onCecMessage(setOsdName); + mTestLooper.dispatchAll(); + + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .hasSize(1); + assertThat(mDeviceEventListeners).isEmpty(); + + // When the device reports its physical address, the listener eventually is invoked. + HdmiCecMessage reportPhysicalAddress = + HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( + ADDR_PLAYBACK_2, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK); + mNativeWrapper.onCecMessage(reportPhysicalAddress); + mTestLooper.dispatchAll(); + + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .hasSize(1); + assertThat(mDeviceEventListeners.size()).isEqualTo(1); + assertThat(mDeviceEventListeners.get(0).getStatus()) + .isEqualTo(HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); + + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java index 42fa32cabc06..03532ae1cb1f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java @@ -102,6 +102,8 @@ public class HdmiCecNetworkTest { new HdmiPortInfo(5, HdmiPortInfo.PORT_OUTPUT, 0x0000, true, false, false); mNativeWrapper.setPortInfo(mHdmiPortInfo); mHdmiCecNetwork.initPortInfo(); + + mHdmiCecNetwork = mHdmiControlService.getHdmiCecNetwork(); } @Test @@ -142,7 +144,24 @@ public class HdmiCecNetworkTest { } @Test + public void physicalAddressToPort_localDevice_weAreSourceDevice() { + mNativeWrapper.setPhysicalAddress(0x2000); + mHdmiCecNetwork.initPortInfo(); + assertThat(mHdmiCecNetwork.physicalAddressToPortId(0x2000)) + .isEqualTo(Constants.CEC_SWITCH_HOME); + } + + @Test + public void physicalAddressToPort_localDevice_weAreTv() { + mNativeWrapper.setPhysicalAddress(0x0000); + mHdmiCecNetwork.initPortInfo(); + assertThat(mHdmiCecNetwork.physicalAddressToPortId(0x0000)) + .isEqualTo(Constants.CEC_SWITCH_HOME); + } + + @Test public void localDevices_verifyOne_tv() { + mHdmiCecNetwork.clearLocalDevices(); mHdmiCecNetwork.addLocalDevice(HdmiDeviceInfo.DEVICE_TV, new HdmiCecLocalDeviceTv(mHdmiControlService)); @@ -155,6 +174,7 @@ public class HdmiCecNetworkTest { @Test public void localDevices_verifyOne_playback() { + mHdmiCecNetwork.clearLocalDevices(); mHdmiCecNetwork.addLocalDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, new HdmiCecLocalDevicePlayback(mHdmiControlService)); @@ -177,27 +197,26 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( HdmiUtils.getDefaultDeviceName(logicalAddress)); assertThat(cecDeviceInfo.getVendorId()).isEqualTo(Constants.VENDOR_ID_UNKNOWN); assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo( HdmiControlManager.POWER_STATUS_UNKNOWN); - assertThat(mDeviceEventListenerStatuses).containsExactly( - HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); + assertThat(mDeviceEventListenerStatuses).isEmpty(); } @Test public void cecDevices_tracking_logicalAddressOnly_doesntNotifyAgain() throws Exception { int logicalAddress = Constants.ADDR_PLAYBACK_1; + int physicalAddress = 0x1000; mHdmiCecNetwork.handleCecMessage( - HdmiCecMessageBuilder.buildActiveSource(logicalAddress, 0x1000)); + HdmiCecMessageBuilder.buildActiveSource(logicalAddress, physicalAddress)); mHdmiCecNetwork.handleCecMessage( - HdmiCecMessageBuilder.buildActiveSource(logicalAddress, 0x1000)); + HdmiCecMessageBuilder.buildActiveSource(logicalAddress, physicalAddress)); - assertThat(mDeviceEventListenerStatuses).containsExactly( - HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); + assertThat(mDeviceEventListenerStatuses).isEmpty(); } @Test @@ -221,6 +240,9 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getVendorId()).isEqualTo(Constants.VENDOR_ID_UNKNOWN); assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo( HdmiControlManager.POWER_STATUS_UNKNOWN); + + assertThat(mDeviceEventListenerStatuses).containsExactly( + HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } @Test @@ -238,11 +260,10 @@ public class HdmiCecNetworkTest { physicalAddress, type)); - // ADD for logical address first detected - // UPDATE for updating device with physical address + // ADD for physical address first detected + // no UPDATE, since physical address didn't change assertThat(mDeviceEventListenerStatuses).containsExactly( - HdmiControlManager.DEVICE_EVENT_ADD_DEVICE, - HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE); + HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } @Test @@ -259,11 +280,13 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); assertThat(cecDeviceInfo.getVendorId()).isEqualTo(Constants.VENDOR_ID_UNKNOWN); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( HdmiUtils.getDefaultDeviceName(logicalAddress)); assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo(powerStatus); + + assertThat(mDeviceEventListenerStatuses).isEmpty(); } @Test @@ -280,11 +303,13 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); assertThat(cecDeviceInfo.getVendorId()).isEqualTo(Constants.VENDOR_ID_UNKNOWN); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo(osdName); assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo( HdmiControlManager.POWER_STATUS_UNKNOWN); + + assertThat(mDeviceEventListenerStatuses).isEmpty(); } @Test @@ -300,12 +325,14 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( HdmiUtils.getDefaultDeviceName(logicalAddress)); assertThat(cecDeviceInfo.getVendorId()).isEqualTo(vendorId); assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo( HdmiControlManager.POWER_STATUS_UNKNOWN); + + assertThat(mDeviceEventListenerStatuses).isEmpty(); } @Test @@ -364,12 +391,10 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo(updatedPhysicalAddress); assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(type); - // ADD for logical address first detected - // UPDATE for updating device with physical address + // ADD for physical address first detected // UPDATE for updating device with new physical address assertThat(mDeviceEventListenerStatuses).containsExactly( HdmiControlManager.DEVICE_EVENT_ADD_DEVICE, - HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE, HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE); } @@ -431,7 +456,7 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( HdmiUtils.getDefaultDeviceName(logicalAddress)); assertThat(cecDeviceInfo.getVendorId()).isEqualTo(updatedVendorId); @@ -453,9 +478,8 @@ public class HdmiCecNetworkTest { assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).isEmpty(); - assertThat(mDeviceEventListenerStatuses).containsExactly( - HdmiControlManager.DEVICE_EVENT_ADD_DEVICE, - HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); + // Physical address never got reported, so no listeners are triggered + assertThat(mDeviceEventListenerStatuses).isEmpty(); } @Test @@ -472,7 +496,7 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); assertThat(cecDeviceInfo.getVendorId()).isEqualTo(Constants.VENDOR_ID_UNKNOWN); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( HdmiUtils.getDefaultDeviceName(logicalAddress)); |