Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +90 −3 Original line number Diff line number Diff line Loading @@ -30,12 +30,15 @@ import android.media.AudioManager; import android.media.AudioSystem; import android.media.tv.TvContract; import android.os.SystemProperties; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.hdmi.Constants.AudioCodec; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import java.io.UnsupportedEncodingException; import java.util.HashMap; /** Loading Loading @@ -101,8 +104,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { final void addCecDevice(HdmiDeviceInfo info) { assertRunOnServiceThread(); HdmiDeviceInfo old = addDeviceInfo(info); if (info.getLogicalAddress() == mAddress) { if (info.getPhysicalAddress() == mService.getPhysicalAddress()) { // The addition of the device itself should not be notified. // Note that different logical address could still be the same local device. return; } if (old == null) { Loading @@ -127,6 +131,23 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); } /** * Called when a device is updated. * * @param info device info of the updating device. */ @ServiceThreadOnly final void updateCecDevice(HdmiDeviceInfo info) { assertRunOnServiceThread(); HdmiDeviceInfo old = addDeviceInfo(info); if (old == null) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } else if (!old.equals(info)) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE); } } /** * Add a new {@link HdmiDeviceInfo}. It returns old device info which has the same * logical address as new device info's. Loading @@ -136,7 +157,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { * that has the same logical address as new one has. */ @ServiceThreadOnly private HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) { @VisibleForTesting protected HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) { assertRunOnServiceThread(); HdmiDeviceInfo oldDeviceInfo = getCecDeviceInfo(deviceInfo.getLogicalAddress()); if (oldDeviceInfo != null) { Loading Loading @@ -262,6 +284,71 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { Constants.PROPERTY_PREFERRED_ADDRESS_AUDIO_SYSTEM, String.valueOf(addr)); } @Override @ServiceThreadOnly protected boolean handleReportPhysicalAddress(HdmiCecMessage message) { assertRunOnServiceThread(); int path = HdmiUtils.twoBytesToInt(message.getParams()); int address = message.getSource(); int type = message.getParams()[2]; // Ignore if [Device Discovery Action] is going on. if (hasAction(DeviceDiscoveryAction.class)) { Slog.i(TAG, "Ignored while Device Discovery Action is in progress: " + message); return true; } // Update the device info with TIF, note that the same device info could have added in // device discovery and we do not want to override it with default OSD name. Therefore we // need the following check to skip redundant device info updating. HdmiDeviceInfo oldDevice = getCecDeviceInfo(address); if (oldDevice == null || oldDevice.getPhysicalAddress() != path) { addCecDevice(new HdmiDeviceInfo( address, path, mService.pathToPortId(path), type, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(address))); // if we are adding a new device info, send out a give osd name command // to update the name of the device in TIF mService.sendCecCommand( HdmiCecMessageBuilder.buildGiveOsdNameCommand(mAddress, address)); return true; } Slog.w(TAG, "Device info exists. Not updating on Physical Address."); return true; } @Override @ServiceThreadOnly protected boolean handleSetOsdName(HdmiCecMessage message) { int source = message.getSource(); String osdName; HdmiDeviceInfo deviceInfo = getCecDeviceInfo(source); // If the device is not in device list, ignore it. if (deviceInfo == null) { Slog.i(TAG, "No source device info for <Set Osd Name>." + message); return true; } try { osdName = new String(message.getParams(), "US-ASCII"); } catch (UnsupportedEncodingException e) { Slog.e(TAG, "Invalid <Set Osd Name> request:" + message, e); return true; } if (deviceInfo.getDisplayName().equals(osdName)) { Slog.d(TAG, "Ignore incoming <Set Osd Name> having same osd name:" + message); return true; } Slog.d(TAG, "Updating device OSD name from " + deviceInfo.getDisplayName() + " to " + osdName); updateCecDevice(new HdmiDeviceInfo(deviceInfo.getLogicalAddress(), deviceInfo.getPhysicalAddress(), deviceInfo.getPortId(), deviceInfo.getDeviceType(), deviceInfo.getVendorId(), osdName)); return true; } @Override @ServiceThreadOnly protected boolean handleReportAudioStatus(HdmiCecMessage message) { Loading services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +89 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE; 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; Loading @@ -25,6 +28,7 @@ import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF; import static com.google.common.truth.Truth.assertThat; import android.hardware.hdmi.HdmiDeviceInfo; import android.media.AudioManager; import android.os.Looper; import android.os.SystemProperties; Loading Loading @@ -64,6 +68,8 @@ public class HdmiCecLocalDeviceAudioSystemTest { private int mMusicMaxVolume; private boolean mMusicMute; private int mAvrPhysicalAddress; private int mInvokeDeviceEventState; private HdmiDeviceInfo mDeviceInfo; @Before public void setUp() { Loading Loading @@ -127,6 +133,18 @@ public class HdmiCecLocalDeviceAudioSystemTest { @Override void wakeUp() {} @Override void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) { mDeviceInfo = device; mInvokeDeviceEventState = status; } @Override int pathToPortId(int path) { // port id is not useful for the test right now return 1; } }; mMyLooper = mTestLooper.getLooper(); Loading Loading @@ -157,6 +175,8 @@ public class HdmiCecLocalDeviceAudioSystemTest { mNativeWrapper.setPhysicalAddress(mAvrPhysicalAddress); SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "true"); SystemProperties.set(Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, "true"); mInvokeDeviceEventState = 0; mDeviceInfo = null; } @Test Loading Loading @@ -611,4 +631,73 @@ public class HdmiCecLocalDeviceAudioSystemTest { mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage); } @Test public void updateCecDevice_deviceNotExists_addDevice() { assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE); HdmiDeviceInfo newDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.updateCecDevice(newDevice); assertThat(mDeviceInfo).isEqualTo(newDevice); assertThat(mHdmiCecLocalDeviceAudioSystem .getCecDeviceInfo(newDevice.getLogicalAddress())).isEqualTo(newDevice); assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_ADD_DEVICE); } @Test public void updateCecDevice_deviceExists_doNothing() { mInvokeDeviceEventState = 0; HdmiDeviceInfo oldDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); mHdmiCecLocalDeviceAudioSystem.updateCecDevice(oldDevice); assertThat(mInvokeDeviceEventState).isEqualTo(0); } @Test public void updateCecDevice_deviceInfoDifferent_updateDevice() { assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_UPDATE_DEVICE); HdmiDeviceInfo oldDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); HdmiDeviceInfo differentDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 4, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.updateCecDevice(differentDevice); assertThat(mDeviceInfo).isEqualTo(differentDevice); assertThat(mHdmiCecLocalDeviceAudioSystem .getCecDeviceInfo(differentDevice.getLogicalAddress())).isEqualTo(differentDevice); assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_UPDATE_DEVICE); } @Test public void handleReportPhysicalAddress_differentPath_addDevice() { assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE); HdmiDeviceInfo oldDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); HdmiDeviceInfo differentDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2200, 1, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); HdmiCecMessage reportPhysicalAddress = HdmiCecMessageBuilder .buildReportPhysicalAddressCommand( ADDR_PLAYBACK_1, 0x2200, HdmiDeviceInfo.DEVICE_PLAYBACK); mHdmiCecLocalDeviceAudioSystem.handleReportPhysicalAddress(reportPhysicalAddress); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); mTestLooper.dispatchAll(); assertThat(mDeviceInfo).isEqualTo(differentDevice); assertThat(mHdmiCecLocalDeviceAudioSystem .getCecDeviceInfo(differentDevice.getLogicalAddress())).isEqualTo(differentDevice); assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_ADD_DEVICE); } } Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +90 −3 Original line number Diff line number Diff line Loading @@ -30,12 +30,15 @@ import android.media.AudioManager; import android.media.AudioSystem; import android.media.tv.TvContract; import android.os.SystemProperties; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.hdmi.Constants.AudioCodec; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import java.io.UnsupportedEncodingException; import java.util.HashMap; /** Loading Loading @@ -101,8 +104,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { final void addCecDevice(HdmiDeviceInfo info) { assertRunOnServiceThread(); HdmiDeviceInfo old = addDeviceInfo(info); if (info.getLogicalAddress() == mAddress) { if (info.getPhysicalAddress() == mService.getPhysicalAddress()) { // The addition of the device itself should not be notified. // Note that different logical address could still be the same local device. return; } if (old == null) { Loading @@ -127,6 +131,23 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); } /** * Called when a device is updated. * * @param info device info of the updating device. */ @ServiceThreadOnly final void updateCecDevice(HdmiDeviceInfo info) { assertRunOnServiceThread(); HdmiDeviceInfo old = addDeviceInfo(info); if (old == null) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); } else if (!old.equals(info)) { invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE); } } /** * Add a new {@link HdmiDeviceInfo}. It returns old device info which has the same * logical address as new device info's. Loading @@ -136,7 +157,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { * that has the same logical address as new one has. */ @ServiceThreadOnly private HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) { @VisibleForTesting protected HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) { assertRunOnServiceThread(); HdmiDeviceInfo oldDeviceInfo = getCecDeviceInfo(deviceInfo.getLogicalAddress()); if (oldDeviceInfo != null) { Loading Loading @@ -262,6 +284,71 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { Constants.PROPERTY_PREFERRED_ADDRESS_AUDIO_SYSTEM, String.valueOf(addr)); } @Override @ServiceThreadOnly protected boolean handleReportPhysicalAddress(HdmiCecMessage message) { assertRunOnServiceThread(); int path = HdmiUtils.twoBytesToInt(message.getParams()); int address = message.getSource(); int type = message.getParams()[2]; // Ignore if [Device Discovery Action] is going on. if (hasAction(DeviceDiscoveryAction.class)) { Slog.i(TAG, "Ignored while Device Discovery Action is in progress: " + message); return true; } // Update the device info with TIF, note that the same device info could have added in // device discovery and we do not want to override it with default OSD name. Therefore we // need the following check to skip redundant device info updating. HdmiDeviceInfo oldDevice = getCecDeviceInfo(address); if (oldDevice == null || oldDevice.getPhysicalAddress() != path) { addCecDevice(new HdmiDeviceInfo( address, path, mService.pathToPortId(path), type, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(address))); // if we are adding a new device info, send out a give osd name command // to update the name of the device in TIF mService.sendCecCommand( HdmiCecMessageBuilder.buildGiveOsdNameCommand(mAddress, address)); return true; } Slog.w(TAG, "Device info exists. Not updating on Physical Address."); return true; } @Override @ServiceThreadOnly protected boolean handleSetOsdName(HdmiCecMessage message) { int source = message.getSource(); String osdName; HdmiDeviceInfo deviceInfo = getCecDeviceInfo(source); // If the device is not in device list, ignore it. if (deviceInfo == null) { Slog.i(TAG, "No source device info for <Set Osd Name>." + message); return true; } try { osdName = new String(message.getParams(), "US-ASCII"); } catch (UnsupportedEncodingException e) { Slog.e(TAG, "Invalid <Set Osd Name> request:" + message, e); return true; } if (deviceInfo.getDisplayName().equals(osdName)) { Slog.d(TAG, "Ignore incoming <Set Osd Name> having same osd name:" + message); return true; } Slog.d(TAG, "Updating device OSD name from " + deviceInfo.getDisplayName() + " to " + osdName); updateCecDevice(new HdmiDeviceInfo(deviceInfo.getLogicalAddress(), deviceInfo.getPhysicalAddress(), deviceInfo.getPortId(), deviceInfo.getDeviceType(), deviceInfo.getVendorId(), osdName)); return true; } @Override @ServiceThreadOnly protected boolean handleReportAudioStatus(HdmiCecMessage message) { Loading
services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +89 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE; 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; Loading @@ -25,6 +28,7 @@ import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF; import static com.google.common.truth.Truth.assertThat; import android.hardware.hdmi.HdmiDeviceInfo; import android.media.AudioManager; import android.os.Looper; import android.os.SystemProperties; Loading Loading @@ -64,6 +68,8 @@ public class HdmiCecLocalDeviceAudioSystemTest { private int mMusicMaxVolume; private boolean mMusicMute; private int mAvrPhysicalAddress; private int mInvokeDeviceEventState; private HdmiDeviceInfo mDeviceInfo; @Before public void setUp() { Loading Loading @@ -127,6 +133,18 @@ public class HdmiCecLocalDeviceAudioSystemTest { @Override void wakeUp() {} @Override void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) { mDeviceInfo = device; mInvokeDeviceEventState = status; } @Override int pathToPortId(int path) { // port id is not useful for the test right now return 1; } }; mMyLooper = mTestLooper.getLooper(); Loading Loading @@ -157,6 +175,8 @@ public class HdmiCecLocalDeviceAudioSystemTest { mNativeWrapper.setPhysicalAddress(mAvrPhysicalAddress); SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "true"); SystemProperties.set(Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, "true"); mInvokeDeviceEventState = 0; mDeviceInfo = null; } @Test Loading Loading @@ -611,4 +631,73 @@ public class HdmiCecLocalDeviceAudioSystemTest { mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage); } @Test public void updateCecDevice_deviceNotExists_addDevice() { assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE); HdmiDeviceInfo newDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.updateCecDevice(newDevice); assertThat(mDeviceInfo).isEqualTo(newDevice); assertThat(mHdmiCecLocalDeviceAudioSystem .getCecDeviceInfo(newDevice.getLogicalAddress())).isEqualTo(newDevice); assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_ADD_DEVICE); } @Test public void updateCecDevice_deviceExists_doNothing() { mInvokeDeviceEventState = 0; HdmiDeviceInfo oldDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); mHdmiCecLocalDeviceAudioSystem.updateCecDevice(oldDevice); assertThat(mInvokeDeviceEventState).isEqualTo(0); } @Test public void updateCecDevice_deviceInfoDifferent_updateDevice() { assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_UPDATE_DEVICE); HdmiDeviceInfo oldDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); HdmiDeviceInfo differentDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 4, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.updateCecDevice(differentDevice); assertThat(mDeviceInfo).isEqualTo(differentDevice); assertThat(mHdmiCecLocalDeviceAudioSystem .getCecDeviceInfo(differentDevice.getLogicalAddress())).isEqualTo(differentDevice); assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_UPDATE_DEVICE); } @Test public void handleReportPhysicalAddress_differentPath_addDevice() { assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE); HdmiDeviceInfo oldDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); HdmiDeviceInfo differentDevice = new HdmiDeviceInfo( ADDR_PLAYBACK_1, 0x2200, 1, HdmiDeviceInfo.DEVICE_PLAYBACK, Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1)); HdmiCecMessage reportPhysicalAddress = HdmiCecMessageBuilder .buildReportPhysicalAddressCommand( ADDR_PLAYBACK_1, 0x2200, HdmiDeviceInfo.DEVICE_PLAYBACK); mHdmiCecLocalDeviceAudioSystem.handleReportPhysicalAddress(reportPhysicalAddress); mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice); mTestLooper.dispatchAll(); assertThat(mDeviceInfo).isEqualTo(differentDevice); assertThat(mHdmiCecLocalDeviceAudioSystem .getCecDeviceInfo(differentDevice.getLogicalAddress())).isEqualTo(differentDevice); assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_ADD_DEVICE); } }