Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +143 −112 Original line number Diff line number Diff line Loading @@ -27,11 +27,9 @@ import android.util.Slog; import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; import java.util.ArrayList; import java.util.Collections; Loading @@ -39,8 +37,8 @@ import java.util.Iterator; import java.util.List; /** * Class that models a logical CEC device hosted in this system. Handles initialization, * CEC commands that call for actions customized per device type. * Class that models a logical CEC device hosted in this system. Handles initialization, CEC * commands that call for actions customized per device type. */ abstract class HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDevice"; Loading Loading @@ -69,47 +67,60 @@ abstract class HdmiCecLocalDevice { public ActiveSource() { invalidate(); } public ActiveSource(int logical, int physical) { logicalAddress = logical; physicalAddress = physical; } public static ActiveSource of(ActiveSource source) { return new ActiveSource(source.logicalAddress, source.physicalAddress); } public static ActiveSource of(int logical, int physical) { return new ActiveSource(logical, physical); } public boolean isValid() { return HdmiUtils.isValidAddress(logicalAddress); } public void invalidate() { logicalAddress = Constants.ADDR_INVALID; physicalAddress = Constants.INVALID_PHYSICAL_ADDRESS; } public boolean equals(int logical, int physical) { return logicalAddress == logical && physicalAddress == physical; } @Override public boolean equals(Object obj) { if (obj instanceof ActiveSource) { ActiveSource that = (ActiveSource) obj; return that.logicalAddress == logicalAddress && that.physicalAddress == physicalAddress; return that.logicalAddress == logicalAddress && that.physicalAddress == physicalAddress; } return false; } @Override public int hashCode() { return logicalAddress * 29 + physicalAddress; } @Override public String toString() { StringBuffer s = new StringBuffer(); String logicalAddressString = (logicalAddress == Constants.ADDR_INVALID) ? "invalid" : String.format("0x%02x", logicalAddress); String logicalAddressString = (logicalAddress == Constants.ADDR_INVALID) ? "invalid" : String.format("0x%02x", logicalAddress); s.append("(").append(logicalAddressString); String physicalAddressString = (physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) ? "invalid" : String.format("0x%04x", physicalAddress); String physicalAddressString = (physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) ? "invalid" : String.format("0x%04x", physicalAddress); s.append(", ").append(physicalAddressString).append(")"); return s.toString(); } Loading @@ -131,7 +142,8 @@ abstract class HdmiCecLocalDevice { // Note that access to this collection should happen in service thread. private final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>(); private final Handler mHandler = new Handler () { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { Loading @@ -146,8 +158,8 @@ abstract class HdmiCecLocalDevice { }; /** * A callback interface to get notified when all pending action is cleared. * It can be called when timeout happened. * A callback interface to get notified when all pending action is cleared. It can be called * when timeout happened. */ interface PendingActionClearedCallback { void onCleared(HdmiCecLocalDevice device); Loading Loading @@ -183,27 +195,22 @@ abstract class HdmiCecLocalDevice { mPendingActionClearedCallback = null; } /** * Called once a logical address of the local device is allocated. */ /** Called once a logical address of the local device is allocated. */ protected abstract void onAddressAllocated(int logicalAddress, int reason); /** * Get the preferred logical address from system properties. */ /** Get the preferred logical address from system properties. */ protected abstract int getPreferredAddress(); /** * Set the preferred logical address to system properties. */ /** Set the preferred logical address to system properties. */ protected abstract void setPreferredAddress(int addr); /** * Returns true if the TV input associated with the CEC device is ready * to accept further processing such as input switching. This is used * to buffer certain CEC commands and process it later if the input is not * ready yet. For other types of local devices(non-TV), this method returns * true by default to let the commands be processed right away. * Returns true if the TV input associated with the CEC device is ready to accept further * processing such as input switching. * * <p>This is used to buffer certain CEC commands and process it later if the input is not ready * yet. For other types of local devices(non-TV), this method returns true by default to let the * commands be processed right away. */ protected boolean isInputReady(int deviceId) { return true; Loading @@ -211,7 +218,8 @@ abstract class HdmiCecLocalDevice { /** * Returns true if the local device allows the system to be put to standby. * The default implementation returns true. * * <p>The default implementation returns true. */ protected boolean canGoToStandby() { return true; Loading Loading @@ -347,7 +355,8 @@ abstract class HdmiCecLocalDevice { assertRunOnServiceThread(); int physicalAddress = mService.getPhysicalAddress(); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( mAddress, physicalAddress, mDeviceType); mService.sendCecCommand(cecMessage, callback); return true; Loading @@ -357,8 +366,8 @@ abstract class HdmiCecLocalDevice { protected boolean handleGiveDeviceVendorId(@Nullable SendMessageCallback callback) { assertRunOnServiceThread(); int vendorId = mService.getVendorId(); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand( mAddress, vendorId); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand(mAddress, vendorId); mService.sendCecCommand(cecMessage, callback); return true; } Loading @@ -367,8 +376,9 @@ abstract class HdmiCecLocalDevice { protected boolean handleGetCecVersion(HdmiCecMessage message) { assertRunOnServiceThread(); int version = mService.getCecVersion(); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion(message.getDestination(), message.getSource(), version); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion( message.getDestination(), message.getSource(), version); mService.sendCecCommand(cecMessage); return true; } Loading Loading @@ -409,7 +419,8 @@ abstract class HdmiCecLocalDevice { assertRunOnServiceThread(); // Note that since this method is called after logical address allocation is done, // mDeviceInfo should not be null. HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand( HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand( mAddress, message.getSource(), mDeviceInfo.getDisplayName()); if (cecMessage != null) { mService.sendCecCommand(cecMessage); Loading Loading @@ -483,7 +494,8 @@ abstract class HdmiCecLocalDevice { protected boolean handleStandby(HdmiCecMessage message) { assertRunOnServiceThread(); // Seq #12 if (mService.isControlEnabled() && !mService.isProhibitMode() if (mService.isControlEnabled() && !mService.isProhibitMode() && mService.isPowerOnOrTransient()) { mService.standby(); return true; Loading Loading @@ -519,7 +531,8 @@ abstract class HdmiCecLocalDevice { if (keycode != HdmiCecKeycode.UNSUPPORTED_KEYCODE) { injectKeyEvent(downTime, KeyEvent.ACTION_DOWN, keycode, keyRepeatCount); mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT), mHandler.sendMessageDelayed( Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT), FOLLOWER_SAFETY_TIMEOUT); return true; } Loading @@ -541,11 +554,21 @@ abstract class HdmiCecLocalDevice { } static void injectKeyEvent(long time, int action, int keycode, int repeat) { KeyEvent keyEvent = KeyEvent.obtain(time, time, action, keycode, repeat, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_HDMI, null); InputManager.getInstance().injectInputEvent(keyEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); KeyEvent keyEvent = KeyEvent.obtain( time, time, action, keycode, repeat, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_HDMI, null); InputManager.getInstance() .injectInputEvent(keyEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); keyEvent.recycle(); } Loading Loading @@ -577,14 +600,16 @@ abstract class HdmiCecLocalDevice { } protected boolean handleGiveDevicePowerStatus(HdmiCecMessage message) { mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPowerStatus( mService.sendCecCommand( HdmiCecMessageBuilder.buildReportPowerStatus( mAddress, message.getSource(), mService.getPowerStatus())); return true; } protected boolean handleMenuRequest(HdmiCecMessage message) { // Always report menu active to receive Remote Control. mService.sendCecCommand(HdmiCecMessageBuilder.buildReportMenuStatus( mService.sendCecCommand( HdmiCecMessageBuilder.buildReportMenuStatus( mAddress, message.getSource(), Constants.MENU_STATE_ACTIVATED)); return true; } Loading @@ -594,8 +619,12 @@ abstract class HdmiCecLocalDevice { } protected boolean handleVendorCommand(HdmiCecMessage message) { if (!mService.invokeVendorCommandListenersOnReceived(mDeviceType, message.getSource(), message.getDestination(), message.getParams(), false)) { if (!mService.invokeVendorCommandListenersOnReceived( mDeviceType, message.getSource(), message.getDestination(), message.getParams(), false)) { // Vendor command listener may not have been registered yet. Respond with // <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later. mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); Loading @@ -607,12 +636,12 @@ abstract class HdmiCecLocalDevice { byte[] params = message.getParams(); int vendorId = HdmiUtils.threeBytesToInt(params); if (vendorId == mService.getVendorId()) { if (!mService.invokeVendorCommandListenersOnReceived(mDeviceType, message.getSource(), message.getDestination(), params, true)) { if (!mService.invokeVendorCommandListenersOnReceived( mDeviceType, message.getSource(), message.getDestination(), params, true)) { mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); } } else if (message.getDestination() != Constants.ADDR_BROADCAST && message.getSource() != Constants.ADDR_UNREGISTERED) { } else if (message.getDestination() != Constants.ADDR_BROADCAST && message.getSource() != Constants.ADDR_UNREGISTERED) { Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>"); mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE); } else { Loading Loading @@ -764,8 +793,8 @@ abstract class HdmiCecLocalDevice { // Remove all actions matched with the given Class type besides |exception|. @ServiceThreadOnly <T extends HdmiCecFeatureAction> void removeActionExcept(final Class<T> clazz, final HdmiCecFeatureAction exception) { <T extends HdmiCecFeatureAction> void removeActionExcept( final Class<T> clazz, final HdmiCecFeatureAction exception) { assertRunOnServiceThread(); Iterator<HdmiCecFeatureAction> iter = mActions.iterator(); while (iter.hasNext()) { Loading Loading @@ -793,8 +822,7 @@ abstract class HdmiCecLocalDevice { } } void setAutoDeviceOff(boolean enabled) { } void setAutoDeviceOff(boolean enabled) {} /** * Called when a hot-plug event issued. Loading @@ -802,8 +830,7 @@ abstract class HdmiCecLocalDevice { * @param portId id of port where a hot-plug event happened * @param connected whether to connected or not on the event */ void onHotplug(int portId, boolean connected) { } void onHotplug(int portId, boolean connected) {} final HdmiControlService getService() { return mService; Loading Loading @@ -886,34 +913,34 @@ abstract class HdmiCecLocalDevice { /** * Called when the system goes to standby mode. * * @param initiatedByCec true if this power sequence is initiated * by the reception the CEC messages like <Standby> * @param standbyAction Intent action that drives the standby process, * either {@link HdmiControlService#STANDBY_SCREEN_OFF} or * {@link HdmiControlService#STANDBY_SHUTDOWN} * @param initiatedByCec true if this power sequence is initiated by the reception the CEC * messages like <Standby> * @param standbyAction Intent action that drives the standby process, either {@link * HdmiControlService#STANDBY_SCREEN_OFF} or {@link HdmiControlService#STANDBY_SHUTDOWN} */ protected void onStandby(boolean initiatedByCec, int standbyAction) {} /** * Disable device. {@code callback} is used to get notified when all pending * actions are completed or timeout is issued. * Disable device. {@code callback} is used to get notified when all pending actions are * completed or timeout is issued. * * @param initiatedByCec true if this sequence is initiated * by the reception the CEC messages like <Standby> * @param initiatedByCec true if this sequence is initiated by the reception the CEC messages * like <Standby> * @param originalCallback callback interface to get notified when all pending actions are * cleared */ protected void disableDevice(boolean initiatedByCec, final PendingActionClearedCallback originalCallback) { mPendingActionClearedCallback = new PendingActionClearedCallback() { protected void disableDevice( boolean initiatedByCec, final PendingActionClearedCallback originalCallback) { mPendingActionClearedCallback = new PendingActionClearedCallback() { @Override public void onCleared(HdmiCecLocalDevice device) { mHandler.removeMessages(MSG_DISABLE_DEVICE_TIMEOUT); originalCallback.onCleared(device); } }; mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_DISABLE_DEVICE_TIMEOUT), DEVICE_CLEANUP_TIMEOUT); mHandler.sendMessageDelayed( Message.obtain(mHandler, MSG_DISABLE_DEVICE_TIMEOUT), DEVICE_CLEANUP_TIMEOUT); } @ServiceThreadOnly Loading Loading @@ -952,8 +979,14 @@ abstract class HdmiCecLocalDevice { int logicalAddress = findKeyReceiverAddress(); if (logicalAddress == Constants.ADDR_INVALID || logicalAddress == mAddress) { // Don't send key event to invalid device or itself. Slog.w(TAG, "Discard key event: " + keyCode + ", pressed:" + isPressed + ", receiverAddr=" + logicalAddress); Slog.w( TAG, "Discard key event: " + keyCode + ", pressed:" + isPressed + ", receiverAddr=" + logicalAddress); } else if (!action.isEmpty()) { action.get(0).processKeyEvent(keyCode, isPressed); } else if (isPressed) { Loading @@ -962,8 +995,8 @@ abstract class HdmiCecLocalDevice { } /** * Returns the logical address of the device which will receive key events via * {@link #sendKeyEvent}. * Returns the logical address of the device which will receive key events via {@link * #sendKeyEvent}. * * @see #sendKeyEvent(int, boolean) */ Loading @@ -973,15 +1006,13 @@ abstract class HdmiCecLocalDevice { } void sendUserControlPressedAndReleased(int targetAddress, int cecKeycode) { mService.sendCecCommand(HdmiCecMessageBuilder.buildUserControlPressed( mAddress, targetAddress, cecKeycode)); mService.sendCecCommand(HdmiCecMessageBuilder.buildUserControlReleased( mAddress, targetAddress)); mService.sendCecCommand( HdmiCecMessageBuilder.buildUserControlPressed(mAddress, targetAddress, cecKeycode)); mService.sendCecCommand( HdmiCecMessageBuilder.buildUserControlReleased(mAddress, targetAddress)); } /** * Dump internal status of HdmiCecLocalDevice object. */ /** Dump internal status of HdmiCecLocalDevice object. */ protected void dump(final IndentingPrintWriter pw) { pw.println("mDeviceType: " + mDeviceType); pw.println("mAddress: " + mAddress); Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +57 −44 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +143 −112 Original line number Diff line number Diff line Loading @@ -27,11 +27,9 @@ import android.util.Slog; import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; import java.util.ArrayList; import java.util.Collections; Loading @@ -39,8 +37,8 @@ import java.util.Iterator; import java.util.List; /** * Class that models a logical CEC device hosted in this system. Handles initialization, * CEC commands that call for actions customized per device type. * Class that models a logical CEC device hosted in this system. Handles initialization, CEC * commands that call for actions customized per device type. */ abstract class HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDevice"; Loading Loading @@ -69,47 +67,60 @@ abstract class HdmiCecLocalDevice { public ActiveSource() { invalidate(); } public ActiveSource(int logical, int physical) { logicalAddress = logical; physicalAddress = physical; } public static ActiveSource of(ActiveSource source) { return new ActiveSource(source.logicalAddress, source.physicalAddress); } public static ActiveSource of(int logical, int physical) { return new ActiveSource(logical, physical); } public boolean isValid() { return HdmiUtils.isValidAddress(logicalAddress); } public void invalidate() { logicalAddress = Constants.ADDR_INVALID; physicalAddress = Constants.INVALID_PHYSICAL_ADDRESS; } public boolean equals(int logical, int physical) { return logicalAddress == logical && physicalAddress == physical; } @Override public boolean equals(Object obj) { if (obj instanceof ActiveSource) { ActiveSource that = (ActiveSource) obj; return that.logicalAddress == logicalAddress && that.physicalAddress == physicalAddress; return that.logicalAddress == logicalAddress && that.physicalAddress == physicalAddress; } return false; } @Override public int hashCode() { return logicalAddress * 29 + physicalAddress; } @Override public String toString() { StringBuffer s = new StringBuffer(); String logicalAddressString = (logicalAddress == Constants.ADDR_INVALID) ? "invalid" : String.format("0x%02x", logicalAddress); String logicalAddressString = (logicalAddress == Constants.ADDR_INVALID) ? "invalid" : String.format("0x%02x", logicalAddress); s.append("(").append(logicalAddressString); String physicalAddressString = (physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) ? "invalid" : String.format("0x%04x", physicalAddress); String physicalAddressString = (physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) ? "invalid" : String.format("0x%04x", physicalAddress); s.append(", ").append(physicalAddressString).append(")"); return s.toString(); } Loading @@ -131,7 +142,8 @@ abstract class HdmiCecLocalDevice { // Note that access to this collection should happen in service thread. private final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>(); private final Handler mHandler = new Handler () { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { Loading @@ -146,8 +158,8 @@ abstract class HdmiCecLocalDevice { }; /** * A callback interface to get notified when all pending action is cleared. * It can be called when timeout happened. * A callback interface to get notified when all pending action is cleared. It can be called * when timeout happened. */ interface PendingActionClearedCallback { void onCleared(HdmiCecLocalDevice device); Loading Loading @@ -183,27 +195,22 @@ abstract class HdmiCecLocalDevice { mPendingActionClearedCallback = null; } /** * Called once a logical address of the local device is allocated. */ /** Called once a logical address of the local device is allocated. */ protected abstract void onAddressAllocated(int logicalAddress, int reason); /** * Get the preferred logical address from system properties. */ /** Get the preferred logical address from system properties. */ protected abstract int getPreferredAddress(); /** * Set the preferred logical address to system properties. */ /** Set the preferred logical address to system properties. */ protected abstract void setPreferredAddress(int addr); /** * Returns true if the TV input associated with the CEC device is ready * to accept further processing such as input switching. This is used * to buffer certain CEC commands and process it later if the input is not * ready yet. For other types of local devices(non-TV), this method returns * true by default to let the commands be processed right away. * Returns true if the TV input associated with the CEC device is ready to accept further * processing such as input switching. * * <p>This is used to buffer certain CEC commands and process it later if the input is not ready * yet. For other types of local devices(non-TV), this method returns true by default to let the * commands be processed right away. */ protected boolean isInputReady(int deviceId) { return true; Loading @@ -211,7 +218,8 @@ abstract class HdmiCecLocalDevice { /** * Returns true if the local device allows the system to be put to standby. * The default implementation returns true. * * <p>The default implementation returns true. */ protected boolean canGoToStandby() { return true; Loading Loading @@ -347,7 +355,8 @@ abstract class HdmiCecLocalDevice { assertRunOnServiceThread(); int physicalAddress = mService.getPhysicalAddress(); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( mAddress, physicalAddress, mDeviceType); mService.sendCecCommand(cecMessage, callback); return true; Loading @@ -357,8 +366,8 @@ abstract class HdmiCecLocalDevice { protected boolean handleGiveDeviceVendorId(@Nullable SendMessageCallback callback) { assertRunOnServiceThread(); int vendorId = mService.getVendorId(); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand( mAddress, vendorId); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand(mAddress, vendorId); mService.sendCecCommand(cecMessage, callback); return true; } Loading @@ -367,8 +376,9 @@ abstract class HdmiCecLocalDevice { protected boolean handleGetCecVersion(HdmiCecMessage message) { assertRunOnServiceThread(); int version = mService.getCecVersion(); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion(message.getDestination(), message.getSource(), version); HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion( message.getDestination(), message.getSource(), version); mService.sendCecCommand(cecMessage); return true; } Loading Loading @@ -409,7 +419,8 @@ abstract class HdmiCecLocalDevice { assertRunOnServiceThread(); // Note that since this method is called after logical address allocation is done, // mDeviceInfo should not be null. HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand( HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand( mAddress, message.getSource(), mDeviceInfo.getDisplayName()); if (cecMessage != null) { mService.sendCecCommand(cecMessage); Loading Loading @@ -483,7 +494,8 @@ abstract class HdmiCecLocalDevice { protected boolean handleStandby(HdmiCecMessage message) { assertRunOnServiceThread(); // Seq #12 if (mService.isControlEnabled() && !mService.isProhibitMode() if (mService.isControlEnabled() && !mService.isProhibitMode() && mService.isPowerOnOrTransient()) { mService.standby(); return true; Loading Loading @@ -519,7 +531,8 @@ abstract class HdmiCecLocalDevice { if (keycode != HdmiCecKeycode.UNSUPPORTED_KEYCODE) { injectKeyEvent(downTime, KeyEvent.ACTION_DOWN, keycode, keyRepeatCount); mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT), mHandler.sendMessageDelayed( Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT), FOLLOWER_SAFETY_TIMEOUT); return true; } Loading @@ -541,11 +554,21 @@ abstract class HdmiCecLocalDevice { } static void injectKeyEvent(long time, int action, int keycode, int repeat) { KeyEvent keyEvent = KeyEvent.obtain(time, time, action, keycode, repeat, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_HDMI, null); InputManager.getInstance().injectInputEvent(keyEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); KeyEvent keyEvent = KeyEvent.obtain( time, time, action, keycode, repeat, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_HDMI, null); InputManager.getInstance() .injectInputEvent(keyEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); keyEvent.recycle(); } Loading Loading @@ -577,14 +600,16 @@ abstract class HdmiCecLocalDevice { } protected boolean handleGiveDevicePowerStatus(HdmiCecMessage message) { mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPowerStatus( mService.sendCecCommand( HdmiCecMessageBuilder.buildReportPowerStatus( mAddress, message.getSource(), mService.getPowerStatus())); return true; } protected boolean handleMenuRequest(HdmiCecMessage message) { // Always report menu active to receive Remote Control. mService.sendCecCommand(HdmiCecMessageBuilder.buildReportMenuStatus( mService.sendCecCommand( HdmiCecMessageBuilder.buildReportMenuStatus( mAddress, message.getSource(), Constants.MENU_STATE_ACTIVATED)); return true; } Loading @@ -594,8 +619,12 @@ abstract class HdmiCecLocalDevice { } protected boolean handleVendorCommand(HdmiCecMessage message) { if (!mService.invokeVendorCommandListenersOnReceived(mDeviceType, message.getSource(), message.getDestination(), message.getParams(), false)) { if (!mService.invokeVendorCommandListenersOnReceived( mDeviceType, message.getSource(), message.getDestination(), message.getParams(), false)) { // Vendor command listener may not have been registered yet. Respond with // <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later. mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); Loading @@ -607,12 +636,12 @@ abstract class HdmiCecLocalDevice { byte[] params = message.getParams(); int vendorId = HdmiUtils.threeBytesToInt(params); if (vendorId == mService.getVendorId()) { if (!mService.invokeVendorCommandListenersOnReceived(mDeviceType, message.getSource(), message.getDestination(), params, true)) { if (!mService.invokeVendorCommandListenersOnReceived( mDeviceType, message.getSource(), message.getDestination(), params, true)) { mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); } } else if (message.getDestination() != Constants.ADDR_BROADCAST && message.getSource() != Constants.ADDR_UNREGISTERED) { } else if (message.getDestination() != Constants.ADDR_BROADCAST && message.getSource() != Constants.ADDR_UNREGISTERED) { Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>"); mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE); } else { Loading Loading @@ -764,8 +793,8 @@ abstract class HdmiCecLocalDevice { // Remove all actions matched with the given Class type besides |exception|. @ServiceThreadOnly <T extends HdmiCecFeatureAction> void removeActionExcept(final Class<T> clazz, final HdmiCecFeatureAction exception) { <T extends HdmiCecFeatureAction> void removeActionExcept( final Class<T> clazz, final HdmiCecFeatureAction exception) { assertRunOnServiceThread(); Iterator<HdmiCecFeatureAction> iter = mActions.iterator(); while (iter.hasNext()) { Loading Loading @@ -793,8 +822,7 @@ abstract class HdmiCecLocalDevice { } } void setAutoDeviceOff(boolean enabled) { } void setAutoDeviceOff(boolean enabled) {} /** * Called when a hot-plug event issued. Loading @@ -802,8 +830,7 @@ abstract class HdmiCecLocalDevice { * @param portId id of port where a hot-plug event happened * @param connected whether to connected or not on the event */ void onHotplug(int portId, boolean connected) { } void onHotplug(int portId, boolean connected) {} final HdmiControlService getService() { return mService; Loading Loading @@ -886,34 +913,34 @@ abstract class HdmiCecLocalDevice { /** * Called when the system goes to standby mode. * * @param initiatedByCec true if this power sequence is initiated * by the reception the CEC messages like <Standby> * @param standbyAction Intent action that drives the standby process, * either {@link HdmiControlService#STANDBY_SCREEN_OFF} or * {@link HdmiControlService#STANDBY_SHUTDOWN} * @param initiatedByCec true if this power sequence is initiated by the reception the CEC * messages like <Standby> * @param standbyAction Intent action that drives the standby process, either {@link * HdmiControlService#STANDBY_SCREEN_OFF} or {@link HdmiControlService#STANDBY_SHUTDOWN} */ protected void onStandby(boolean initiatedByCec, int standbyAction) {} /** * Disable device. {@code callback} is used to get notified when all pending * actions are completed or timeout is issued. * Disable device. {@code callback} is used to get notified when all pending actions are * completed or timeout is issued. * * @param initiatedByCec true if this sequence is initiated * by the reception the CEC messages like <Standby> * @param initiatedByCec true if this sequence is initiated by the reception the CEC messages * like <Standby> * @param originalCallback callback interface to get notified when all pending actions are * cleared */ protected void disableDevice(boolean initiatedByCec, final PendingActionClearedCallback originalCallback) { mPendingActionClearedCallback = new PendingActionClearedCallback() { protected void disableDevice( boolean initiatedByCec, final PendingActionClearedCallback originalCallback) { mPendingActionClearedCallback = new PendingActionClearedCallback() { @Override public void onCleared(HdmiCecLocalDevice device) { mHandler.removeMessages(MSG_DISABLE_DEVICE_TIMEOUT); originalCallback.onCleared(device); } }; mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_DISABLE_DEVICE_TIMEOUT), DEVICE_CLEANUP_TIMEOUT); mHandler.sendMessageDelayed( Message.obtain(mHandler, MSG_DISABLE_DEVICE_TIMEOUT), DEVICE_CLEANUP_TIMEOUT); } @ServiceThreadOnly Loading Loading @@ -952,8 +979,14 @@ abstract class HdmiCecLocalDevice { int logicalAddress = findKeyReceiverAddress(); if (logicalAddress == Constants.ADDR_INVALID || logicalAddress == mAddress) { // Don't send key event to invalid device or itself. Slog.w(TAG, "Discard key event: " + keyCode + ", pressed:" + isPressed + ", receiverAddr=" + logicalAddress); Slog.w( TAG, "Discard key event: " + keyCode + ", pressed:" + isPressed + ", receiverAddr=" + logicalAddress); } else if (!action.isEmpty()) { action.get(0).processKeyEvent(keyCode, isPressed); } else if (isPressed) { Loading @@ -962,8 +995,8 @@ abstract class HdmiCecLocalDevice { } /** * Returns the logical address of the device which will receive key events via * {@link #sendKeyEvent}. * Returns the logical address of the device which will receive key events via {@link * #sendKeyEvent}. * * @see #sendKeyEvent(int, boolean) */ Loading @@ -973,15 +1006,13 @@ abstract class HdmiCecLocalDevice { } void sendUserControlPressedAndReleased(int targetAddress, int cecKeycode) { mService.sendCecCommand(HdmiCecMessageBuilder.buildUserControlPressed( mAddress, targetAddress, cecKeycode)); mService.sendCecCommand(HdmiCecMessageBuilder.buildUserControlReleased( mAddress, targetAddress)); mService.sendCecCommand( HdmiCecMessageBuilder.buildUserControlPressed(mAddress, targetAddress, cecKeycode)); mService.sendCecCommand( HdmiCecMessageBuilder.buildUserControlReleased(mAddress, targetAddress)); } /** * Dump internal status of HdmiCecLocalDevice object. */ /** Dump internal status of HdmiCecLocalDevice object. */ protected void dump(final IndentingPrintWriter pw) { pw.println("mDeviceType: " + mDeviceType); pw.println("mAddress: " + mAddress); Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +57 −44 File changed.Preview size limit exceeded, changes collapsed. Show changes