Loading services/core/java/com/android/server/hdmi/HdmiCecController.java +1 −1 Original line number Diff line number Diff line Loading @@ -505,7 +505,7 @@ final class HdmiCecController { // Reply <Feature Abort> to initiator (source) for all requests. HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand( sourceAddress, message.getSource(), message.getOpcode(), HdmiCecMessageBuilder.ABORT_REFUSED); HdmiConstants.ABORT_REFUSED); sendCommand(cecMessage, null); } } Loading services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +58 −9 Original line number Diff line number Diff line Loading @@ -26,15 +26,6 @@ import java.util.Arrays; * A helper class to build {@link HdmiCecMessage} from various cec commands. */ public class HdmiCecMessageBuilder { // TODO: move these values to HdmiCec.java once make it internal constant class. // CEC's ABORT reason values. static final int ABORT_UNRECOGNIZED_MODE = 0; static final int ABORT_NOT_IN_CORRECT_MODE = 1; static final int ABORT_CANNOT_PROVIDE_SOURCE = 2; static final int ABORT_INVALID_OPERAND = 3; static final int ABORT_REFUSED = 4; static final int ABORT_UNABLE_TO_DETERMINE = 5; private static final int OSD_NAME_MAX_LENGTH = 13; private HdmiCecMessageBuilder() {} Loading Loading @@ -289,6 +280,64 @@ public class HdmiCecMessageBuilder { return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS); } /** * Build <System Audio Mode Request> command. * * @param src source address of command * @param avr destination address of command, it should be AVR * @param avrPhysicalAddress physical address of AVR * @param enableSystemAudio whether to enable System Audio Mode or not * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildSystemAudioModeRequest(int src, int avr, int avrPhysicalAddress, boolean enableSystemAudio) { if (enableSystemAudio) { return buildCommand(src, avr, HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST, physicalAddressToParam(avrPhysicalAddress)); } else { return buildCommand(src, avr, HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST); } } /** * Build <Give Audio Status> command. * * @param src source address of command * @param dest destination address of command * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildGiveAudioStatus(int src, int dest) { return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_AUDIO_STATUS); } /** * Build <User Control Pressed> command. * * @param src source address of command * @param dest destination address of command * @param uiCommand keycode that user pressed * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildUserControlPressed(int src, int dest, int uiCommand) { byte[] params = new byte[] { (byte) uiCommand }; return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_PRESSED, params); } /** * Build <User Control Released> command. * * @param src source address of command * @param dest destination address of command * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildUserControlReleased(int src, int dest) { return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_RELEASED); } /***** Please ADD new buildXXX() methods above. ******/ /** * Build a {@link HdmiCecMessage} without extra parameter. * Loading services/core/java/com/android/server/hdmi/HdmiConstants.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.hdmi; /** * Defines constants related to HDMI-CEC protocol internal implementation. * If a constant will be used in the public api, it should be located in * {@link android.hardware.hdmi.HdmiCec}. */ final class HdmiConstants { // Constants related to operands of HDMI CEC commands. // Refer to CEC Table 29 in HDMI Spec v1.4b. // [Abort Reason] static final int ABORT_UNRECOGNIZED_MODE = 0; static final int ABORT_NOT_IN_CORRECT_MODE = 1; static final int ABORT_CANNOT_PROVIDE_SOURCE = 2; static final int ABORT_INVALID_OPERAND = 3; static final int ABORT_REFUSED = 4; static final int ABORT_UNABLE_TO_DETERMINE = 5; // [Audio Status] static final int SYSTEM_AUDIO_STATUS_OFF = 0; static final int SYSTEM_AUDIO_STATUS_ON = 1; // Constants related to UI Command Codes. // Refer to CEC Table 30 in HDMI Spec v1.4b. static final int UI_COMMAND_MUTE = 0x43; static final int UI_COMMAND_MUTE_FUNCTION = 0x65; static final int UI_COMMAND_RESTORE_VOLUME_FUNCTION = 0x66; private HdmiConstants() { /* cannot be instantiated */ } } services/core/java/com/android/server/hdmi/HdmiControlService.java +95 −22 Original line number Diff line number Diff line Loading @@ -118,8 +118,11 @@ public final class HdmiControlService extends SystemService { // TODO: it may need to hold lock if it's accessed from others. private boolean mArcStatusEnabled = false; // Whether SystemAudioMode is "On" or not. private boolean mSystemAudioMode; // Handler running on service thread. It's used to run a task in service thread. private Handler mHandler = new Handler(); private final Handler mHandler = new Handler(); public HdmiControlService(Context context) { super(context); Loading Loading @@ -158,6 +161,9 @@ public final class HdmiControlService extends SystemService { } publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService()); // TODO: Read the preference for SystemAudioMode and initialize mSystemAudioMode and // start to monitor the preference value and invoke SystemAudioActionFromTv if needed. } /** Loading Loading @@ -211,35 +217,43 @@ public final class HdmiControlService extends SystemService { * @param action {@link FeatureAction} to remove */ void removeAction(final FeatureAction action) { runOnServiceThread(new Runnable() { @Override public void run() { assertRunOnServiceThread(); mActions.remove(action); } }); } // Remove all actions matched with the given Class type. private <T extends FeatureAction> void removeAction(final Class<T> clazz) { runOnServiceThread(new Runnable() { @Override public void run() { removeActionExcept(clazz, null); } // Remove all actions matched with the given Class type besides |exception|. <T extends FeatureAction> void removeActionExcept(final Class<T> clazz, final FeatureAction exception) { assertRunOnServiceThread(); Iterator<FeatureAction> iter = mActions.iterator(); while (iter.hasNext()) { FeatureAction action = iter.next(); if (action.getClass().equals(clazz)) { if (action != exception && action.getClass().equals(clazz)) { action.clear(); mActions.remove(action); } } } }); } private void runOnServiceThread(Runnable runnable) { mHandler.post(runnable); } void runOnServiceThreadAtFrontOfQueue(Runnable runnable) { mHandler.postAtFrontOfQueue(runnable); } private void assertRunOnServiceThread() { if (Looper.myLooper() != mHandler.getLooper()) { throw new IllegalStateException("Should run on service thread."); } } /** * Change ARC status into the given {@code enabled} status. * Loading Loading @@ -306,8 +320,12 @@ public final class HdmiControlService extends SystemService { case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS: handleReportPhysicalAddress(message); return true; // TODO: Add remaining system information query such as // <Give Device Power Status> and <Request Active Source> handler. case HdmiCec.MESSAGE_SET_SYSTEM_AUDIO_MODE: handleSetSystemAudioMode(message); return true; case HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_STATUS: handleSystemAudioModeStatus(message); return true; default: return dispatchMessageToAction(message); } Loading Loading @@ -413,7 +431,7 @@ public final class HdmiControlService extends SystemService { sendCecCommand( HdmiCecMessageBuilder.buildFeatureAbortCommand(message.getDestination(), message.getSource(), HdmiCec.MESSAGE_GET_MENU_LANGUAGE, HdmiCecMessageBuilder.ABORT_UNRECOGNIZED_MODE)); HdmiConstants.ABORT_UNRECOGNIZED_MODE)); return; } Loading @@ -438,6 +456,33 @@ public final class HdmiControlService extends SystemService { return false; } private void handleSetSystemAudioMode(HdmiCecMessage message) { if (dispatchMessageToAction(message) || !isMessageForSystemAudio(message)) { return; } SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this, message.getDestination(), message.getSource(), HdmiUtils.parseCommandParamSystemAudioStatus(message)); addAndStartAction(action); } private void handleSystemAudioModeStatus(HdmiCecMessage message) { if (!isMessageForSystemAudio(message)) { return; } setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message)); } private boolean isMessageForSystemAudio(HdmiCecMessage message) { if (message.getSource() != HdmiCec.ADDR_AUDIO_SYSTEM || message.getDestination() != HdmiCec.ADDR_TV || getAvrDeviceInfo() == null) { Slog.w(TAG, "Skip abnormal CecMessage: " + message); return false; } return true; } // Record class that monitors the event of the caller of being killed. Used to clean up // the listener list and record list accordingly. private final class HotplugEventListenerRecord implements IBinder.DeathRecipient { Loading Loading @@ -627,4 +672,32 @@ public final class HdmiControlService extends SystemService { Slog.e(TAG, "Invoking callback failed:" + e); } } HdmiCecDeviceInfo getAvrDeviceInfo() { return mCecController.getDeviceInfo(HdmiCec.ADDR_AUDIO_SYSTEM); } void setSystemAudioMode(boolean newMode) { assertRunOnServiceThread(); if (newMode != mSystemAudioMode) { // TODO: Need to set the preference for SystemAudioMode. // TODO: Need to handle the notification of changing the mode and // to identify the notification should be handled in the service or TvSettings. mSystemAudioMode = newMode; } } boolean getSystemAudioMode() { assertRunOnServiceThread(); return mSystemAudioMode; } void setAudioStatus(boolean mute, int volume) { // TODO: Hook up with AudioManager. } boolean isInPresetInstallationMode() { // TODO: Implement this. return false; } } services/core/java/com/android/server/hdmi/HdmiUtils.java 0 → 100644 +74 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.hdmi; import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecMessage; import android.util.Slog; /** * Various utilities to handle HDMI CEC messages. */ final class HdmiUtils { private HdmiUtils() { /* cannot be instantiated */ } /** * Verify if the given address is for the given device type. If not it will throw * {@link IllegalArgumentException}. * * @param logicalAddress the logical address to verify * @param deviceType the device type to check * @throw IllegalArgumentException */ static void verifyAddressType(int logicalAddress, int deviceType) { int actualDeviceType = HdmiCec.getTypeFromAddress(logicalAddress); if (actualDeviceType != deviceType) { throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType + ", Actual:" + actualDeviceType); } } /** * Check if the given CEC message come from the given address. * * @param cmd the CEC message to check * @param expectedAddress the expected source address of the given message * @param tag the tag of caller module (for log message) * @return true if the CEC message comes from the given address */ static boolean checkCommandSource(HdmiCecMessage cmd, int expectedAddress, String tag) { int src = cmd.getSource(); if (src != expectedAddress) { Slog.w(tag, "Invalid source [Expected:" + expectedAddress + ", Actual:" + src + "]"); return false; } return true; } /** * Parse the parameter block of CEC message as [System Audio Status]. * * @param cmd the CEC message to parse * @return true if the given parameter has [ON] value */ static boolean parseCommandParamSystemAudioStatus(HdmiCecMessage cmd) { // TODO: Handle the exception when the length is wrong. return cmd.getParams().length > 0 && cmd.getParams()[0] == HdmiConstants.SYSTEM_AUDIO_STATUS_ON; } } Loading
services/core/java/com/android/server/hdmi/HdmiCecController.java +1 −1 Original line number Diff line number Diff line Loading @@ -505,7 +505,7 @@ final class HdmiCecController { // Reply <Feature Abort> to initiator (source) for all requests. HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand( sourceAddress, message.getSource(), message.getOpcode(), HdmiCecMessageBuilder.ABORT_REFUSED); HdmiConstants.ABORT_REFUSED); sendCommand(cecMessage, null); } } Loading
services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +58 −9 Original line number Diff line number Diff line Loading @@ -26,15 +26,6 @@ import java.util.Arrays; * A helper class to build {@link HdmiCecMessage} from various cec commands. */ public class HdmiCecMessageBuilder { // TODO: move these values to HdmiCec.java once make it internal constant class. // CEC's ABORT reason values. static final int ABORT_UNRECOGNIZED_MODE = 0; static final int ABORT_NOT_IN_CORRECT_MODE = 1; static final int ABORT_CANNOT_PROVIDE_SOURCE = 2; static final int ABORT_INVALID_OPERAND = 3; static final int ABORT_REFUSED = 4; static final int ABORT_UNABLE_TO_DETERMINE = 5; private static final int OSD_NAME_MAX_LENGTH = 13; private HdmiCecMessageBuilder() {} Loading Loading @@ -289,6 +280,64 @@ public class HdmiCecMessageBuilder { return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS); } /** * Build <System Audio Mode Request> command. * * @param src source address of command * @param avr destination address of command, it should be AVR * @param avrPhysicalAddress physical address of AVR * @param enableSystemAudio whether to enable System Audio Mode or not * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildSystemAudioModeRequest(int src, int avr, int avrPhysicalAddress, boolean enableSystemAudio) { if (enableSystemAudio) { return buildCommand(src, avr, HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST, physicalAddressToParam(avrPhysicalAddress)); } else { return buildCommand(src, avr, HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST); } } /** * Build <Give Audio Status> command. * * @param src source address of command * @param dest destination address of command * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildGiveAudioStatus(int src, int dest) { return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_AUDIO_STATUS); } /** * Build <User Control Pressed> command. * * @param src source address of command * @param dest destination address of command * @param uiCommand keycode that user pressed * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildUserControlPressed(int src, int dest, int uiCommand) { byte[] params = new byte[] { (byte) uiCommand }; return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_PRESSED, params); } /** * Build <User Control Released> command. * * @param src source address of command * @param dest destination address of command * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildUserControlReleased(int src, int dest) { return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_RELEASED); } /***** Please ADD new buildXXX() methods above. ******/ /** * Build a {@link HdmiCecMessage} without extra parameter. * Loading
services/core/java/com/android/server/hdmi/HdmiConstants.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.hdmi; /** * Defines constants related to HDMI-CEC protocol internal implementation. * If a constant will be used in the public api, it should be located in * {@link android.hardware.hdmi.HdmiCec}. */ final class HdmiConstants { // Constants related to operands of HDMI CEC commands. // Refer to CEC Table 29 in HDMI Spec v1.4b. // [Abort Reason] static final int ABORT_UNRECOGNIZED_MODE = 0; static final int ABORT_NOT_IN_CORRECT_MODE = 1; static final int ABORT_CANNOT_PROVIDE_SOURCE = 2; static final int ABORT_INVALID_OPERAND = 3; static final int ABORT_REFUSED = 4; static final int ABORT_UNABLE_TO_DETERMINE = 5; // [Audio Status] static final int SYSTEM_AUDIO_STATUS_OFF = 0; static final int SYSTEM_AUDIO_STATUS_ON = 1; // Constants related to UI Command Codes. // Refer to CEC Table 30 in HDMI Spec v1.4b. static final int UI_COMMAND_MUTE = 0x43; static final int UI_COMMAND_MUTE_FUNCTION = 0x65; static final int UI_COMMAND_RESTORE_VOLUME_FUNCTION = 0x66; private HdmiConstants() { /* cannot be instantiated */ } }
services/core/java/com/android/server/hdmi/HdmiControlService.java +95 −22 Original line number Diff line number Diff line Loading @@ -118,8 +118,11 @@ public final class HdmiControlService extends SystemService { // TODO: it may need to hold lock if it's accessed from others. private boolean mArcStatusEnabled = false; // Whether SystemAudioMode is "On" or not. private boolean mSystemAudioMode; // Handler running on service thread. It's used to run a task in service thread. private Handler mHandler = new Handler(); private final Handler mHandler = new Handler(); public HdmiControlService(Context context) { super(context); Loading Loading @@ -158,6 +161,9 @@ public final class HdmiControlService extends SystemService { } publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService()); // TODO: Read the preference for SystemAudioMode and initialize mSystemAudioMode and // start to monitor the preference value and invoke SystemAudioActionFromTv if needed. } /** Loading Loading @@ -211,35 +217,43 @@ public final class HdmiControlService extends SystemService { * @param action {@link FeatureAction} to remove */ void removeAction(final FeatureAction action) { runOnServiceThread(new Runnable() { @Override public void run() { assertRunOnServiceThread(); mActions.remove(action); } }); } // Remove all actions matched with the given Class type. private <T extends FeatureAction> void removeAction(final Class<T> clazz) { runOnServiceThread(new Runnable() { @Override public void run() { removeActionExcept(clazz, null); } // Remove all actions matched with the given Class type besides |exception|. <T extends FeatureAction> void removeActionExcept(final Class<T> clazz, final FeatureAction exception) { assertRunOnServiceThread(); Iterator<FeatureAction> iter = mActions.iterator(); while (iter.hasNext()) { FeatureAction action = iter.next(); if (action.getClass().equals(clazz)) { if (action != exception && action.getClass().equals(clazz)) { action.clear(); mActions.remove(action); } } } }); } private void runOnServiceThread(Runnable runnable) { mHandler.post(runnable); } void runOnServiceThreadAtFrontOfQueue(Runnable runnable) { mHandler.postAtFrontOfQueue(runnable); } private void assertRunOnServiceThread() { if (Looper.myLooper() != mHandler.getLooper()) { throw new IllegalStateException("Should run on service thread."); } } /** * Change ARC status into the given {@code enabled} status. * Loading Loading @@ -306,8 +320,12 @@ public final class HdmiControlService extends SystemService { case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS: handleReportPhysicalAddress(message); return true; // TODO: Add remaining system information query such as // <Give Device Power Status> and <Request Active Source> handler. case HdmiCec.MESSAGE_SET_SYSTEM_AUDIO_MODE: handleSetSystemAudioMode(message); return true; case HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_STATUS: handleSystemAudioModeStatus(message); return true; default: return dispatchMessageToAction(message); } Loading Loading @@ -413,7 +431,7 @@ public final class HdmiControlService extends SystemService { sendCecCommand( HdmiCecMessageBuilder.buildFeatureAbortCommand(message.getDestination(), message.getSource(), HdmiCec.MESSAGE_GET_MENU_LANGUAGE, HdmiCecMessageBuilder.ABORT_UNRECOGNIZED_MODE)); HdmiConstants.ABORT_UNRECOGNIZED_MODE)); return; } Loading @@ -438,6 +456,33 @@ public final class HdmiControlService extends SystemService { return false; } private void handleSetSystemAudioMode(HdmiCecMessage message) { if (dispatchMessageToAction(message) || !isMessageForSystemAudio(message)) { return; } SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this, message.getDestination(), message.getSource(), HdmiUtils.parseCommandParamSystemAudioStatus(message)); addAndStartAction(action); } private void handleSystemAudioModeStatus(HdmiCecMessage message) { if (!isMessageForSystemAudio(message)) { return; } setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message)); } private boolean isMessageForSystemAudio(HdmiCecMessage message) { if (message.getSource() != HdmiCec.ADDR_AUDIO_SYSTEM || message.getDestination() != HdmiCec.ADDR_TV || getAvrDeviceInfo() == null) { Slog.w(TAG, "Skip abnormal CecMessage: " + message); return false; } return true; } // Record class that monitors the event of the caller of being killed. Used to clean up // the listener list and record list accordingly. private final class HotplugEventListenerRecord implements IBinder.DeathRecipient { Loading Loading @@ -627,4 +672,32 @@ public final class HdmiControlService extends SystemService { Slog.e(TAG, "Invoking callback failed:" + e); } } HdmiCecDeviceInfo getAvrDeviceInfo() { return mCecController.getDeviceInfo(HdmiCec.ADDR_AUDIO_SYSTEM); } void setSystemAudioMode(boolean newMode) { assertRunOnServiceThread(); if (newMode != mSystemAudioMode) { // TODO: Need to set the preference for SystemAudioMode. // TODO: Need to handle the notification of changing the mode and // to identify the notification should be handled in the service or TvSettings. mSystemAudioMode = newMode; } } boolean getSystemAudioMode() { assertRunOnServiceThread(); return mSystemAudioMode; } void setAudioStatus(boolean mute, int volume) { // TODO: Hook up with AudioManager. } boolean isInPresetInstallationMode() { // TODO: Implement this. return false; } }
services/core/java/com/android/server/hdmi/HdmiUtils.java 0 → 100644 +74 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.hdmi; import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecMessage; import android.util.Slog; /** * Various utilities to handle HDMI CEC messages. */ final class HdmiUtils { private HdmiUtils() { /* cannot be instantiated */ } /** * Verify if the given address is for the given device type. If not it will throw * {@link IllegalArgumentException}. * * @param logicalAddress the logical address to verify * @param deviceType the device type to check * @throw IllegalArgumentException */ static void verifyAddressType(int logicalAddress, int deviceType) { int actualDeviceType = HdmiCec.getTypeFromAddress(logicalAddress); if (actualDeviceType != deviceType) { throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType + ", Actual:" + actualDeviceType); } } /** * Check if the given CEC message come from the given address. * * @param cmd the CEC message to check * @param expectedAddress the expected source address of the given message * @param tag the tag of caller module (for log message) * @return true if the CEC message comes from the given address */ static boolean checkCommandSource(HdmiCecMessage cmd, int expectedAddress, String tag) { int src = cmd.getSource(); if (src != expectedAddress) { Slog.w(tag, "Invalid source [Expected:" + expectedAddress + ", Actual:" + src + "]"); return false; } return true; } /** * Parse the parameter block of CEC message as [System Audio Status]. * * @param cmd the CEC message to parse * @return true if the given parameter has [ON] value */ static boolean parseCommandParamSystemAudioStatus(HdmiCecMessage cmd) { // TODO: Handle the exception when the length is wrong. return cmd.getParams().length > 0 && cmd.getParams()[0] == HdmiConstants.SYSTEM_AUDIO_STATUS_ON; } }